diff options
990 files changed, 56700 insertions, 98994 deletions
diff --git a/.appveyor.yml b/.appveyor.yml index bd4a7b0ca8..b04e7d9ce8 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -12,6 +12,9 @@ environment: TARGET: release_debug ARCH: amd64 +init: + - ps: if ($env:APPVEYOR_REPO_BRANCH -ne "master") { $env:APPVEYOR_CACHE_SKIP_SAVE = "true" } + cache: - "%SCONS_CACHE_ROOT%" @@ -26,7 +29,7 @@ before_build: - python --version - scons --version - cl.exe - - SET "SCONS_CACHE=%SCONS_CACHE_ROOT%\master" + - set "SCONS_CACHE=%SCONS_CACHE_ROOT%\%APPVEYOR_REPO_BRANCH%" build_script: -- scons platform=%GD_PLATFORM% target=%TARGET% tools=%TOOLS% debug_symbols=no verbose=yes progress=no gdnative_wrapper=yes + - scons platform=%GD_PLATFORM% target=%TARGET% tools=%TOOLS% debug_symbols=no verbose=yes progress=no gdnative_wrapper=yes diff --git a/.gitignore b/.gitignore index 7a836240b8..f43f68f25f 100644 --- a/.gitignore +++ b/.gitignore @@ -343,3 +343,5 @@ platform/windows/godot_res.res # compile commands (https://clang.llvm.org/docs/JSONCompilationDatabase.html) compile_commands.json +# Cppcheck +*.cppcheck diff --git a/.travis.yml b/.travis.yml index 09d8cad07e..b52e40200f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,17 +28,17 @@ matrix: packages: - clang-format-8 - - name: Linux editor (debug, GCC 8, with Mono) - env: PLATFORM=x11 TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-mono-gcc-8 MATRIX_EVAL="CC=gcc-8 && CXX=g++-8" EXTRA_ARGS="module_mono_enabled=yes mono_glue=no warnings=extra werror=yes" + - name: Linux editor (debug, GCC 9, with Mono) + env: PLATFORM=x11 TOOLS=yes TARGET=debug CACHE_NAME=${PLATFORM}-tools-mono-gcc-9 MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" EXTRA_ARGS="module_mono_enabled=yes mono_glue=no warnings=extra werror=yes" os: linux - compiler: gcc-8 + compiler: gcc-9 addons: apt: sources: - mono - ubuntu-toolchain-r-test packages: - - &gcc8_deps [gcc-8, g++-8] + - &gcc9_deps [gcc-9, g++-9] - &linux_deps [libasound2-dev, libgl1-mesa-dev, libglu1-mesa-dev, libx11-dev, libxcursor-dev, libxi-dev, libxinerama-dev, libxrandr-dev] - &linux_mono_deps [mono-devel, msbuild, nuget] @@ -75,16 +75,16 @@ matrix: os: osx compiler: clang - - name: Linux headless editor (release_debug, GCC 8) - env: PLATFORM=server TOOLS=yes TARGET=release_debug CACHE_NAME=${PLATFORM}-tools-gcc-8 MATRIX_EVAL="CC=gcc-8 && CXX=g++-8" EXTRA_ARGS="warnings=extra werror=yes" + - name: Linux headless editor (release_debug, GCC 9) + env: PLATFORM=server TOOLS=yes TARGET=release_debug CACHE_NAME=${PLATFORM}-tools-gcc-9 MATRIX_EVAL="CC=gcc-9 && CXX=g++-9" EXTRA_ARGS="warnings=extra werror=yes" os: linux - compiler: gcc-8 + compiler: gcc-9 addons: apt: sources: - ubuntu-toolchain-r-test packages: - - *gcc8_deps + - *gcc9_deps - *linux_deps - name: Linux export template (release_debug, GCC 5, without 3D support) diff --git a/AUTHORS.md b/AUTHORS.md index ba563eb507..43b4917382 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -52,6 +52,7 @@ name is available. Clay John (clayjohn) Dana Olson (adolson) Daniel J. Ramirez (djrm) + Daniel Rakos (aqnuep) Dharkael (lupoDharkael) Dmitry Koteroff (Krakean) DualMatrix diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt index 5431e2b403..94e182e47e 100644 --- a/COPYRIGHT.txt +++ b/COPYRIGHT.txt @@ -165,12 +165,12 @@ License: Expat and Bitstream Vera Fonts Copyright Files: ./thirdparty/freetype/ Comment: The FreeType Project -Copyright: 1996-2018, David Turner, Robert Wilhelm, and Werner Lemberg. +Copyright: 1996-2019, David Turner, Robert Wilhelm, and Werner Lemberg. License: FTL Files: ./thirdparty/glad/ Comment: glad -Copyright: 2013-2018, David Herberth +Copyright: 2013-2019, David Herberth License: Expat Files: ./thirdparty/jpeg_compressor/ @@ -228,11 +228,6 @@ Comment: WebP codec Copyright: 2010, Google Inc. License: BSD-3-clause -Files: ./thirdparty/libwebsockets/ -Comment: libwebsockets -Copyright: 2010-2018, Andy Green -License: LGPL-2.1+SLE (libwebsockets) - Files: ./thirdparty/mbedtls/ Comment: Mbed TLS Copyright: 2006-2018, Arm Limited (or its affiliates) @@ -250,20 +245,6 @@ Copyright: 1998-2010, Gilles Vollant 2009-2010, Mathias Svensson License: Zlib -Files: ./thirdparty/misc/aes256.cpp - ./thirdparty/misc/aes256.h - ./thirdparty/misc/sha256.c - ./thirdparty/misc/sha256.h -Comment: AES-256 and SHA-256 implementation -Copyright: 2007-2011, Ilya O. Levin -License: ISC - -Files: ./thirdparty/misc/base64.c - ./thirdparty/misc/base64.h -Comment: BASE64 conversion methods -Copyright: Ari Edelkind -License: public-domain - Files: ./thirdparty/misc/clipper.cpp ./thirdparty/misc/clipper.hpp Comment: Clipper @@ -299,12 +280,6 @@ Comment: libjingle Copyright: 2012-2013, Google Inc. License: BSD-3-clause -Files: ./thirdparty/misc/md5.cpp - ./thirdparty/misc/md5.h -Comment: MD5 Message Digest Algorithm -Copyright: 1990, RSA Data Security, Inc. -License: RSA-MD - Files: ./thirdparty/misc/mikktspace.c ./thirdparty/misc/mikktspace.h Comment: Tangent Space Normal Maps implementation @@ -326,7 +301,7 @@ License: BSD-3-clause Files: ./thirdparty/misc/stb_truetype.h ./thirdparty/misc/stb_vorbis.c Comment: stb libraries -Copyright: 2007-2017, Sean Barrett +Copyright: 2007-2019, Sean Barrett License: public-domain Files: ./thirdparty/misc/triangulator.cpp @@ -355,8 +330,8 @@ License: BSD-3-clause Files: ./thirdparty/pcre2/ Comment: PCRE2 -Copyright: 1997-2018, University of Cambridge, - 2009-2018, Zoltan Herczeg +Copyright: 1997-2019, University of Cambridge, + 2009-2019, Zoltan Herczeg License: BSD-3-clause Files: ./thirdparty/pvrtccompressor/ @@ -376,7 +351,7 @@ License: Expat Files: ./thirdparty/tinyexr/ Comment: TinyEXR -Copyright: 2014-2018, Syoyo Fujita +Copyright: 2014-2019, Syoyo Fujita 2002, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC License: BSD-3-clause @@ -386,6 +361,11 @@ Copyright: 2011, Khaled Mamou 2003-2009, Erwin Coumans License: BSD-3-clause +Files: ./thirdparty/wslay/ +Comment: Wslay +Copyright: 2011-2015, Tatsuhiro Tsujikawa +License: Expat + Files: ./thirdparty/xatlas/ Comment: xatlas Copyright: 2018, Jonathan Young @@ -1072,577 +1052,6 @@ License: FTL Robert Wilhelm <robert.wilhelm@freetype.org> Werner Lemberg <werner.lemberg@freetype.org> -License: ISC - Permission to use, copy, modify, and/or distribute this software for any - purpose with or without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies. - . - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -License: LGPL-2.1+SLE (libwebsockets) - Libwebsockets and included programs are provided under the terms of the GNU - Library General Public License (LGPL) 2.1, with the following exceptions: - . - 1) Any reference, whether in these modifications or in the GNU - Library General Public License 2.1, to this License, these terms, the - GNU Lesser Public License, GNU Library General Public License, LGPL, or - any similar reference shall refer to the GNU Library General Public - License 2.1 as modified by these paragraphs 1) through 4). - . - 2) Static linking of programs with the libwebsockets library does not - constitute a derivative work and does not require the author to provide - source code for the program, use the shared libwebsockets libraries, or - link their program against a user-supplied version of libwebsockets. - . - If you link the program to a modified version of libwebsockets, then the - changes to libwebsockets must be provided under the terms of the LGPL in - sections 1, 2, and 4. - . - 3) You do not have to provide a copy of the libwebsockets license with - programs that are linked to the libwebsockets library, nor do you have to - identify the libwebsockets license in your program or documentation as - required by section 6 of the LGPL. - . - However, programs must still identify their use of libwebsockets. The - following example statement can be included in user documentation to - satisfy this requirement: - . - "[program] is based in part on the work of the libwebsockets project - (https://libwebsockets.org)" - . - 4) Some sources included have their own, more liberal licenses, or options - to get original sources with the liberal terms. - . - Original liberal license retained - . - - lib/misc/sha-1.c - 3-clause BSD license retained, link to original - - win32port/zlib - ZLIB license (see zlib.h) - - lib/tls/mbedtls/wrapper - Apache 2.0 (only built if linked against mbedtls) - . - Relicensed to libwebsocket license - . - - lib/misc/base64-decode.c - relicensed to LGPL2.1+SLE, link to original - - lib/misc/daemonize.c - relicensed from Public Domain to LGPL2.1+SLE, - link to original Public Domain version - . - Public Domain (CC-zero) to simplify reuse - . - - test-apps/*.c - - test-apps/*.h - - minimal-examples/* - - lwsws/* - . - ------ end of exceptions - . - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - . - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - . - [This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - . - Preamble - . - The licenses for most software are designed to take away your - freedom to share and change it. By contrast, the GNU General Public - Licenses are intended to guarantee your freedom to share and change - free software--to make sure the software is free for all its users. - . - This license, the Lesser General Public License, applies to some - specially designated software packages--typically libraries--of the - Free Software Foundation and other authors who decide to use it. You - can use it too, but we suggest you first think carefully about whether - this license or the ordinary General Public License is the better - strategy to use in any particular case, based on the explanations below. - . - When we speak of free software, we are referring to freedom of use, - not price. Our General Public Licenses are designed to make sure that - you have the freedom to distribute copies of free software (and charge - for this service if you wish); that you receive source code or can get - it if you want it; that you can change the software and use pieces of - it in new free programs; and that you are informed that you can do - these things. - . - To protect your rights, we need to make restrictions that forbid - distributors to deny you these rights or to ask you to surrender these - rights. These restrictions translate to certain responsibilities for - you if you distribute copies of the library or if you modify it. - . - For example, if you distribute copies of the library, whether gratis - or for a fee, you must give the recipients all the rights that we gave - you. You must make sure that they, too, receive or can get the source - code. If you link other code with the library, you must provide - complete object files to the recipients, so that they can relink them - with the library after making changes to the library and recompiling - it. And you must show them these terms so they know their rights. - . - We protect your rights with a two-step method: (1) we copyright the - library, and (2) we offer you this license, which gives you legal - permission to copy, distribute and/or modify the library. - . - To protect each distributor, we want to make it very clear that - there is no warranty for the free library. Also, if the library is - modified by someone else and passed on, the recipients should know - that what they have is not the original version, so that the original - author's reputation will not be affected by problems that might be - introduced by others. - . - Finally, software patents pose a constant threat to the existence of - any free program. We wish to make sure that a company cannot - effectively restrict the users of a free program by obtaining a - restrictive license from a patent holder. Therefore, we insist that - any patent license obtained for a version of the library must be - consistent with the full freedom of use specified in this license. - . - Most GNU software, including some libraries, is covered by the - ordinary GNU General Public License. This license, the GNU Lesser - General Public License, applies to certain designated libraries, and - is quite different from the ordinary General Public License. We use - this license for certain libraries in order to permit linking those - libraries into non-free programs. - . - When a program is linked with a library, whether statically or using - a shared library, the combination of the two is legally speaking a - combined work, a derivative of the original library. The ordinary - General Public License therefore permits such linking only if the - entire combination fits its criteria of freedom. The Lesser General - Public License permits more lax criteria for linking other code with - the library. - . - We call this license the "Lesser" General Public License because it - does Less to protect the user's freedom than the ordinary General - Public License. It also provides other free software developers Less - of an advantage over competing non-free programs. These disadvantages - are the reason we use the ordinary General Public License for many - libraries. However, the Lesser license provides advantages in certain - special circumstances. - . - For example, on rare occasions, there may be a special need to - encourage the widest possible use of a certain library, so that it becomes - a de-facto standard. To achieve this, non-free programs must be - allowed to use the library. A more frequent case is that a free - library does the same job as widely used non-free libraries. In this - case, there is little to gain by limiting the free library to free - software only, so we use the Lesser General Public License. - . - In other cases, permission to use a particular library in non-free - programs enables a greater number of people to use a large body of - free software. For example, permission to use the GNU C Library in - non-free programs enables many more people to use the whole GNU - operating system, as well as its variant, the GNU/Linux operating - system. - . - Although the Lesser General Public License is Less protective of the - users' freedom, it does ensure that the user of a program that is - linked with the Library has the freedom and the wherewithal to run - that program using a modified version of the Library. - . - The precise terms and conditions for copying, distribution and - modification follow. Pay close attention to the difference between a - "work based on the library" and a "work that uses the library". The - former contains code derived from the library, whereas the latter must - be combined with the library in order to run. - . - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - . - 0. This License Agreement applies to any software library or other - program which contains a notice placed by the copyright holder or - other authorized party saying it may be distributed under the terms of - this Lesser General Public License (also called "this License"). - Each licensee is addressed as "you". - . - A "library" means a collection of software functions and/or data - prepared so as to be conveniently linked with application programs - (which use some of those functions and data) to form executables. - . - The "Library", below, refers to any such software library or work - which has been distributed under these terms. A "work based on the - Library" means either the Library or any derivative work under - copyright law: that is to say, a work containing the Library or a - portion of it, either verbatim or with modifications and/or translated - straightforwardly into another language. (Hereinafter, translation is - included without limitation in the term "modification".) - . - "Source code" for a work means the preferred form of the work for - making modifications to it. For a library, complete source code means - all the source code for all modules it contains, plus any associated - interface definition files, plus the scripts used to control compilation - and installation of the library. - . - Activities other than copying, distribution and modification are not - covered by this License; they are outside its scope. The act of - running a program using the Library is not restricted, and output from - such a program is covered only if its contents constitute a work based - on the Library (independent of the use of the Library in a tool for - writing it). Whether that is true depends on what the Library does - and what the program that uses the Library does. - . - 1. You may copy and distribute verbatim copies of the Library's - complete source code as you receive it, in any medium, provided that - you conspicuously and appropriately publish on each copy an - appropriate copyright notice and disclaimer of warranty; keep intact - all the notices that refer to this License and to the absence of any - warranty; and distribute a copy of this License along with the - Library. - . - You may charge a fee for the physical act of transferring a copy, - and you may at your option offer warranty protection in exchange for a - fee. - . - 2. You may modify your copy or copies of the Library or any portion - of it, thus forming a work based on the Library, and copy and - distribute such modifications or work under the terms of Section 1 - above, provided that you also meet all of these conditions: - . - a) The modified work must itself be a software library. - . - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - . - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - . - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - . - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - . - These requirements apply to the modified work as a whole. If - identifiable sections of that work are not derived from the Library, - and can be reasonably considered independent and separate works in - themselves, then this License, and its terms, do not apply to those - sections when you distribute them as separate works. But when you - distribute the same sections as part of a whole which is a work based - on the Library, the distribution of the whole must be on the terms of - this License, whose permissions for other licensees extend to the - entire whole, and thus to each and every part regardless of who wrote - it. - . - Thus, it is not the intent of this section to claim rights or contest - your rights to work written entirely by you; rather, the intent is to - exercise the right to control the distribution of derivative or - collective works based on the Library. - . - In addition, mere aggregation of another work not based on the Library - with the Library (or with a work based on the Library) on a volume of - a storage or distribution medium does not bring the other work under - the scope of this License. - . - 3. You may opt to apply the terms of the ordinary GNU General Public - License instead of this License to a given copy of the Library. To do - this, you must alter all the notices that refer to this License, so - that they refer to the ordinary GNU General Public License, version 2, - instead of to this License. (If a newer version than version 2 of the - ordinary GNU General Public License has appeared, then you can specify - that version instead if you wish.) Do not make any other change in - these notices. - . - Once this change is made in a given copy, it is irreversible for - that copy, so the ordinary GNU General Public License applies to all - subsequent copies and derivative works made from that copy. - . - This option is useful when you wish to copy part of the code of - the Library into a program that is not a library. - . - 4. You may copy and distribute the Library (or a portion or - derivative of it, under Section 2) in object code or executable form - under the terms of Sections 1 and 2 above provided that you accompany - it with the complete corresponding machine-readable source code, which - must be distributed under the terms of Sections 1 and 2 above on a - medium customarily used for software interchange. - . - If distribution of object code is made by offering access to copy - from a designated place, then offering equivalent access to copy the - source code from the same place satisfies the requirement to - distribute the source code, even though third parties are not - compelled to copy the source along with the object code. - . - 5. A program that contains no derivative of any portion of the - Library, but is designed to work with the Library by being compiled or - linked with it, is called a "work that uses the Library". Such a - work, in isolation, is not a derivative work of the Library, and - therefore falls outside the scope of this License. - . - However, linking a "work that uses the Library" with the Library - creates an executable that is a derivative of the Library (because it - contains portions of the Library), rather than a "work that uses the - library". The executable is therefore covered by this License. - Section 6 states terms for distribution of such executables. - . - When a "work that uses the Library" uses material from a header file - that is part of the Library, the object code for the work may be a - derivative work of the Library even though the source code is not. - Whether this is true is especially significant if the work can be - linked without the Library, or if the work is itself a library. The - threshold for this to be true is not precisely defined by law. - . - If such an object file uses only numerical parameters, data - structure layouts and accessors, and small macros and small inline - functions (ten lines or less in length), then the use of the object - file is unrestricted, regardless of whether it is legally a derivative - work. (Executables containing this object code plus portions of the - Library will still fall under Section 6.) - . - Otherwise, if the work is a derivative of the Library, you may - distribute the object code for the work under the terms of Section 6. - Any executables containing that work also fall under Section 6, - whether or not they are linked directly with the Library itself. - . - 6. As an exception to the Sections above, you may also combine or - link a "work that uses the Library" with the Library to produce a - work containing portions of the Library, and distribute that work - under terms of your choice, provided that the terms permit - modification of the work for the customer's own use and reverse - engineering for debugging such modifications. - . - You must give prominent notice with each copy of the work that the - Library is used in it and that the Library and its use are covered by - this License. You must supply a copy of this License. If the work - during execution displays copyright notices, you must include the - copyright notice for the Library among them, as well as a reference - directing the user to the copy of this License. Also, you must do one - of these things: - . - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - . - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - . - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - . - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - . - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - . - For an executable, the required form of the "work that uses the - Library" must include any data and utility programs needed for - reproducing the executable from it. However, as a special exception, - the materials to be distributed need not include anything that is - normally distributed (in either source or binary form) with the major - components (compiler, kernel, and so on) of the operating system on - which the executable runs, unless that component itself accompanies - the executable. - . - It may happen that this requirement contradicts the license - restrictions of other proprietary libraries that do not normally - accompany the operating system. Such a contradiction means you cannot - use both them and the Library together in an executable that you - distribute. - . - 7. You may place library facilities that are a work based on the - Library side-by-side in a single library together with other library - facilities not covered by this License, and distribute such a combined - library, provided that the separate distribution of the work based on - the Library and of the other library facilities is otherwise - permitted, and provided that you do these two things: - . - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - . - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - . - 8. You may not copy, modify, sublicense, link with, or distribute - the Library except as expressly provided under this License. Any - attempt otherwise to copy, modify, sublicense, link with, or - distribute the Library is void, and will automatically terminate your - rights under this License. However, parties who have received copies, - or rights, from you under this License will not have their licenses - terminated so long as such parties remain in full compliance. - . - 9. You are not required to accept this License, since you have not - signed it. However, nothing else grants you permission to modify or - distribute the Library or its derivative works. These actions are - prohibited by law if you do not accept this License. Therefore, by - modifying or distributing the Library (or any work based on the - Library), you indicate your acceptance of this License to do so, and - all its terms and conditions for copying, distributing or modifying - the Library or works based on it. - . - 10. Each time you redistribute the Library (or any work based on the - Library), the recipient automatically receives a license from the - original licensor to copy, distribute, link with or modify the Library - subject to these terms and conditions. You may not impose any further - restrictions on the recipients' exercise of the rights granted herein. - You are not responsible for enforcing compliance by third parties with - this License. - . - 11. If, as a consequence of a court judgment or allegation of patent - infringement or for any other reason (not limited to patent issues), - conditions are imposed on you (whether by court order, agreement or - otherwise) that contradict the conditions of this License, they do not - excuse you from the conditions of this License. If you cannot - distribute so as to satisfy simultaneously your obligations under this - License and any other pertinent obligations, then as a consequence you - may not distribute the Library at all. For example, if a patent - license would not permit royalty-free redistribution of the Library by - all those who receive copies directly or indirectly through you, then - the only way you could satisfy both it and this License would be to - refrain entirely from distribution of the Library. - . - If any portion of this section is held invalid or unenforceable under any - particular circumstance, the balance of the section is intended to apply, - and the section as a whole is intended to apply in other circumstances. - . - It is not the purpose of this section to induce you to infringe any - patents or other property right claims or to contest validity of any - such claims; this section has the sole purpose of protecting the - integrity of the free software distribution system which is - implemented by public license practices. Many people have made - generous contributions to the wide range of software distributed - through that system in reliance on consistent application of that - system; it is up to the author/donor to decide if he or she is willing - to distribute software through any other system and a licensee cannot - impose that choice. - . - This section is intended to make thoroughly clear what is believed to - be a consequence of the rest of this License. - . - 12. If the distribution and/or use of the Library is restricted in - certain countries either by patents or by copyrighted interfaces, the - original copyright holder who places the Library under this License may add - an explicit geographical distribution limitation excluding those countries, - so that distribution is permitted only in or among countries not thus - excluded. In such case, this License incorporates the limitation as if - written in the body of this License. - . - 13. The Free Software Foundation may publish revised and/or new - versions of the Lesser General Public License from time to time. - Such new versions will be similar in spirit to the present version, - but may differ in detail to address new problems or concerns. - . - Each version is given a distinguishing version number. If the Library - specifies a version number of this License which applies to it and - "any later version", you have the option of following the terms and - conditions either of that version or of any later version published by - the Free Software Foundation. If the Library does not specify a - license version number, you may choose any version ever published by - the Free Software Foundation. - . - 14. If you wish to incorporate parts of the Library into other free - programs whose distribution conditions are incompatible with these, - write to the author to ask for permission. For software which is - copyrighted by the Free Software Foundation, write to the Free - Software Foundation; we sometimes make exceptions for this. Our - decision will be guided by the two goals of preserving the free status - of all derivatives of our free software and of promoting the sharing - and reuse of software generally. - . - NO WARRANTY - . - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO - WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. - EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR - OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY - KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE - LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME - THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - . - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN - WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY - AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU - FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR - CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE - LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING - RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A - FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF - SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - DAMAGES. - . - END OF TERMS AND CONDITIONS - . - How to Apply These Terms to Your New Libraries - . - If you develop a new library, and you want it to be of the greatest - possible use to the public, we recommend making it free software that - everyone can redistribute and change. You can do so by permitting - redistribution under these terms (or, alternatively, under the terms of the - ordinary General Public License). - . - To apply these terms, attach the following notices to the library. It is - safest to attach them to the start of each source file to most effectively - convey the exclusion of warranty; and each file should have at least the - "copyright" line and a pointer to where the full notice is found. - . - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - . - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - . - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - . - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - . - Also add information on how to contact you by electronic and paper mail. - . - You should also get your employer (if you work as a programmer) or your - school, if any, to sign a "copyright disclaimer" for the library, if - necessary. Here is a sample; alter the names: - . - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - . - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - . - That's all there is to it! - License: MPL-2.0 Mozilla Public License Version 2.0 ================================== @@ -2101,24 +1510,6 @@ License: OFL-1.1 DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE. -License: RSA-MD - License to copy and use this software is granted provided that it is - identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" - in all material mentioning or referencing this software or this function. - . - License is also granted to make and use derivative works provided that such - works are identified as "derived from the RSA Data Security, Inc. MD5 - Message-Digest Algorithm" in all material mentioning or referencing the - derived work. - . - RSA Data Security, Inc. makes no representations concerning either the - merchantability of this software or the suitability of this software for - any particular purpose. It is provided "as is" without express or implied - warranty of any kind. - . - These notices must be retained in any copies of any part of this - documentation and/or software. - 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 @@ -41,6 +41,7 @@ generous deed immortalized in the next stable release of Godot Engine. Matthieu Huvé Maxim Karsten Mike King + Nathan Warden Neal Gompa (Conan Kudo) Patrick Aarstad Slobodan Milnovic @@ -49,13 +50,11 @@ generous deed immortalized in the next stable release of Godot Engine. Steve VilliHaukka Xananax - Y8.com Zashi ## Gold donors Andrei - Brandon Waite cheese65536 David Gehrig Ed Morley @@ -66,12 +65,12 @@ generous deed immortalized in the next stable release of Godot Engine. Manuele Finocchiaro Officine Pixel S.n.c. Retro Village + Ronan Zeegers Sofox Zaven Muradyan Alexander Trey Saunders Allen Schade - Andreas Schüle Asher Glick Austen McRae Brian van der Stel @@ -85,8 +84,6 @@ generous deed immortalized in the next stable release of Godot Engine. Jay Horton Jon Smith Jon Woodward - Jorge Bernal - Joshua Lesperance Justo Delgado Baudà Karl Werf Kommentgames @@ -96,11 +93,13 @@ generous deed immortalized in the next stable release of Godot Engine. Mored1984 paul gruenbacher Paul LaMotte + Péter Magyar Rob Messick Ross Esmond Ryan Badour Scott Wadden Sergey + Shawn Yu Svenne Krap Tom Langwaldt William Wold @@ -129,6 +128,7 @@ generous deed immortalized in the next stable release of Godot Engine. Robin Arys Ronnie Ashlock ScottMakesGames + Tad C Johnson Thomas Bjarnelöf Vincent Henderson Wojciech Chojnacki @@ -149,24 +149,25 @@ generous deed immortalized in the next stable release of Godot Engine. D Daniel Daniel Eichler + David White Deadly Lampshade Eric Eric Monson - Ethan Bennis Eugenio Hugo Salgüero Jáñez flesk Francisco Javier Moreno Carracedo gavlig GGGames.org Giles Montgomery - Giovanni Solimeno Guilherme Felipe de C. G. da Silva Heath Hayes Hysteria Idzard Kwadijk Jared White + Jesse Nave Jose Malheiro Joshua Flores + Joshua Lesperance Juan T Chen Juraj Móza Kasper Jeppesen @@ -174,13 +175,13 @@ generous deed immortalized in the next stable release of Godot Engine. Klavdij Voncina Leandro Voltolino Maarten Elings - Malcolm Peralty Markus Fehr Markus Wiesner Martin Eigel Marvin Matt Eunson Matthew Hillier + Max Bulai Max R.R. Collada M H Nick Nikitin @@ -219,14 +220,18 @@ generous deed immortalized in the next stable release of Godot Engine. Alice Robinson Andreas Evers Andreas Krampitz + Andreas Schüle Andrew Peart Anthony Bongiovanni Anthony Staunton Antony K. Jones Arda Erol + Artem Bashev Arthur S. Muszynski + Artistofdeath Aubrey Falconer Avencherus + B A Balázs Batári Bastian Böhm Beliar @@ -242,6 +247,7 @@ generous deed immortalized in the next stable release of Godot Engine. Boyquotes Branwyn Tylwyth Bryan Stevenson + Caleb Dumitry Carwyn Edwards Chris Brown Chris Chapin @@ -250,7 +256,6 @@ generous deed immortalized in the next stable release of Godot Engine. Christian Winter Christoffer Sundbom Christopher Schmitt - Chris Wilson Clay Heaton Cobaltum Collin Shooltz @@ -263,7 +268,9 @@ generous deed immortalized in the next stable release of Godot Engine. David Cravens David May Dimitri Stanojevic + Dominic Cooney Dominik Wetzel + DrevanTonder Duobix Edward Herbert Egon Elbre @@ -272,12 +279,12 @@ generous deed immortalized in the next stable release of Godot Engine. Emanuel Kotzayan Eric Ellingson Eric Martini - Eric McCarthy Eric Williams Evan Rose Felix Kollmann fengjiongmax Flaredown + FuDiggity G3Dev sà rl Gary Hulst Gerrit Großkopf @@ -286,9 +293,9 @@ generous deed immortalized in the next stable release of Godot Engine. Greg Olson Greg P Guldoman + Hal A Heribert Hirth Hiroshi Naruo - HMan Hunter Jones Hylpher ialex32x @@ -310,6 +317,7 @@ generous deed immortalized in the next stable release of Godot Engine. Joel Setterberg Johannes Eichler Johannes Wuensch + Jomei Jackson Jonas Rudlang Jonas Yamazaki Jonathan G @@ -318,21 +326,24 @@ generous deed immortalized in the next stable release of Godot Engine. Jon Bonazza Jon Sully Jose Aleman + Joseph Catrambone Josh 'Cheeseness' Bush Juanfran Juan Negrier Judd + Jueast Julian Murgia Kasier Bald0 KC Chan kickmaniac Kiyohiro Kawamura (kyorohiro) Klagsam + Klassix KR McGinley KsyTek Games Kuan Cheang kycho - Lavik1988 + Leviathan Hunter Levi Lindsey Linus Lind Lundgren Lionel Gaillard @@ -344,6 +355,7 @@ generous deed immortalized in the next stable release of Godot Engine. Malcolm Malik Ahmed Malik Nejer + Marc Urlus Marcus Richter Markus Michael Egger Martin Holas @@ -357,6 +369,7 @@ generous deed immortalized in the next stable release of Godot Engine. Mikael Olsson Mikayla Hutchinson Mike Cunningham + Mitchell J. Wagner mlevin cantu MoM Moritz Laass @@ -365,6 +378,7 @@ generous deed immortalized in the next stable release of Godot Engine. nee Neil Blakey-Milner Nerdforge + Nicholas Niclas Eriksen Nicolás Montaña Nicolas SAN AGUSTIN @@ -372,6 +386,7 @@ generous deed immortalized in the next stable release of Godot Engine. NZ Omar Delarosa Oscar Norlander + Pafka Pan Ip Patrick Forringer Patrick Nafarrete @@ -382,6 +397,7 @@ generous deed immortalized in the next stable release of Godot Engine. Pierre-Igor Berthet Pietro Vertechi Pitsanu Tongprasin + Point08 Poryg Rafa Laguna Rafal Wyszomirski @@ -408,7 +424,7 @@ generous deed immortalized in the next stable release of Godot Engine. Simon Wenner SK Sootstone - Theo Cranmore + Stonepyre Thibault Barbaroux thomas Thomas Bell @@ -434,7 +450,6 @@ generous deed immortalized in the next stable release of Godot Engine. Veodok Victor Vigilant Watch - Viktor Ferenczi waka nya Wayne Haak werner mendizabal @@ -442,6 +457,7 @@ generous deed immortalized in the next stable release of Godot Engine. Will William Hogben Wout Standaert + Yeung Si Xiang ## Bronze donors @@ -69,3 +69,4 @@ for more info. [](https://travis-ci.org/godotengine/godot) [](https://ci.appveyor.com/project/akien-mga/godot) [](https://www.codetriage.com/godotengine/godot) +[](https://hosted.weblate.org/engage/godot-engine/?utm_source=widget) diff --git a/SConstruct b/SConstruct index c2524a4a4d..92dc4d9da2 100644 --- a/SConstruct +++ b/SConstruct @@ -145,7 +145,7 @@ opts.Add(BoolVariable('builtin_libtheora', "Use the built-in libtheora library", opts.Add(BoolVariable('builtin_libvorbis', "Use the built-in libvorbis library", True)) opts.Add(BoolVariable('builtin_libvpx', "Use the built-in libvpx library", True)) opts.Add(BoolVariable('builtin_libwebp', "Use the built-in libwebp library", True)) -opts.Add(BoolVariable('builtin_libwebsockets', "Use the built-in libwebsockets library", True)) +opts.Add(BoolVariable('builtin_wslay', "Use the built-in wslay library", True)) opts.Add(BoolVariable('builtin_mbedtls', "Use the built-in mbedTLS library", True)) opts.Add(BoolVariable('builtin_miniupnpc', "Use the built-in miniupnpc library", True)) opts.Add(BoolVariable('builtin_opus', "Use the built-in Opus library", True)) @@ -422,7 +422,7 @@ if selected_platform in platform_list: if (can_build): config.configure(env) env.module_list.append(x) - + # Get doc classes paths (if present) try: doc_classes = config.get_doc_classes() @@ -522,13 +522,23 @@ if selected_platform in platform_list: env.AppendUnique(CPPDEFINES=[header[1]]) elif selected_platform != "": + if selected_platform == "list": + print("The following platforms are available:\n") + else: + print('Invalid target platform "' + selected_platform + '".') + print("The following platforms were detected:\n") - print("Invalid target platform: " + selected_platform) - print("The following platforms were detected:") for x in platform_list: print("\t" + x) + print("\nPlease run SCons again and select a valid platform: platform=<string>") + if selected_platform == "list": + # Exit early to suppress the rest of the built-in SCons messages + sys.exit(0) + else: + sys.exit(255) + # The following only makes sense when the env is defined, and assumes it is if 'env' in locals(): screen = sys.stdout diff --git a/core/SCsub b/core/SCsub index 166b7083e4..85e5f1b089 100644 --- a/core/SCsub +++ b/core/SCsub @@ -47,15 +47,11 @@ env_thirdparty.disable_warnings() thirdparty_misc_dir = "#thirdparty/misc/" thirdparty_misc_sources = [ # C sources - "base64.c", "fastlz.c", - "sha256.c", "smaz.c", # C++ sources - "aes256.cpp", "hq2x.cpp", - "md5.cpp", "pcg.cpp", "triangulator.cpp", "clipper.cpp", @@ -130,10 +126,10 @@ if env['builtin_zstd']: thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources] env_thirdparty.Prepend(CPPPATH=[thirdparty_zstd_dir, thirdparty_zstd_dir + "common"]) - env_thirdparty.Append(CPPFLAGS="-DZSTD_STATIC_LINKING_ONLY") + env_thirdparty.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"]) env.Prepend(CPPPATH=thirdparty_zstd_dir) # Also needed in main env includes will trigger warnings - env.Append(CPPFLAGS="-DZSTD_STATIC_LINKING_ONLY") + env.Append(CPPDEFINES=["ZSTD_STATIC_LINKING_ONLY"]) env_thirdparty.add_source_files(env.core_sources, thirdparty_zstd_sources) @@ -146,7 +142,7 @@ env.Depends("#core/io/certs_compressed.gen.h", ["#thirdparty/certs/ca-certificat env.CommandNoCache("#core/io/certs_compressed.gen.h", "#thirdparty/certs/ca-certificates.crt", run_in_subprocess(core_builders.make_certs_header)) # Make binders -env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run)) +env.CommandNoCache(['method_bind.gen.inc', 'method_bind_ext.gen.inc', 'method_bind_free_func.gen.inc'], 'make_binders.py', run_in_subprocess(make_binders.run)) # Authors env.Depends('#core/authors.gen.h', "../AUTHORS.md") diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 01419607b3..b41b84ab1e 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -34,13 +34,12 @@ #include "core/io/file_access_encrypted.h" #include "core/io/json.h" #include "core/io/marshalls.h" +#include "core/math/crypto_core.h" #include "core/math/geometry.h" #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/project_settings.h" -#include "thirdparty/misc/base64.h" - /** * Time constants borrowed from loc_time.h */ @@ -1933,13 +1932,15 @@ PoolVector<uint8_t> _File::get_buffer(int p_length) const { ERR_FAIL_COND_V(p_length < 0, data); if (p_length == 0) return data; + Error err = data.resize(p_length); ERR_FAIL_COND_V(err != OK, data); + PoolVector<uint8_t>::Write w = data.write(); int len = f->get_buffer(&w[0], p_length); ERR_FAIL_COND_V(len < 0, PoolVector<uint8_t>()); - w = PoolVector<uint8_t>::Write(); + w.release(); if (len < p_length) data.resize(p_length); @@ -2114,11 +2115,11 @@ void _File::store_var(const Variant &p_var, bool p_full_objects) { PoolVector<uint8_t> buff; buff.resize(len); - PoolVector<uint8_t>::Write w = buff.write(); + PoolVector<uint8_t>::Write w = buff.write(); err = encode_variant(p_var, &w[0], len, p_full_objects); ERR_FAIL_COND(err != OK); - w = PoolVector<uint8_t>::Write(); + w.release(); store_32(len); store_buffer(buff); @@ -2433,15 +2434,8 @@ String _Marshalls::variant_to_base64(const Variant &p_var, bool p_full_objects) err = encode_variant(p_var, &w[0], len, p_full_objects); ERR_FAIL_COND_V(err != OK, ""); - int b64len = len / 3 * 4 + 4 + 1; - PoolVector<uint8_t> b64buff; - b64buff.resize(b64len); - PoolVector<uint8_t>::Write w64 = b64buff.write(); - - int strlen = base64_encode((char *)(&w64[0]), (char *)(&w[0]), len); - //OS::get_singleton()->print("len is %i, vector size is %i\n", b64len, strlen); - w64[strlen] = 0; - String ret = (char *)&w64[0]; + String ret = CryptoCore::b64_encode_str(&w[0], len); + ERR_FAIL_COND_V(ret == "", ret); return ret; }; @@ -2455,7 +2449,8 @@ Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects) buf.resize(strlen / 4 * 3 + 1); PoolVector<uint8_t>::Write w = buf.write(); - int len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen); + size_t len = 0; + ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &len, (unsigned char *)cstr.get_data(), strlen) != OK, Variant()); Variant v; Error err = decode_variant(v, &w[0], len, NULL, p_allow_objects); @@ -2466,18 +2461,8 @@ Variant _Marshalls::base64_to_variant(const String &p_str, bool p_allow_objects) String _Marshalls::raw_to_base64(const PoolVector<uint8_t> &p_arr) { - int len = p_arr.size(); - PoolVector<uint8_t>::Read r = p_arr.read(); - - int b64len = len / 3 * 4 + 4 + 1; - PoolVector<uint8_t> b64buff; - b64buff.resize(b64len); - PoolVector<uint8_t>::Write w64 = b64buff.write(); - - int strlen = base64_encode((char *)(&w64[0]), (char *)(&r[0]), len); - w64[strlen] = 0; - String ret = (char *)&w64[0]; - + String ret = CryptoCore::b64_encode_str(p_arr.read().ptr(), p_arr.size()); + ERR_FAIL_COND_V(ret == "", ret); return ret; }; @@ -2486,35 +2471,24 @@ PoolVector<uint8_t> _Marshalls::base64_to_raw(const String &p_str) { int strlen = p_str.length(); CharString cstr = p_str.ascii(); - int arr_len; + size_t arr_len = 0; PoolVector<uint8_t> buf; { buf.resize(strlen / 4 * 3 + 1); PoolVector<uint8_t>::Write w = buf.write(); - arr_len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen); - }; + ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &arr_len, (unsigned char *)cstr.get_data(), strlen) != OK, PoolVector<uint8_t>()); + } buf.resize(arr_len); - // conversion from PoolVector<uint8_t> to raw array? return buf; }; String _Marshalls::utf8_to_base64(const String &p_str) { CharString cstr = p_str.utf8(); - int len = cstr.length(); - - int b64len = len / 3 * 4 + 4 + 1; - PoolVector<uint8_t> b64buff; - b64buff.resize(b64len); - PoolVector<uint8_t>::Write w64 = b64buff.write(); - - int strlen = base64_encode((char *)(&w64[0]), (char *)cstr.get_data(), len); - - w64[strlen] = 0; - String ret = (char *)&w64[0]; - + String ret = CryptoCore::b64_encode_str((unsigned char *)cstr.get_data(), cstr.length()); + ERR_FAIL_COND_V(ret == "", ret); return ret; }; @@ -2527,7 +2501,8 @@ String _Marshalls::base64_to_utf8(const String &p_str) { buf.resize(strlen / 4 * 3 + 1 + 1); PoolVector<uint8_t>::Write w = buf.write(); - int len = base64_decode((char *)(&w[0]), (char *)cstr.get_data(), strlen); + size_t len = 0; + ERR_FAIL_COND_V(CryptoCore::b64_decode(&w[0], buf.size(), &len, (unsigned char *)cstr.get_data(), strlen) != OK, String()); w[len] = 0; String ret = String::utf8((char *)&w[0]); @@ -2702,6 +2677,8 @@ Variant _Thread::wait_to_finish() { target_method = StringName(); target_instance = NULL; userdata = Variant(); + if (thread) + memdelete(thread); thread = NULL; return r; diff --git a/core/class_db.cpp b/core/class_db.cpp index 2cbf53ba0b..794d990083 100644 --- a/core/class_db.cpp +++ b/core/class_db.cpp @@ -1148,7 +1148,7 @@ Variant::Type ClassDB::get_property_type(const StringName &p_class, const String return Variant::NIL; } -StringName ClassDB::get_property_setter(StringName p_class, const StringName p_property) { +StringName ClassDB::get_property_setter(StringName p_class, const StringName &p_property) { ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; @@ -1165,7 +1165,7 @@ StringName ClassDB::get_property_setter(StringName p_class, const StringName p_p return StringName(); } -StringName ClassDB::get_property_getter(StringName p_class, const StringName p_property) { +StringName ClassDB::get_property_getter(StringName p_class, const StringName &p_property) { ClassInfo *type = classes.getptr(p_class); ClassInfo *check = type; diff --git a/core/class_db.h b/core/class_db.h index 237ae9b806..3d9a695f02 100644 --- a/core/class_db.h +++ b/core/class_db.h @@ -337,8 +337,8 @@ public: static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false); static int get_property_index(const StringName &p_class, const StringName &p_property, bool *r_is_valid = NULL); static Variant::Type get_property_type(const StringName &p_class, const StringName &p_property, bool *r_is_valid = NULL); - static StringName get_property_setter(StringName p_class, const StringName p_property); - static StringName get_property_getter(StringName p_class, const StringName p_property); + static StringName get_property_setter(StringName p_class, const StringName &p_property); + static StringName get_property_getter(StringName p_class, const StringName &p_property); static bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false); static void set_method_flags(StringName p_class, StringName p_method, int p_flags); diff --git a/core/image.cpp b/core/image.cpp index 18a3aae88f..a88395204a 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -495,8 +495,8 @@ void Image::convert(Format p_new_format) { case FORMAT_RGBA8 | (FORMAT_RGB8 << 8): _convert<3, true, 3, false, false, false>(width, height, rptr, wptr); break; } - r = PoolVector<uint8_t>::Read(); - w = PoolVector<uint8_t>::Write(); + r.release(); + w.release(); bool gen_mipmaps = mipmaps; @@ -1091,8 +1091,8 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { } break; } - r = PoolVector<uint8_t>::Read(); - w = PoolVector<uint8_t>::Write(); + r.release(); + w.release(); if (interpolate_mipmaps) { dst._copy_internals_from(dst2); @@ -2394,7 +2394,7 @@ void Image::lock() { void Image::unlock() { - write_lock = PoolVector<uint8_t>::Write(); + write_lock.release(); } Color Image::get_pixelv(const Point2 &p_src) const { diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 7dea749a43..ccee6aeb15 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -30,13 +30,11 @@ #include "file_access_encrypted.h" +#include "core/math/crypto_core.h" #include "core/os/copymem.h" #include "core/print_string.h" #include "core/variant.h" -#include "thirdparty/misc/aes256.h" -#include "thirdparty/misc/md5.h" - #include <stdio.h> #define COMP_MAGIC 0x43454447 @@ -83,25 +81,21 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8 uint32_t blen = p_base->get_buffer(data.ptrw(), ds); ERR_FAIL_COND_V(blen != ds, ERR_FILE_CORRUPT); - aes256_context ctx; - aes256_init(&ctx, key.ptrw()); + CryptoCore::AESContext ctx; + ctx.set_decode_key(key.ptrw(), 256); for (size_t i = 0; i < ds; i += 16) { - aes256_decrypt_ecb(&ctx, &data.write[i]); + ctx.decrypt_ecb(&data.write[i], &data.write[i]); } - aes256_done(&ctx); - data.resize(length); - MD5_CTX md5; - MD5Init(&md5); - MD5Update(&md5, (uint8_t *)data.ptr(), data.size()); - MD5Final(&md5); + unsigned char hash[16]; + ERR_FAIL_COND_V(CryptoCore::md5(data.ptr(), data.size(), hash) != OK, ERR_BUG); ERR_EXPLAIN("The MD5 sum of the decrypted file does not match the expected value. It could be that the file is corrupt, or that the provided decryption key is invalid."); - ERR_FAIL_COND_V(String::md5(md5.digest) != String::md5(md5d), ERR_FILE_CORRUPT); + ERR_FAIL_COND_V(String::md5(hash) != String::md5(md5d), ERR_FILE_CORRUPT); file = p_base; } @@ -140,10 +134,8 @@ void FileAccessEncrypted::close() { len += 16 - (len % 16); } - MD5_CTX md5; - MD5Init(&md5); - MD5Update(&md5, (uint8_t *)data.ptr(), data.size()); - MD5Final(&md5); + unsigned char hash[16]; + ERR_FAIL_COND(CryptoCore::md5(data.ptr(), data.size(), hash) != OK); // Bug? compressed.resize(len); zeromem(compressed.ptrw(), len); @@ -151,20 +143,18 @@ void FileAccessEncrypted::close() { compressed.write[i] = data[i]; } - aes256_context ctx; - aes256_init(&ctx, key.ptrw()); + CryptoCore::AESContext ctx; + ctx.set_encode_key(key.ptrw(), 256); for (size_t i = 0; i < len; i += 16) { - aes256_encrypt_ecb(&ctx, &compressed.write[i]); + ctx.encrypt_ecb(&compressed.write[i], &compressed.write[i]); } - aes256_done(&ctx); - file->store_32(COMP_MAGIC); file->store_32(mode); - file->store_buffer(md5.digest, 16); + file->store_buffer(hash, 16); file->store_64(data.size()); file->store_buffer(compressed.ptr(), compressed.size()); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index d38d09c6bb..ca66b34e17 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -144,7 +144,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path) { uint32_t magic = f->get_32(); if (magic != 0x43504447) { - //maybe at he end.... self contained exe + //maybe at the end.... self contained exe f->seek_end(); f->seek(f->get_position() - 4); magic = f->get_32(); diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 17a3f52a65..dc5581ea01 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -558,8 +558,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int w[i] = buf[i]; } - - w = PoolVector<uint8_t>::Write(); } r_variant = data; @@ -590,8 +588,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int w[i] = decode_uint32(&buf[i * 4]); } - - w = PoolVector<int>::Write(); } r_variant = Variant(data); if (r_len) { @@ -618,8 +614,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int w[i] = decode_float(&buf[i * 4]); } - - w = PoolVector<float>::Write(); } r_variant = data; diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 688dfc21e5..861e34e415 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -410,7 +410,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { PoolVector<uint8_t>::Write w = array.write(); f->get_buffer(w.ptr(), len); _advance_padding(len); - w = PoolVector<uint8_t>::Write(); + w.release(); r_v = array; } break; @@ -432,7 +432,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { } #endif - w = PoolVector<int>::Write(); + w.release(); r_v = array; } break; case VARIANT_REAL_ARRAY: { @@ -454,7 +454,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { #endif - w = PoolVector<real_t>::Write(); + w.release(); r_v = array; } break; case VARIANT_STRING_ARRAY: { @@ -465,7 +465,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { PoolVector<String>::Write w = array.write(); for (uint32_t i = 0; i < len; i++) w[i] = get_unicode_string(); - w = PoolVector<String>::Write(); + w.release(); r_v = array; } break; @@ -493,7 +493,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { ERR_EXPLAIN("Vector2 size is NOT 8!"); ERR_FAIL_V(ERR_UNAVAILABLE); } - w = PoolVector<Vector2>::Write(); + w.release(); r_v = array; } break; @@ -521,7 +521,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { ERR_EXPLAIN("Vector3 size is NOT 12!"); ERR_FAIL_V(ERR_UNAVAILABLE); } - w = PoolVector<Vector3>::Write(); + w.release(); r_v = array; } break; @@ -549,7 +549,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { ERR_EXPLAIN("Color size is NOT 16!"); ERR_FAIL_V(ERR_UNAVAILABLE); } - w = PoolVector<Color>::Write(); + w.release(); r_v = array; } break; #ifndef DISABLE_DEPRECATED @@ -584,7 +584,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { PoolVector<uint8_t>::Write w = imgdata.write(); f->get_buffer(w.ptr(), datalen); _advance_padding(datalen); - w = PoolVector<uint8_t>::Write(); + w.release(); Ref<Image> image; image.instance(); @@ -597,7 +597,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) { data.resize(f->get_32()); PoolVector<uint8_t>::Write w = data.write(); f->get_buffer(w.ptr(), data.size()); - w = PoolVector<uint8_t>::Write(); + w.release(); Ref<Image> image; diff --git a/core/io/stream_peer.cpp b/core/io/stream_peer.cpp index 6ad24a5f3a..acf72dbba5 100644 --- a/core/io/stream_peer.cpp +++ b/core/io/stream_peer.cpp @@ -79,7 +79,7 @@ Array StreamPeer::_get_data(int p_bytes) { PoolVector<uint8_t>::Write w = data.write(); Error err = get_data(&w[0], p_bytes); - w = PoolVector<uint8_t>::Write(); + w.release(); ret.push_back(err); ret.push_back(data); return ret; @@ -101,7 +101,7 @@ Array StreamPeer::_get_partial_data(int p_bytes) { PoolVector<uint8_t>::Write w = data.write(); int received; Error err = get_partial_data(&w[0], p_bytes, received); - w = PoolVector<uint8_t>::Write(); + w.release(); if (err != OK) { data.resize(0); diff --git a/core/io/stream_peer_ssl.cpp b/core/io/stream_peer_ssl.cpp index 254ae84bf5..ccce48ccd7 100644 --- a/core/io/stream_peer_ssl.cpp +++ b/core/io/stream_peer_ssl.cpp @@ -39,7 +39,9 @@ StreamPeerSSL *(*StreamPeerSSL::_create)() = NULL; StreamPeerSSL *StreamPeerSSL::create() { - return _create(); + if (_create) + return _create(); + return NULL; } StreamPeerSSL::LoadCertsFromMemory StreamPeerSSL::load_certs_func = NULL; diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index bcdae343b8..310bb12bc0 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -30,6 +30,8 @@ #include "stream_peer_tcp.h" +#include "core/project_settings.h" + Error StreamPeerTCP::_poll_connection() { ERR_FAIL_COND_V(status != STATUS_CONNECTING || !_sock.is_valid() || !_sock->is_open(), FAILED); @@ -40,6 +42,12 @@ Error StreamPeerTCP::_poll_connection() { status = STATUS_CONNECTED; return OK; } else if (err == ERR_BUSY) { + // Check for connect timeout + if (OS::get_singleton()->get_ticks_msec() > timeout) { + disconnect_from_host(); + status = STATUS_ERROR; + return ERR_CONNECTION_ERROR; + } // Still trying to connect return OK; } @@ -54,6 +62,7 @@ void StreamPeerTCP::accept_socket(Ref<NetSocket> p_sock, IP_Address p_host, uint _sock = p_sock; _sock->set_blocking_enabled(false); + timeout = OS::get_singleton()->get_ticks_msec() + (((uint64_t)GLOBAL_GET("network/limits/tcp/connect_timeout_seconds")) * 1000); status = STATUS_CONNECTING; peer_host = p_host; @@ -74,6 +83,7 @@ Error StreamPeerTCP::connect_to_host(const IP_Address &p_host, uint16_t p_port) _sock->set_blocking_enabled(false); + timeout = OS::get_singleton()->get_ticks_msec() + (((uint64_t)GLOBAL_GET("network/limits/tcp/connect_timeout_seconds")) * 1000); err = _sock->connect_to_host(p_host, p_port); if (err == OK) { @@ -217,6 +227,11 @@ Error StreamPeerTCP::read(uint8_t *p_buffer, int p_bytes, int &r_received, bool to_read -= read; total_read += read; + + if (!p_block) { + r_received = total_read; + return OK; + } } } @@ -276,6 +291,7 @@ void StreamPeerTCP::disconnect_from_host() { if (_sock.is_valid() && _sock->is_open()) _sock->close(); + timeout = 0; status = STATUS_NONE; peer_host = IP_Address(); peer_port = 0; @@ -351,6 +367,7 @@ void StreamPeerTCP::_bind_methods() { StreamPeerTCP::StreamPeerTCP() : _sock(Ref<NetSocket>(NetSocket::create())), + timeout(0), status(STATUS_NONE), peer_port(0) { } diff --git a/core/io/stream_peer_tcp.h b/core/io/stream_peer_tcp.h index 1ca39375aa..321fb3a6c8 100644 --- a/core/io/stream_peer_tcp.h +++ b/core/io/stream_peer_tcp.h @@ -52,6 +52,7 @@ public: protected: Ref<NetSocket> _sock; + uint64_t timeout; Status status; IP_Address peer_host; uint16_t peer_port; diff --git a/core/io/tcp_server.cpp b/core/io/tcp_server.cpp index be87f47d50..a2756164bc 100644 --- a/core/io/tcp_server.cpp +++ b/core/io/tcp_server.cpp @@ -34,6 +34,7 @@ void TCP_Server::_bind_methods() { ClassDB::bind_method(D_METHOD("listen", "port", "bind_address"), &TCP_Server::listen, DEFVAL("*")); ClassDB::bind_method(D_METHOD("is_connection_available"), &TCP_Server::is_connection_available); + ClassDB::bind_method(D_METHOD("is_listening"), &TCP_Server::is_listening); ClassDB::bind_method(D_METHOD("take_connection"), &TCP_Server::take_connection); ClassDB::bind_method(D_METHOD("stop"), &TCP_Server::stop); } @@ -75,6 +76,12 @@ Error TCP_Server::listen(uint16_t p_port, const IP_Address &p_bind_address) { return OK; } +bool TCP_Server::is_listening() const { + ERR_FAIL_COND_V(!_sock.is_valid(), false); + + return _sock->is_open(); +} + bool TCP_Server::is_connection_available() const { ERR_FAIL_COND_V(!_sock.is_valid(), false); diff --git a/core/io/tcp_server.h b/core/io/tcp_server.h index 538db175ad..ef64044599 100644 --- a/core/io/tcp_server.h +++ b/core/io/tcp_server.h @@ -50,6 +50,7 @@ protected: public: Error listen(uint16_t p_port, const IP_Address &p_bind_address = IP_Address("*")); + bool is_listening() const; bool is_connection_available() const; Ref<StreamPeerTCP> take_connection(); diff --git a/core/make_binders.py b/core/make_binders.py index 5c1c66cab6..24901c42a1 100644 --- a/core/make_binders.py +++ b/core/make_binders.py @@ -191,6 +191,96 @@ MethodBind* create_method_bind($ifret R$ $ifnoret void$ (T::*p_method)($arg, P@$ """ +template_typed_free_func = """ +#ifdef TYPED_METHOD_BIND +template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$> +class FunctionBind$argc$$ifret R$$ifconst C$ : public MethodBind { +public: + + $ifret R$ $ifnoret void$ (*method) ($ifconst const$ T *$ifargs , $$arg, P@$); +#ifdef DEBUG_METHODS_ENABLED + virtual Variant::Type _gen_argument_type(int p_arg) const { return _get_argument_type(p_arg); } + virtual GodotTypeInfo::Metadata get_argument_meta(int p_arg) const { + $ifret if (p_arg==-1) return GetTypeInfo<R>::METADATA;$ + $arg if (p_arg==(@-1)) return GetTypeInfo<P@>::METADATA; + $ + return GodotTypeInfo::METADATA_NONE; + } + Variant::Type _get_argument_type(int p_argument) const { + $ifret if (p_argument==-1) return (Variant::Type)GetTypeInfo<R>::VARIANT_TYPE;$ + $arg if (p_argument==(@-1)) return (Variant::Type)GetTypeInfo<P@>::VARIANT_TYPE; + $ + return Variant::NIL; + } + virtual PropertyInfo _gen_argument_type_info(int p_argument) const { + $ifret if (p_argument==-1) return GetTypeInfo<R>::get_class_info();$ + $arg if (p_argument==(@-1)) return GetTypeInfo<P@>::get_class_info(); + $ + return PropertyInfo(); + } +#endif + virtual String get_instance_class() const { + return T::get_class_static(); + } + + virtual Variant call(Object* p_object,const Variant** p_args,int p_arg_count, Variant::CallError& r_error) { + + T *instance=Object::cast_to<T>(p_object); + r_error.error=Variant::CallError::CALL_OK; +#ifdef DEBUG_METHODS_ENABLED + + ERR_FAIL_COND_V(!instance,Variant()); + if (p_arg_count>get_argument_count()) { + r_error.error=Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.argument=get_argument_count(); + return Variant(); + + } + if (p_arg_count<(get_argument_count()-get_default_argument_count())) { + + r_error.error=Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.argument=get_argument_count()-get_default_argument_count(); + return Variant(); + } + $arg CHECK_ARG(@); + $ +#endif + $ifret Variant ret = $(method)(instance$ifargs , $$arg, _VC(@)$); + $ifret return Variant(ret);$ + $ifnoret return Variant();$ + } + +#ifdef PTRCALL_ENABLED + virtual void ptrcall(Object*p_object,const void** p_args,void *r_ret) { + + T *instance=Object::cast_to<T>(p_object); + $ifret PtrToArg<R>::encode( $ (method)(instance$ifargs , $$arg, PtrToArg<P@>::convert(p_args[@-1])$) $ifret ,r_ret)$ ; + } +#endif + FunctionBind$argc$$ifret R$$ifconst C$ () { +#ifdef DEBUG_METHODS_ENABLED + _set_const($ifconst true$$ifnoconst false$); + _generate_argument_types($argc$); +#else + set_argument_count($argc$); +#endif + + $ifret _set_returns(true); $ + }; +}; + +template<class T $ifret ,class R$ $ifargs ,$ $arg, class P@$> +MethodBind* create_method_bind($ifret R$ $ifnoret void$ (*p_method)($ifconst const$ T *$ifargs , $$arg, P@$) ) { + + FunctionBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$> * a = memnew( (FunctionBind$argc$$ifret R$$ifconst C$<T $ifret ,R$ $ifargs ,$ $arg, P@$>) ); + a->method=p_method; + return a; +} +#endif +""" + + + def make_version(template, nargs, argmax, const, ret): intext = template @@ -259,6 +349,9 @@ def run(target, source, env): versions_ext = 6 text = "" text_ext = "" + text_free_func = "#ifndef METHOD_BIND_FREE_FUNC_H\n#define METHOD_BIND_FREE_FUNC_H\n" + text_free_func += "\n//including this header file allows method binding to use free functions\n" + text_free_func += "//note that the free function must have a pointer to an instance of the class as its first parameter\n" for i in range(0, versions + 1): @@ -276,12 +369,22 @@ def run(target, source, env): else: text += t + text_free_func += make_version(template_typed_free_func, i, versions, False, False) + text_free_func += make_version(template_typed_free_func, i, versions, False, True) + text_free_func += make_version(template_typed_free_func, i, versions, True, False) + text_free_func += make_version(template_typed_free_func, i, versions, True, True) + + text_free_func += "#endif" + with open(target[0], "w") as f: f.write(text) with open(target[1], "w") as f: f.write(text_ext) + with open(target[2], "w") as f: + f.write(text_free_func) + if __name__ == '__main__': from platform_methods import subprocess_main diff --git a/core/math/SCsub b/core/math/SCsub index 1c5f954470..0995298a4b 100644 --- a/core/math/SCsub +++ b/core/math/SCsub @@ -2,4 +2,37 @@ Import('env') -env.add_source_files(env.core_sources, "*.cpp") +env_math = env.Clone() # Maybe make one specific for crypto? + +is_builtin = env["builtin_mbedtls"] +has_module = env["module_mbedtls_enabled"] + +if is_builtin or not has_module: + # Use our headers for builtin or if the module is not going to be compiled. + # We decided not to depend on system mbedtls just for these few files that can + # be easily extracted. + env_math.Prepend(CPPPATH=["#thirdparty/mbedtls/include"]) + +# MbedTLS core functions (for CryptoCore). +# If the mbedtls module is compiled we don't need to add the .c files with our +# custom config since they will be built by the module itself. +# Only if the module is not enabled, we must compile here the required sources +# to make a "light" build with only the necessary mbedtls files. +if not has_module: + env_thirdparty = env_math.Clone() + env_thirdparty.disable_warnings() + # Custom config file + env_thirdparty.Append(CPPDEFINES=[('MBEDTLS_CONFIG_FILE', '\\"thirdparty/mbedtls/include/godot_core_mbedtls_config.h\\"')]) + thirdparty_mbedtls_dir = "#thirdparty/mbedtls/library/" + thirdparty_mbedtls_sources = [ + "aes.c", + "base64.c", + "md5.c", + "sha1.c", + "sha256.c", + "godot_core_mbedtls_platform.c" + ] + thirdparty_mbedtls_sources = [thirdparty_mbedtls_dir + file for file in thirdparty_mbedtls_sources] + env_thirdparty.add_source_files(env.core_sources, thirdparty_mbedtls_sources) + +env_math.add_source_files(env.core_sources, "*.cpp") diff --git a/core/math/basis.cpp b/core/math/basis.cpp index 1540bc8fe1..400f342018 100644 --- a/core/math/basis.cpp +++ b/core/math/basis.cpp @@ -852,7 +852,7 @@ void Basis::set_quat_scale(const Quat &p_quat, const Vector3 &p_scale) { rotate(p_quat); } -void Basis::set_diagonal(const Vector3 p_diag) { +void Basis::set_diagonal(const Vector3 &p_diag) { elements[0][0] = p_diag.x; elements[0][1] = 0; elements[0][2] = 0; diff --git a/core/math/basis.h b/core/math/basis.h index 75037c2c52..d3adad3d90 100644 --- a/core/math/basis.h +++ b/core/math/basis.h @@ -153,7 +153,7 @@ public: int get_orthogonal_index() const; void set_orthogonal_index(int p_index); - void set_diagonal(const Vector3 p_diag); + void set_diagonal(const Vector3 &p_diag); bool is_orthogonal() const; bool is_diagonal() const; diff --git a/core/math/crypto_core.cpp b/core/math/crypto_core.cpp new file mode 100644 index 0000000000..d7ba54e469 --- /dev/null +++ b/core/math/crypto_core.cpp @@ -0,0 +1,157 @@ +/*************************************************************************/ +/* crypto_core.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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 "crypto_core.h" + +#include <mbedtls/aes.h> +#include <mbedtls/base64.h> +#include <mbedtls/md5.h> +#include <mbedtls/sha1.h> +#include <mbedtls/sha256.h> + +// MD5 +CryptoCore::MD5Context::MD5Context() { + ctx = memalloc(sizeof(mbedtls_md5_context)); + mbedtls_md5_init((mbedtls_md5_context *)ctx); +} + +CryptoCore::MD5Context::~MD5Context() { + mbedtls_md5_free((mbedtls_md5_context *)ctx); + memfree((mbedtls_md5_context *)ctx); +} + +Error CryptoCore::MD5Context::start() { + int ret = mbedtls_md5_starts_ret((mbedtls_md5_context *)ctx); + return ret ? FAILED : OK; +} + +Error CryptoCore::MD5Context::update(uint8_t *p_src, size_t p_len) { + int ret = mbedtls_md5_update_ret((mbedtls_md5_context *)ctx, p_src, p_len); + return ret ? FAILED : OK; +} + +Error CryptoCore::MD5Context::finish(unsigned char r_hash[16]) { + int ret = mbedtls_md5_finish_ret((mbedtls_md5_context *)ctx, r_hash); + return ret ? FAILED : OK; +} + +// SHA256 +CryptoCore::SHA256Context::SHA256Context() { + ctx = memalloc(sizeof(mbedtls_sha256_context)); + mbedtls_sha256_init((mbedtls_sha256_context *)ctx); +} + +CryptoCore::SHA256Context::~SHA256Context() { + mbedtls_sha256_free((mbedtls_sha256_context *)ctx); + memfree((mbedtls_sha256_context *)ctx); +} + +Error CryptoCore::SHA256Context::start() { + int ret = mbedtls_sha256_starts_ret((mbedtls_sha256_context *)ctx, 0); + return ret ? FAILED : OK; +} + +Error CryptoCore::SHA256Context::update(uint8_t *p_src, size_t p_len) { + int ret = mbedtls_sha256_update_ret((mbedtls_sha256_context *)ctx, p_src, p_len); + return ret ? FAILED : OK; +} + +Error CryptoCore::SHA256Context::finish(unsigned char r_hash[16]) { + int ret = mbedtls_sha256_finish_ret((mbedtls_sha256_context *)ctx, r_hash); + return ret ? FAILED : OK; +} + +// AES256 +CryptoCore::AESContext::AESContext() { + ctx = memalloc(sizeof(mbedtls_aes_context)); + mbedtls_aes_init((mbedtls_aes_context *)ctx); +} + +CryptoCore::AESContext::~AESContext() { + mbedtls_aes_free((mbedtls_aes_context *)ctx); + memfree((mbedtls_aes_context *)ctx); +} + +Error CryptoCore::AESContext::set_encode_key(const uint8_t *p_key, size_t p_bits) { + int ret = mbedtls_aes_setkey_enc((mbedtls_aes_context *)ctx, p_key, p_bits); + return ret ? FAILED : OK; +} + +Error CryptoCore::AESContext::set_decode_key(const uint8_t *p_key, size_t p_bits) { + int ret = mbedtls_aes_setkey_dec((mbedtls_aes_context *)ctx, p_key, p_bits); + return ret ? FAILED : OK; +} + +Error CryptoCore::AESContext::encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) { + int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_ENCRYPT, p_src, r_dst); + return ret ? FAILED : OK; +} + +Error CryptoCore::AESContext::decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]) { + int ret = mbedtls_aes_crypt_ecb((mbedtls_aes_context *)ctx, MBEDTLS_AES_DECRYPT, p_src, r_dst); + return ret ? FAILED : OK; +} + +// CryptoCore +String CryptoCore::b64_encode_str(const uint8_t *p_src, int p_src_len) { + int b64len = p_src_len / 3 * 4 + 4 + 1; + PoolVector<uint8_t> b64buff; + b64buff.resize(b64len); + PoolVector<uint8_t>::Write w64 = b64buff.write(); + size_t strlen = 0; + int ret = b64_encode(&w64[0], b64len, &strlen, p_src, p_src_len); + w64[strlen] = 0; + return ret ? String() : (const char *)&w64[0]; +} + +Error CryptoCore::b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { + int ret = mbedtls_base64_encode(r_dst, p_dst_len, r_len, p_src, p_src_len); + return ret ? FAILED : OK; +} + +Error CryptoCore::b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len) { + int ret = mbedtls_base64_decode(r_dst, p_dst_len, r_len, p_src, p_src_len); + return ret ? FAILED : OK; +} + +Error CryptoCore::md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]) { + int ret = mbedtls_md5_ret(p_src, p_src_len, r_hash); + return ret ? FAILED : OK; +} + +Error CryptoCore::sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]) { + int ret = mbedtls_sha1_ret(p_src, p_src_len, r_hash); + return ret ? FAILED : OK; +} + +Error CryptoCore::sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]) { + int ret = mbedtls_sha256_ret(p_src, p_src_len, r_hash, 0); + return ret ? FAILED : OK; +} diff --git a/core/math/crypto_core.h b/core/math/crypto_core.h new file mode 100644 index 0000000000..e28cb5a792 --- /dev/null +++ b/core/math/crypto_core.h @@ -0,0 +1,90 @@ +/*************************************************************************/ +/* crypto_core.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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 CRYPTO_CORE_H +#define CRYPTO_CORE_H + +#include "core/reference.h" + +class CryptoCore { + +public: + class MD5Context { + + private: + void *ctx; // To include, or not to include... + + public: + MD5Context(); + ~MD5Context(); + + Error start(); + Error update(uint8_t *p_src, size_t p_len); + Error finish(unsigned char r_hash[16]); + }; + + class SHA256Context { + + private: + void *ctx; // To include, or not to include... + + public: + SHA256Context(); + ~SHA256Context(); + + Error start(); + Error update(uint8_t *p_src, size_t p_len); + Error finish(unsigned char r_hash[16]); + }; + + class AESContext { + + private: + void *ctx; // To include, or not to include... + + public: + AESContext(); + ~AESContext(); + + Error set_encode_key(const uint8_t *p_key, size_t p_bits); + Error set_decode_key(const uint8_t *p_key, size_t p_bits); + Error encrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]); + Error decrypt_ecb(const uint8_t p_src[16], uint8_t r_dst[16]); + }; + + static String b64_encode_str(const uint8_t *p_src, int p_src_len); + static Error b64_encode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); + static Error b64_decode(uint8_t *r_dst, int p_dst_len, size_t *r_len, const uint8_t *p_src, int p_src_len); + + static Error md5(const uint8_t *p_src, int p_src_len, unsigned char r_hash[16]); + static Error sha1(const uint8_t *p_src, int p_src_len, unsigned char r_hash[20]); + static Error sha256(const uint8_t *p_src, int p_src_len, unsigned char r_hash[32]); +}; +#endif // CRYPTO_CORE_H diff --git a/core/math/geometry.h b/core/math/geometry.h index 0e144e491f..e4f3ff799e 100644 --- a/core/math/geometry.h +++ b/core/math/geometry.h @@ -455,16 +455,15 @@ public: Vector3 p = p_point - p_segment[0]; Vector3 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; if (d <= 0.0) return p_segment[0]; // before first point - else if (d >= l) + else if (d >= 1.0) return p_segment[1]; // after first point else return p_segment[0] + n * d; // inside @@ -474,12 +473,11 @@ public: Vector3 p = p_point - p_segment[0]; Vector3 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; return p_segment[0] + n * d; // inside } @@ -488,16 +486,15 @@ public: Vector2 p = p_point - p_segment[0]; Vector2 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; if (d <= 0.0) return p_segment[0]; // before first point - else if (d >= l) + else if (d >= 1.0) return p_segment[1]; // after first point else return p_segment[0] + n * d; // inside @@ -521,12 +518,11 @@ public: Vector2 p = p_point - p_segment[0]; Vector2 n = p_segment[1] - p_segment[0]; - real_t l = n.length(); - if (l < 1e-10) + real_t l2 = n.length_squared(); + if (l2 < 1e-20) return p_segment[0]; // both points are the same, just give any - n /= l; - real_t d = n.dot(p); + real_t d = n.dot(p) / l2; return p_segment[0] + n * d; // inside } diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp index 83784a1fa7..546981be44 100644 --- a/core/math/triangle_mesh.cpp +++ b/core/math/triangle_mesh.cpp @@ -182,7 +182,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) { int max_alloc = fc; _create_bvh(bw.ptr(), bwp.ptr(), 0, fc, 1, max_depth, max_alloc); - bw = PoolVector<BVH>::Write(); //clearup + bw.release(); //clearup bvh.resize(max_alloc); //resize back valid = true; @@ -751,7 +751,7 @@ PoolVector<Face3> TriangleMesh::get_faces() const { } } - w = PoolVector<Face3>::Write(); + w.release(); return faces; } diff --git a/core/math/vector3.h b/core/math/vector3.h index 811a207138..45bdfee487 100644 --- a/core/math/vector3.h +++ b/core/math/vector3.h @@ -219,10 +219,6 @@ Vector3 Vector3::linear_interpolate(const Vector3 &p_b, real_t p_t) const { } Vector3 Vector3::slerp(const Vector3 &p_b, real_t p_t) const { -#ifdef MATH_CHECKS - ERR_FAIL_COND_V(!is_normalized(), Vector3()); -#endif - real_t theta = angle_to(p_b); return rotated(cross(p_b).normalized(), theta * p_t); } diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp index b5580b5c6e..7509050b2b 100644 --- a/core/os/file_access.cpp +++ b/core/os/file_access.cpp @@ -32,12 +32,10 @@ #include "core/io/file_access_pack.h" #include "core/io/marshalls.h" +#include "core/math/crypto_core.h" #include "core/os/os.h" #include "core/project_settings.h" -#include "thirdparty/misc/md5.h" -#include "thirdparty/misc/sha256.h" - FileAccess::CreateFunc FileAccess::create_func[ACCESS_MAX] = { 0, 0 }; FileAccess::FileCloseFailNotify FileAccess::close_fail_notify = NULL; @@ -637,8 +635,8 @@ String FileAccess::get_md5(const String &p_file) { if (!f) return String(); - MD5_CTX md5; - MD5Init(&md5); + CryptoCore::MD5Context ctx; + ctx.start(); unsigned char step[32768]; @@ -647,24 +645,24 @@ String FileAccess::get_md5(const String &p_file) { int br = f->get_buffer(step, 32768); if (br > 0) { - MD5Update(&md5, step, br); + ctx.update(step, br); } if (br < 4096) break; } - MD5Final(&md5); - - String ret = String::md5(md5.digest); + unsigned char hash[16]; + ctx.finish(hash); memdelete(f); - return ret; + + return String::md5(hash); } String FileAccess::get_multiple_md5(const Vector<String> &p_file) { - MD5_CTX md5; - MD5Init(&md5); + CryptoCore::MD5Context ctx; + ctx.start(); for (int i = 0; i < p_file.size(); i++) { FileAccess *f = FileAccess::open(p_file[i], READ); @@ -677,7 +675,7 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) { int br = f->get_buffer(step, 32768); if (br > 0) { - MD5Update(&md5, step, br); + ctx.update(step, br); } if (br < 4096) break; @@ -685,11 +683,10 @@ String FileAccess::get_multiple_md5(const Vector<String> &p_file) { memdelete(f); } - MD5Final(&md5); + unsigned char hash[16]; + ctx.finish(hash); - String ret = String::md5(md5.digest); - - return ret; + return String::md5(hash); } String FileAccess::get_sha256(const String &p_file) { @@ -698,8 +695,8 @@ String FileAccess::get_sha256(const String &p_file) { if (!f) return String(); - sha256_context sha256; - sha256_init(&sha256); + CryptoCore::SHA256Context ctx; + ctx.start(); unsigned char step[32768]; @@ -708,15 +705,14 @@ String FileAccess::get_sha256(const String &p_file) { int br = f->get_buffer(step, 32768); if (br > 0) { - sha256_hash(&sha256, step, br); + ctx.update(step, br); } if (br < 4096) break; } unsigned char hash[32]; - - sha256_done(&sha256, hash); + ctx.finish(hash); memdelete(f); return String::hex_encode_buffer(hash, 32); diff --git a/core/os/os.cpp b/core/os/os.cpp index 08067385ab..925154af7d 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -51,6 +51,35 @@ uint32_t OS::get_ticks_msec() const { return get_ticks_usec() / 1000; } +String OS::get_iso_date_time(bool local) const { + OS::Date date = get_date(local); + OS::Time time = get_time(local); + + String timezone; + if (!local) { + TimeZoneInfo zone = get_time_zone_info(); + if (zone.bias >= 0) { + timezone = "+"; + } + timezone = timezone + itos(zone.bias / 60).pad_zeros(2) + itos(zone.bias % 60).pad_zeros(2); + } else { + timezone = "Z"; + } + + return itos(date.year).pad_zeros(2) + + "-" + + itos(date.month).pad_zeros(2) + + "-" + + itos(date.day).pad_zeros(2) + + "T" + + itos(time.hour).pad_zeros(2) + + ":" + + itos(time.min).pad_zeros(2) + + ":" + + itos(time.sec).pad_zeros(2) + + timezone; +} + uint64_t OS::get_splash_tick_msec() const { return _msec_splash; } diff --git a/core/os/os.h b/core/os/os.h index 1b19ddff26..2224d3b006 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -336,6 +336,7 @@ public: virtual Date get_date(bool local = false) const = 0; virtual Time get_time(bool local = false) const = 0; virtual TimeZoneInfo get_time_zone_info() const = 0; + virtual String get_iso_date_time(bool local = false) const; virtual uint64_t get_unix_time() const; virtual uint64_t get_system_time_secs() const; virtual uint64_t get_system_time_msecs() const; diff --git a/core/pool_vector.h b/core/pool_vector.h index 338de966f6..98a52c6938 100644 --- a/core/pool_vector.h +++ b/core/pool_vector.h @@ -301,6 +301,10 @@ public: virtual ~Access() { _unref(); } + + void release() { + _unref(); + } }; class Read : public Access { @@ -484,9 +488,7 @@ T PoolVector<T>::get(int p_index) const { template <class T> void PoolVector<T>::set(int p_index, const T &p_val) { - if (p_index < 0 || p_index >= size()) { - ERR_FAIL_COND(p_index < 0 || p_index >= size()); - } + ERR_FAIL_INDEX(p_index, size()); Write w = write(); w[p_index] = p_val; diff --git a/core/project_settings.cpp b/core/project_settings.cpp index fc1a74801d..c1d4967f55 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -83,6 +83,10 @@ String ProjectSettings::localize_path(const String &p_path) const { // `plus_file("")` is an easy way to ensure we have a trailing '/'. const String res_path = resource_path.plus_file(""); + // DirAccess::get_current_dir() is not guaranteed to return a path that with a trailing '/', + // so we must make sure we have it as well in order to compare with 'res_path'. + cwd = cwd.plus_file(""); + if (!cwd.begins_with(res_path)) { return p_path; }; @@ -343,17 +347,17 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b return err; } - // Attempt with exec_name.pck - // (This is the usual case when distributing a Godot game.) - - // Based on the OS, it can be the exec path + '.pck' (Linux w/o extension, macOS in .app bundle) - // or the exec path's basename + '.pck' (Windows). - // We need to test both possibilities as extensions for Linux binaries are optional - // (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck'). - String exec_path = OS::get_singleton()->get_executable_path(); if (exec_path != "") { + // Attempt with exec_name.pck + // (This is the usual case when distributing a Godot game.) + + // Based on the OS, it can be the exec path + '.pck' (Linux w/o extension, macOS in .app bundle) + // or the exec path's basename + '.pck' (Windows). + // We need to test both possibilities as extensions for Linux binaries are optional + // (so both 'mygame.bin' and 'mygame' should be able to find 'mygame.pck'). + bool found = false; String exec_dir = exec_path.get_base_dir(); @@ -375,6 +379,14 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b } } + // Attempt with PCK bundled into executable + + if (!found) { + if (_load_resource_pack(exec_path)) { + found = true; + } + } + // If we opened our package, try and load our project if (found) { Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); @@ -475,7 +487,7 @@ void ProjectSettings::set_registering_order(bool p_enable) { registering_order = p_enable; } -Error ProjectSettings::_load_settings_binary(const String p_path) { +Error ProjectSettings::_load_settings_binary(const String &p_path) { Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); @@ -518,7 +530,7 @@ Error ProjectSettings::_load_settings_binary(const String p_path) { return OK; } -Error ProjectSettings::_load_settings_text(const String p_path) { +Error ProjectSettings::_load_settings_text(const String &p_path) { Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); @@ -581,7 +593,7 @@ Error ProjectSettings::_load_settings_text(const String p_path) { } } -Error ProjectSettings::_load_settings_text_or_binary(const String p_text_path, const String p_bin_path) { +Error ProjectSettings::_load_settings_text_or_binary(const String &p_text_path, const String &p_bin_path) { // Attempt first to load the text-based project.godot file Error err_text = _load_settings_text(p_text_path); diff --git a/core/project_settings.h b/core/project_settings.h index 0ff18ab3f5..d7651417d5 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -97,9 +97,9 @@ protected: static ProjectSettings *singleton; - Error _load_settings_text(const String p_path); - Error _load_settings_binary(const String p_path); - Error _load_settings_text_or_binary(const String p_text_path, const String p_bin_path); + Error _load_settings_text(const String &p_path); + Error _load_settings_binary(const String &p_path); + Error _load_settings_text_or_binary(const String &p_text_path, const String &p_bin_path); Error _save_settings_text(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String()); Error _save_settings_binary(const String &p_file, const Map<String, List<String> > &props, const CustomMap &p_custom = CustomMap(), const String &p_custom_features = String()); diff --git a/core/reference.cpp b/core/reference.cpp index 7b5145184a..1984af9a34 100644 --- a/core/reference.cpp +++ b/core/reference.cpp @@ -70,7 +70,7 @@ bool Reference::reference() { if (get_script_instance()) { get_script_instance()->refcount_incremented(); } - if (instance_binding_count > 0) { + if (instance_binding_count > 0 && !ScriptServer::are_languages_finished()) { for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { if (_script_instance_bindings[i]) { ScriptServer::get_language(i)->refcount_incremented_instance_binding(this); @@ -91,7 +91,7 @@ bool Reference::unreference() { bool script_ret = get_script_instance()->refcount_decremented(); die = die && script_ret; } - if (instance_binding_count > 0) { + if (instance_binding_count > 0 && !ScriptServer::are_languages_finished()) { for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) { if (_script_instance_bindings[i]) { bool script_ret = ScriptServer::get_language(i)->refcount_decremented_instance_binding(this); diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp index af863dd385..e442546124 100644 --- a/core/register_core_types.cpp +++ b/core/register_core_types.cpp @@ -190,6 +190,8 @@ void register_core_types() { ClassDB::register_class<JSONParseResult>(); + ClassDB::register_virtual_class<ResourceImporter>(); + ip = IP::create(); _geometry = memnew(_Geometry); @@ -205,6 +207,8 @@ void register_core_types() { void register_core_settings() { //since in register core types, globals may not e present + GLOBAL_DEF("network/limits/tcp/connect_timeout_seconds", (30)); + ProjectSettings::get_singleton()->set_custom_property_info("network/limits/tcp/connect_timeout_seconds", PropertyInfo(Variant::INT, "network/limits/tcp/connect_timeout_seconds", PROPERTY_HINT_RANGE, "1,1800,1")); GLOBAL_DEF_RST("network/limits/packet_peer_stream/max_buffer_po2", (16)); ProjectSettings::get_singleton()->set_custom_property_info("network/limits/packet_peer_stream/max_buffer_po2", PropertyInfo(Variant::INT, "network/limits/packet_peer_stream/max_buffer_po2", PROPERTY_HINT_RANGE, "0,64,1,or_greater")); } diff --git a/core/script_language.h b/core/script_language.h index b0c60b4e90..87f103bb33 100644 --- a/core/script_language.h +++ b/core/script_language.h @@ -200,6 +200,35 @@ public: virtual ~ScriptInstance(); }; +struct ScriptCodeCompletionOption { + enum Kind { + KIND_CLASS, + KIND_FUNCTION, + KIND_SIGNAL, + KIND_VARIABLE, + KIND_MEMBER, + KIND_ENUM, + KIND_CONSTANT, + KIND_NODE_PATH, + KIND_FILE_PATH, + KIND_PLAIN_TEXT, + }; + Kind kind; + String display; + String insert_text; + RES icon; + + ScriptCodeCompletionOption() { + kind = KIND_PLAIN_TEXT; + } + + ScriptCodeCompletionOption(const String &p_text, Kind p_kind) { + display = p_text; + insert_text = p_text; + kind = p_kind; + } +}; + class ScriptCodeCompletionCache { static ScriptCodeCompletionCache *singleton; @@ -250,7 +279,7 @@ public: virtual Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { return ERR_UNAVAILABLE; } virtual bool overrides_external_editor() { return false; } - virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; } + virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) { return ERR_UNAVAILABLE; } struct LookupResult { enum Type { diff --git a/core/ustring.cpp b/core/ustring.cpp index 18c48b4dad..75e3b6f22e 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -31,6 +31,7 @@ #include "ustring.h" #include "core/color.h" +#include "core/math/crypto_core.h" #include "core/math/math_funcs.h" #include "core/os/memory.h" #include "core/print_string.h" @@ -38,9 +39,6 @@ #include "core/ucaps.h" #include "core/variant.h" -#include "thirdparty/misc/md5.h" -#include "thirdparty/misc/sha256.h" - #include <wchar.h> #ifndef NO_USE_STDLIB @@ -780,7 +778,7 @@ Vector<String> String::split(const String &p_splitter, bool p_allow_empty, int p if (p_allow_empty || (end > from)) { if (p_maxsplit <= 0) ret.push_back(substr(from, end - from)); - else if (p_maxsplit > 0) { + else { // Put rest of the string and leave cycle. if (p_maxsplit == ret.size()) { @@ -2254,54 +2252,63 @@ uint64_t String::hash64() const { String String::md5_text() const { CharString cs = utf8(); - MD5_CTX ctx; - MD5Init(&ctx); - MD5Update(&ctx, (unsigned char *)cs.ptr(), cs.length()); - MD5Final(&ctx); - return String::md5(ctx.digest); + unsigned char hash[16]; + CryptoCore::md5((unsigned char *)cs.ptr(), cs.length(), hash); + return String::hex_encode_buffer(hash, 16); +} + +String String::sha1_text() const { + CharString cs = utf8(); + unsigned char hash[20]; + CryptoCore::sha1((unsigned char *)cs.ptr(), cs.length(), hash); + return String::hex_encode_buffer(hash, 20); } String String::sha256_text() const { CharString cs = utf8(); unsigned char hash[32]; - sha256_context ctx; - sha256_init(&ctx); - sha256_hash(&ctx, (unsigned char *)cs.ptr(), cs.length()); - sha256_done(&ctx, hash); + CryptoCore::sha256((unsigned char *)cs.ptr(), cs.length(), hash); return String::hex_encode_buffer(hash, 32); } Vector<uint8_t> String::md5_buffer() const { CharString cs = utf8(); - MD5_CTX ctx; - MD5Init(&ctx); - MD5Update(&ctx, (unsigned char *)cs.ptr(), cs.length()); - MD5Final(&ctx); + unsigned char hash[16]; + CryptoCore::md5((unsigned char *)cs.ptr(), cs.length(), hash); Vector<uint8_t> ret; ret.resize(16); for (int i = 0; i < 16; i++) { - ret.write[i] = ctx.digest[i]; - }; - + ret.write[i] = hash[i]; + } return ret; }; +Vector<uint8_t> String::sha1_buffer() const { + CharString cs = utf8(); + unsigned char hash[20]; + CryptoCore::sha1((unsigned char *)cs.ptr(), cs.length(), hash); + + Vector<uint8_t> ret; + ret.resize(20); + for (int i = 0; i < 20; i++) { + ret.write[i] = hash[i]; + } + + return ret; +} + Vector<uint8_t> String::sha256_buffer() const { CharString cs = utf8(); unsigned char hash[32]; - sha256_context ctx; - sha256_init(&ctx); - sha256_hash(&ctx, (unsigned char *)cs.ptr(), cs.length()); - sha256_done(&ctx, hash); + CryptoCore::sha256((unsigned char *)cs.ptr(), cs.length(), hash); Vector<uint8_t> ret; ret.resize(32); for (int i = 0; i < 32; i++) { ret.write[i] = hash[i]; } - return ret; } @@ -3331,7 +3338,7 @@ String String::http_unescape() const { if ((ord1 >= '0' && ord1 <= '9') || (ord1 >= 'A' && ord1 <= 'Z')) { CharType ord2 = ord_at(i + 2); if ((ord2 >= '0' && ord2 <= '9') || (ord2 >= 'A' && ord2 <= 'Z')) { - char bytes[2] = { (char)ord1, (char)ord2 }; + char bytes[3] = { (char)ord1, (char)ord2, 0 }; res += (char)strtol(bytes, NULL, 16); i += 2; } diff --git a/core/ustring.h b/core/ustring.h index a32daabb91..8a52c53238 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -305,8 +305,10 @@ public: uint32_t hash() const; /* hash the string */ uint64_t hash64() const; /* hash the string */ String md5_text() const; + String sha1_text() const; String sha256_text() const; Vector<uint8_t> md5_buffer() const; + Vector<uint8_t> sha1_buffer() const; Vector<uint8_t> sha256_buffer() const; _FORCE_INLINE_ bool empty() const { return length() == 0; } diff --git a/core/variant.cpp b/core/variant.cpp index 5b51a4e513..fe9623d068 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -2418,9 +2418,6 @@ Variant::Variant(const PoolVector<Face3> &p_face_array) { for (int j = 0; j < 3; j++) w[i * 3 + j] = r[i].vertex[j]; } - - r = PoolVector<Face3>::Read(); - w = PoolVector<Vector3>::Write(); } type = NIL; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index dc28f1ca02..3fdd18a630 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -33,10 +33,10 @@ #include "core/color_names.inc" #include "core/core_string_names.h" #include "core/io/compression.h" +#include "core/math/crypto_core.h" #include "core/object.h" #include "core/os/os.h" #include "core/script_language.h" -#include "thirdparty/misc/sha256.h" typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args); typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args); @@ -275,8 +275,10 @@ struct _VariantCall { VCALL_LOCALMEM2(String, erase); VCALL_LOCALMEM0R(String, hash); VCALL_LOCALMEM0R(String, md5_text); + VCALL_LOCALMEM0R(String, sha1_text); VCALL_LOCALMEM0R(String, sha256_text); VCALL_LOCALMEM0R(String, md5_buffer); + VCALL_LOCALMEM0R(String, sha1_buffer); VCALL_LOCALMEM0R(String, sha256_buffer); VCALL_LOCALMEM0R(String, empty); VCALL_LOCALMEM0R(String, is_abs_path); @@ -317,7 +319,7 @@ struct _VariantCall { retval.resize(len); PoolByteArray::Write w = retval.write(); copymem(w.ptr(), charstr.ptr(), len); - w = PoolVector<uint8_t>::Write(); + w.release(); r_ret = retval; } @@ -332,7 +334,7 @@ struct _VariantCall { retval.resize(len); PoolByteArray::Write w = retval.write(); copymem(w.ptr(), charstr.ptr(), len); - w = PoolVector<uint8_t>::Write(); + w.release(); r_ret = retval; } @@ -598,10 +600,7 @@ struct _VariantCall { PoolByteArray::Read r = ba->read(); String s; unsigned char hash[32]; - sha256_context sha256; - sha256_init(&sha256); - sha256_hash(&sha256, (unsigned char *)r.ptr(), ba->size()); - sha256_done(&sha256, hash); + CryptoCore::sha256((unsigned char *)r.ptr(), ba->size(), hash); s = String::hex_encode_buffer(hash, 32); r_ret = s; } @@ -1542,8 +1541,10 @@ void register_variant_methods() { ADDFUNC2(STRING, NIL, String, erase, INT, "position", INT, "chars", varray()); ADDFUNC0R(STRING, INT, String, hash, varray()); ADDFUNC0R(STRING, STRING, String, md5_text, varray()); + ADDFUNC0R(STRING, STRING, String, sha1_text, varray()); ADDFUNC0R(STRING, STRING, String, sha256_text, varray()); ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, md5_buffer, varray()); + ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, sha1_buffer, varray()); ADDFUNC0R(STRING, POOL_BYTE_ARRAY, String, sha256_buffer, varray()); ADDFUNC0R(STRING, BOOL, String, empty, varray()); ADDFUNC0R(STRING, BOOL, String, is_abs_path, varray()); diff --git a/doc/classes/ARVRServer.xml b/doc/classes/ARVRServer.xml index af1a1b0fff..b71a18858f 100644 --- a/doc/classes/ARVRServer.xml +++ b/doc/classes/ARVRServer.xml @@ -107,7 +107,7 @@ </method> </methods> <members> - <member name="primary_interface" type="ARVRInterface" setter="set_primary_interface" getter="get_primary_interface" default="null"> + <member name="primary_interface" type="ARVRInterface" setter="set_primary_interface" getter="get_primary_interface"> </member> <member name="world_scale" type="float" setter="set_world_scale" getter="get_world_scale" default="1.0"> Allows you to adjust the scale to your game's units. Most AR/VR platforms assume a scale of 1 game world unit = 1 real world meter. diff --git a/doc/classes/AnimatedSprite.xml b/doc/classes/AnimatedSprite.xml index 72d1fa4881..10ee4222c8 100644 --- a/doc/classes/AnimatedSprite.xml +++ b/doc/classes/AnimatedSprite.xml @@ -51,7 +51,7 @@ <member name="frame" type="int" setter="set_frame" getter="get_frame" default="0"> The displayed animation frame's index. </member> - <member name="frames" type="SpriteFrames" setter="set_sprite_frames" getter="get_sprite_frames" default="null"> + <member name="frames" type="SpriteFrames" setter="set_sprite_frames" getter="get_sprite_frames"> The [SpriteFrames] resource containing the animation(s). </member> <member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )"> diff --git a/doc/classes/AnimatedSprite3D.xml b/doc/classes/AnimatedSprite3D.xml index ff7d2fb9eb..eac5822d53 100644 --- a/doc/classes/AnimatedSprite3D.xml +++ b/doc/classes/AnimatedSprite3D.xml @@ -40,7 +40,7 @@ <member name="frame" type="int" setter="set_frame" getter="get_frame" default="0"> The displayed animation frame's index. </member> - <member name="frames" type="SpriteFrames" setter="set_sprite_frames" getter="get_sprite_frames" default="null"> + <member name="frames" type="SpriteFrames" setter="set_sprite_frames" getter="get_sprite_frames"> The [SpriteFrames] resource containing the animation(s). </member> <member name="playing" type="bool" setter="_set_playing" getter="_is_playing" default="false"> diff --git a/doc/classes/AnimationNodeTransition.xml b/doc/classes/AnimationNodeTransition.xml index 4d2a11578f..82839b6bab 100644 --- a/doc/classes/AnimationNodeTransition.xml +++ b/doc/classes/AnimationNodeTransition.xml @@ -7,6 +7,42 @@ <tutorials> </tutorials> <methods> + <method name="get_input_caption" qualifiers="const"> + <return type="String"> + </return> + <argument index="0" name="input" type="int"> + </argument> + <description> + </description> + </method> + <method name="is_input_set_as_auto_advance" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="input" type="int"> + </argument> + <description> + </description> + </method> + <method name="set_input_as_auto_advance"> + <return type="void"> + </return> + <argument index="0" name="input" type="int"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_input_caption"> + <return type="void"> + </return> + <argument index="0" name="input" type="int"> + </argument> + <argument index="1" name="caption" type="String"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="input_0/auto_advance" type="bool" setter="set_input_as_auto_advance" getter="is_input_set_as_auto_advance"> diff --git a/doc/classes/AnimationTree.xml b/doc/classes/AnimationTree.xml index 70c1b783df..d1c24e466d 100644 --- a/doc/classes/AnimationTree.xml +++ b/doc/classes/AnimationTree.xml @@ -43,7 +43,7 @@ </member> <member name="root_motion_track" type="NodePath" setter="set_root_motion_track" getter="get_root_motion_track" default="NodePath("")"> </member> - <member name="tree_root" type="AnimationNode" setter="set_tree_root" getter="get_tree_root" default="null"> + <member name="tree_root" type="AnimationNode" setter="set_tree_root" getter="get_tree_root"> </member> </members> <constants> diff --git a/doc/classes/AtlasTexture.xml b/doc/classes/AtlasTexture.xml index 1363287dc1..5b0a06a7fb 100644 --- a/doc/classes/AtlasTexture.xml +++ b/doc/classes/AtlasTexture.xml @@ -12,7 +12,7 @@ <methods> </methods> <members> - <member name="atlas" type="Texture" setter="set_atlas" getter="get_atlas" default="null"> + <member name="atlas" type="Texture" setter="set_atlas" getter="get_atlas"> The texture that contains the atlas. Can be any [Texture] subtype. </member> <member name="filter_clip" type="bool" setter="set_filter_clip" getter="has_filter_clip" default="false"> diff --git a/doc/classes/AudioEffectChorus.xml b/doc/classes/AudioEffectChorus.xml index 13bc6ac097..4da125ba63 100644 --- a/doc/classes/AudioEffectChorus.xml +++ b/doc/classes/AudioEffectChorus.xml @@ -9,6 +9,114 @@ <tutorials> </tutorials> <methods> + <method name="get_voice_cutoff_hz" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_voice_delay_ms" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_voice_depth_ms" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_voice_level_db" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_voice_pan" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="get_voice_rate_hz" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="set_voice_cutoff_hz"> + <return type="void"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <argument index="1" name="cutoff_hz" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_voice_delay_ms"> + <return type="void"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <argument index="1" name="delay_ms" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_voice_depth_ms"> + <return type="void"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <argument index="1" name="depth_ms" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_voice_level_db"> + <return type="void"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <argument index="1" name="level_db" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_voice_pan"> + <return type="void"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <argument index="1" name="pan" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_voice_rate_hz"> + <return type="void"> + </return> + <argument index="0" name="voice_idx" type="int"> + </argument> + <argument index="1" name="rate_hz" type="float"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="dry" type="float" setter="set_dry" getter="get_dry" default="1.0"> diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml index f063cfe5ce..7581ae6935 100644 --- a/doc/classes/AudioServer.xml +++ b/doc/classes/AudioServer.xml @@ -68,13 +68,6 @@ Returns the amount of channels of the bus at index [code]bus_idx[/code]. </description> </method> - <method name="get_bus_count" qualifiers="const"> - <return type="int"> - </return> - <description> - Returns the number of available buses. - </description> - </method> <method name="get_bus_effect"> <return type="AudioEffect"> </return> @@ -165,36 +158,25 @@ Returns the volume of the bus at index [code]bus_idx[/code] in dB. </description> </method> - <method name="get_device"> - <return type="String"> - </return> - <description> - </description> - </method> <method name="get_device_list"> <return type="Array"> </return> <description> - </description> - </method> - <method name="get_global_rate_scale"> - <return type="float"> - </return> - <description> - Returns the global rate scale at which audio is being played. + Returns the names of all audio devices detected on the system. </description> </method> <method name="get_mix_rate" qualifiers="const"> <return type="float"> </return> <description> - Returns the sample rate at the output of the audioserver. + Returns the sample rate at the output of the [AudioServer]. </description> </method> <method name="get_output_latency" qualifiers="const"> <return type="float"> </return> <description> + Returns the audio driver's output latency. </description> </method> <method name="get_speaker_mode" qualifiers="const"> @@ -258,7 +240,7 @@ <return type="void"> </return> <description> - Locks the audio drivers mainloop. Remember to unlock it afterwards. + Locks the audio driver's main loop. Remember to unlock it afterwards. </description> </method> <method name="move_bus"> @@ -303,15 +285,6 @@ If [code]true[/code], the bus at index [code]bus_idx[/code] is bypassing effects. </description> </method> - <method name="set_bus_count"> - <return type="void"> - </return> - <argument index="0" name="amount" type="int"> - </argument> - <description> - Adds and removes buses to make the number of buses match [code]amount[/code]. - </description> - </method> <method name="set_bus_effect_enabled"> <return type="void"> </return> @@ -389,23 +362,6 @@ Sets the volume of the bus at index [code]bus_idx[/code] to [code]volume_db[/code]. </description> </method> - <method name="set_device"> - <return type="void"> - </return> - <argument index="0" name="device" type="String"> - </argument> - <description> - </description> - </method> - <method name="set_global_rate_scale"> - <return type="void"> - </return> - <argument index="0" name="scale" type="float"> - </argument> - <description> - Scales the rate at which audio is played (i.e. setting it to [code]0.5[/code] will make the audio be played twice as fast). - </description> - </method> <method name="swap_bus_effects"> <return type="void"> </return> @@ -428,12 +384,13 @@ </method> </methods> <members> - <member name="bus_count" type="int" setter="set_bus_count" getter="get_bus_count"> - Adds and removes buses to make the number of buses match [code]amount[/code]. + <member name="bus_count" type="int" setter="set_bus_count" getter="get_bus_count" default="1"> + Number of available audio buses. </member> - <member name="device" type="string" setter="set_device" getter="get_device"> + <member name="device" type="String" setter="set_device" getter="get_device" default=""Default""> + Name of the current device (see [method get_device_list]). </member> - <member name="global_rate_scale" type="float" setter="set_global_rate_scale" getter="get_global_rate_scale"> + <member name="global_rate_scale" type="float" setter="set_global_rate_scale" getter="get_global_rate_scale" default="1.0"> Scales the rate at which audio is played (i.e. setting it to [code]0.5[/code] will make the audio be played twice as fast). </member> </members> @@ -446,15 +403,16 @@ </signals> <constants> <constant name="SPEAKER_MODE_STEREO" value="0" enum="SpeakerMode"> - Two or fewer speakers are detected. + Two or fewer speakers were detected. </constant> <constant name="SPEAKER_SURROUND_31" value="1" enum="SpeakerMode"> + A 3.1 channel surround setup was detected. </constant> <constant name="SPEAKER_SURROUND_51" value="2" enum="SpeakerMode"> - A 5.1 channel surround setup detected. + A 5.1 channel surround setup was detected. </constant> <constant name="SPEAKER_SURROUND_71" value="3" enum="SpeakerMode"> - A 7.1 channel surround setup detected. + A 7.1 channel surround setup was detected. </constant> </constants> </class> diff --git a/doc/classes/AudioStreamPlayer.xml b/doc/classes/AudioStreamPlayer.xml index 92f3a9bd73..4bc29335ff 100644 --- a/doc/classes/AudioStreamPlayer.xml +++ b/doc/classes/AudioStreamPlayer.xml @@ -65,7 +65,7 @@ <member name="playing" type="bool" setter="_set_playing" getter="is_playing" default="false"> If [code]true[/code], audio is playing. </member> - <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream" default="null"> + <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream"> The [AudioStream] object to be played. </member> <member name="stream_paused" type="bool" setter="set_stream_paused" getter="get_stream_paused" default="false"> diff --git a/doc/classes/AudioStreamPlayer2D.xml b/doc/classes/AudioStreamPlayer2D.xml index 362a096810..4734aff770 100644 --- a/doc/classes/AudioStreamPlayer2D.xml +++ b/doc/classes/AudioStreamPlayer2D.xml @@ -71,7 +71,7 @@ <member name="playing" type="bool" setter="_set_playing" getter="is_playing" default="false"> If [code]true[/code], audio is playing. </member> - <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream" default="null"> + <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream"> The [AudioStream] object to be played. </member> <member name="stream_paused" type="bool" setter="set_stream_paused" getter="get_stream_paused" default="false"> diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml index d722f2164d..a73f96d082 100644 --- a/doc/classes/AudioStreamPlayer3D.xml +++ b/doc/classes/AudioStreamPlayer3D.xml @@ -95,7 +95,7 @@ <member name="playing" type="bool" setter="_set_playing" getter="is_playing" default="false"> If [code]true[/code], audio is playing. </member> - <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream" default="null"> + <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream"> The [AudioStream] object to be played. </member> <member name="stream_paused" type="bool" setter="set_stream_paused" getter="get_stream_paused" default="false"> diff --git a/doc/classes/AudioStreamRandomPitch.xml b/doc/classes/AudioStreamRandomPitch.xml index 9c73a64537..a2ee314d92 100644 --- a/doc/classes/AudioStreamRandomPitch.xml +++ b/doc/classes/AudioStreamRandomPitch.xml @@ -11,7 +11,7 @@ <methods> </methods> <members> - <member name="audio_stream" type="AudioStream" setter="set_audio_stream" getter="get_audio_stream" default="null"> + <member name="audio_stream" type="AudioStream" setter="set_audio_stream" getter="get_audio_stream"> The current [AudioStream]. </member> <member name="random_pitch" type="float" setter="set_random_pitch" getter="get_random_pitch" default="1.1"> diff --git a/doc/classes/BakedLightmap.xml b/doc/classes/BakedLightmap.xml index 571a6fde80..4a1381295f 100644 --- a/doc/classes/BakedLightmap.xml +++ b/doc/classes/BakedLightmap.xml @@ -18,12 +18,14 @@ <argument index="1" name="create_visual_debug" type="bool" default="false"> </argument> <description> + Bakes the lightmaps within the currently edited scene. </description> </method> <method name="debug_bake"> <return type="void"> </return> <description> + Executes a dry run bake of lightmaps within the currently edited scene. </description> </method> </methods> @@ -31,7 +33,11 @@ <member name="bake_cell_size" type="float" setter="set_bake_cell_size" getter="get_bake_cell_size" default="0.25"> Grid subdivision size for lightmapper calculation. The default value will work for most cases. Increase for better lighting on small details or if your scene is very large. </member> + <member name="bake_default_texels_per_unit" type="float" setter="set_bake_default_texels_per_unit" getter="get_bake_default_texels_per_unit" default="20.0"> + If a [member Mesh.lightmap_size_hint] isn't specified, the lightmap baker will dynamically set the lightmap size using this value. This value is measured in texels per world unit. The maximum lightmap texture size is 4096x4096. + </member> <member name="bake_energy" type="float" setter="set_energy" getter="get_energy" default="1.0"> + Multiplies the light sources' intensity by this value. For instance, if the value is set to 2, lights will be twice as bright. If the value is set to 0.5, lights will be half as bright. </member> <member name="bake_extents" type="Vector3" setter="set_extents" getter="get_extents" default="Vector3( 10, 10, 10 )"> The size of the affected area. @@ -43,6 +49,7 @@ Lightmapping mode. See [enum BakeMode]. </member> <member name="bake_propagation" type="float" setter="set_propagation" getter="get_propagation" default="1.0"> + Defines how far the light will travel before it is no longer effective. The higher the number, the farther the light will travel. For instance, if the value is set to 2, the light will go twice as far. If the value is set to 0.5, the light will only go half as far. </member> <member name="bake_quality" type="int" setter="set_bake_quality" getter="get_bake_quality" enum="BakedLightmap.BakeQuality" default="1"> Three quality modes are available. Higher quality requires more rendering time. See [enum BakeQuality]. @@ -53,7 +60,7 @@ <member name="image_path" type="String" setter="set_image_path" getter="get_image_path" default="".""> The location where lightmaps will be saved. </member> - <member name="light_data" type="BakedLightmapData" setter="set_light_data" getter="get_light_data" default="null"> + <member name="light_data" type="BakedLightmapData" setter="set_light_data" getter="get_light_data"> The calculated light data. </member> </members> diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml index f306adced2..9d1c80d3be 100644 --- a/doc/classes/BaseButton.xml +++ b/doc/classes/BaseButton.xml @@ -54,7 +54,7 @@ <member name="enabled_focus_mode" type="int" setter="set_enabled_focus_mode" getter="get_enabled_focus_mode" enum="Control.FocusMode" default="2"> Focus access mode to use when switching between enabled/disabled (see [member Control.focus_mode] and [member disabled]). </member> - <member name="group" type="ButtonGroup" setter="set_button_group" getter="get_button_group" default="null"> + <member name="group" type="ButtonGroup" setter="set_button_group" getter="get_button_group"> [ButtonGroup] associated to the button. </member> <member name="keep_pressed_outside" type="bool" setter="set_keep_pressed_outside" getter="is_keep_pressed_outside" default="false"> @@ -63,7 +63,7 @@ <member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" default="false"> If [code]true[/code], the button's state is pressed. Means the button is pressed down or toggled (if toggle_mode is active). </member> - <member name="shortcut" type="ShortCut" setter="set_shortcut" getter="get_shortcut" default="null"> + <member name="shortcut" type="ShortCut" setter="set_shortcut" getter="get_shortcut"> [ShortCut] associated to the button. </member> <member name="shortcut_in_tooltip" type="bool" setter="set_shortcut_in_tooltip" getter="is_shortcut_in_tooltip_enabled" default="true"> diff --git a/doc/classes/BitmapFont.xml b/doc/classes/BitmapFont.xml index 5ec4947f46..16a28978d5 100644 --- a/doc/classes/BitmapFont.xml +++ b/doc/classes/BitmapFont.xml @@ -110,7 +110,7 @@ <member name="distance_field" type="bool" setter="set_distance_field_hint" getter="is_distance_field_hint" default="false"> If [code]true[/code], distance field hint is enabled. </member> - <member name="fallback" type="BitmapFont" setter="set_fallback" getter="get_fallback" default="null"> + <member name="fallback" type="BitmapFont" setter="set_fallback" getter="get_fallback"> The fallback font. </member> <member name="height" type="float" setter="set_height" getter="get_height" default="1.0"> diff --git a/doc/classes/Button.xml b/doc/classes/Button.xml index 3d8730b588..adf826c26b 100644 --- a/doc/classes/Button.xml +++ b/doc/classes/Button.xml @@ -20,7 +20,7 @@ <member name="flat" type="bool" setter="set_flat" getter="is_flat" default="false"> Flat buttons don't display decoration. </member> - <member name="icon" type="Texture" setter="set_button_icon" getter="get_button_icon" default="null"> + <member name="icon" type="Texture" setter="set_button_icon" getter="get_button_icon"> Button's icon, if text is present the icon will be placed before the text. </member> <member name="text" type="String" setter="set_text" getter="get_text" default=""""> @@ -45,11 +45,11 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> </theme_item> diff --git a/doc/classes/CPUParticles.xml b/doc/classes/CPUParticles.xml index bd59bdbf9f..e68b0feb2d 100644 --- a/doc/classes/CPUParticles.xml +++ b/doc/classes/CPUParticles.xml @@ -19,6 +19,38 @@ Sets this node's properties to match a given [Particles] node with an assigned [ParticlesMaterial]. </description> </method> + <method name="get_param" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles.Parameter"> + </argument> + <description> + </description> + </method> + <method name="get_param_curve" qualifiers="const"> + <return type="Curve"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles.Parameter"> + </argument> + <description> + </description> + </method> + <method name="get_param_randomness" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles.Parameter"> + </argument> + <description> + </description> + </method> + <method name="get_particle_flag" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="flag" type="int" enum="CPUParticles.Flags"> + </argument> + <description> + </description> + </method> <method name="restart"> <return type="void"> </return> @@ -26,6 +58,46 @@ Restarts the particle emitter. </description> </method> + <method name="set_param"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles.Parameter"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_param_curve"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles.Parameter"> + </argument> + <argument index="1" name="curve" type="Curve"> + </argument> + <description> + </description> + </method> + <method name="set_param_randomness"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles.Parameter"> + </argument> + <argument index="1" name="randomness" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_particle_flag"> + <return type="void"> + </return> + <argument index="0" name="flag" type="int" enum="CPUParticles.Flags"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="amount" type="int" setter="set_amount" getter="get_amount" default="8"> @@ -34,7 +106,7 @@ <member name="angle" type="float" setter="set_param" getter="get_param" default="0.0"> Initial rotation applied to each particle, in degrees. </member> - <member name="angle_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="angle_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's rotation will be animated along this [Curve]. </member> <member name="angle_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -43,7 +115,7 @@ <member name="angular_velocity" type="float" setter="set_param" getter="get_param" default="0.0"> Initial angular velocity applied to each particle. Sets the speed of rotation of the particle. </member> - <member name="angular_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="angular_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's angular velocity will vary along this [Curve]. </member> <member name="angular_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -52,7 +124,7 @@ <member name="anim_offset" type="float" setter="set_param" getter="get_param" default="0.0"> Particle animation offset. </member> - <member name="anim_offset_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="anim_offset_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's animation offset will vary along this [Curve]. </member> <member name="anim_offset_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -61,7 +133,7 @@ <member name="anim_speed" type="float" setter="set_param" getter="get_param" default="0.0"> Particle animation speed. </member> - <member name="anim_speed_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="anim_speed_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's animation speed will vary along this [Curve]. </member> <member name="anim_speed_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -70,18 +142,21 @@ <member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 1, 1, 1, 1 )"> Unused for 3D particles. </member> - <member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp" default="null"> + <member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp"> Unused for 3D particles. </member> <member name="damping" type="float" setter="set_param" getter="get_param" default="0.0"> The rate at which particles lose velocity. </member> - <member name="damping_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="damping_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Damping will vary along this [Curve]. </member> <member name="damping_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> Damping randomness ratio. </member> + <member name="direction" type="Vector3" setter="set_direction" getter="get_direction" default="Vector3( 1, 0, 0 )"> + Unit vector specifying the particles' emission direction. + </member> <member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" enum="CPUParticles.DrawOrder" default="0"> Particle draw order. Uses [enum DrawOrder] values. </member> @@ -130,7 +205,7 @@ <member name="hue_variation" type="float" setter="set_param" getter="get_param" default="0.0"> Initial hue variation applied to each particle. </member> - <member name="hue_variation_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="hue_variation_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's hue will vary along this [Curve]. </member> <member name="hue_variation_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -145,10 +220,13 @@ <member name="lifetime" type="float" setter="set_lifetime" getter="get_lifetime" default="1.0"> Amount of time each particle will exist. </member> + <member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0"> + Particle lifetime randomness ratio. + </member> <member name="linear_accel" type="float" setter="set_param" getter="get_param" default="0.0"> Linear acceleration applied to each particle in the direction of motion. </member> - <member name="linear_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="linear_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's linear acceleration will vary along this [Curve]. </member> <member name="linear_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -157,7 +235,7 @@ <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. </member> - <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh" default="null"> + <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh"> The [Mesh] used for each particle. If [code]null[/code], particles will be spheres. </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false"> @@ -179,7 +257,7 @@ <member name="radial_accel" type="float" setter="set_param" getter="get_param" default="0.0"> Radial acceleration applied to each particle. Makes particle accelerate away from origin. </member> - <member name="radial_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="radial_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's radial acceleration will vary along this [Curve]. </member> <member name="radial_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -191,7 +269,7 @@ <member name="scale_amount" type="float" setter="set_param" getter="get_param" default="1.0"> Initial scale applied to each particle. </member> - <member name="scale_amount_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="scale_amount_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's scale will vary along this [Curve]. </member> <member name="scale_amount_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -206,7 +284,7 @@ <member name="tangential_accel" type="float" setter="set_param" getter="get_param" default="0.0"> Tangential acceleration applied to each particle. Tangential acceleration is perpendicular to the particle's velocity giving the particles a swirling motion. </member> - <member name="tangential_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="tangential_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's tangential acceleration will vary along this [Curve]. </member> <member name="tangential_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -224,52 +302,52 @@ Particles are drawn in order of depth. </constant> <constant name="PARAM_INITIAL_LINEAR_VELOCITY" value="0" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set initial velocity properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set initial velocity properties. </constant> <constant name="PARAM_ANGULAR_VELOCITY" value="1" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set angular velocity properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set angular velocity properties. </constant> <constant name="PARAM_ORBIT_VELOCITY" value="2" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set orbital velocity properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set orbital velocity properties. </constant> <constant name="PARAM_LINEAR_ACCEL" value="3" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set linear acceleration properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set linear acceleration properties. </constant> <constant name="PARAM_RADIAL_ACCEL" value="4" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set radial acceleration properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set radial acceleration properties. </constant> <constant name="PARAM_TANGENTIAL_ACCEL" value="5" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set tangential acceleration properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set tangential acceleration properties. </constant> <constant name="PARAM_DAMPING" value="6" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set damping properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set damping properties. </constant> <constant name="PARAM_ANGLE" value="7" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set angle properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set angle properties. </constant> <constant name="PARAM_SCALE" value="8" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set scale properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set scale properties. </constant> <constant name="PARAM_HUE_VARIATION" value="9" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set hue variation properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set hue variation properties. </constant> <constant name="PARAM_ANIM_SPEED" value="10" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set animation speed properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set animation speed properties. </constant> <constant name="PARAM_ANIM_OFFSET" value="11" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set animation offset properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set animation offset properties. </constant> <constant name="PARAM_MAX" value="12" enum="Parameter"> Represents the size of the [enum Parameter] enum. </constant> <constant name="FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="Flags"> - Use with [method set_flag] to set [member flag_align_y]. + Use with [method set_particle_flag] to set [member flag_align_y]. </constant> <constant name="FLAG_ROTATE_Y" value="1" enum="Flags"> - Use with [method set_flag] to set [member flag_rotate_y]. + Use with [method set_particle_flag] to set [member flag_rotate_y]. </constant> <constant name="FLAG_DISABLE_Z" value="2" enum="Flags"> - Use with [method set_flag] to set [member flag_disable_z]. + Use with [method set_particle_flag] to set [member flag_disable_z]. </constant> <constant name="FLAG_MAX" value="3" enum="Flags"> Represents the size of the [enum Flags] enum. diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml index 5ec460abb7..c8dbffb4cb 100644 --- a/doc/classes/CPUParticles2D.xml +++ b/doc/classes/CPUParticles2D.xml @@ -20,6 +20,38 @@ Sets this node's properties to match a given [Particles2D] node with an assigned [ParticlesMaterial]. </description> </method> + <method name="get_param" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter"> + </argument> + <description> + </description> + </method> + <method name="get_param_curve" qualifiers="const"> + <return type="Curve"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter"> + </argument> + <description> + </description> + </method> + <method name="get_param_randomness" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter"> + </argument> + <description> + </description> + </method> + <method name="get_particle_flag" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="flag" type="int" enum="CPUParticles2D.Flags"> + </argument> + <description> + </description> + </method> <method name="restart"> <return type="void"> </return> @@ -27,6 +59,46 @@ Restarts the particle emitter. </description> </method> + <method name="set_param"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_param_curve"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter"> + </argument> + <argument index="1" name="curve" type="Curve"> + </argument> + <description> + </description> + </method> + <method name="set_param_randomness"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter"> + </argument> + <argument index="1" name="randomness" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_particle_flag"> + <return type="void"> + </return> + <argument index="0" name="flag" type="int" enum="CPUParticles2D.Flags"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="amount" type="int" setter="set_amount" getter="get_amount" default="8"> @@ -35,7 +107,7 @@ <member name="angle" type="float" setter="set_param" getter="get_param" default="0.0"> Initial rotation applied to each particle, in degrees. </member> - <member name="angle_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="angle_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's rotation will be animated along this [Curve]. </member> <member name="angle_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -44,7 +116,7 @@ <member name="angular_velocity" type="float" setter="set_param" getter="get_param" default="0.0"> Initial angular velocity applied to each particle. Sets the speed of rotation of the particle. </member> - <member name="angular_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="angular_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's angular velocity will vary along this [Curve]. </member> <member name="angular_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -53,7 +125,7 @@ <member name="anim_offset" type="float" setter="set_param" getter="get_param" default="0.0"> Particle animation offset. </member> - <member name="anim_offset_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="anim_offset_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's animation offset will vary along this [Curve]. </member> <member name="anim_offset_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -62,7 +134,7 @@ <member name="anim_speed" type="float" setter="set_param" getter="get_param" default="0.0"> Particle animation speed. </member> - <member name="anim_speed_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="anim_speed_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's animation speed will vary along this [Curve]. </member> <member name="anim_speed_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -71,18 +143,21 @@ <member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 1, 1, 1, 1 )"> Each particle's initial color. If [member texture] is defined, it will be multiplied by this color. </member> - <member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp" default="null"> + <member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp"> Each particle's color will vary along this [Gradient]. </member> <member name="damping" type="float" setter="set_param" getter="get_param" default="0.0"> The rate at which particles lose velocity. </member> - <member name="damping_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="damping_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Damping will vary along this [Curve]. </member> <member name="damping_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> Damping randomness ratio. </member> + <member name="direction" type="Vector2" setter="set_direction" getter="get_direction" default="Vector2( 1, 0 )"> + Unit vector specifying the particles' emission direction. + </member> <member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" enum="CPUParticles2D.DrawOrder" default="0"> Particle draw order. Uses [enum DrawOrder] values. </member> @@ -124,7 +199,7 @@ <member name="hue_variation" type="float" setter="set_param" getter="get_param" default="0.0"> Initial hue variation applied to each particle. </member> - <member name="hue_variation_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="hue_variation_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's hue will vary along this [Curve]. </member> <member name="hue_variation_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -139,10 +214,13 @@ <member name="lifetime" type="float" setter="set_lifetime" getter="get_lifetime" default="1.0"> Amount of time each particle will exist. </member> + <member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0"> + Particle lifetime randomness ratio. + </member> <member name="linear_accel" type="float" setter="set_param" getter="get_param" default="0.0"> Linear acceleration applied to each particle in the direction of motion. </member> - <member name="linear_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="linear_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's linear acceleration will vary along this [Curve]. </member> <member name="linear_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -151,7 +229,7 @@ <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. </member> - <member name="normalmap" type="Texture" setter="set_normalmap" getter="get_normalmap" default="null"> + <member name="normalmap" type="Texture" setter="set_normalmap" getter="get_normalmap"> Normal map to be used for the [member texture] property. </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false"> @@ -160,7 +238,7 @@ <member name="orbit_velocity" type="float" setter="set_param" getter="get_param" default="0.0"> Orbital velocity applied to each particle. Makes the particles circle around origin. Specified in number of full rotations around origin per second. </member> - <member name="orbit_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="orbit_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's orbital velocity will vary along this [Curve]. </member> <member name="orbit_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -172,7 +250,7 @@ <member name="radial_accel" type="float" setter="set_param" getter="get_param" default="0.0"> Radial acceleration applied to each particle. Makes particle accelerate away from origin. </member> - <member name="radial_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="radial_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's radial acceleration will vary along this [Curve]. </member> <member name="radial_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -184,7 +262,7 @@ <member name="scale_amount" type="float" setter="set_param" getter="get_param" default="1.0"> Initial scale applied to each particle. </member> - <member name="scale_amount_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="scale_amount_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's scale will vary along this [Curve]. </member> <member name="scale_amount_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -199,13 +277,13 @@ <member name="tangential_accel" type="float" setter="set_param" getter="get_param" default="0.0"> Tangential acceleration applied to each particle. Tangential acceleration is perpendicular to the particle's velocity giving the particles a swirling motion. </member> - <member name="tangential_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve" default="null"> + <member name="tangential_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve"> Each particle's tangential acceleration will vary along this [Curve]. </member> <member name="tangential_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> Tangential acceleration randomness ratio. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> Particle texture. If [code]null[/code], particles will be squares. </member> </members> @@ -217,46 +295,46 @@ Particles are drawn in order of remaining lifetime. </constant> <constant name="PARAM_INITIAL_LINEAR_VELOCITY" value="0" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set initial velocity properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set initial velocity properties. </constant> <constant name="PARAM_ANGULAR_VELOCITY" value="1" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set angular velocity properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set angular velocity properties. </constant> <constant name="PARAM_ORBIT_VELOCITY" value="2" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set orbital velocity properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set orbital velocity properties. </constant> <constant name="PARAM_LINEAR_ACCEL" value="3" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set linear acceleration properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set linear acceleration properties. </constant> <constant name="PARAM_RADIAL_ACCEL" value="4" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set radial acceleration properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set radial acceleration properties. </constant> <constant name="PARAM_TANGENTIAL_ACCEL" value="5" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set tangential acceleration properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set tangential acceleration properties. </constant> <constant name="PARAM_DAMPING" value="6" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set damping properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set damping properties. </constant> <constant name="PARAM_ANGLE" value="7" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set angle properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set angle properties. </constant> <constant name="PARAM_SCALE" value="8" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set scale properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set scale properties. </constant> <constant name="PARAM_HUE_VARIATION" value="9" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set hue variation properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set hue variation properties. </constant> <constant name="PARAM_ANIM_SPEED" value="10" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set animation speed properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set animation speed properties. </constant> <constant name="PARAM_ANIM_OFFSET" value="11" enum="Parameter"> - Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set animation offset properties. + Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set animation offset properties. </constant> <constant name="PARAM_MAX" value="12" enum="Parameter"> Represents the size of the [enum Parameter] enum. </constant> <constant name="FLAG_ALIGN_Y_TO_VELOCITY" value="0" enum="Flags"> - Use with [method set_flag] to set [member flag_align_y]. + Use with [method set_particle_flag] to set [member flag_align_y]. </constant> <constant name="FLAG_ROTATE_Y" value="1" enum="Flags"> Present for consistency with 3D particle nodes, not used in 2D. diff --git a/doc/classes/Camera.xml b/doc/classes/Camera.xml index c22413ae7e..d410800141 100644 --- a/doc/classes/Camera.xml +++ b/doc/classes/Camera.xml @@ -171,7 +171,7 @@ <member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" enum="Camera.DopplerTracking" default="0"> If not [constant DOPPLER_TRACKING_DISABLED], this camera will simulate the Doppler effect for objects changed in particular [code]_process[/code] methods. See [enum DopplerTracking] for possible values. </member> - <member name="environment" type="Environment" setter="set_environment" getter="get_environment" default="null"> + <member name="environment" type="Environment" setter="set_environment" getter="get_environment"> The [Environment] to use for this camera. </member> <member name="far" type="float" setter="set_zfar" getter="get_zfar" default="100.0"> diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml index e9a9f22e82..750b6851b6 100644 --- a/doc/classes/Camera2D.xml +++ b/doc/classes/Camera2D.xml @@ -45,6 +45,22 @@ Returns the location of the [Camera2D]'s screen-center, relative to the origin. </description> </method> + <method name="get_drag_margin" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> + <method name="get_limit" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> <method name="make_current"> <return type="void"> </return> @@ -60,6 +76,26 @@ This has no effect if smoothing is disabled. </description> </method> + <method name="set_drag_margin"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="drag_margin" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_limit"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="limit" type="int"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="anchor_mode" type="int" setter="set_anchor_mode" getter="get_anchor_mode" enum="Camera2D.AnchorMode" default="1"> diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml index 5ac825ddcd..87b8f5c83d 100644 --- a/doc/classes/CanvasItem.xml +++ b/doc/classes/CanvasItem.xml @@ -223,8 +223,13 @@ </argument> <argument index="2" name="filled" type="bool" default="true"> </argument> + <argument index="3" name="width" type="float" default="1.0"> + </argument> + <argument index="4" name="antialiased" type="bool" default="false"> + </argument> <description> - Draws a colored rectangle. + Draws a rectangle. If [code]filled[/code] is [code]true[/code], the rectangle will be filled with the [code]color[/code] specified. If [code]filled[/code] is [code]false[/code], the rectangle will be drawn as a stroke with the [code]color[/code] and [code]width[/code] specified. If [code]antialiased[/code] is [code]true[/code], the lines will be antialiased. + [b]Note:[/b] [code]width[/code] and [code]antialiased[/code] are only effective if [code]filled[/code] is [code]false[/code]. </description> </method> <method name="draw_set_transform"> @@ -514,7 +519,7 @@ <member name="light_mask" type="int" setter="set_light_mask" getter="get_light_mask" default="1"> The rendering layers in which this [CanvasItem] responds to [Light2D] nodes. </member> - <member name="material" type="Material" setter="set_material" getter="get_material" default="null"> + <member name="material" type="Material" setter="set_material" getter="get_material"> The material applied to textures on this [CanvasItem]. </member> <member name="modulate" type="Color" setter="set_modulate" getter="get_modulate" default="Color( 1, 1, 1, 1 )"> diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml index 5583775f95..80b5e90717 100644 --- a/doc/classes/CheckBox.xml +++ b/doc/classes/CheckBox.xml @@ -23,11 +23,11 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="font_color_hover_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> </theme_item> diff --git a/doc/classes/CheckButton.xml b/doc/classes/CheckButton.xml index daed9128a9..f4d0e0657b 100644 --- a/doc/classes/CheckButton.xml +++ b/doc/classes/CheckButton.xml @@ -21,11 +21,11 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="font_color_hover_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> </theme_item> diff --git a/doc/classes/CollisionShape.xml b/doc/classes/CollisionShape.xml index bbbc07e6d3..c34c0be839 100644 --- a/doc/classes/CollisionShape.xml +++ b/doc/classes/CollisionShape.xml @@ -31,7 +31,7 @@ <member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" default="false"> A disabled collision shape has no effect in the world. </member> - <member name="shape" type="Shape" setter="set_shape" getter="get_shape" default="null"> + <member name="shape" type="Shape" setter="set_shape" getter="get_shape"> The actual shape owned by this collision shape. </member> </members> diff --git a/doc/classes/CollisionShape2D.xml b/doc/classes/CollisionShape2D.xml index fa002bc881..5fd8826a98 100644 --- a/doc/classes/CollisionShape2D.xml +++ b/doc/classes/CollisionShape2D.xml @@ -20,7 +20,7 @@ </member> <member name="one_way_collision_margin" type="float" setter="set_one_way_collision_margin" getter="get_one_way_collision_margin" default="1.0"> </member> - <member name="shape" type="Shape2D" setter="set_shape" getter="get_shape" default="null"> + <member name="shape" type="Shape2D" setter="set_shape" getter="get_shape"> The actual shape owned by this collision shape. </member> </members> diff --git a/doc/classes/ConeTwistJoint.xml b/doc/classes/ConeTwistJoint.xml index ad9c2b3a35..4c95a4bef9 100644 --- a/doc/classes/ConeTwistJoint.xml +++ b/doc/classes/ConeTwistJoint.xml @@ -11,6 +11,24 @@ <tutorials> </tutorials> <methods> + <method name="get_param" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="ConeTwistJoint.Param"> + </argument> + <description> + </description> + </method> + <method name="set_param"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="ConeTwistJoint.Param"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="bias" type="float" setter="set_param" getter="get_param" default="0.3"> diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index d25c2b31ee..69fec750a2 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -173,6 +173,14 @@ The methods [method can_drop_data] and [method drop_data] must be implemented on controls that want to receive drop data. </description> </method> + <method name="get_anchor" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> <method name="get_begin" qualifiers="const"> <return type="Vector2"> </return> @@ -240,6 +248,14 @@ Returns [member margin_right] and [member margin_bottom]. </description> </method> + <method name="get_focus_neighbour" qualifiers="const"> + <return type="NodePath"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> <method name="get_focus_owner" qualifiers="const"> <return type="Control"> </return> @@ -274,6 +290,14 @@ <description> </description> </method> + <method name="get_margin" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> <method name="get_minimum_size" qualifiers="const"> <return type="Vector2"> </return> @@ -574,6 +598,16 @@ Sets [member margin_right] and [member margin_bottom] at the same time. </description> </method> + <method name="set_focus_neighbour"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="neighbour" type="NodePath"> + </argument> + <description> + </description> + </method> <method name="set_global_position"> <return type="void"> </return> @@ -584,6 +618,16 @@ <description> </description> </method> + <method name="set_margin"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="offset" type="float"> + </argument> + <description> + </description> + </method> <method name="set_margins_preset"> <return type="void"> </return> @@ -744,7 +788,7 @@ <member name="size_flags_vertical" type="int" setter="set_v_size_flags" getter="get_v_size_flags" default="1"> Tells the parent [Container] nodes how they should resize and place the node on the Y axis. Use one of the [code]SIZE_*[/code] constants to change the flags. See the constants to learn what each does. </member> - <member name="theme" type="Theme" setter="set_theme" getter="get_theme" default="null"> + <member name="theme" type="Theme" setter="set_theme" getter="get_theme"> Changing this property replaces the current [Theme] resource this node and all its [Control] children use. </member> </members> diff --git a/doc/classes/CurveTexture.xml b/doc/classes/CurveTexture.xml index 666284138b..e8df560a4c 100644 --- a/doc/classes/CurveTexture.xml +++ b/doc/classes/CurveTexture.xml @@ -11,7 +11,7 @@ <methods> </methods> <members> - <member name="curve" type="Curve" setter="set_curve" getter="get_curve" default="null"> + <member name="curve" type="Curve" setter="set_curve" getter="get_curve"> The [code]curve[/code] rendered onto the texture. </member> <member name="width" type="int" setter="set_width" getter="get_width" default="2048"> diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml index b7710068a6..0820d4e1b6 100644 --- a/doc/classes/DynamicFont.xml +++ b/doc/classes/DynamicFont.xml @@ -40,6 +40,14 @@ Returns the number of fallback fonts. </description> </method> + <method name="get_spacing" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="type" type="int"> + </argument> + <description> + </description> + </method> <method name="remove_fallback"> <return type="void"> </return> @@ -60,6 +68,16 @@ Sets the fallback font at index [code]idx[/code]. </description> </method> + <method name="set_spacing"> + <return type="void"> + </return> + <argument index="0" name="type" type="int"> + </argument> + <argument index="1" name="value" type="int"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="extra_spacing_bottom" type="int" setter="set_spacing" getter="get_spacing" default="0"> @@ -74,7 +92,7 @@ <member name="extra_spacing_top" type="int" setter="set_spacing" getter="get_spacing" default="0"> Extra spacing at the top in pixels. </member> - <member name="font_data" type="DynamicFontData" setter="set_font_data" getter="get_font_data" default="null"> + <member name="font_data" type="DynamicFontData" setter="set_font_data" getter="get_font_data"> The font data. </member> <member name="outline_color" type="Color" setter="set_outline_color" getter="get_outline_color" default="Color( 1, 1, 1, 1 )"> diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml index 3719ad67de..5395a8fcb0 100644 --- a/doc/classes/EditorSettings.xml +++ b/doc/classes/EditorSettings.xml @@ -176,9 +176,13 @@ <signals> <signal name="settings_changed"> <description> + Emitted when editor settings change. </description> </signal> </signals> <constants> + <constant name="NOTIFICATION_EDITOR_SETTINGS_CHANGED" value="10000"> + Emitted when editor settings change. It used by various editor plugins to update their visuals on theme changes or logic on configuration changes. + </constant> </constants> </class> diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml index 9df8ae1aa5..cc3d5a1139 100644 --- a/doc/classes/Environment.xml +++ b/doc/classes/Environment.xml @@ -15,12 +15,30 @@ <link>https://docs.godotengine.org/en/latest/tutorials/3d/high_dynamic_range.html</link> </tutorials> <methods> + <method name="is_glow_level_enabled" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <description> + </description> + </method> + <method name="set_glow_level"> + <return type="void"> + </return> + <argument index="0" name="idx" type="int"> + </argument> + <argument index="1" name="enabled" type="bool"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="adjustment_brightness" type="float" setter="set_adjustment_brightness" getter="get_adjustment_brightness" default="1.0"> Global brightness value of the rendered scene (default value is 1). </member> - <member name="adjustment_color_correction" type="Texture" setter="set_adjustment_color_correction" getter="get_adjustment_color_correction" default="null"> + <member name="adjustment_color_correction" type="Texture" setter="set_adjustment_color_correction" getter="get_adjustment_color_correction"> Applies the provided [Texture] resource to affect the global color aspect of the rendered scene. </member> <member name="adjustment_contrast" type="float" setter="set_adjustment_contrast" getter="get_adjustment_contrast" default="1.0"> @@ -71,7 +89,7 @@ <member name="background_mode" type="int" setter="set_background" getter="get_background" enum="Environment.BGMode" default="0"> Defines the mode of background. </member> - <member name="background_sky" type="Sky" setter="set_sky" getter="get_sky" default="null"> + <member name="background_sky" type="Sky" setter="set_sky" getter="get_sky"> [Sky] resource defined as background. </member> <member name="background_sky_custom_fov" type="float" setter="set_sky_custom_fov" getter="get_sky_custom_fov" default="0.0"> diff --git a/doc/classes/GIProbe.xml b/doc/classes/GIProbe.xml index 6f672bd01a..a9192d1942 100644 --- a/doc/classes/GIProbe.xml +++ b/doc/classes/GIProbe.xml @@ -30,7 +30,7 @@ </member> <member name="compress" type="bool" setter="set_compress" getter="is_compressed" default="false"> </member> - <member name="data" type="GIProbeData" setter="set_probe_data" getter="get_probe_data" default="null"> + <member name="data" type="GIProbeData" setter="set_probe_data" getter="get_probe_data"> </member> <member name="dynamic_range" type="int" setter="set_dynamic_range" getter="get_dynamic_range" default="4"> </member> diff --git a/doc/classes/Generic6DOFJoint.xml b/doc/classes/Generic6DOFJoint.xml index 91a1cb1cd4..bc34f3ac0d 100644 --- a/doc/classes/Generic6DOFJoint.xml +++ b/doc/classes/Generic6DOFJoint.xml @@ -9,6 +9,114 @@ <tutorials> </tutorials> <methods> + <method name="get_flag_x" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag"> + </argument> + <description> + </description> + </method> + <method name="get_flag_y" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag"> + </argument> + <description> + </description> + </method> + <method name="get_flag_z" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag"> + </argument> + <description> + </description> + </method> + <method name="get_param_x" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param"> + </argument> + <description> + </description> + </method> + <method name="get_param_y" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param"> + </argument> + <description> + </description> + </method> + <method name="get_param_z" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param"> + </argument> + <description> + </description> + </method> + <method name="set_flag_x"> + <return type="void"> + </return> + <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag"> + </argument> + <argument index="1" name="value" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_flag_y"> + <return type="void"> + </return> + <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag"> + </argument> + <argument index="1" name="value" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_flag_z"> + <return type="void"> + </return> + <argument index="0" name="flag" type="int" enum="Generic6DOFJoint.Flag"> + </argument> + <argument index="1" name="value" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_param_x"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_param_y"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_param_z"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="Generic6DOFJoint.Param"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="angular_limit_x/damping" type="float" setter="set_param_x" getter="get_param_x" default="1.0"> diff --git a/doc/classes/GeometryInstance.xml b/doc/classes/GeometryInstance.xml index eb1847a055..b108e1be7c 100644 --- a/doc/classes/GeometryInstance.xml +++ b/doc/classes/GeometryInstance.xml @@ -9,6 +9,14 @@ <tutorials> </tutorials> <methods> + <method name="get_flag" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="flag" type="int" enum="GeometryInstance.Flags"> + </argument> + <description> + </description> + </method> <method name="set_custom_aabb"> <return type="void"> </return> @@ -18,6 +26,16 @@ Overrides the bounding box of this node with a custom one. To remove it, set an [AABB] with all fields set to zero. </description> </method> + <method name="set_flag"> + <return type="void"> + </return> + <argument index="0" name="flag" type="int" enum="GeometryInstance.Flags"> + </argument> + <argument index="1" name="value" type="bool"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="cast_shadow" type="int" setter="set_cast_shadows_setting" getter="get_cast_shadows_setting" enum="GeometryInstance.ShadowCastingSetting" default="1"> @@ -38,7 +56,7 @@ <member name="lod_min_hysteresis" type="float" setter="set_lod_min_hysteresis" getter="get_lod_min_hysteresis" default="0.0"> The GeometryInstance's min LOD margin. </member> - <member name="material_override" type="Material" setter="set_material_override" getter="get_material_override" default="null"> + <member name="material_override" type="Material" setter="set_material_override" getter="get_material_override"> The material override for the whole geometry. If there is a material in [code]material_override[/code], it will be used instead of any material set in any material slot of the mesh. </member> diff --git a/doc/classes/GradientTexture.xml b/doc/classes/GradientTexture.xml index ef46491e02..3492b2e261 100644 --- a/doc/classes/GradientTexture.xml +++ b/doc/classes/GradientTexture.xml @@ -11,7 +11,7 @@ <methods> </methods> <members> - <member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient" default="null"> + <member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient"> The [Gradient] that will be used to fill the texture. </member> <member name="width" type="int" setter="set_width" getter="get_width" default="2048"> diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml index 306f17ea44..53ee0b6132 100644 --- a/doc/classes/HTTPRequest.xml +++ b/doc/classes/HTTPRequest.xml @@ -68,6 +68,8 @@ <member name="max_redirects" type="int" setter="set_max_redirects" getter="get_max_redirects" default="8"> Maximum number of allowed redirects. </member> + <member name="timeout" type="int" setter="set_timeout" getter="get_timeout" default="0"> + </member> <member name="use_threads" type="bool" setter="set_use_threads" getter="is_using_threads" default="false"> If [code]true[/code], multithreading is used to improve performance. </member> @@ -123,5 +125,7 @@ <constant name="RESULT_REDIRECT_LIMIT_REACHED" value="11" enum="Result"> Request reached its maximum redirect limit, see [member max_redirects]. </constant> + <constant name="RESULT_TIMEOUT" value="12" enum="Result"> + </constant> </constants> </class> diff --git a/doc/classes/HingeJoint.xml b/doc/classes/HingeJoint.xml index 0ac67be96c..4582e36da6 100644 --- a/doc/classes/HingeJoint.xml +++ b/doc/classes/HingeJoint.xml @@ -9,6 +9,42 @@ <tutorials> </tutorials> <methods> + <method name="get_flag" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="flag" type="int" enum="HingeJoint.Flag"> + </argument> + <description> + </description> + </method> + <method name="get_param" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="HingeJoint.Param"> + </argument> + <description> + </description> + </method> + <method name="set_flag"> + <return type="void"> + </return> + <argument index="0" name="flag" type="int" enum="HingeJoint.Flag"> + </argument> + <argument index="1" name="enabled" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_param"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="HingeJoint.Param"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="angular_limit/bias" type="float" setter="set_param" getter="get_param" default="0.3"> diff --git a/doc/classes/Image.xml b/doc/classes/Image.xml index 65d5fbedc3..8cd69ba0da 100644 --- a/doc/classes/Image.xml +++ b/doc/classes/Image.xml @@ -469,13 +469,7 @@ </method> </methods> <members> - <member name="data" type="Dictionary" setter="_set_data" getter="_get_data" default="{ -"data": PoolByteArray( ), -"format": "Lum8", -"height": 0, -"mipmaps": false, -"width": 0 -}"> + <member name="data" type="Dictionary" setter="_set_data" getter="_get_data" default="{"data": PoolByteArray( ),"format": "Lum8","height": 0,"mipmaps": false,"width": 0}"> Holds all of the image's color data in a given format. See [code]FORMAT_*[/code] constants. </member> </members> diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml index efd8d33faf..bbf1ee186f 100644 --- a/doc/classes/Input.xml +++ b/doc/classes/Input.xml @@ -392,7 +392,7 @@ Makes the mouse cursor hidden if it is visible. </constant> <constant name="MOUSE_MODE_CAPTURED" value="2" enum="MouseMode"> - Captures the mouse. The mouse will be hidden and unable to leave the game window, but it will still register movement and mouse button presses. + Captures the mouse. The mouse will be hidden and unable to leave the game window, but it will still register movement and mouse button presses. On Windows and Linux, the mouse will use raw input mode, which means the reported movement will be unaffected by the OS' mouse acceleration settings. </constant> <constant name="MOUSE_MODE_CONFINED" value="3" enum="MouseMode"> Makes the mouse cursor visible but confines it to the game window. diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml index 95c0e663ce..8515d1063d 100644 --- a/doc/classes/ItemList.xml +++ b/doc/classes/ItemList.xml @@ -505,7 +505,7 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.627451, 0.627451, 0.627451, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.63, 0.63, 0.63, 1 )"> </theme_item> <theme_item name="font_color_selected" type="Color" default="Color( 1, 1, 1, 1 )"> </theme_item> diff --git a/doc/classes/KinematicBody.xml b/doc/classes/KinematicBody.xml index b4e6b0abab..b7c4200b95 100644 --- a/doc/classes/KinematicBody.xml +++ b/doc/classes/KinematicBody.xml @@ -12,6 +12,14 @@ <link>https://docs.godotengine.org/en/latest/tutorials/physics/kinematic_character_2d.html</link> </tutorials> <methods> + <method name="get_axis_lock" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="axis" type="int" enum="PhysicsServer.BodyAxis"> + </argument> + <description> + </description> + </method> <method name="get_floor_velocity" qualifiers="const"> <return type="Vector3"> </return> @@ -120,6 +128,16 @@ As long as the [code]snap[/code] vector is in contact with the ground, the body will remain attached to the surface. This means you must disable snap in order to jump, for example. You can do this by setting[code]snap[/code] to[code](0, 0, 0)[/code] or by using [method move_and_slide] instead. </description> </method> + <method name="set_axis_lock"> + <return type="void"> + </return> + <argument index="0" name="axis" type="int" enum="PhysicsServer.BodyAxis"> + </argument> + <argument index="1" name="lock" type="bool"> + </argument> + <description> + </description> + </method> <method name="test_move"> <return type="bool"> </return> diff --git a/doc/classes/KinematicCollision.xml b/doc/classes/KinematicCollision.xml index 4ce28b25c9..44447c8fc8 100644 --- a/doc/classes/KinematicCollision.xml +++ b/doc/classes/KinematicCollision.xml @@ -12,7 +12,7 @@ <methods> </methods> <members> - <member name="collider" type="Object" setter="" getter="get_collider" default="null"> + <member name="collider" type="Object" setter="" getter="get_collider"> The colliding body. </member> <member name="collider_id" type="int" setter="" getter="get_collider_id" default="0"> @@ -21,7 +21,7 @@ <member name="collider_metadata" type="Variant" setter="" getter="get_collider_metadata"> The colliding body's metadata. See [Object]. </member> - <member name="collider_shape" type="Object" setter="" getter="get_collider_shape" default="null"> + <member name="collider_shape" type="Object" setter="" getter="get_collider_shape"> The colliding body's shape. </member> <member name="collider_shape_index" type="int" setter="" getter="get_collider_shape_index" default="0"> @@ -30,7 +30,7 @@ <member name="collider_velocity" type="Vector3" setter="" getter="get_collider_velocity" default="Vector3( 0, 0, 0 )"> The colliding object's velocity. </member> - <member name="local_shape" type="Object" setter="" getter="get_local_shape" default="null"> + <member name="local_shape" type="Object" setter="" getter="get_local_shape"> The moving object's colliding shape. </member> <member name="normal" type="Vector3" setter="" getter="get_normal" default="Vector3( 0, 0, 0 )"> diff --git a/doc/classes/KinematicCollision2D.xml b/doc/classes/KinematicCollision2D.xml index 91cee3d05a..51c2277fb2 100644 --- a/doc/classes/KinematicCollision2D.xml +++ b/doc/classes/KinematicCollision2D.xml @@ -12,7 +12,7 @@ <methods> </methods> <members> - <member name="collider" type="Object" setter="" getter="get_collider" default="null"> + <member name="collider" type="Object" setter="" getter="get_collider"> The colliding body. </member> <member name="collider_id" type="int" setter="" getter="get_collider_id" default="0"> @@ -21,7 +21,7 @@ <member name="collider_metadata" type="Variant" setter="" getter="get_collider_metadata"> The colliding body's metadata. See [Object]. </member> - <member name="collider_shape" type="Object" setter="" getter="get_collider_shape" default="null"> + <member name="collider_shape" type="Object" setter="" getter="get_collider_shape"> The colliding body's shape. </member> <member name="collider_shape_index" type="int" setter="" getter="get_collider_shape_index" default="0"> @@ -30,7 +30,7 @@ <member name="collider_velocity" type="Vector2" setter="" getter="get_collider_velocity" default="Vector2( 0, 0 )"> The colliding object's velocity. </member> - <member name="local_shape" type="Object" setter="" getter="get_local_shape" default="null"> + <member name="local_shape" type="Object" setter="" getter="get_local_shape"> The moving object's colliding shape. </member> <member name="normal" type="Vector2" setter="" getter="get_normal" default="Vector2( 0, 0 )"> diff --git a/doc/classes/Light.xml b/doc/classes/Light.xml index 64d8442180..6ef7c2652d 100644 --- a/doc/classes/Light.xml +++ b/doc/classes/Light.xml @@ -10,6 +10,24 @@ <link>https://docs.godotengine.org/en/latest/tutorials/3d/lights_and_shadows.html</link> </tutorials> <methods> + <method name="get_param" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="Light.Param"> + </argument> + <description> + </description> + </method> + <method name="set_param"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="Light.Param"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="editor_only" type="bool" setter="set_editor_only" getter="is_editor_only" default="false"> diff --git a/doc/classes/Light2D.xml b/doc/classes/Light2D.xml index 88ad371983..f61be5a5af 100644 --- a/doc/classes/Light2D.xml +++ b/doc/classes/Light2D.xml @@ -70,7 +70,7 @@ <member name="shadow_item_cull_mask" type="int" setter="set_item_shadow_cull_mask" getter="get_item_shadow_cull_mask" default="1"> The shadow mask. Used with [LightOccluder2D] to cast shadows. Only occluders with a matching shadow mask will cast shadows. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> [Texture] used for the Light2D's appearance. </member> <member name="texture_scale" type="float" setter="set_texture_scale" getter="get_texture_scale" default="1.0"> diff --git a/doc/classes/LightOccluder2D.xml b/doc/classes/LightOccluder2D.xml index 55978aa0a1..c7d52e6ef4 100644 --- a/doc/classes/LightOccluder2D.xml +++ b/doc/classes/LightOccluder2D.xml @@ -15,7 +15,7 @@ <member name="light_mask" type="int" setter="set_occluder_light_mask" getter="get_occluder_light_mask" default="1"> The LightOccluder2D's light mask. The LightOccluder2D will cast shadows only from Light2D(s) that have the same light mask(s). </member> - <member name="occluder" type="OccluderPolygon2D" setter="set_occluder_polygon" getter="get_occluder_polygon" default="null"> + <member name="occluder" type="OccluderPolygon2D" setter="set_occluder_polygon" getter="get_occluder_polygon"> The [OccluderPolygon2D] used to compute the shadow. </member> </members> diff --git a/doc/classes/Line2D.xml b/doc/classes/Line2D.xml index b627ae7344..3cb04b8b89 100644 --- a/doc/classes/Line2D.xml +++ b/doc/classes/Line2D.xml @@ -75,7 +75,7 @@ <member name="end_cap_mode" type="int" setter="set_end_cap_mode" getter="get_end_cap_mode" enum="Line2D.LineCapMode" default="0"> Controls the style of the line's last point. Use [code]LINE_CAP_*[/code] constants. </member> - <member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient" default="null"> + <member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient"> The gradient is drawn through the whole line from start to finish. The default color will not be used if a gradient is set. </member> <member name="joint_mode" type="int" setter="set_joint_mode" getter="get_joint_mode" enum="Line2D.LineJointMode" default="0"> @@ -90,7 +90,7 @@ <member name="sharp_limit" type="float" setter="set_sharp_limit" getter="get_sharp_limit" default="2.0"> The direction difference in radians between vector points. This value is only used if [code]joint mode[/code] is set to [constant LINE_JOINT_SHARP]. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> The texture used for the line's texture. Uses [code]texture_mode[/code] for drawing style. </member> <member name="texture_mode" type="int" setter="set_texture_mode" getter="get_texture_mode" enum="Line2D.LineTextureMode" default="0"> diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index 482ec28c56..d90a290fdc 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -187,21 +187,21 @@ <theme_items> <theme_item name="clear" type="Texture"> </theme_item> - <theme_item name="clear_button_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="clear_button_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> <theme_item name="clear_button_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> </theme_item> - <theme_item name="cursor_color" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="cursor_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="focus" type="StyleBox"> </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> <theme_item name="font_color_selected" type="Color" default="Color( 0, 0, 0, 1 )"> </theme_item> - <theme_item name="font_color_uneditable" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 0.5 )"> + <theme_item name="font_color_uneditable" type="Color" default="Color( 0.88, 0.88, 0.88, 0.5 )"> </theme_item> <theme_item name="minimum_spaces" type="int" default="12"> </theme_item> @@ -209,7 +209,7 @@ </theme_item> <theme_item name="read_only" type="StyleBox"> </theme_item> - <theme_item name="selection_color" type="Color" default="Color( 0.490196, 0.490196, 0.490196, 1 )"> + <theme_item name="selection_color" type="Color" default="Color( 0.49, 0.49, 0.49, 1 )"> </theme_item> </theme_items> </class> diff --git a/doc/classes/LinkButton.xml b/doc/classes/LinkButton.xml index 5dfb55a8dd..3e6b5e8c1a 100644 --- a/doc/classes/LinkButton.xml +++ b/doc/classes/LinkButton.xml @@ -32,9 +32,9 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> </theme_item> diff --git a/doc/classes/Material.xml b/doc/classes/Material.xml index 80d8b674f3..f584c5207a 100644 --- a/doc/classes/Material.xml +++ b/doc/classes/Material.xml @@ -11,7 +11,7 @@ <methods> </methods> <members> - <member name="next_pass" type="Material" setter="set_next_pass" getter="get_next_pass" default="null"> + <member name="next_pass" type="Material" setter="set_next_pass" getter="get_next_pass"> </member> <member name="render_priority" type="int" setter="set_render_priority" getter="get_render_priority" default="0"> </member> diff --git a/doc/classes/MenuButton.xml b/doc/classes/MenuButton.xml index 609bf6317a..40d2160baa 100644 --- a/doc/classes/MenuButton.xml +++ b/doc/classes/MenuButton.xml @@ -46,11 +46,11 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> <theme_item name="font_color_disabled" type="Color" default="Color( 1, 1, 1, 0.3 )"> </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> </theme_item> diff --git a/doc/classes/MeshInstance.xml b/doc/classes/MeshInstance.xml index e7dbb8e017..c577635c98 100644 --- a/doc/classes/MeshInstance.xml +++ b/doc/classes/MeshInstance.xml @@ -59,7 +59,7 @@ </method> </methods> <members> - <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh" default="null"> + <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh"> The [Mesh] resource for the instance. </member> <member name="skeleton" type="NodePath" setter="set_skeleton_path" getter="get_skeleton_path" default="NodePath("..")"> diff --git a/doc/classes/MeshInstance2D.xml b/doc/classes/MeshInstance2D.xml index a44b009fb6..4b38b9aa96 100644 --- a/doc/classes/MeshInstance2D.xml +++ b/doc/classes/MeshInstance2D.xml @@ -12,13 +12,13 @@ <methods> </methods> <members> - <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh" default="null"> + <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh"> The [Mesh] that will be drawn by the [MeshInstance2D]. </member> - <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map" default="null"> + <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map"> The normal map that will be used if using the default [CanvasItemMaterial]. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> The [Texture] that will be used if using the default [CanvasItemMaterial]. Can be accessed as [code]TEXTURE[/code] in CanvasItem shader. </member> </members> diff --git a/doc/classes/MeshTexture.xml b/doc/classes/MeshTexture.xml index 4ec8268cc5..f8e02d1851 100644 --- a/doc/classes/MeshTexture.xml +++ b/doc/classes/MeshTexture.xml @@ -11,13 +11,13 @@ <methods> </methods> <members> - <member name="base_texture" type="Texture" setter="set_base_texture" getter="get_base_texture" default="null"> + <member name="base_texture" type="Texture" setter="set_base_texture" getter="get_base_texture"> Sets the base texture that the Mesh will use to draw. </member> <member name="image_size" type="Vector2" setter="set_image_size" getter="get_image_size" default="Vector2( 0, 0 )"> Sets the size of the image, needed for reference. </member> - <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh" default="null"> + <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh"> Sets the mesh used to draw. It must be a mesh using 2D vertices. </member> </members> diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml index 295f23a92c..8a72aa155b 100644 --- a/doc/classes/MultiMesh.xml +++ b/doc/classes/MultiMesh.xml @@ -123,7 +123,7 @@ <member name="instance_count" type="int" setter="set_instance_count" getter="get_instance_count" default="0"> Number of instances that will get drawn. This clears and (re)sizes the buffers. By default, all instances are drawn but you can limit this with [member visible_instance_count]. </member> - <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh" default="null"> + <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh"> Mesh to be drawn. </member> <member name="transform_format" type="int" setter="set_transform_format" getter="get_transform_format" enum="MultiMesh.TransformFormat" default="0"> diff --git a/doc/classes/MultiMeshInstance.xml b/doc/classes/MultiMeshInstance.xml index 5e8cb83a39..16f16fdc8b 100644 --- a/doc/classes/MultiMeshInstance.xml +++ b/doc/classes/MultiMeshInstance.xml @@ -14,7 +14,7 @@ <methods> </methods> <members> - <member name="multimesh" type="MultiMesh" setter="set_multimesh" getter="get_multimesh" default="null"> + <member name="multimesh" type="MultiMesh" setter="set_multimesh" getter="get_multimesh"> The [MultiMesh] resource that will be used and shared among all instances of the [MultiMeshInstance]. </member> </members> diff --git a/doc/classes/MultiMeshInstance2D.xml b/doc/classes/MultiMeshInstance2D.xml index 28cee1aeba..8509986c3c 100644 --- a/doc/classes/MultiMeshInstance2D.xml +++ b/doc/classes/MultiMeshInstance2D.xml @@ -12,13 +12,13 @@ <methods> </methods> <members> - <member name="multimesh" type="MultiMesh" setter="set_multimesh" getter="get_multimesh" default="null"> + <member name="multimesh" type="MultiMesh" setter="set_multimesh" getter="get_multimesh"> The [MultiMesh] that will be drawn by the [MultiMeshInstance2D]. </member> - <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map" default="null"> + <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map"> The normal map that will be used if using the default [CanvasItemMaterial]. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> The [Texture] that will be used if using the default [CanvasItemMaterial]. Can be accessed as [code]TEXTURE[/code] in CanvasItem shader. </member> </members> diff --git a/doc/classes/NavigationMeshInstance.xml b/doc/classes/NavigationMeshInstance.xml index a6266aac0a..2f9cc58aea 100644 --- a/doc/classes/NavigationMeshInstance.xml +++ b/doc/classes/NavigationMeshInstance.xml @@ -11,7 +11,7 @@ <members> <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true"> </member> - <member name="navmesh" type="NavigationMesh" setter="set_navigation_mesh" getter="get_navigation_mesh" default="null"> + <member name="navmesh" type="NavigationMesh" setter="set_navigation_mesh" getter="get_navigation_mesh"> </member> </members> <constants> diff --git a/doc/classes/NavigationPolygonInstance.xml b/doc/classes/NavigationPolygonInstance.xml index 26cc7fbf31..83f3386af6 100644 --- a/doc/classes/NavigationPolygonInstance.xml +++ b/doc/classes/NavigationPolygonInstance.xml @@ -11,7 +11,7 @@ <members> <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" default="true"> </member> - <member name="navpoly" type="NavigationPolygon" setter="set_navigation_polygon" getter="get_navigation_polygon" default="null"> + <member name="navpoly" type="NavigationPolygon" setter="set_navigation_polygon" getter="get_navigation_polygon"> </member> </members> <constants> diff --git a/doc/classes/NinePatchRect.xml b/doc/classes/NinePatchRect.xml index 0723d50ba1..f191b08d96 100644 --- a/doc/classes/NinePatchRect.xml +++ b/doc/classes/NinePatchRect.xml @@ -9,6 +9,24 @@ <tutorials> </tutorials> <methods> + <method name="get_patch_margin" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> + <method name="set_patch_margin"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="value" type="int"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="axis_stretch_horizontal" type="int" setter="set_h_axis_stretch_mode" getter="get_h_axis_stretch_mode" enum="NinePatchRect.AxisStretchMode" default="0"> @@ -35,7 +53,7 @@ <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2( 0, 0, 0, 0 )"> Rectangular region of the texture to sample from. If you're working with an atlas, use this property to define the area the 9-slice should use. All other properties are relative to this one. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> The node's texture resource. </member> </members> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 5a90354124..889ce4d3eb 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -553,7 +553,7 @@ <return type="void"> </return> <description> - Moves this node to the top of the array of nodes of the parent node. This is often useful in GUIs ([Control] nodes), because their order of drawing depends on their order in the tree. + 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. </description> </method> <method name="remove_and_skip"> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index d73c85a6d9..c770e78c7c 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -463,7 +463,7 @@ Returns the absolute directory path where user data is written ([code]user://[/code]). On Linux, this is [code]~/.local/share/godot/app_userdata/[project_name][/code], or [code]~/.local/share/[custom_name][/code] if [code]use_custom_user_dir[/code] is set. On macOS, this is [code]~/Library/Application Support/Godot/app_userdata/[project_name][/code], or [code]~/Library/Application Support/[custom_name][/code] if [code]use_custom_user_dir[/code] is set. - On Windows, this is [code]%APPDATA%/Godot/app_userdata/[project_name][/code], or [code]%APPDATA%/[custom_name][/code] if [code]use_custom_user_dir[/code] is set. + On Windows, this is [code]%APPDATA%\Godot\app_userdata\[project_name][/code], or [code]%APPDATA%\[custom_name][/code] if [code]use_custom_user_dir[/code] is set. [code]%APPDATA%[/code] expands to [code]%USERPROFILE%\AppData\Roaming[/code]. If the project name is empty, [code]user://[/code] falls back to [code]res://[/code]. </description> </method> diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml index c44495ead9..0c2566e845 100644 --- a/doc/classes/OptionButton.xml +++ b/doc/classes/OptionButton.xml @@ -229,11 +229,11 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> </theme_item> diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml index f01ef78c02..0400f2704b 100644 --- a/doc/classes/PackedScene.xml +++ b/doc/classes/PackedScene.xml @@ -65,17 +65,7 @@ </method> </methods> <members> - <member name="_bundled" type="Dictionary" setter="_set_bundled_scene" getter="_get_bundled_scene" default="{ -"conn_count": 0, -"conns": PoolIntArray( ), -"editable_instances": [ ], -"names": PoolStringArray( ), -"node_count": 0, -"node_paths": [ ], -"nodes": PoolIntArray( ), -"variants": [ ], -"version": 2 -}"> + <member name="_bundled" type="Dictionary" setter="_set_bundled_scene" getter="_get_bundled_scene" default="{"conn_count": 0,"conns": PoolIntArray( ),"editable_instances": [ ],"names": PoolStringArray( ),"node_count": 0,"node_paths": [ ],"nodes": PoolIntArray( ),"variants": [ ],"version": 2}"> A dictionary representation of the scene contents. Available keys include "rnames" and "variants" for resources, "node_count", "nodes", "node_paths" for nodes, "editable_instances" for base scene children overrides, "conn_count" and "conns" for signal connections, and "version" for the format style of the PackedScene. </member> diff --git a/doc/classes/PanoramaSky.xml b/doc/classes/PanoramaSky.xml index 93a8bc6166..96aefc0623 100644 --- a/doc/classes/PanoramaSky.xml +++ b/doc/classes/PanoramaSky.xml @@ -11,7 +11,7 @@ <methods> </methods> <members> - <member name="panorama" type="Texture" setter="set_panorama" getter="get_panorama" default="null"> + <member name="panorama" type="Texture" setter="set_panorama" getter="get_panorama"> [Texture] to be applied to the PanoramaSky. </member> </members> diff --git a/doc/classes/Particles.xml b/doc/classes/Particles.xml index 7ff99ebb73..fb74c5a3d4 100644 --- a/doc/classes/Particles.xml +++ b/doc/classes/Particles.xml @@ -18,6 +18,14 @@ Returns the axis-aligned bounding box that contains all the particles that are active in the current frame. </description> </method> + <method name="get_draw_pass_mesh" qualifiers="const"> + <return type="Mesh"> + </return> + <argument index="0" name="pass" type="int"> + </argument> + <description> + </description> + </method> <method name="restart"> <return type="void"> </return> @@ -25,6 +33,16 @@ Restarts the particle emission, clearing existing particles. </description> </method> + <method name="set_draw_pass_mesh"> + <return type="void"> + </return> + <argument index="0" name="pass" type="int"> + </argument> + <argument index="1" name="mesh" type="Mesh"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="amount" type="int" setter="set_amount" getter="get_amount" default="8"> @@ -33,7 +51,7 @@ <member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" enum="Particles.DrawOrder" default="0"> Particle draw order. Uses [code]DRAW_ORDER_*[/code] values. </member> - <member name="draw_pass_1" type="Mesh" setter="set_draw_pass_mesh" getter="get_draw_pass_mesh" default="null"> + <member name="draw_pass_1" type="Mesh" setter="set_draw_pass_mesh" getter="get_draw_pass_mesh"> [Mesh] that is drawn for the first draw pass. </member> <member name="draw_pass_2" type="Mesh" setter="set_draw_pass_mesh" getter="get_draw_pass_mesh"> @@ -72,7 +90,7 @@ <member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" default="0.0"> Amount of time to preprocess the particles before animation starts. Lets you start the animation some time after particles have started emitting. </member> - <member name="process_material" type="Material" setter="set_process_material" getter="get_process_material" default="null"> + <member name="process_material" type="Material" setter="set_process_material" getter="get_process_material"> [Material] for processing particles. Can be a [ParticlesMaterial] or a [ShaderMaterial]. </member> <member name="randomness" type="float" setter="set_randomness_ratio" getter="get_randomness_ratio" default="0.0"> diff --git a/doc/classes/Particles2D.xml b/doc/classes/Particles2D.xml index 52b0c846ca..7c7b42ce88 100644 --- a/doc/classes/Particles2D.xml +++ b/doc/classes/Particles2D.xml @@ -51,7 +51,7 @@ <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true"> If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. </member> - <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map" default="null"> + <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map"> Normal map to be used for the [member texture] property. </member> <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false"> @@ -60,7 +60,7 @@ <member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" default="0.0"> Particle system starts as if it had already run for this many seconds. </member> - <member name="process_material" type="Material" setter="set_process_material" getter="get_process_material" default="null"> + <member name="process_material" type="Material" setter="set_process_material" getter="get_process_material"> [Material] for processing particles. Can be a [ParticlesMaterial] or a [ShaderMaterial]. </member> <member name="randomness" type="float" setter="set_randomness_ratio" getter="get_randomness_ratio" default="0.0"> @@ -69,7 +69,7 @@ <member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0"> Particle system's running speed scaling ratio. A value of [code]0[/code] can be used to pause the particles. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> 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 )"> diff --git a/doc/classes/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml index e0618a87c1..64751cdf76 100644 --- a/doc/classes/ParticlesMaterial.xml +++ b/doc/classes/ParticlesMaterial.xml @@ -11,13 +11,85 @@ <tutorials> </tutorials> <methods> + <method name="get_flag" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="flag" type="int" enum="ParticlesMaterial.Flags"> + </argument> + <description> + </description> + </method> + <method name="get_param" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter"> + </argument> + <description> + </description> + </method> + <method name="get_param_randomness" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter"> + </argument> + <description> + </description> + </method> + <method name="get_param_texture" qualifiers="const"> + <return type="Texture"> + </return> + <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter"> + </argument> + <description> + </description> + </method> + <method name="set_flag"> + <return type="void"> + </return> + <argument index="0" name="flag" type="int" enum="ParticlesMaterial.Flags"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_param"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_param_randomness"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter"> + </argument> + <argument index="1" name="randomness" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_param_texture"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter"> + </argument> + <argument index="1" name="texture" type="Texture"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="angle" type="float" setter="set_param" getter="get_param" default="0.0"> Initial rotation applied to each particle, in degrees. Only applied when [member flag_disable_z] or [member flag_rotate_y] are [code]true[/code] or the [SpatialMaterial] being used to draw the particle is using [constant SpatialMaterial.BILLBOARD_PARTICLES]. </member> - <member name="angle_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" default="null"> + <member name="angle_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Each particle's rotation will be animated along this [CurveTexture]. </member> <member name="angle_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -27,7 +99,7 @@ Initial angular velocity applied to each particle. Sets the speed of rotation of the particle. Only applied when [member flag_disable_z] or [member flag_rotate_y] are [code]true[/code] or the [SpatialMaterial] being used to draw the particle is using [constant SpatialMaterial.BILLBOARD_PARTICLES]. </member> - <member name="angular_velocity_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" default="null"> + <member name="angular_velocity_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Each particle's angular velocity will vary along this [CurveTexture]. </member> <member name="angular_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -36,7 +108,7 @@ <member name="anim_offset" type="float" setter="set_param" getter="get_param" default="0.0"> Particle animation offset. </member> - <member name="anim_offset_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" default="null"> + <member name="anim_offset_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Each particle's animation offset will vary along this [CurveTexture]. </member> <member name="anim_offset_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -45,7 +117,7 @@ <member name="anim_speed" type="float" setter="set_param" getter="get_param" default="0.0"> Particle animation speed. </member> - <member name="anim_speed_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" default="null"> + <member name="anim_speed_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Each particle's animation speed will vary along this [CurveTexture]. </member> <member name="anim_speed_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -54,18 +126,21 @@ <member name="color" type="Color" setter="set_color" getter="get_color" default="Color( 1, 1, 1, 1 )"> Each particle's initial color. If the [Particles2D]'s [code]texture[/code] is defined, it will be multiplied by this color. To have particle display color in a [SpatialMaterial] make sure to set [member SpatialMaterial.vertex_color_use_as_albedo] to [code]true[/code]. </member> - <member name="color_ramp" type="Texture" setter="set_color_ramp" getter="get_color_ramp" default="null"> + <member name="color_ramp" type="Texture" setter="set_color_ramp" getter="get_color_ramp"> Each particle's color will vary along this [GradientTexture]. </member> <member name="damping" type="float" setter="set_param" getter="get_param" default="0.0"> The rate at which particles lose velocity. </member> - <member name="damping_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" default="null"> + <member name="damping_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Damping will vary along this [CurveTexture]. </member> <member name="damping_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> Damping randomness ratio. </member> + <member name="direction" type="Vector3" setter="set_direction" getter="get_direction" default="Vector3( 1, 0, 0 )"> + Unit vector specifying the particles' emission direction. + </member> <member name="emission_box_extents" type="Vector3" setter="set_emission_box_extents" getter="get_emission_box_extents"> The box's extents if [code]emission_shape[/code] is set to [constant EMISSION_SHAPE_BOX]. </member> @@ -105,7 +180,7 @@ <member name="hue_variation" type="float" setter="set_param" getter="get_param" default="0.0"> Initial hue variation applied to each particle. </member> - <member name="hue_variation_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" default="null"> + <member name="hue_variation_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Each particle's hue will vary along this [CurveTexture]. </member> <member name="hue_variation_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -117,10 +192,13 @@ <member name="initial_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> Initial velocity randomness ratio. </member> + <member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0"> + Particle lifetime randomness ratio. + </member> <member name="linear_accel" type="float" setter="set_param" getter="get_param" default="0.0"> Linear acceleration applied to each particle in the direction of motion. </member> - <member name="linear_accel_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" default="null"> + <member name="linear_accel_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Each particle's linear acceleration will vary along this [CurveTexture]. </member> <member name="linear_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -139,7 +217,7 @@ <member name="radial_accel" type="float" setter="set_param" getter="get_param" default="0.0"> Radial acceleration applied to each particle. Makes particle accelerate away from origin. </member> - <member name="radial_accel_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" default="null"> + <member name="radial_accel_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Each particle's radial acceleration will vary along this [CurveTexture]. </member> <member name="radial_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -148,7 +226,7 @@ <member name="scale" type="float" setter="set_param" getter="get_param" default="1.0"> Initial scale applied to each particle. </member> - <member name="scale_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" default="null"> + <member name="scale_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Each particle's scale will vary along this [CurveTexture]. </member> <member name="scale_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> @@ -160,19 +238,19 @@ <member name="tangential_accel" type="float" setter="set_param" getter="get_param" default="0.0"> Tangential acceleration applied to each particle. Tangential acceleration is perpendicular to the particle's velocity giving the particles a swirling motion. </member> - <member name="tangential_accel_curve" type="Texture" setter="set_param_texture" getter="get_param_texture" default="null"> + <member name="tangential_accel_curve" type="Texture" setter="set_param_texture" getter="get_param_texture"> Each particle's tangential acceleration will vary along this [CurveTexture]. </member> <member name="tangential_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0"> Tangential acceleration randomness ratio. </member> - <member name="trail_color_modifier" type="GradientTexture" setter="set_trail_color_modifier" getter="get_trail_color_modifier" default="null"> + <member name="trail_color_modifier" type="GradientTexture" setter="set_trail_color_modifier" getter="get_trail_color_modifier"> Trail particles' color will vary along this [GradientTexture]. </member> <member name="trail_divisor" type="int" setter="set_trail_divisor" getter="get_trail_divisor" default="1"> Emitter will emit [code]amount[/code] divided by [code]trail_divisor[/code] particles. The remaining particles will be used as trail(s). </member> - <member name="trail_size_modifier" type="CurveTexture" setter="set_trail_size_modifier" getter="get_trail_size_modifier" default="null"> + <member name="trail_size_modifier" type="CurveTexture" setter="set_trail_size_modifier" getter="get_trail_size_modifier"> Trail particles' size will vary along this [CurveTexture]. </member> </members> diff --git a/doc/classes/Path.xml b/doc/classes/Path.xml index 5c1100e670..12ae8fd3d5 100644 --- a/doc/classes/Path.xml +++ b/doc/classes/Path.xml @@ -12,11 +12,7 @@ <methods> </methods> <members> - <member name="curve" type="Curve3D" setter="set_curve" getter="get_curve" default="Object(Curve3D,"resource_local_to_scene":false,"resource_name":"","bake_interval":0.2,"_data":{ -"points": PoolVector3Array( ), -"tilts": PoolRealArray( ) -},"up_vector_enabled":true,"script":null) -"> + <member name="curve" type="Curve3D" setter="set_curve" getter="get_curve"> A [Curve3D] describing the path. </member> </members> diff --git a/doc/classes/Path2D.xml b/doc/classes/Path2D.xml index 960cd5163d..b49a3d928d 100644 --- a/doc/classes/Path2D.xml +++ b/doc/classes/Path2D.xml @@ -12,10 +12,7 @@ <methods> </methods> <members> - <member name="curve" type="Curve2D" setter="set_curve" getter="get_curve" default="Object(Curve2D,"resource_local_to_scene":false,"resource_name":"","bake_interval":5.0,"_data":{ -"points": PoolVector2Array( ) -},"script":null) -"> + <member name="curve" type="Curve2D" setter="set_curve" getter="get_curve"> A [Curve2D] describing the path. </member> </members> diff --git a/doc/classes/Physics2DTestMotionResult.xml b/doc/classes/Physics2DTestMotionResult.xml index 410bffc0f0..752b50922d 100644 --- a/doc/classes/Physics2DTestMotionResult.xml +++ b/doc/classes/Physics2DTestMotionResult.xml @@ -9,7 +9,7 @@ <methods> </methods> <members> - <member name="collider" type="Object" setter="" getter="get_collider" default="null"> + <member name="collider" type="Object" setter="" getter="get_collider"> </member> <member name="collider_id" type="int" setter="" getter="get_collider_id" default="0"> </member> diff --git a/doc/classes/PinJoint.xml b/doc/classes/PinJoint.xml index 10ae3d27d9..647a59feef 100644 --- a/doc/classes/PinJoint.xml +++ b/doc/classes/PinJoint.xml @@ -9,6 +9,24 @@ <tutorials> </tutorials> <methods> + <method name="get_param" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="PinJoint.Param"> + </argument> + <description> + </description> + </method> + <method name="set_param"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="PinJoint.Param"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="params/bias" type="float" setter="set_param" getter="get_param" default="0.3"> diff --git a/doc/classes/Polygon2D.xml b/doc/classes/Polygon2D.xml index 6fc0d76d02..7c2aa468ab 100644 --- a/doc/classes/Polygon2D.xml +++ b/doc/classes/Polygon2D.xml @@ -104,7 +104,7 @@ </member> <member name="skeleton" type="NodePath" setter="set_skeleton" getter="get_skeleton" default="NodePath("")"> </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> The polygon's fill texture. Use [code]uv[/code] to set texture coordinates. </member> <member name="texture_offset" type="Vector2" setter="set_texture_offset" getter="get_texture_offset" default="Vector2( 0, 0 )"> diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index a05aff9a59..3d6693da15 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -598,7 +598,7 @@ <theme_item name="font" type="Font"> Sets a custom [Font]. </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> Sets a custom [Color] for the [Font]. </theme_item> <theme_item name="font_color_accel" type="Color" default="Color( 0.7, 0.7, 0.7, 0.8 )"> @@ -606,7 +606,7 @@ <theme_item name="font_color_disabled" type="Color" default="Color( 0.4, 0.4, 0.4, 0.8 )"> Sets a custom [Color] for disabled text. </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="font_color_hover" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> Sets a custom [Color] for the hovered text. </theme_item> <theme_item name="hover" type="StyleBox"> diff --git a/doc/classes/PrimitiveMesh.xml b/doc/classes/PrimitiveMesh.xml index 83d4dea5b1..b0e69bd089 100644 --- a/doc/classes/PrimitiveMesh.xml +++ b/doc/classes/PrimitiveMesh.xml @@ -24,7 +24,7 @@ <member name="flip_faces" type="bool" setter="set_flip_faces" getter="get_flip_faces" default="false"> If set, the order of the vertices in each triangle are reversed resulting in the backside of the mesh being drawn. Result is the same as using *CULL_BACK* in [SpatialMaterial]. </member> - <member name="material" type="Material" setter="set_material" getter="get_material" default="null"> + <member name="material" type="Material" setter="set_material" getter="get_material"> The current [Material] of the primitive mesh. </member> </members> diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml index a8168958cf..96d377fd5e 100644 --- a/doc/classes/ProgressBar.xml +++ b/doc/classes/ProgressBar.xml @@ -24,7 +24,7 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="font_color_shadow" type="Color" default="Color( 0, 0, 0, 1 )"> </theme_item> diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 3e9e063c0c..7ab29e67ae 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -164,7 +164,7 @@ <member name="android/modules" type="String" setter="" getter="" default=""""> Comma-separated list of custom Android modules (which must have been built in the Android export templates) using their Java package path, e.g. [code]org/godotengine/org/GodotPaymentV3,org/godotengine/godot/MyCustomSingleton"[/code]. </member> - <member name="application/boot_splash/bg_color" type="Color" setter="" getter="" default="Color( 0.137255, 0.137255, 0.137255, 1 )"> + <member name="application/boot_splash/bg_color" type="Color" setter="" getter="" default="Color( 0.14, 0.14, 0.14, 1 )"> Background color for the boot splash. </member> <member name="application/boot_splash/fullsize" type="bool" setter="" getter="" default="true"> @@ -434,92 +434,31 @@ <member name="gui/timers/text_edit_idle_detect_sec" type="float" setter="" getter="" default="3"> Timer for detecting idle in the editor (in seconds). </member> - <member name="input/ui_accept" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777221,"unicode":0,"echo":false,"script":null) -, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777222,"unicode":0,"echo":false,"script":null) -, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null) -, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null) - ] -}"> - </member> - <member name="input/ui_cancel" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"unicode":0,"echo":false,"script":null) -, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null) - ] -}"> - </member> - <member name="input/ui_down" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null) -, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) - ] -}"> - </member> - <member name="input/ui_end" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777230,"unicode":0,"echo":false,"script":null) - ] -}"> - </member> - <member name="input/ui_focus_next" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777218,"unicode":0,"echo":false,"script":null) - ] -}"> - </member> - <member name="input/ui_focus_prev" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":true,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777218,"unicode":0,"echo":false,"script":null) - ] -}"> - </member> - <member name="input/ui_home" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777229,"unicode":0,"echo":false,"script":null) - ] -}"> - </member> - <member name="input/ui_left" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null) -, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) - ] -}"> - </member> - <member name="input/ui_page_down" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777236,"unicode":0,"echo":false,"script":null) - ] -}"> - </member> - <member name="input/ui_page_up" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777235,"unicode":0,"echo":false,"script":null) - ] -}"> - </member> - <member name="input/ui_right" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null) -, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null) - ] -}"> - </member> - <member name="input/ui_select" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null) -, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null) - ] -}"> - </member> - <member name="input/ui_up" type="Dictionary" setter="" getter="" default="{ -"deadzone": 0.5, -"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null) -, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) - ] -}"> + <member name="input/ui_accept" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777221,"unicode":0,"echo":false,"script":null), Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777222,"unicode":0,"echo":false,"script":null), Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null), Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":0,"pressure":0.0,"pressed":false,"script":null) ]}"> + </member> + <member name="input/ui_cancel" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777217,"unicode":0,"echo":false,"script":null), Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":1,"pressure":0.0,"pressed":false,"script":null) ]}"> + </member> + <member name="input/ui_down" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null), Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) ]}"> + </member> + <member name="input/ui_end" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777230,"unicode":0,"echo":false,"script":null) ]}"> + </member> + <member name="input/ui_focus_next" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777218,"unicode":0,"echo":false,"script":null) ]}"> + </member> + <member name="input/ui_focus_prev" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":true,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777218,"unicode":0,"echo":false,"script":null) ]}"> + </member> + <member name="input/ui_home" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777229,"unicode":0,"echo":false,"script":null) ]}"> + </member> + <member name="input/ui_left" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null), Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) ]}"> + </member> + <member name="input/ui_page_down" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777236,"unicode":0,"echo":false,"script":null) ]}"> + </member> + <member name="input/ui_page_up" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777235,"unicode":0,"echo":false,"script":null) ]}"> + </member> + <member name="input/ui_right" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null), Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null) ]}"> + </member> + <member name="input/ui_select" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":32,"unicode":0,"echo":false,"script":null), Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":3,"pressure":0.0,"pressed":false,"script":null) ]}"> + </member> + <member name="input/ui_up" type="Dictionary" setter="" getter="" default="{"deadzone": 0.5,"events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null), Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) ]}"> </member> <member name="input_devices/pointing/emulate_mouse_from_touch" type="bool" setter="" getter="" default="true"> If [code]true[/code], sends mouse input events when tapping or swiping on the touchscreen. @@ -720,6 +659,8 @@ <member name="network/limits/packet_peer_stream/max_buffer_po2" type="int" setter="" getter="" default="16"> Default size of packet peer stream for deserializing Godot data. Over this size, data is dropped. </member> + <member name="network/limits/tcp/connect_timeout_seconds" type="int" setter="" getter="" default="30"> + </member> <member name="network/limits/websocket_client/max_in_buffer_kb" type="int" setter="" getter="" default="64"> </member> <member name="network/limits/websocket_client/max_in_packets" type="int" setter="" getter="" default="1024"> @@ -905,7 +846,7 @@ <member name="rendering/vram_compression/import_s3tc" type="bool" setter="" getter="" default="true"> If [code]true[/code], the texture importer will import VRAM-compressed textures using the S3 Texture Compression algorithm. This algorithm is only supported on desktop platforms and consoles. </member> - <member name="script" type="Script" setter="" getter="" default="null"> + <member name="script" type="Script" setter="" getter=""> </member> </members> <constants> diff --git a/doc/classes/ProxyTexture.xml b/doc/classes/ProxyTexture.xml index d403196022..a36f670c42 100644 --- a/doc/classes/ProxyTexture.xml +++ b/doc/classes/ProxyTexture.xml @@ -9,7 +9,7 @@ <methods> </methods> <members> - <member name="base" type="Texture" setter="set_base" getter="get_base" default="null"> + <member name="base" type="Texture" setter="set_base" getter="get_base"> </member> </members> <constants> diff --git a/doc/classes/RemoteTransform.xml b/doc/classes/RemoteTransform.xml index 4628ef8519..377f9cc34b 100644 --- a/doc/classes/RemoteTransform.xml +++ b/doc/classes/RemoteTransform.xml @@ -10,6 +10,13 @@ <tutorials> </tutorials> <methods> + <method name="force_update_cache"> + <return type="void"> + </return> + <description> + [RemoteTransform] caches the remote node. It may not notice if the remote node disappears; [method force_update_cache] forces it to update the cache again. + </description> + </method> </methods> <members> <member name="remote_path" type="NodePath" setter="set_remote_node" getter="get_remote_node" default="NodePath("")"> diff --git a/doc/classes/RemoteTransform2D.xml b/doc/classes/RemoteTransform2D.xml index 6a317724a0..f5d509782f 100644 --- a/doc/classes/RemoteTransform2D.xml +++ b/doc/classes/RemoteTransform2D.xml @@ -10,6 +10,13 @@ <tutorials> </tutorials> <methods> + <method name="force_update_cache"> + <return type="void"> + </return> + <description> + [RemoteTransform2D] caches the remote node. It may not notice if the remote node disappears; [method force_update_cache] forces it to update the cache again. + </description> + </method> </methods> <members> <member name="remote_path" type="NodePath" setter="set_remote_node" getter="get_remote_node" default="NodePath("")"> diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml index 405eb59563..81f5f44866 100644 --- a/doc/classes/RichTextLabel.xml +++ b/doc/classes/RichTextLabel.xml @@ -331,7 +331,7 @@ </theme_item> <theme_item name="focus" type="StyleBox"> </theme_item> - <theme_item name="font_color_selected" type="Color" default="Color( 0.490196, 0.490196, 0.490196, 1 )"> + <theme_item name="font_color_selected" type="Color" default="Color( 0.49, 0.49, 0.49, 1 )"> </theme_item> <theme_item name="font_color_shadow" type="Color" default="Color( 0, 0, 0, 0 )"> </theme_item> diff --git a/doc/classes/RigidBody.xml b/doc/classes/RigidBody.xml index a705789413..4378fc3ffe 100644 --- a/doc/classes/RigidBody.xml +++ b/doc/classes/RigidBody.xml @@ -82,6 +82,14 @@ Applies a torque impulse which will be affected by the body mass and shape. This will rotate the body around the [code]impulse[/code] vector passed. </description> </method> + <method name="get_axis_lock" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="axis" type="int" enum="PhysicsServer.BodyAxis"> + </argument> + <description> + </description> + </method> <method name="get_colliding_bodies" qualifiers="const"> <return type="Array"> </return> @@ -90,6 +98,16 @@ [b]Note:[/b] The result of this test is not immediate after moving objects. For performance, list of collisions is updated once per frame and before the physics step. Consider using signals instead. </description> </method> + <method name="set_axis_lock"> + <return type="void"> + </return> + <argument index="0" name="axis" type="int" enum="PhysicsServer.BodyAxis"> + </argument> + <argument index="1" name="lock" type="bool"> + </argument> + <description> + </description> + </method> <method name="set_axis_velocity"> <return type="void"> </return> @@ -164,7 +182,7 @@ <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="RigidBody.Mode" default="0"> The body mode. See [enum Mode] for possible values. </member> - <member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override" default="null"> + <member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override"> </member> <member name="sleeping" type="bool" setter="set_sleeping" getter="is_sleeping" default="false"> If [code]true[/code], the body is sleeping and will not calculate forces until woken up by a collision or the [code]apply_impulse[/code] method. diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml index 907a82d51d..f280dc81c2 100644 --- a/doc/classes/RigidBody2D.xml +++ b/doc/classes/RigidBody2D.xml @@ -168,7 +168,7 @@ <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="RigidBody2D.Mode" default="0"> The body's mode. See [enum Mode] for possible values. </member> - <member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override" default="null"> + <member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override"> </member> <member name="sleeping" type="bool" setter="set_sleeping" getter="is_sleeping" default="false"> If [code]true[/code], the body is sleeping and will not calculate forces until woken up by a collision or by using [method apply_impulse] or [method add_force]. diff --git a/doc/classes/ShaderMaterial.xml b/doc/classes/ShaderMaterial.xml index 01d9055569..ef355c4417 100644 --- a/doc/classes/ShaderMaterial.xml +++ b/doc/classes/ShaderMaterial.xml @@ -48,7 +48,7 @@ </method> </methods> <members> - <member name="shader" type="Shader" setter="set_shader" getter="get_shader" default="null"> + <member name="shader" type="Shader" setter="set_shader" getter="get_shader"> The [Shader] program used to render this material. </member> </members> diff --git a/doc/classes/ShortCut.xml b/doc/classes/ShortCut.xml index 44a10ba598..4c5dc0e77b 100644 --- a/doc/classes/ShortCut.xml +++ b/doc/classes/ShortCut.xml @@ -35,7 +35,7 @@ </method> </methods> <members> - <member name="shortcut" type="InputEvent" setter="set_shortcut" getter="get_shortcut" default="null"> + <member name="shortcut" type="InputEvent" setter="set_shortcut" getter="get_shortcut"> The shortcut's [InputEvent]. Generally the [InputEvent] is a keyboard key, though it can be any [InputEvent]. </member> diff --git a/doc/classes/SliderJoint.xml b/doc/classes/SliderJoint.xml index a91f67f107..3f22b5a37c 100644 --- a/doc/classes/SliderJoint.xml +++ b/doc/classes/SliderJoint.xml @@ -9,6 +9,24 @@ <tutorials> </tutorials> <methods> + <method name="get_param" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="param" type="int" enum="SliderJoint.Param"> + </argument> + <description> + </description> + </method> + <method name="set_param"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="SliderJoint.Param"> + </argument> + <argument index="1" name="value" type="float"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="angular_limit/damping" type="float" setter="set_param" getter="get_param" default="0.0"> diff --git a/doc/classes/Spatial.xml b/doc/classes/Spatial.xml index 9f4118aa7b..09a5bf3b8f 100644 --- a/doc/classes/Spatial.xml +++ b/doc/classes/Spatial.xml @@ -274,6 +274,7 @@ </argument> <description> Changes the node's position by given offset [Vector3]. + Note that the translation [code]offset[/code] is affected by the node's scale, so if scaled by e.g. [code](10, 1, 1)[/code], a translation by an offset of [code](2, 0, 0)[/code] would actually add 20 ([code]2 * 10[/code]) to the X coordinate. </description> </method> <method name="translate_object_local"> diff --git a/doc/classes/SpatialMaterial.xml b/doc/classes/SpatialMaterial.xml index 5e18e72f90..f684f09263 100644 --- a/doc/classes/SpatialMaterial.xml +++ b/doc/classes/SpatialMaterial.xml @@ -10,12 +10,66 @@ <link>https://docs.godotengine.org/en/latest/tutorials/3d/spatial_material.html</link> </tutorials> <methods> + <method name="get_feature" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="feature" type="int" enum="SpatialMaterial.Feature"> + </argument> + <description> + </description> + </method> + <method name="get_flag" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="flag" type="int" enum="SpatialMaterial.Flags"> + </argument> + <description> + </description> + </method> + <method name="get_texture" qualifiers="const"> + <return type="Texture"> + </return> + <argument index="0" name="param" type="int" enum="SpatialMaterial.TextureParam"> + </argument> + <description> + </description> + </method> + <method name="set_feature"> + <return type="void"> + </return> + <argument index="0" name="feature" type="int" enum="SpatialMaterial.Feature"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_flag"> + <return type="void"> + </return> + <argument index="0" name="flag" type="int" enum="SpatialMaterial.Flags"> + </argument> + <argument index="1" name="enable" type="bool"> + </argument> + <description> + </description> + </method> + <method name="set_texture"> + <return type="void"> + </return> + <argument index="0" name="param" type="int" enum="SpatialMaterial.TextureParam"> + </argument> + <argument index="1" name="texture" type="Texture"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="albedo_color" type="Color" setter="set_albedo" getter="get_albedo" default="Color( 1, 1, 1, 1 )"> The material's base color. </member> - <member name="albedo_texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="albedo_texture" type="Texture" setter="set_texture" getter="get_texture"> </member> <member name="anisotropy" type="float" setter="set_anisotropy" getter="get_anisotropy"> The strength of the anisotropy effect. @@ -136,7 +190,7 @@ General reflectivity amount. [b]Note:[/b] unlike [member metallic], this is not energy-conserving, so it should be left at [code]0.5[/code] in most cases. See also [member roughness]. </member> - <member name="metallic_texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="metallic_texture" type="Texture" setter="set_texture" getter="get_texture"> </member> <member name="metallic_texture_channel" type="int" setter="set_metallic_texture_channel" getter="get_metallic_texture_channel" enum="SpatialMaterial.TextureChannel" default="2"> </member> @@ -221,7 +275,7 @@ <member name="roughness" type="float" setter="set_roughness" getter="get_roughness" default="1.0"> Surface reflection. A value of [code]0[/code] represents a perfect mirror while a value of [code]1[/code] completely blurs the reflection. See also [member metallic]. </member> - <member name="roughness_texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="roughness_texture" type="Texture" setter="set_texture" getter="get_texture"> </member> <member name="roughness_texture_channel" type="int" setter="set_roughness_texture_channel" getter="get_roughness_texture_channel" enum="SpatialMaterial.TextureChannel" default="1"> </member> diff --git a/doc/classes/SpringArm.xml b/doc/classes/SpringArm.xml index 16b4b846e4..438d96f2b3 100644 --- a/doc/classes/SpringArm.xml +++ b/doc/classes/SpringArm.xml @@ -41,7 +41,7 @@ </member> <member name="margin" type="float" setter="set_margin" getter="get_margin" default="0.01"> </member> - <member name="shape" type="Shape" setter="set_shape" getter="get_shape" default="null"> + <member name="shape" type="Shape" setter="set_shape" getter="get_shape"> </member> <member name="spring_length" type="float" setter="set_length" getter="get_length" default="1.0"> </member> diff --git a/doc/classes/Sprite.xml b/doc/classes/Sprite.xml index c14ae43f66..e5aea961f4 100644 --- a/doc/classes/Sprite.xml +++ b/doc/classes/Sprite.xml @@ -49,7 +49,7 @@ <member name="hframes" type="int" setter="set_hframes" getter="get_hframes" default="1"> The number of columns in the sprite sheet. </member> - <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map" default="null"> + <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map"> The normal map gives depth to the Sprite. </member> <member name="offset" type="Vector2" setter="set_offset" getter="get_offset" default="Vector2( 0, 0 )"> @@ -64,7 +64,7 @@ <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2( 0, 0, 0, 0 )"> The region of the atlas texture to display. [member region_enabled] must be [code]true[/code]. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> [Texture] object to draw. </member> <member name="vframes" type="int" setter="set_vframes" getter="get_vframes" default="1"> diff --git a/doc/classes/Sprite3D.xml b/doc/classes/Sprite3D.xml index 78004c60ee..9a51302bf1 100644 --- a/doc/classes/Sprite3D.xml +++ b/doc/classes/Sprite3D.xml @@ -23,7 +23,7 @@ <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2( 0, 0, 0, 0 )"> The region of the atlas texture to display. [member region_enabled] must be [code]true[/code]. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> [Texture] object to draw. </member> <member name="vframes" type="int" setter="set_vframes" getter="get_vframes" default="1"> diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml index 9c5ed213a8..5529da909d 100644 --- a/doc/classes/SpriteBase3D.xml +++ b/doc/classes/SpriteBase3D.xml @@ -15,12 +15,30 @@ <description> </description> </method> + <method name="get_draw_flag" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="flag" type="int" enum="SpriteBase3D.DrawFlags"> + </argument> + <description> + </description> + </method> <method name="get_item_rect" qualifiers="const"> <return type="Rect2"> </return> <description> </description> </method> + <method name="set_draw_flag"> + <return type="void"> + </return> + <argument index="0" name="flag" type="int" enum="SpriteBase3D.DrawFlags"> + </argument> + <argument index="1" name="enabled" type="bool"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="alpha_cut" type="int" setter="set_alpha_cut_mode" getter="get_alpha_cut_mode" enum="SpriteBase3D.AlphaCutMode" default="0"> diff --git a/doc/classes/StaticBody.xml b/doc/classes/StaticBody.xml index 878d76a2e3..a9709d00df 100644 --- a/doc/classes/StaticBody.xml +++ b/doc/classes/StaticBody.xml @@ -27,7 +27,7 @@ The body's friction, from 0 (frictionless) to 1 (full friction). Deprecated, use [member PhysicsMaterial.friction] instead via [member physics_material_override]. </member> - <member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override" default="null"> + <member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override"> </member> </members> <constants> diff --git a/doc/classes/StaticBody2D.xml b/doc/classes/StaticBody2D.xml index 4522a50557..4a7f71b667 100644 --- a/doc/classes/StaticBody2D.xml +++ b/doc/classes/StaticBody2D.xml @@ -26,7 +26,7 @@ The body's friction. Values range from [code]0[/code] (no friction) to [code]1[/code] (full friction). Deprecated, use [member PhysicsMaterial.friction] instead via [member physics_material_override]. </member> - <member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override" default="null"> + <member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override"> </member> </members> <constants> diff --git a/doc/classes/StreamTexture.xml b/doc/classes/StreamTexture.xml index 20cbadb5f0..9c7adea079 100644 --- a/doc/classes/StreamTexture.xml +++ b/doc/classes/StreamTexture.xml @@ -9,6 +9,14 @@ <tutorials> </tutorials> <methods> + <method name="load"> + <return type="int" enum="Error"> + </return> + <argument index="0" name="path" type="String"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="load_path" type="String" setter="load" getter="get_load_path" default=""""> diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 2b16bd2b33..e513a44b1d 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -385,19 +385,30 @@ <return type="int"> </return> <description> - Converts a string containing a hexadecimal number into an integer. + Converts a string containing a hexadecimal number into an integer. Hexadecimal strings are expected to be prefixed with "[code]0x[/code]" otherwise [code]0[/code] is returned. + [codeblock] + print("0xff".hex_to_int()) # Print "255" + [/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] </description> </method> <method name="insert"> @@ -696,6 +707,20 @@ Returns a copy of the string with characters removed from the right. </description> </method> + <method name="sha1_buffer"> + <return type="PoolByteArray"> + </return> + <description> + Returns the SHA-1 hash of the string as an array of bytes. + </description> + </method> + <method name="sha1_text"> + <return type="String"> + </return> + <description> + Returns the SHA-1 hash of the string as a string. + </description> + </method> <method name="sha256_buffer"> <return type="PoolByteArray"> </return> diff --git a/doc/classes/StyleBox.xml b/doc/classes/StyleBox.xml index 6b8f076211..1d873ef0b1 100644 --- a/doc/classes/StyleBox.xml +++ b/doc/classes/StyleBox.xml @@ -31,6 +31,14 @@ <description> </description> </method> + <method name="get_default_margin" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> <method name="get_margin" qualifiers="const"> <return type="float"> </return> @@ -55,6 +63,16 @@ Returns the "offset" of a stylebox. This helper function returns a value equivalent to [code]Vector2(style.get_margin(MARGIN_LEFT), style.get_margin(MARGIN_TOP))[/code]. </description> </method> + <method name="set_default_margin"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="offset" type="float"> + </argument> + <description> + </description> + </method> <method name="test_mask" qualifiers="const"> <return type="bool"> </return> diff --git a/doc/classes/StyleBoxFlat.xml b/doc/classes/StyleBoxFlat.xml index 28f49f831c..05ee79eef2 100644 --- a/doc/classes/StyleBoxFlat.xml +++ b/doc/classes/StyleBoxFlat.xml @@ -24,12 +24,46 @@ <tutorials> </tutorials> <methods> + <method name="get_border_width" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> <method name="get_border_width_min" qualifiers="const"> <return type="int"> </return> <description> </description> </method> + <method name="get_corner_radius" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="corner" type="int" enum="Corner"> + </argument> + <description> + </description> + </method> + <method name="get_expand_margin" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> + <method name="set_border_width"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="width" type="int"> + </argument> + <description> + </description> + </method> <method name="set_border_width_all"> <return type="void"> </return> @@ -38,6 +72,16 @@ <description> </description> </method> + <method name="set_corner_radius"> + <return type="void"> + </return> + <argument index="0" name="corner" type="int" enum="Corner"> + </argument> + <argument index="1" name="radius" type="int"> + </argument> + <description> + </description> + </method> <method name="set_corner_radius_all"> <return type="void"> </return> @@ -60,6 +104,16 @@ <description> </description> </method> + <method name="set_expand_margin"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="size" type="float"> + </argument> + <description> + </description> + </method> <method name="set_expand_margin_all"> <return type="void"> </return> diff --git a/doc/classes/StyleBoxTexture.xml b/doc/classes/StyleBoxTexture.xml index e51120f269..d5efc80846 100644 --- a/doc/classes/StyleBoxTexture.xml +++ b/doc/classes/StyleBoxTexture.xml @@ -9,6 +9,22 @@ <tutorials> </tutorials> <methods> + <method name="get_expand_margin_size" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> + <method name="get_margin_size" qualifiers="const"> + <return type="float"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> <method name="set_expand_margin_all"> <return type="void"> </return> @@ -31,6 +47,26 @@ <description> </description> </method> + <method name="set_expand_margin_size"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="size" type="float"> + </argument> + <description> + </description> + </method> + <method name="set_margin_size"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="size" type="float"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="axis_stretch_horizontal" type="int" setter="set_h_axis_stretch_mode" getter="get_h_axis_stretch_mode" enum="StyleBoxTexture.AxisStretchMode" default="0"> @@ -74,14 +110,14 @@ <member name="modulate_color" type="Color" setter="set_modulate" getter="get_modulate" default="Color( 1, 1, 1, 1 )"> Modulates the color of the texture when this style box is drawn. </member> - <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map" default="null"> + <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map"> The normal map to use when drawing this style box. </member> <member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" default="Rect2( 0, 0, 0, 0 )"> Species a sub region of the texture to use. This is equivalent to first wrapping the texture in an [AtlasTexture] with the same region. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> The texture to use when drawing this style box. </member> </members> diff --git a/doc/classes/TCP_Server.xml b/doc/classes/TCP_Server.xml index 432d83f25b..cac3a0b082 100644 --- a/doc/classes/TCP_Server.xml +++ b/doc/classes/TCP_Server.xml @@ -16,6 +16,13 @@ Returns [code]true[/code] if a connection is available for taking. </description> </method> + <method name="is_listening" qualifiers="const"> + <return type="bool"> + </return> + <description> + Returns [code]true[/code] if the server is currently listening for connections. + </description> + </method> <method name="listen"> <return type="int" enum="Error"> </return> diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml index 2eb8411078..22b009a15a 100644 --- a/doc/classes/TabContainer.xml +++ b/doc/classes/TabContainer.xml @@ -189,11 +189,11 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color_bg" type="Color" default="Color( 0.690196, 0.690196, 0.690196, 1 )"> + <theme_item name="font_color_bg" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )"> </theme_item> <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> </theme_item> - <theme_item name="font_color_fg" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="font_color_fg" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="hseparation" type="int" default="4"> </theme_item> diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml index b6d702ba45..6bd7b8c2c3 100644 --- a/doc/classes/Tabs.xml +++ b/doc/classes/Tabs.xml @@ -260,11 +260,11 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color_bg" type="Color" default="Color( 0.690196, 0.690196, 0.690196, 1 )"> + <theme_item name="font_color_bg" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )"> </theme_item> <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.9, 0.9, 0.2 )"> </theme_item> - <theme_item name="font_color_fg" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="font_color_fg" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="hseparation" type="int" default="4"> </theme_item> diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml index e665178809..22c769330d 100644 --- a/doc/classes/TextEdit.xml +++ b/doc/classes/TextEdit.xml @@ -520,7 +520,7 @@ </constant> </constants> <theme_items> - <theme_item name="background_color" type="Color" default="Color( 0, 0, 0, 0 )"> + <theme_item name="background_color" type="Color" default="Color( 0, 0, 0, 1 )"> Sets the background [Color] of this [TextEdit]. [member syntax_highlighting] has to be enabled. </theme_item> <theme_item name="bookmark_color" type="Color" default="Color( 0.08, 0.49, 0.98, 1 )"> @@ -533,17 +533,17 @@ </theme_item> <theme_item name="caret_background_color" type="Color" default="Color( 0, 0, 0, 1 )"> </theme_item> - <theme_item name="caret_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="caret_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> <theme_item name="code_folding_color" type="Color" default="Color( 0.8, 0.8, 0.8, 0.8 )"> </theme_item> <theme_item name="completion" type="StyleBox"> </theme_item> - <theme_item name="completion_background_color" type="Color" default="Color( 0.172549, 0.164706, 0.196078, 1 )"> + <theme_item name="completion_background_color" type="Color" default="Color( 0.17, 0.16, 0.2, 1 )"> </theme_item> - <theme_item name="completion_existing_color" type="Color" default="Color( 0.87451, 0.87451, 0.87451, 0.129412 )"> + <theme_item name="completion_existing_color" type="Color" default="Color( 0.87, 0.87, 0.87, 0.13 )"> </theme_item> - <theme_item name="completion_font_color" type="Color" default="Color( 0.666667, 0.666667, 0.666667, 1 )"> + <theme_item name="completion_font_color" type="Color" default="Color( 0.67, 0.67, 0.67, 1 )"> </theme_item> <theme_item name="completion_lines" type="int" default="7"> </theme_item> @@ -553,7 +553,7 @@ </theme_item> <theme_item name="completion_scroll_width" type="int" default="3"> </theme_item> - <theme_item name="completion_selected_color" type="Color" default="Color( 0.262745, 0.258824, 0.266667, 1 )"> + <theme_item name="completion_selected_color" type="Color" default="Color( 0.26, 0.26, 0.27, 1 )"> </theme_item> <theme_item name="current_line_color" type="Color" default="Color( 0.25, 0.25, 0.26, 0.8 )"> Sets the [Color] of the breakpoints. [member breakpoint_gutter] has to be enabled. @@ -569,16 +569,16 @@ <theme_item name="font" type="Font"> Sets the default [Font]. </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <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.878431, 0.878431, 0.878431, 0.5 )"> + <theme_item name="font_color_readonly" 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> - <theme_item name="function_color" type="Color" default="Color( 0.4, 0.635294, 0.807843, 1 )"> + <theme_item name="function_color" type="Color" default="Color( 0.4, 0.64, 0.81, 1 )"> </theme_item> - <theme_item name="line_number_color" type="Color" default="Color( 0.666667, 0.666667, 0.666667, 0.4 )"> + <theme_item name="line_number_color" type="Color" default="Color( 0.67, 0.67, 0.67, 0.4 )"> Sets the [Color] of the line numbers. [member show_line_numbers] has to be enabled. </theme_item> <theme_item name="line_spacing" type="int" default="4"> @@ -587,24 +587,24 @@ <theme_item name="mark_color" type="Color" default="Color( 1, 0.4, 0.4, 0.4 )"> Sets the [Color] of marked text. </theme_item> - <theme_item name="member_variable_color" type="Color" default="Color( 0.901961, 0.305882, 0.34902, 1 )"> + <theme_item name="member_variable_color" type="Color" default="Color( 0.9, 0.31, 0.35, 1 )"> </theme_item> <theme_item name="normal" type="StyleBox"> Sets the [StyleBox] of this [TextEdit]. </theme_item> - <theme_item name="number_color" type="Color" default="Color( 0.921569, 0.584314, 0.196078, 1 )"> + <theme_item name="number_color" type="Color" default="Color( 0.92, 0.58, 0.2, 1 )"> </theme_item> <theme_item name="read_only" type="StyleBox"> Sets the [StyleBox] of this [TextEdit] when [member readonly] is enabled. </theme_item> - <theme_item name="safe_line_number_color" type="Color" default="Color( 0.666667, 0.784314, 0.666667, 0.6 )"> + <theme_item name="safe_line_number_color" type="Color" default="Color( 0.67, 0.78, 0.67, 0.6 )"> </theme_item> - <theme_item name="selection_color" type="Color" default="Color( 0.490196, 0.490196, 0.490196, 1 )"> + <theme_item name="selection_color" type="Color" default="Color( 0.49, 0.49, 0.49, 1 )"> Sets the highlight [Color] of text selections. </theme_item> <theme_item name="space" type="Texture"> </theme_item> - <theme_item name="symbol_color" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="symbol_color" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="tab" type="Texture"> Sets a custom [Texture] for tab text characters. diff --git a/doc/classes/TextureButton.xml b/doc/classes/TextureButton.xml index e3396a10c2..899ab8b875 100644 --- a/doc/classes/TextureButton.xml +++ b/doc/classes/TextureButton.xml @@ -18,22 +18,22 @@ <member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" enum="TextureButton.StretchMode" default="0"> Controls the texture's behavior when you resize the node's bounding rectangle, [b]only if[/b] [member expand] is [code]true[/code]. Set it to one of the [code]STRETCH_*[/code] constants. See the constants to learn more. </member> - <member name="texture_click_mask" type="BitMap" setter="set_click_mask" getter="get_click_mask" default="null"> + <member name="texture_click_mask" type="BitMap" setter="set_click_mask" getter="get_click_mask"> Pure black and white [BitMap] image to use for click detection. On the mask, white pixels represent the button's clickable area. Use it to create buttons with curved shapes. </member> - <member name="texture_disabled" type="Texture" setter="set_disabled_texture" getter="get_disabled_texture" default="null"> + <member name="texture_disabled" type="Texture" setter="set_disabled_texture" getter="get_disabled_texture"> Texture to display when the node is disabled. See [member BaseButton.disabled]. </member> - <member name="texture_focused" type="Texture" setter="set_focused_texture" getter="get_focused_texture" default="null"> + <member name="texture_focused" type="Texture" setter="set_focused_texture" getter="get_focused_texture"> Texture to display when the node has mouse or keyboard focus. </member> - <member name="texture_hover" type="Texture" setter="set_hover_texture" getter="get_hover_texture" default="null"> + <member name="texture_hover" type="Texture" setter="set_hover_texture" getter="get_hover_texture"> Texture to display when the mouse hovers the node. </member> - <member name="texture_normal" type="Texture" setter="set_normal_texture" getter="get_normal_texture" default="null"> + <member name="texture_normal" type="Texture" setter="set_normal_texture" getter="get_normal_texture"> Texture to display by default, when the node is [b]not[/b] in the disabled, focused, hover or pressed state. </member> - <member name="texture_pressed" type="Texture" setter="set_pressed_texture" getter="get_pressed_texture" default="null"> + <member name="texture_pressed" type="Texture" setter="set_pressed_texture" getter="get_pressed_texture"> Texture to display on mouse down over the node, if the node has keyboard focus and the player presses the Enter key or if the player presses the [member BaseButton.shortcut] key. </member> </members> diff --git a/doc/classes/TextureLayered.xml b/doc/classes/TextureLayered.xml index a9ad5c251d..232df8f59b 100644 --- a/doc/classes/TextureLayered.xml +++ b/doc/classes/TextureLayered.xml @@ -83,14 +83,7 @@ </method> </methods> <members> - <member name="data" type="Dictionary" setter="_set_data" getter="_get_data" default="{ -"depth": 0, -"flags": 4, -"format": 37, -"height": 0, -"layers": [ ], -"width": 0 -}"> + <member name="data" type="Dictionary" setter="_set_data" getter="_get_data" default="{"depth": 0,"flags": 4,"format": 37,"height": 0,"layers": [ ],"width": 0}"> </member> <member name="flags" type="int" setter="set_flags" getter="get_flags" default="4"> </member> diff --git a/doc/classes/TextureProgress.xml b/doc/classes/TextureProgress.xml index 409d005067..4f8ea6438b 100644 --- a/doc/classes/TextureProgress.xml +++ b/doc/classes/TextureProgress.xml @@ -9,6 +9,24 @@ <tutorials> </tutorials> <methods> + <method name="get_stretch_margin" qualifiers="const"> + <return type="int"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <description> + </description> + </method> + <method name="set_stretch_margin"> + <return type="void"> + </return> + <argument index="0" name="margin" type="int" enum="Margin"> + </argument> + <argument index="1" name="value" type="int"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="fill_mode" type="int" setter="set_fill_mode" getter="get_fill_mode" default="0"> @@ -39,14 +57,14 @@ <member name="stretch_margin_top" type="int" setter="set_stretch_margin" getter="get_stretch_margin" default="0"> The height of the 9-patch's top row. </member> - <member name="texture_over" type="Texture" setter="set_over_texture" getter="get_over_texture" default="null"> + <member name="texture_over" type="Texture" setter="set_over_texture" getter="get_over_texture"> [Texture] that draws over the progress bar. Use it to add highlights or an upper-frame that hides part of [member texture_progress]. </member> - <member name="texture_progress" type="Texture" setter="set_progress_texture" getter="get_progress_texture" default="null"> + <member name="texture_progress" type="Texture" setter="set_progress_texture" getter="get_progress_texture"> [Texture] that clips based on the node's [code]value[/code] and [member fill_mode]. As [code]value[/code] increased, the texture fills up. It shows entirely when [code]value[/code] reaches [code]max_value[/code]. It doesn't show at all if [code]value[/code] is equal to [code]min_value[/code]. The [code]value[/code] property comes from [Range]. See [member Range.value], [member Range.min_value], [member Range.max_value]. </member> - <member name="texture_under" type="Texture" setter="set_under_texture" getter="get_under_texture" default="null"> + <member name="texture_under" type="Texture" setter="set_under_texture" getter="get_under_texture"> [Texture] that draws under the progress bar. The bar's background. </member> <member name="tint_over" type="Color" setter="set_tint_over" getter="get_tint_over" default="Color( 1, 1, 1, 1 )"> diff --git a/doc/classes/TextureRect.xml b/doc/classes/TextureRect.xml index 8320d535ea..be46459b21 100644 --- a/doc/classes/TextureRect.xml +++ b/doc/classes/TextureRect.xml @@ -23,7 +23,7 @@ <member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" enum="TextureRect.StretchMode" default="0"> Controls the texture's behavior when resizing the node's bounding rectangle. See [enum StretchMode]. </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> The node's [Texture] resource. </member> </members> diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml index 9c2676a55a..e4db9243ef 100644 --- a/doc/classes/Theme.xml +++ b/doc/classes/Theme.xml @@ -335,7 +335,7 @@ </method> </methods> <members> - <member name="default_font" type="Font" setter="set_default_font" getter="get_default_font" default="null"> + <member name="default_font" type="Font" setter="set_default_font" getter="get_default_font"> The theme's default font. </member> </members> diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml index 55666b94b5..efb7a0d900 100644 --- a/doc/classes/TileMap.xml +++ b/doc/classes/TileMap.xml @@ -274,6 +274,10 @@ <member name="cell_y_sort" type="bool" setter="set_y_sort_mode" getter="is_y_sort_mode_enabled" default="false"> If [code]true[/code], the TileMap's children will be drawn in order of their Y coordinate. </member> + <member name="centered_textures" type="bool" setter="set_centered_textures" getter="is_centered_textures_enabled" default="false"> + If [code]true[/code], the textures will be centered in the middle of each tile. This is useful for certain isometric or top-down modes when textures are made larger or smaller than the tiles (e.g. to avoid flickering on tile edges). The offset is still applied, but from the center of the tile. If used, [member compatibility_mode] is ignored. + If [code]false[/code], the texture position start in the top-left corner unless [member compatibility_mode] is enabled. + </member> <member name="collision_bounce" type="float" setter="set_collision_bounce" getter="get_collision_bounce" default="0.0"> Bounce value for static body collisions (see [code]collision_use_kinematic[/code]). </member> @@ -291,13 +295,18 @@ </member> <member name="collision_use_parent" type="bool" setter="set_collision_use_parent" getter="get_collision_use_parent" default="false"> </member> + <member name="compatibility_mode" type="bool" setter="set_compatibility_mode" getter="is_compatibility_mode_enabled" default="false"> + If [code]true[/code], the compatibility with the tilemaps made in Godot 3.1 or earlier is maintained (textures move when the tile origin changes and rotate if the texture size is not homogeneous). This mode presents problems when doing [code]flip_h[/code], [code]flip_v[/code] and [code]transpose[/code] tile operations on non-homogeneous isometric tiles (e.g. 2:1), in which the texture could not coincide with the collision, thus it is not recommended for isometric or non-square tiles. + If [code]false[/code], the textures do not move when doing [code]flip_h[/code], [code]flip_v[/code] operations if no offset is used, nor when changing the tile origin. + The compatibility mode doesn't work with the [member centered_textures] option, because displacing textures with the [member cell_tile_origin] option or in irregular tiles is not relevant when centering those textures. + </member> <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="TileMap.Mode" default="0"> The TileMap orientation mode. See [enum Mode] for possible values. </member> <member name="occluder_light_mask" type="int" setter="set_occluder_light_mask" getter="get_occluder_light_mask" default="1"> The light mask assigned to all light occluders in the TileMap. The TileSet's light occluders will cast shadows only from Light2D(s) that have the same light mask(s). </member> - <member name="tile_set" type="TileSet" setter="set_tileset" getter="get_tileset" default="null"> + <member name="tile_set" type="TileSet" setter="set_tileset" getter="get_tileset"> The assigned [TileSet]. </member> </members> diff --git a/doc/classes/ToolButton.xml b/doc/classes/ToolButton.xml index 3511987474..f617c2a94f 100644 --- a/doc/classes/ToolButton.xml +++ b/doc/classes/ToolButton.xml @@ -23,11 +23,11 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> <theme_item name="font_color_disabled" type="Color" default="Color( 0.9, 0.95, 1, 0.3 )"> </theme_item> - <theme_item name="font_color_hover" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="font_color_hover" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="font_color_pressed" type="Color" default="Color( 1, 1, 1, 1 )"> </theme_item> diff --git a/doc/classes/TouchScreenButton.xml b/doc/classes/TouchScreenButton.xml index fd9f96a41e..fccfb4cd6d 100644 --- a/doc/classes/TouchScreenButton.xml +++ b/doc/classes/TouchScreenButton.xml @@ -21,19 +21,19 @@ <member name="action" type="String" setter="set_action" getter="get_action" default=""""> The button's action. Actions can be handled with [InputEventAction]. </member> - <member name="bitmask" type="BitMap" setter="set_bitmask" getter="get_bitmask" default="null"> + <member name="bitmask" type="BitMap" setter="set_bitmask" getter="get_bitmask"> The button's bitmask. </member> - <member name="normal" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="normal" type="Texture" setter="set_texture" getter="get_texture"> The button's texture for the normal state. </member> <member name="passby_press" type="bool" setter="set_passby_press" getter="is_passby_press_enabled" default="false"> If [code]true[/code], pass-by presses are enabled. </member> - <member name="pressed" type="Texture" setter="set_texture_pressed" getter="get_texture_pressed" default="null"> + <member name="pressed" type="Texture" setter="set_texture_pressed" getter="get_texture_pressed"> The button's texture for the pressed state. </member> - <member name="shape" type="Shape2D" setter="set_shape" getter="get_shape" default="null"> + <member name="shape" type="Shape2D" setter="set_shape" getter="get_shape"> The button's shape. </member> <member name="shape_centered" type="bool" setter="set_shape_centered" getter="is_shape_centered" default="true"> diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml index 80a393dcee..9916d25af5 100644 --- a/doc/classes/Transform.xml +++ b/doc/classes/Transform.xml @@ -167,12 +167,16 @@ </members> <constants> <constant name="IDENTITY" value="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + [Transform] with no translation, rotation or scaling applied. When applied to other data structures, [constant IDENTITY] performs no transformation. </constant> <constant name="FLIP_X" value="Transform( -1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )"> + [Transform] with mirroring applied perpendicular to the YZ plane. </constant> <constant name="FLIP_Y" value="Transform( 1, 0, 0, 0, -1, 0, 0, 0, 1, 0, 0, 0 )"> + [Transform] with mirroring applied perpendicular to the XZ plane. </constant> <constant name="FLIP_Z" value="Transform( 1, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0 )"> + [Transform] with mirroring applied perpendicular to the XY plane. </constant> </constants> </class> diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml index c5ae88d050..f6fce1aaa1 100644 --- a/doc/classes/Transform2D.xml +++ b/doc/classes/Transform2D.xml @@ -172,10 +172,13 @@ </members> <constants> <constant name="IDENTITY" value="Transform2D( 1, 0, 0, 1, 0, 0 )"> + [Transform2D] with no translation, rotation or scaling applied. When applied to other data structures, [constant IDENTITY] performs no transformation. </constant> <constant name="FLIP_X" value="Transform2D( -1, 0, 0, 1, 0, 0 )"> + [Transform2D] with mirroring applied parallel to the X axis. </constant> <constant name="FLIP_Y" value="Transform2D( 1, 0, 0, -1, 0, 0 )"> + [Transform2D] with mirroring applied parallel to the Y axis. </constant> </constants> </class> diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index 416a9eb656..22c74d4ca5 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -382,7 +382,7 @@ </theme_item> <theme_item name="custom_button" type="StyleBox"> </theme_item> - <theme_item name="custom_button_font_highlight" type="Color" default="Color( 0.941176, 0.941176, 0.941176, 1 )"> + <theme_item name="custom_button_font_highlight" type="Color" default="Color( 0.94, 0.94, 0.94, 1 )"> </theme_item> <theme_item name="custom_button_hover" type="StyleBox"> </theme_item> @@ -396,7 +396,7 @@ </theme_item> <theme_item name="font" type="Font"> </theme_item> - <theme_item name="font_color" type="Color" default="Color( 0.690196, 0.690196, 0.690196, 1 )"> + <theme_item name="font_color" type="Color" default="Color( 0.69, 0.69, 0.69, 1 )"> </theme_item> <theme_item name="font_color_selected" type="Color" default="Color( 1, 1, 1, 1 )"> </theme_item> @@ -408,7 +408,7 @@ </theme_item> <theme_item name="item_margin" type="int" default="12"> </theme_item> - <theme_item name="relationship_line_color" type="Color" default="Color( 0.27451, 0.27451, 0.27451, 1 )"> + <theme_item name="relationship_line_color" type="Color" default="Color( 0.27, 0.27, 0.27, 1 )"> </theme_item> <theme_item name="scroll_border" type="int" default="4"> </theme_item> @@ -422,7 +422,7 @@ </theme_item> <theme_item name="selection_color" type="Color" default="Color( 0.1, 0.1, 1, 0.8 )"> </theme_item> - <theme_item name="title_button_color" type="Color" default="Color( 0.878431, 0.878431, 0.878431, 1 )"> + <theme_item name="title_button_color" type="Color" default="Color( 0.88, 0.88, 0.88, 1 )"> </theme_item> <theme_item name="title_button_font" type="Font"> </theme_item> diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index d9c7013d34..56b4b21525 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -337,6 +337,19 @@ Sets the given column's button [Texture] at index [code]button_idx[/code] to [code]button[/code]. </description> </method> + <method name="set_button_disabled"> + <return type="void"> + </return> + <argument index="0" name="column" type="int"> + </argument> + <argument index="1" name="button_idx" type="int"> + </argument> + <argument index="2" name="disabled" type="bool"> + </argument> + <description> + If [code]true[/code], disables the button at index [code]button_idx[/code] in column [code]column[/code]. + </description> + </method> <method name="set_cell_mode"> <return type="void"> </return> diff --git a/doc/classes/VideoPlayer.xml b/doc/classes/VideoPlayer.xml index 45341cee74..18a85d496f 100644 --- a/doc/classes/VideoPlayer.xml +++ b/doc/classes/VideoPlayer.xml @@ -64,7 +64,7 @@ <member name="paused" type="bool" setter="set_paused" getter="is_paused" default="false"> If [code]true[/code], the video is paused. </member> - <member name="stream" type="VideoStream" setter="set_stream" getter="get_stream" default="null"> + <member name="stream" type="VideoStream" setter="set_stream" getter="get_stream"> </member> <member name="stream_position" type="float" setter="set_stream_position" getter="get_stream_position"> The current position of the stream, in seconds. diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml index a9ffd9f66d..117c4835eb 100644 --- a/doc/classes/Viewport.xml +++ b/doc/classes/Viewport.xml @@ -67,6 +67,14 @@ Returns information about the viewport from the rendering pipeline. </description> </method> + <method name="get_shadow_atlas_quadrant_subdiv" qualifiers="const"> + <return type="int" enum="Viewport.ShadowAtlasQuadrantSubdiv"> + </return> + <argument index="0" name="quadrant" type="int"> + </argument> + <description> + </description> + </method> <method name="get_size_override" qualifiers="const"> <return type="Vector2"> </return> @@ -141,13 +149,6 @@ Returns [code]true[/code] if the size override is enabled. See [method set_size_override]. </description> </method> - <method name="is_size_override_stretch_enabled" qualifiers="const"> - <return type="bool"> - </return> - <description> - Returns [code]true[/code] if the size stretch override is enabled. See [method set_size_override_stretch]. - </description> - </method> <method name="set_attach_to_screen_rect"> <return type="void"> </return> @@ -162,26 +163,27 @@ <description> </description> </method> - <method name="set_size_override"> + <method name="set_shadow_atlas_quadrant_subdiv"> <return type="void"> </return> - <argument index="0" name="enable" type="bool"> + <argument index="0" name="quadrant" type="int"> </argument> - <argument index="1" name="size" type="Vector2" default="Vector2( -1, -1 )"> - </argument> - <argument index="2" name="margin" type="Vector2" default="Vector2( 0, 0 )"> + <argument index="1" name="subdiv" type="int" enum="Viewport.ShadowAtlasQuadrantSubdiv"> </argument> <description> - Sets the size override of the viewport. If the [code]enable[/code] parameter is [code]true[/code] the override is used, otherwise it uses the default size. If the size parameter is [code](-1, -1)[/code], it won't update the size. </description> </method> - <method name="set_size_override_stretch"> + <method name="set_size_override"> <return type="void"> </return> - <argument index="0" name="enabled" type="bool"> + <argument index="0" name="enable" type="bool"> + </argument> + <argument index="1" name="size" type="Vector2" default="Vector2( -1, -1 )"> + </argument> + <argument index="2" name="margin" type="Vector2" default="Vector2( 0, 0 )"> </argument> <description> - If [code]true[/code], the size override affects stretch as well. + Sets the size override of the viewport. If the [code]enable[/code] parameter is [code]true[/code] the override is used, otherwise it uses the default size. If the size parameter is [code](-1, -1)[/code], it won't update the size. </description> </method> <method name="unhandled_input"> @@ -284,13 +286,16 @@ <member name="size" type="Vector2" setter="set_size" getter="get_size" default="Vector2( 0, 0 )"> The width and height of viewport. </member> + <member name="size_override_stretch" type="bool" setter="set_size_override_stretch" getter="is_size_override_stretch_enabled" default="false"> + If [code]true[/code], the size override affects stretch as well. + </member> <member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background" default="false"> If [code]true[/code], the viewport should render its background as transparent. </member> <member name="usage" type="int" setter="set_usage" getter="get_usage" enum="Viewport.Usage" default="2"> The rendering mode of viewport. </member> - <member name="world" type="World" setter="set_world" getter="get_world" default="null"> + <member name="world" type="World" setter="set_world" getter="get_world"> The custom [World] which can be used as 3D environment source. </member> <member name="world_2d" type="World2D" setter="set_world_2d" getter="get_world_2d"> diff --git a/doc/classes/VisibilityEnabler.xml b/doc/classes/VisibilityEnabler.xml index 4acb4d87c1..e3c7d05fce 100644 --- a/doc/classes/VisibilityEnabler.xml +++ b/doc/classes/VisibilityEnabler.xml @@ -9,6 +9,24 @@ <tutorials> </tutorials> <methods> + <method name="is_enabler_enabled" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="enabler" type="int" enum="VisibilityEnabler.Enabler"> + </argument> + <description> + </description> + </method> + <method name="set_enabler"> + <return type="void"> + </return> + <argument index="0" name="enabler" type="int" enum="VisibilityEnabler.Enabler"> + </argument> + <argument index="1" name="enabled" type="bool"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="freeze_bodies" type="bool" setter="set_enabler" getter="is_enabler_enabled" default="true"> diff --git a/doc/classes/VisibilityEnabler2D.xml b/doc/classes/VisibilityEnabler2D.xml index dbea3f5de8..0f25c00489 100644 --- a/doc/classes/VisibilityEnabler2D.xml +++ b/doc/classes/VisibilityEnabler2D.xml @@ -9,6 +9,24 @@ <tutorials> </tutorials> <methods> + <method name="is_enabler_enabled" qualifiers="const"> + <return type="bool"> + </return> + <argument index="0" name="enabler" type="int" enum="VisibilityEnabler2D.Enabler"> + </argument> + <description> + </description> + </method> + <method name="set_enabler"> + <return type="void"> + </return> + <argument index="0" name="enabler" type="int" enum="VisibilityEnabler2D.Enabler"> + </argument> + <argument index="1" name="enabled" type="bool"> + </argument> + <description> + </description> + </method> </methods> <members> <member name="freeze_bodies" type="bool" setter="set_enabler" getter="is_enabler_enabled" default="true"> diff --git a/doc/classes/VisualShaderNodeCompare.xml b/doc/classes/VisualShaderNodeCompare.xml new file mode 100644 index 0000000000..7edad5294d --- /dev/null +++ b/doc/classes/VisualShaderNodeCompare.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeCompare" inherits="VisualShaderNode" category="Core" version="3.2"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="condition" type="int" setter="set_condition" getter="get_condition" enum="VisualShaderNodeCompare.Condition" default="0"> + </member> + <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeCompare.Function" default="0"> + </member> + <member name="type" type="int" setter="set_comparsion_type" getter="get_comparsion_type" enum="VisualShaderNodeCompare.ComparsionType" default="0"> + </member> + </members> + <constants> + <constant name="CTYPE_SCALAR" value="0" enum="ComparsionType"> + </constant> + <constant name="CTYPE_VECTOR" value="1" enum="ComparsionType"> + </constant> + <constant name="CTYPE_BOOLEAN" value="2" enum="ComparsionType"> + </constant> + <constant name="CTYPE_TRANSFORM" value="3" enum="ComparsionType"> + </constant> + <constant name="FUNC_EQUAL" value="0" enum="Function"> + </constant> + <constant name="FUNC_NOT_EQUAL" value="1" enum="Function"> + </constant> + <constant name="FUNC_GREATER_THAN" value="2" enum="Function"> + </constant> + <constant name="FUNC_GREATER_THAN_EQUAL" value="3" enum="Function"> + </constant> + <constant name="FUNC_LESS_THAN" value="4" enum="Function"> + </constant> + <constant name="FUNC_LESS_THAN_EQUAL" value="5" enum="Function"> + </constant> + <constant name="COND_ALL" value="0" enum="Condition"> + </constant> + <constant name="COND_ANY" value="1" enum="Condition"> + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeCubeMap.xml b/doc/classes/VisualShaderNodeCubeMap.xml index 9a4cb5b17c..b695297f07 100644 --- a/doc/classes/VisualShaderNodeCubeMap.xml +++ b/doc/classes/VisualShaderNodeCubeMap.xml @@ -9,7 +9,7 @@ <methods> </methods> <members> - <member name="cube_map" type="CubeMap" setter="set_cube_map" getter="get_cube_map" default="null"> + <member name="cube_map" type="CubeMap" setter="set_cube_map" getter="get_cube_map"> </member> <member name="texture_type" type="int" setter="set_texture_type" getter="get_texture_type" enum="VisualShaderNodeCubeMap.TextureType" default="0"> </member> diff --git a/doc/classes/VisualShaderNodeIs.xml b/doc/classes/VisualShaderNodeIs.xml new file mode 100644 index 0000000000..8db64b7cde --- /dev/null +++ b/doc/classes/VisualShaderNodeIs.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeIs" inherits="VisualShaderNode" category="Core" version="3.2"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <members> + <member name="function" type="int" setter="set_function" getter="get_function" enum="VisualShaderNodeIs.Function" default="0"> + </member> + </members> + <constants> + <constant name="FUNC_IS_INF" value="0" enum="Function"> + </constant> + <constant name="FUNC_IS_NAN" value="1" enum="Function"> + </constant> + </constants> +</class> diff --git a/doc/classes/VisualShaderNodeTexture.xml b/doc/classes/VisualShaderNodeTexture.xml index 1f4d3b16d1..f3bade9303 100644 --- a/doc/classes/VisualShaderNodeTexture.xml +++ b/doc/classes/VisualShaderNodeTexture.xml @@ -11,7 +11,7 @@ <members> <member name="source" type="int" setter="set_source" getter="get_source" enum="VisualShaderNodeTexture.Source" default="0"> </member> - <member name="texture" type="Texture" setter="set_texture" getter="get_texture" default="null"> + <member name="texture" type="Texture" setter="set_texture" getter="get_texture"> </member> <member name="texture_type" type="int" setter="set_texture_type" getter="get_texture_type" enum="VisualShaderNodeTexture.TextureType" default="0"> </member> @@ -25,6 +25,8 @@ </constant> <constant name="SOURCE_2D_NORMAL" value="3" enum="Source"> </constant> + <constant name="SOURCE_DEPTH" value="4" enum="Source"> + </constant> <constant name="TYPE_DATA" value="0" enum="TextureType"> </constant> <constant name="TYPE_COLOR" value="1" enum="TextureType"> diff --git a/doc/classes/VisualShaderNodeTextureUniformTriplanar.xml b/doc/classes/VisualShaderNodeTextureUniformTriplanar.xml new file mode 100644 index 0000000000..d4e142651e --- /dev/null +++ b/doc/classes/VisualShaderNodeTextureUniformTriplanar.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<class name="VisualShaderNodeTextureUniformTriplanar" inherits="VisualShaderNodeTextureUniform" category="Core" version="3.2"> + <brief_description> + </brief_description> + <description> + </description> + <tutorials> + </tutorials> + <methods> + </methods> + <constants> + </constants> +</class> diff --git a/doc/classes/World.xml b/doc/classes/World.xml index adb3286c51..c8e6944b83 100644 --- a/doc/classes/World.xml +++ b/doc/classes/World.xml @@ -15,10 +15,10 @@ <member name="direct_space_state" type="PhysicsDirectSpaceState" setter="" getter="get_direct_space_state"> The World's physics direct space state, used for making various queries. Might be used only during [code]_physics_process[/code]. </member> - <member name="environment" type="Environment" setter="set_environment" getter="get_environment" default="null"> + <member name="environment" type="Environment" setter="set_environment" getter="get_environment"> The World's [Environment]. </member> - <member name="fallback_environment" type="Environment" setter="set_fallback_environment" getter="get_fallback_environment" default="null"> + <member name="fallback_environment" type="Environment" setter="set_fallback_environment" getter="get_fallback_environment"> The World's fallback_environment will be used if the World's [Environment] fails or is missing. </member> <member name="scenario" type="RID" setter="" getter="get_scenario"> diff --git a/doc/classes/WorldEnvironment.xml b/doc/classes/WorldEnvironment.xml index a2a454d1b3..b4524bfea0 100644 --- a/doc/classes/WorldEnvironment.xml +++ b/doc/classes/WorldEnvironment.xml @@ -14,7 +14,7 @@ <methods> </methods> <members> - <member name="environment" type="Environment" setter="set_environment" getter="get_environment" default="null"> + <member name="environment" type="Environment" setter="set_environment" getter="get_environment"> The [Environment] resource used by this [WorldEnvironment], defining the default properties. </member> </members> diff --git a/drivers/gl_context/SCsub b/drivers/gl_context/SCsub index ef5b57a0cc..b9f0ea2254 100644 --- a/drivers/gl_context/SCsub +++ b/drivers/gl_context/SCsub @@ -12,8 +12,8 @@ if (env["platform"] in ["haiku", "osx", "windows", "x11"]): env.Prepend(CPPPATH=[thirdparty_dir]) - env.Append(CPPFLAGS=['-DGLAD_ENABLED']) - env.Append(CPPFLAGS=['-DGLES_OVER_GL']) + env.Append(CPPDEFINES=['GLAD_ENABLED']) + env.Append(CPPDEFINES=['GLES_OVER_GL']) env_thirdparty = env.Clone() env_thirdparty.disable_warnings() diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp index b82186162d..8a177e32b0 100644 --- a/drivers/gles2/rasterizer_canvas_gles2.cpp +++ b/drivers/gles2/rasterizer_canvas_gles2.cpp @@ -498,7 +498,16 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur Vector2(line->to.x, line->to.y) }; +#ifdef GLES_OVER_GL + if (line->antialiased) + glEnable(GL_LINE_SMOOTH); +#endif _draw_gui_primitive(2, verts, NULL, NULL); + +#ifdef GLES_OVER_GL + if (line->antialiased) + glDisable(GL_LINE_SMOOTH); +#endif } else { Vector2 t = (line->from - line->to).normalized().tangent() * line->width * 0.5; @@ -510,6 +519,19 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur }; _draw_gui_primitive(4, verts, NULL, NULL); +#ifdef GLES_OVER_GL + if (line->antialiased) { + glEnable(GL_LINE_SMOOTH); + for (int j = 0; j < 4; j++) { + Vector2 vertsl[2] = { + verts[j], + verts[(j + 1) % 4], + }; + _draw_gui_primitive(2, vertsl, NULL, NULL); + } + glDisable(GL_LINE_SMOOTH); + } +#endif } } break; @@ -919,6 +941,13 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur } _draw_polygon(polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1, polygon->weights.ptr(), polygon->bones.ptr()); +#ifdef GLES_OVER_GL + if (polygon->antialiased) { + glEnable(GL_LINE_SMOOTH); + _draw_generic(GL_LINE_LOOP, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1); + glDisable(GL_LINE_SMOOTH); + } +#endif } break; case Item::Command::TYPE_MESH: { @@ -1120,7 +1149,22 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur if (pline->triangles.size()) { _draw_generic(GL_TRIANGLE_STRIP, pline->triangles.size(), pline->triangles.ptr(), NULL, pline->triangle_colors.ptr(), pline->triangle_colors.size() == 1); +#ifdef GLES_OVER_GL + glEnable(GL_LINE_SMOOTH); + if (pline->multiline) { + //needs to be different + } else { + _draw_generic(GL_LINE_LOOP, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); + } + glDisable(GL_LINE_SMOOTH); +#endif } else { + +#ifdef GLES_OVER_GL + if (pline->antialiased) + glEnable(GL_LINE_SMOOTH); +#endif + if (pline->multiline) { int todo = pline->lines.size() / 2; int max_per_call = data.polygon_buffer_size / (sizeof(real_t) * 4); @@ -1135,6 +1179,11 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur } else { _draw_generic(GL_LINES, pline->lines.size(), pline->lines.ptr(), NULL, pline->line_colors.ptr(), pline->line_colors.size() == 1); } + +#ifdef GLES_OVER_GL + if (pline->antialiased) + glDisable(GL_LINE_SMOOTH); +#endif } } break; diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index ea29af7d9e..c8ceca8d97 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -1133,8 +1133,8 @@ void RasterizerSceneGLES2::_add_geometry_with_material(RasterizerStorageGLES2::G LightInstance *li = light_instance_owner.getornull(e->instance->light_instances[i]); - if (li->light_index >= render_light_instance_count) { - continue; // too many + if (li->light_index >= render_light_instance_count || render_light_instances[li->light_index] != li) { + continue; // too many or light_index did not correspond to the light instances to be rendered } if (copy) { diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp index b08202ae45..c591db4f3d 100644 --- a/drivers/gles2/rasterizer_storage_gles2.cpp +++ b/drivers/gles2/rasterizer_storage_gles2.cpp @@ -807,7 +807,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer) } } - wb = PoolVector<uint8_t>::Write(); + wb.release(); data.resize(data_size); @@ -871,7 +871,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer) glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &temp_framebuffer); - wb = PoolVector<uint8_t>::Write(); + wb.release(); data.resize(data_size); @@ -2155,8 +2155,8 @@ static PoolVector<uint8_t> _unpack_half_floats(const PoolVector<uint8_t> &array, dst_offset += dst_size[i]; } - r = PoolVector<uint8_t>::Read(); - w = PoolVector<uint8_t>::Write(); + r.release(); + w.release(); return ret; } diff --git a/drivers/gles2/shader_compiler_gles2.cpp b/drivers/gles2/shader_compiler_gles2.cpp index b48b93944c..df7eee2301 100644 --- a/drivers/gles2/shader_compiler_gles2.cpp +++ b/drivers/gles2/shader_compiler_gles2.cpp @@ -318,7 +318,7 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener // use highp if no precision is specified to prevent different default values in fragment and vertex shader SL::DataPrecision precision = E->get().precision; - if (precision == SL::PRECISION_DEFAULT) { + if (precision == SL::PRECISION_DEFAULT && E->get().type != SL::TYPE_BOOL) { precision = SL::PRECISION_HIGHP; } @@ -510,7 +510,97 @@ String ShaderCompilerGLES2::_dump_node_code(SL::Node *p_node, int p_level, Gener } } } break; + case SL::Node::TYPE_ARRAY_DECLARATION: { + SL::ArrayDeclarationNode *var_dec_node = (SL::ArrayDeclarationNode *)p_node; + + StringBuffer<> declaration; + + declaration += _prestr(var_dec_node->precision); + declaration += _typestr(var_dec_node->datatype); + + for (int i = 0; i < var_dec_node->declarations.size(); i++) { + + if (i > 0) { + declaration += ","; + } + + declaration += " "; + + declaration += _mkid(var_dec_node->declarations[i].name); + declaration += "["; + declaration += itos(var_dec_node->declarations[i].size); + declaration += "]"; + int sz = var_dec_node->declarations[i].initializer.size(); + if (sz > 0) { + declaration += "="; + declaration += _typestr(var_dec_node->datatype); + declaration += "["; + declaration += itos(sz); + declaration += "]"; + declaration += "("; + for (int j = 0; j < sz; j++) { + declaration += _dump_node_code(var_dec_node->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + if (j != sz - 1) { + declaration += ", "; + } + } + declaration += ")"; + } + } + + code += declaration.as_string(); + } break; + case SL::Node::TYPE_ARRAY: { + SL::ArrayNode *var_node = (SL::ArrayNode *)p_node; + + if (p_assigning && p_actions.write_flag_pointers.has(var_node->name)) { + *p_actions.write_flag_pointers[var_node->name] = true; + } + + if (p_default_actions.usage_defines.has(var_node->name) && !used_name_defines.has(var_node->name)) { + String define = p_default_actions.usage_defines[var_node->name]; + + if (define.begins_with("@")) { + define = p_default_actions.usage_defines[define.substr(1, define.length())]; + } + + r_gen_code.custom_defines.push_back(define.utf8()); + used_name_defines.insert(var_node->name); + } + + if (p_actions.usage_flag_pointers.has(var_node->name) && !used_flag_pointers.has(var_node->name)) { + *p_actions.usage_flag_pointers[var_node->name] = true; + used_flag_pointers.insert(var_node->name); + } + + if (p_default_actions.renames.has(var_node->name)) { + code += p_default_actions.renames[var_node->name]; + } else { + code += _mkid(var_node->name); + } + + if (var_node->call_expression != NULL) { + code += "."; + code += _dump_node_code(var_node->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } + + if (var_node->index_expression != NULL) { + code += "["; + code += _dump_node_code(var_node->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += "]"; + } + + if (var_node->name == time_name) { + if (current_func_name == vertex_name) { + r_gen_code.uses_vertex_time = true; + } + if (current_func_name == fragment_name || current_func_name == light_name) { + r_gen_code.uses_fragment_time = true; + } + } + + } break; case SL::Node::TYPE_CONSTANT: { SL::ConstantNode *const_node = (SL::ConstantNode *)p_node; diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 91c0693538..fb3d154a7a 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1459,8 +1459,8 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo #else PoolVector<RasterizerGLES3Particle> particle_vector; particle_vector.resize(particles->amount); - PoolVector<RasterizerGLES3Particle>::Write w = particle_vector.write(); - particle_array = w.ptr(); + PoolVector<RasterizerGLES3Particle>::Write particle_writer = particle_vector.write(); + particle_array = particle_writer.ptr(); glGetBufferSubData(GL_ARRAY_BUFFER, 0, particles->amount * sizeof(RasterizerGLES3Particle), particle_array); #endif @@ -1477,7 +1477,7 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo #ifndef __EMSCRIPTEN__ glUnmapBuffer(GL_ARRAY_BUFFER); #else - w = PoolVector<RasterizerGLES3Particle>::Write(); + particle_writer.release(); particle_array = NULL; { PoolVector<RasterizerGLES3Particle>::Read r = particle_vector.read(); @@ -4990,6 +4990,20 @@ bool RasterizerSceneGLES3::free(RID p_rid) { reflection_probe_instance_owner.free(p_rid); memdelete(reflection_instance); + } else if (environment_owner.owns(p_rid)) { + + Environment *environment = environment_owner.get(p_rid); + + environment_owner.free(p_rid); + memdelete(environment); + + } else if (gi_probe_instance_owner.owns(p_rid)) { + + GIProbeInstance *gi_probe_instance = gi_probe_instance_owner.get(p_rid); + + gi_probe_instance_owner.free(p_rid); + memdelete(gi_probe_instance); + } else { return false; } diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index b280898188..994ed25f01 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -1144,8 +1144,12 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) shaders.copy.set_conditional(CopyShaderGLES3::USE_TEXTURE2DARRAY, texture->type == VS::TEXTURE_TYPE_2D_ARRAY); shaders.copy.bind(); - // calculate the normalized z coordinate for the layer - float layer = (float)p_layer / (float)texture->alloc_depth; + float layer; + if (texture->type == VS::TEXTURE_TYPE_2D_ARRAY) + layer = (float)p_layer; + else + // calculate the normalized z coordinate for the layer + layer = (float)p_layer / (float)texture->alloc_depth; shaders.copy.set_uniform(CopyShaderGLES3::LAYER, layer); @@ -1173,7 +1177,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) glDeleteFramebuffers(1, &tmp_fbo); } - wb = PoolVector<uint8_t>::Write(); + wb.release(); data.resize(data_size); @@ -1248,7 +1252,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) img_format = real_format; } - wb = PoolVector<uint8_t>::Write(); + wb.release(); data.resize(data_size); @@ -1316,7 +1320,7 @@ Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, int p_layer) glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &temp_framebuffer); - wb = PoolVector<uint8_t>::Write(); + wb.release(); data.resize(data_size); @@ -2526,19 +2530,19 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy int v = value; GLuint *gui = (GLuint *)data; - gui[0] = v & 1 ? GL_TRUE : GL_FALSE; - gui[1] = v & 2 ? GL_TRUE : GL_FALSE; - gui[2] = v & 4 ? GL_TRUE : GL_FALSE; + gui[0] = (v & 1) ? GL_TRUE : GL_FALSE; + gui[1] = (v & 2) ? GL_TRUE : GL_FALSE; + gui[2] = (v & 4) ? GL_TRUE : GL_FALSE; } break; case ShaderLanguage::TYPE_BVEC4: { int v = value; GLuint *gui = (GLuint *)data; - gui[0] = v & 1 ? GL_TRUE : GL_FALSE; - gui[1] = v & 2 ? GL_TRUE : GL_FALSE; - gui[2] = v & 4 ? GL_TRUE : GL_FALSE; - gui[3] = v & 8 ? GL_TRUE : GL_FALSE; + gui[0] = (v & 1) ? GL_TRUE : GL_FALSE; + gui[1] = (v & 2) ? GL_TRUE : GL_FALSE; + gui[2] = (v & 4) ? GL_TRUE : GL_FALSE; + gui[3] = (v & 8) ? GL_TRUE : GL_FALSE; } break; case ShaderLanguage::TYPE_INT: { @@ -3441,7 +3445,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS: glGenBuffers(1, &surface->vertex_id); glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); - glBufferData(GL_ARRAY_BUFFER, array_size, vr.ptr(), p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, array_size, vr.ptr(), (p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE) ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind if (p_format & VS::ARRAY_FORMAT_INDEX) { @@ -6337,7 +6341,7 @@ AABB RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) { } #if defined(GLES_OVER_GL) || defined(__EMSCRIPTEN__) - r = PoolVector<uint8_t>::Read(); + r.release(); vector = PoolVector<uint8_t>(); #else glUnmapBuffer(GL_ARRAY_BUFFER); diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index b0f0a71d56..f826bdf5a2 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -607,6 +607,88 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener } } break; + case SL::Node::TYPE_ARRAY_DECLARATION: { + + SL::ArrayDeclarationNode *vdnode = (SL::ArrayDeclarationNode *)p_node; + + String declaration = _prestr(vdnode->precision) + _typestr(vdnode->datatype); + for (int i = 0; i < vdnode->declarations.size(); i++) { + if (i > 0) { + declaration += ","; + } else { + declaration += " "; + } + declaration += _mkid(vdnode->declarations[i].name); + declaration += "["; + declaration += itos(vdnode->declarations[i].size); + declaration += "]"; + int sz = vdnode->declarations[i].initializer.size(); + if (sz > 0) { + declaration += "="; + declaration += _typestr(vdnode->datatype); + declaration += "["; + declaration += itos(sz); + declaration += "]"; + declaration += "("; + for (int j = 0; j < sz; j++) { + declaration += _dump_node_code(vdnode->declarations[i].initializer[j], p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + if (j != sz - 1) { + declaration += ", "; + } + } + declaration += ")"; + } + } + + code += declaration; + } break; + case SL::Node::TYPE_ARRAY: { + SL::ArrayNode *vnode = (SL::ArrayNode *)p_node; + + if (p_assigning && p_actions.write_flag_pointers.has(vnode->name)) { + *p_actions.write_flag_pointers[vnode->name] = true; + } + + if (p_default_actions.usage_defines.has(vnode->name) && !used_name_defines.has(vnode->name)) { + String define = p_default_actions.usage_defines[vnode->name]; + if (define.begins_with("@")) { + define = p_default_actions.usage_defines[define.substr(1, define.length())]; + } + r_gen_code.defines.push_back(define.utf8()); + used_name_defines.insert(vnode->name); + } + + if (p_actions.usage_flag_pointers.has(vnode->name) && !used_flag_pointers.has(vnode->name)) { + *p_actions.usage_flag_pointers[vnode->name] = true; + used_flag_pointers.insert(vnode->name); + } + + if (p_default_actions.renames.has(vnode->name)) + code = p_default_actions.renames[vnode->name]; + else + code = _mkid(vnode->name); + + if (vnode->call_expression != NULL) { + code += "."; + code += _dump_node_code(vnode->call_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + } + + if (vnode->index_expression != NULL) { + code += "["; + code += _dump_node_code(vnode->index_expression, p_level, r_gen_code, p_actions, p_default_actions, p_assigning); + code += "]"; + } + + if (vnode->name == time_name) { + if (current_func_name == vertex_name) { + r_gen_code.uses_vertex_time = true; + } + if (current_func_name == fragment_name || current_func_name == light_name) { + r_gen_code.uses_fragment_time = true; + } + } + + } break; case SL::Node::TYPE_CONSTANT: { SL::ConstantNode *cnode = (SL::ConstantNode *)p_node; return get_constant_text(cnode->datatype, cnode->values); diff --git a/drivers/png/SCsub b/drivers/png/SCsub index 9dc80244ff..87b54cecaf 100644 --- a/drivers/png/SCsub +++ b/drivers/png/SCsub @@ -34,9 +34,9 @@ if env['builtin_libpng']: import os use_neon = "neon_enabled" in env and env["neon_enabled"] and os.name != "nt" if use_neon: - env_png.Append(CPPFLAGS=["-DPNG_ARM_NEON_OPT=2"]) + env_png.Append(CPPDEFINES=[("PNG_ARM_NEON_OPT", 2)]) else: - env_png.Append(CPPFLAGS=["-DPNG_ARM_NEON_OPT=0"]) + env_png.Append(CPPDEFINES=[("PNG_ARM_NEON_OPT", 0)]) env_thirdparty = env_png.Clone() env_thirdparty.disable_warnings() diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp index 89e8ee32cc..43a30f055b 100644 --- a/drivers/png/resource_saver_png.cpp +++ b/drivers/png/resource_saver_png.cpp @@ -79,7 +79,7 @@ bool ResourceSaverPNG::recognize(const RES &p_resource) const { void ResourceSaverPNG::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { - if (Object::cast_to<Texture>(*p_resource)) { + if (Object::cast_to<ImageTexture>(*p_resource)) { p_extensions->push_back("png"); } } diff --git a/drivers/pulseaudio/audio_driver_pulseaudio.cpp b/drivers/pulseaudio/audio_driver_pulseaudio.cpp index aec3d27d69..a61fa449f1 100644 --- a/drivers/pulseaudio/audio_driver_pulseaudio.cpp +++ b/drivers/pulseaudio/audio_driver_pulseaudio.cpp @@ -191,6 +191,14 @@ Error AudioDriverPulseAudio::init_device() { spec.format = PA_SAMPLE_S16LE; spec.channels = pa_map.channels; spec.rate = mix_rate; + pa_map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; + pa_map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; + pa_map.map[2] = PA_CHANNEL_POSITION_FRONT_CENTER; + pa_map.map[3] = PA_CHANNEL_POSITION_LFE; + pa_map.map[4] = PA_CHANNEL_POSITION_REAR_LEFT; + pa_map.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT; + pa_map.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT; + pa_map.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT; pa_str = pa_stream_new(pa_ctx, "Sound", &spec, &pa_map); if (pa_str == NULL) { diff --git a/drivers/unix/dir_access_unix.cpp b/drivers/unix/dir_access_unix.cpp index 251bab5783..d5582d00ed 100644 --- a/drivers/unix/dir_access_unix.cpp +++ b/drivers/unix/dir_access_unix.cpp @@ -136,27 +136,31 @@ String DirAccessUnix::get_next() { return ""; } - //typedef struct stat Stat; - struct stat flags; - String fname = fix_unicode_name(entry->d_name); - String f = current_dir.plus_file(fname); + if (entry->d_type == DT_UNKNOWN) { + //typedef struct stat Stat; + struct stat flags; + + String f = current_dir.plus_file(fname); + + if (stat(f.utf8().get_data(), &flags) == 0) { - if (stat(f.utf8().get_data(), &flags) == 0) { + if (S_ISDIR(flags.st_mode)) { - if (S_ISDIR(flags.st_mode)) { + _cisdir = true; - _cisdir = true; + } else { + + _cisdir = false; + } } else { _cisdir = false; } - } else { - - _cisdir = false; + _cisdir = (entry->d_type == DT_DIR); } _cishidden = (fname != "." && fname != ".." && fname.begins_with(".")); diff --git a/drivers/unix/net_socket_posix.cpp b/drivers/unix/net_socket_posix.cpp index f8e771aea0..6a57a2e562 100644 --- a/drivers/unix/net_socket_posix.cpp +++ b/drivers/unix/net_socket_posix.cpp @@ -212,7 +212,7 @@ NetSocketPosix::NetError NetSocketPosix::_get_socket_error() { #pragma GCC diagnostic pop #endif -bool NetSocketPosix::_can_use_ip(const IP_Address p_ip, const bool p_for_bind) const { +bool NetSocketPosix::_can_use_ip(const IP_Address &p_ip, const bool p_for_bind) const { if (p_for_bind && !(p_ip.is_valid() || p_ip.is_wildcard())) { return false; diff --git a/drivers/unix/net_socket_posix.h b/drivers/unix/net_socket_posix.h index ce6dc00d42..40406b241a 100644 --- a/drivers/unix/net_socket_posix.h +++ b/drivers/unix/net_socket_posix.h @@ -65,7 +65,7 @@ private: protected: static NetSocket *_create_func(); - bool _can_use_ip(const IP_Address p_ip, const bool p_for_bind) const; + bool _can_use_ip(const IP_Address &p_ip, const bool p_for_bind) const; public: static void make_default(); diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp index 4de910ee1c..aa61cf5dcc 100644 --- a/drivers/unix/os_unix.cpp +++ b/drivers/unix/os_unix.cpp @@ -256,7 +256,7 @@ 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) }; + struct timespec rem = { static_cast<time_t>(p_usec / 1000000), (static_cast<long>(p_usec) % 1000000) * 1000 }; while (nanosleep(&rem, &rem) == EINTR) { } } diff --git a/drivers/xaudio2/SCsub b/drivers/xaudio2/SCsub index dfc877b6f5..de750525ab 100644 --- a/drivers/xaudio2/SCsub +++ b/drivers/xaudio2/SCsub @@ -3,5 +3,5 @@ Import('env') env.add_source_files(env.drivers_sources, "*.cpp") -env.Append(CPPFLAGS=['-DXAUDIO2_ENABLED']) +env.Append(CPPDEFINES=['XAUDIO2_ENABLED']) env.Append(LINKFLAGS=['xaudio2_8.lib']) diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 721ed23d8a..f5b5cfa848 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -1796,7 +1796,8 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const { return TTR("Toggle this track on/off."); } - if (path_rect.has_point(p_pos)) { + // Don't overlap track keys if they start at 0. + if (path_rect.has_point(p_pos + Size2(type_icon->get_width(), 0))) { return animation->track_get_path(track); } @@ -1816,16 +1817,22 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const { return TTR("Remove this track."); } - if (p_pos.x >= timeline->get_name_limit() && p_pos.x <= (get_size().width - timeline->get_buttons_width())) { + int limit = timeline->get_name_limit(); + int limit_end = get_size().width - timeline->get_buttons_width(); + // Left Border including space occupied by keyframes on t=0. + int limit_start_hitbox = limit - type_icon->get_width(); + + if (p_pos.x >= limit_start_hitbox && p_pos.x <= limit_end) { int key_idx = -1; float key_distance = 1e20; - for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) { //select should happen in the opposite order of drawing for more accurate overlap select + // Select should happen in the opposite order of drawing for more accurate overlap select. + for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) { Rect2 rect = const_cast<AnimationTrackEdit *>(this)->get_key_rect(i, timeline->get_zoom_scale()); float offset = animation->track_get_key_time(track, i) - timeline->get_value(); - offset = offset * timeline->get_zoom_scale() + timeline->get_name_limit(); + offset = offset * timeline->get_zoom_scale() + limit; rect.position.x += offset; if (rect.has_point(p_pos)) { @@ -1932,7 +1939,6 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const { } void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { - if (p_event->is_pressed()) { if (ED_GET_SHORTCUT("animation_editor/duplicate_selection")->is_shortcut(p_event)) { emit_signal("duplicate_request"); @@ -1962,8 +1968,9 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { update(); accept_event(); } - if (path_rect.has_point(pos)) { + // Don't overlap track keys if they start at 0. + if (path_rect.has_point(pos + Size2(type_icon->get_width(), 0))) { clicking_on_name = true; accept_event(); } @@ -2033,18 +2040,21 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { accept_event(); } - //check keyframes + // Check keyframes. float scale = timeline->get_zoom_scale(); int limit = timeline->get_name_limit(); int limit_end = get_size().width - timeline->get_buttons_width(); + // Left Border including space occupied by keyframes on t=0. + int limit_start_hitbox = limit - type_icon->get_width(); - if (pos.x >= limit && pos.x <= limit_end) { + if (pos.x >= limit_start_hitbox && pos.x <= limit_end) { int key_idx = -1; float key_distance = 1e20; - for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) { //select should happen in the opposite order of drawing for more accurate overlap select + // Select should happen in the opposite order of drawing for more accurate overlap select. + for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) { Rect2 rect = get_key_rect(i, scale); float offset = animation->track_get_key_time(track, i) - timeline->get_value(); @@ -2060,7 +2070,7 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { key_distance = distance; } } else { - //first one does it + // First one does it. key_idx = i; break; } @@ -2071,12 +2081,11 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { if (mb->get_command() || mb->get_shift()) { if (editor->is_key_selected(track, key_idx)) { emit_signal("deselect_key", key_idx); - } else { emit_signal("select_key", key_idx, false); moving_selection_attempt = true; select_single_attempt = -1; - moving_selection_from_ofs = (mb->get_position().x - timeline->get_name_limit()) / timeline->get_zoom_scale(); + moving_selection_from_ofs = (mb->get_position().x - limit) / timeline->get_zoom_scale(); } } else { if (!editor->is_key_selected(track, key_idx)) { @@ -2087,24 +2096,17 @@ void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) { } moving_selection_attempt = true; - moving_selection_from_ofs = (mb->get_position().x - timeline->get_name_limit()) / timeline->get_zoom_scale(); + moving_selection_from_ofs = (mb->get_position().x - limit) / timeline->get_zoom_scale(); } accept_event(); } } - - /*using focus instead - * if (!selected && pos.x >= timeline->get_name_limit() && pos.x < (get_size().width - timeline->get_buttons_width())) { - set_selected(true); - emit_signal("selected"); - } - */ } if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) { Point2 pos = mb->get_position(); if (pos.x >= timeline->get_name_limit() && pos.x <= get_size().width - timeline->get_buttons_width()) { - //can do something with menu too! show insert key + // Can do something with menu too! show insert key. float offset = (pos.x - timeline->get_name_limit()) / timeline->get_zoom_scale(); if (!menu) { menu = memnew(PopupMenu); @@ -2332,11 +2334,13 @@ void AnimationTrackEdit::set_in_group(bool p_enable) { } void AnimationTrackEdit::append_to_selection(const Rect2 &p_box, bool p_deselection) { - - Rect2 select_rect(timeline->get_name_limit(), 0, get_size().width - timeline->get_name_limit() - timeline->get_buttons_width(), get_size().height); + // Left Border including space occupied by keyframes on t=0. + int limit_start_hitbox = timeline->get_name_limit() - type_icon->get_width(); + Rect2 select_rect(limit_start_hitbox, 0, get_size().width - timeline->get_name_limit() - timeline->get_buttons_width(), get_size().height); select_rect = select_rect.clip(p_box); - for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) { //select should happen in the opposite order of drawing for more accurate overlap select + // Select should happen in the opposite order of drawing for more accurate overlap select. + for (int i = animation->track_get_key_count(track) - 1; i >= 0; i--) { Rect2 rect = const_cast<AnimationTrackEdit *>(this)->get_key_rect(i, timeline->get_zoom_scale()); float offset = animation->track_get_key_time(track, i) - timeline->get_value(); @@ -5269,17 +5273,17 @@ AnimationTrackEditor::AnimationTrackEditor() { VBoxContainer *cleanup_vb = memnew(VBoxContainer); cleanup_dialog->add_child(cleanup_vb); - cleanup_keys = memnew(CheckButton); + cleanup_keys = memnew(CheckBox); cleanup_keys->set_text(TTR("Remove invalid keys")); cleanup_keys->set_pressed(true); cleanup_vb->add_child(cleanup_keys); - cleanup_tracks = memnew(CheckButton); + cleanup_tracks = memnew(CheckBox); cleanup_tracks->set_text(TTR("Remove unresolved and empty tracks")); cleanup_tracks->set_pressed(true); cleanup_vb->add_child(cleanup_tracks); - cleanup_all = memnew(CheckButton); + cleanup_all = memnew(CheckBox); cleanup_all->set_text(TTR("Clean-up all animations")); cleanup_vb->add_child(cleanup_all); diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h index 0d5a621e07..8dc2304a95 100644 --- a/editor/animation_track_editor.h +++ b/editor/animation_track_editor.h @@ -439,9 +439,9 @@ class AnimationTrackEditor : public VBoxContainer { SpinBox *optimize_max_angle; ConfirmationDialog *cleanup_dialog; - CheckButton *cleanup_keys; - CheckButton *cleanup_tracks; - CheckButton *cleanup_all; + CheckBox *cleanup_keys; + CheckBox *cleanup_tracks; + CheckBox *cleanup_all; ConfirmationDialog *scale_dialog; SpinBox *scale; diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp index ed50c7914e..4862d4bb5b 100644 --- a/editor/code_editor.cpp +++ b/editor/code_editor.cpp @@ -161,7 +161,8 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col) result_line = line; result_col = col; - set_error(""); + _update_results_count(); + set_error(vformat(TTR("Found %d match(es)."), results_count)); } else { result_line = -1; result_col = -1; @@ -184,6 +185,8 @@ void FindReplaceBar::_replace() { text_edit->insert_text_at_cursor(get_replace_text()); text_edit->end_complex_operation(); + + results_count = -1; } search_current(); @@ -271,6 +274,7 @@ void FindReplaceBar::_replace_all() { set_error(vformat(TTR("Replaced %d occurrence(s)."), rc)); text_edit->call_deferred("connect", "text_changed", this, "_editor_text_changed"); + results_count = -1; } void FindReplaceBar::_get_search_from(int &r_line, int &r_col) { @@ -297,6 +301,36 @@ void FindReplaceBar::_get_search_from(int &r_line, int &r_col) { } } +void FindReplaceBar::_update_results_count() { + if (results_count != -1) + return; + + results_count = 0; + + String searched = get_search_text(); + if (searched.empty()) return; + + String full_text = text_edit->get_text(); + + int from_pos = 0; + + while (true) { + int pos = is_case_sensitive() ? full_text.find(searched, from_pos) : full_text.findn(searched, from_pos); + if (pos == -1) break; + + if (is_whole_words()) { + from_pos++; // Making sure we won't hit the same match next time, if we get out via a continue. + if (pos > 0 && !is_symbol(full_text[pos - 1])) + continue; + if (pos + searched.length() < full_text.length() && !is_symbol(full_text[pos + searched.length()])) + continue; + } + + results_count++; + from_pos = pos + searched.length(); + } +} + bool FindReplaceBar::search_current() { uint32_t flags = 0; @@ -341,7 +375,11 @@ bool FindReplaceBar::search_prev() { bool FindReplaceBar::search_next() { uint32_t flags = 0; - String text = get_search_text(); + String text; + if (replace_all_mode) + text = get_replace_text(); + else + text = get_search_text(); if (is_whole_words()) flags |= TextEdit::SEARCH_WHOLE_WORDS; @@ -416,11 +454,13 @@ void FindReplaceBar::popup_replace() { void FindReplaceBar::_search_options_changed(bool p_pressed) { + results_count = -1; search_current(); } void FindReplaceBar::_editor_text_changed() { + results_count = -1; if (is_visible_in_tree()) { preserve_cursor = true; search_current(); @@ -430,6 +470,7 @@ void FindReplaceBar::_editor_text_changed() { void FindReplaceBar::_search_text_changed(const String &p_text) { + results_count = -1; search_current(); } @@ -482,6 +523,7 @@ void FindReplaceBar::set_error(const String &p_label) { void FindReplaceBar::set_text_edit(TextEdit *p_text_edit) { + results_count = -1; text_edit = p_text_edit; text_edit->connect("text_changed", this, "_editor_text_changed"); } @@ -508,6 +550,7 @@ void FindReplaceBar::_bind_methods() { FindReplaceBar::FindReplaceBar() { + results_count = -1; replace_all_mode = false; preserve_cursor = false; @@ -724,7 +767,7 @@ void CodeTextEditor::_code_complete_timer_timeout() { void CodeTextEditor::_complete_request() { - List<String> entries; + List<ScriptCodeCompletionOption> entries; String ctext = text_editor->get_text_for_completion(); _code_complete_script(ctext, &entries); bool forced = false; @@ -733,15 +776,55 @@ void CodeTextEditor::_complete_request() { } if (entries.size() == 0) return; - Vector<String> strs; - strs.resize(entries.size()); - int i = 0; - for (List<String>::Element *E = entries.front(); E; E = E->next()) { - strs.write[i++] = E->get(); + for (List<ScriptCodeCompletionOption>::Element *E = entries.front(); E; E = E->next()) { + E->get().icon = _get_completion_icon(E->get()); } + text_editor->code_complete(entries, forced); +} - text_editor->code_complete(strs, forced); +Ref<Texture> CodeTextEditor::_get_completion_icon(const ScriptCodeCompletionOption &p_option) { + Ref<Texture> tex; + switch (p_option.kind) { + case ScriptCodeCompletionOption::KIND_CLASS: { + if (has_icon(p_option.display, "EditorIcons")) { + tex = get_icon(p_option.display, "EditorIcons"); + } else { + tex = get_icon("Object", "EditorIcons"); + } + } break; + case ScriptCodeCompletionOption::KIND_ENUM: + tex = get_icon("Enum", "EditorIcons"); + break; + case ScriptCodeCompletionOption::KIND_FILE_PATH: + tex = get_icon("File", "EditorIcons"); + break; + case ScriptCodeCompletionOption::KIND_NODE_PATH: + tex = get_icon("NodePath", "EditorIcons"); + break; + case ScriptCodeCompletionOption::KIND_VARIABLE: + tex = get_icon("Variant", "EditorIcons"); + break; + case ScriptCodeCompletionOption::KIND_CONSTANT: + tex = get_icon("MemberConstant", "EditorIcons"); + break; + case ScriptCodeCompletionOption::KIND_MEMBER: + tex = get_icon("MemberProperty", "EditorIcons"); + break; + case ScriptCodeCompletionOption::KIND_SIGNAL: + tex = get_icon("MemberSignal", "EditorIcons"); + break; + case ScriptCodeCompletionOption::KIND_FUNCTION: + tex = get_icon("MemberMethod", "EditorIcons"); + break; + case ScriptCodeCompletionOption::KIND_PLAIN_TEXT: + tex = get_icon("CubeMesh", "EditorIcons"); + break; + default: + tex = get_icon("String", "EditorIcons"); + break; + } + return tex; } void CodeTextEditor::_font_resize_timeout() { diff --git a/editor/code_editor.h b/editor/code_editor.h index c0989f9704..700e72627c 100644 --- a/editor/code_editor.h +++ b/editor/code_editor.h @@ -83,11 +83,13 @@ class FindReplaceBar : public HBoxContainer { int result_line; int result_col; + int results_count; bool replace_all_mode; bool preserve_cursor; void _get_search_from(int &r_line, int &r_col); + void _update_results_count(); void _show_search(); void _hide_bar(); @@ -131,7 +133,7 @@ public: FindReplaceBar(); }; -typedef void (*CodeTextEditorCodeCompleteFunc)(void *p_ud, const String &p_code, List<String> *r_options, bool &r_forced); +typedef void (*CodeTextEditorCodeCompleteFunc)(void *p_ud, const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_forced); class CodeTextEditor : public VBoxContainer { @@ -162,6 +164,7 @@ class CodeTextEditor : public VBoxContainer { void _update_font(); void _complete_request(); + Ref<Texture> _get_completion_icon(const ScriptCodeCompletionOption &p_option); void _font_resize_timeout(); bool _add_font_size(int p_delta); @@ -183,7 +186,7 @@ class CodeTextEditor : public VBoxContainer { protected: virtual void _load_theme_settings() {} virtual void _validate_script() {} - virtual void _code_complete_script(const String &p_code, List<String> *r_options) {} + virtual void _code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options) {} void _text_changed_idle_timeout(); void _code_complete_timer_timeout(); diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index d04392dabf..48bc409b73 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -459,6 +459,21 @@ ConnectDialog::~ConnectDialog() { ////////////////////////////////////////// +// Originally copied and adapted from EditorProperty, try to keep style in sync. +Control *ConnectionsDockTree::make_custom_tooltip(const String &p_text) const { + + EditorHelpBit *help_bit = memnew(EditorHelpBit); + help_bit->add_style_override("panel", get_stylebox("panel", "TooltipPanel")); + help_bit->get_rich_text()->set_fixed_size_to_width(360 * EDSCALE); + + String text = TTR("Signal:") + " [u][b]" + p_text.get_slice("::", 0) + "[/b][/u]"; + text += p_text.get_slice("::", 1).strip_edges() + "\n"; + text += p_text.get_slice("::", 2).strip_edges(); + help_bit->set_text(text); + help_bit->call_deferred("set_text", text); //hack so it uses proper theme once inside scene + return help_bit; +} + struct _ConnectionsDockMethodInfoSort { _FORCE_INLINE_ bool operator()(const MethodInfo &a, const MethodInfo &b) const { @@ -892,8 +907,8 @@ void ConnectionsDock::update_tree() { MethodInfo &mi = E->get(); - String signaldesc; - signaldesc = mi.name + "("; + StringName signal_name = mi.name; + String signaldesc = "("; PoolStringArray argnames; if (mi.arguments.size()) { signaldesc += " "; @@ -914,19 +929,56 @@ void ConnectionsDock::update_tree() { } signaldesc += " "; } - signaldesc += ")"; TreeItem *item = tree->create_item(pitem); - item->set_text(0, signaldesc); + item->set_text(0, String(signal_name) + signaldesc); Dictionary sinfo; - sinfo["name"] = mi.name; + sinfo["name"] = signal_name; sinfo["args"] = argnames; item->set_metadata(0, sinfo); item->set_icon(0, get_icon("Signal", "EditorIcons")); + // Set tooltip with the signal's documentation + { + String descr; + bool found = false; + + Map<StringName, Map<StringName, String> >::Element *G = descr_cache.find(base); + if (G) { + Map<StringName, String>::Element *F = G->get().find(signal_name); + if (F) { + found = true; + descr = F->get(); + } + } + + if (!found) { + DocData *dd = EditorHelp::get_doc_data(); + Map<String, DocData::ClassDoc>::Element *F = dd->class_list.find(base); + while (F && descr == String()) { + for (int i = 0; i < F->get().signals.size(); i++) { + if (F->get().signals[i].name == signal_name.operator String()) { + descr = F->get().signals[i].description.strip_edges(); + break; + } + } + if (!F->get().inherits.empty()) { + F = dd->class_list.find(F->get().inherits); + } else { + break; + } + } + descr_cache[base][signal_name] = descr; + } + + // "::" separators used in make_custom_tooltip for formatting. + item->set_tooltip(0, String(signal_name) + "::" + signaldesc + "::" + descr); + } + + // List existing connections List<Object::Connection> connections; - selectedNode->get_signal_connection_list(mi.name, &connections); + selectedNode->get_signal_connection_list(signal_name, &connections); for (List<Object::Connection>::Element *F = connections.front(); F; F = F->next()) { @@ -980,7 +1032,7 @@ ConnectionsDock::ConnectionsDock(EditorNode *p_editor) { VBoxContainer *vbc = this; - tree = memnew(Tree); + tree = memnew(ConnectionsDockTree); tree->set_columns(1); tree->set_select_mode(Tree::SELECT_ROW); tree->set_hide_root(true); diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h index 195c9e1e7d..3846fa4d9f 100644 --- a/editor/connections_dialog.h +++ b/editor/connections_dialog.h @@ -106,6 +106,13 @@ public: ////////////////////////////////////////// +// Custom Tree needed to use a RichTextLabel as tooltip control +// when display signal documentation. +class ConnectionsDockTree : public Tree { + + virtual Control *make_custom_tooltip(const String &p_text) const; +}; + class ConnectionsDock : public VBoxContainer { GDCLASS(ConnectionsDock, VBoxContainer); @@ -123,7 +130,7 @@ class ConnectionsDock : public VBoxContainer { }; Node *selectedNode; - Tree *tree; + ConnectionsDockTree *tree; EditorNode *editor; ConfirmationDialog *disconnect_all_dialog; @@ -133,6 +140,8 @@ class ConnectionsDock : public VBoxContainer { PopupMenu *slot_menu; UndoRedo *undo_redo; + Map<StringName, Map<StringName, String> > descr_cache; + void _make_or_edit_connection(); void _connect(Connection cToMake); void _disconnect(TreeItem &item); diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp index 547d627925..8a8d52c6f1 100644 --- a/editor/create_dialog.cpp +++ b/editor/create_dialog.cpp @@ -210,13 +210,13 @@ void CreateDialog::add_type(const String &p_type, HashMap<String, TreeItem *> &p if (is_subsequence_of_type && !is_selected_equal) { if (is_substring_of_type) { - if (!is_substring_of_selected || (is_substring_of_selected && (current_type_prefered && !selected_type_prefered))) { + if (!is_substring_of_selected || (current_type_prefered && !selected_type_prefered)) { *to_select = item; } } else { // substring results weigh more than subsequences, so let's make sure we don't override them if (!is_substring_of_selected) { - if (!is_subsequence_of_selected || (is_subsequence_of_selected && (current_type_prefered && !selected_type_prefered))) { + if (!is_subsequence_of_selected || (current_type_prefered && !selected_type_prefered)) { *to_select = item; } } diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 9a049f3ae3..5f8660e108 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -474,7 +474,7 @@ void DependencyRemoveDialog::show(const Vector<String> &p_folders, const Vector< removed_deps.sort(); if (removed_deps.empty()) { owners->hide(); - text->set_text(TTR("Remove selected files from the project? (no undo)")); + text->set_text(TTR("Remove selected files from the project? (Can't be restored)")); set_size(Size2()); popup_centered(); } else { diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp index 6ee07d3661..6f09e73fab 100644 --- a/editor/doc/doc_data.cpp +++ b/editor/doc/doc_data.cpp @@ -266,8 +266,8 @@ void DocData::generate(bool p_basic_types) { } } - if (default_value_valid) { - prop.default_value = default_value.get_construct_string(); + if (default_value_valid && default_value.get_type() != Variant::OBJECT) { + prop.default_value = default_value.get_construct_string().replace("\n", ""); } bool found_type = false; @@ -323,8 +323,14 @@ void DocData::generate(bool p_basic_types) { if (E->get().name == "" || (E->get().name[0] == '_' && !(E->get().flags & METHOD_FLAG_VIRTUAL))) continue; //hidden, don't count - if (skip_setter_getter_methods && setters_getters.has(E->get().name) && E->get().name.find("/") == -1) - continue; + if (skip_setter_getter_methods && setters_getters.has(E->get().name)) { + // Don't skip parametric setters and getters, i.e. method which require + // one or more parameters to define what property should be set or retrieved. + // E.g. CPUParticles::set_param(Parameter param, float value). + if (E->get().arguments.size() == 0 /* getter */ || (E->get().arguments.size() == 1 && E->get().return_val.type == Variant::NIL /* setter */)) { + continue; + } + } MethodDoc method; @@ -366,21 +372,6 @@ void DocData::generate(bool p_basic_types) { method.arguments.push_back(argument); } - - /* - String hint; - switch(arginfo.hint) { - case PROPERTY_HINT_DIR: hint="A directory."; break; - case PROPERTY_HINT_RANGE: hint="Range - min: "+arginfo.hint_string.get_slice(",",0)+" max: "+arginfo.hint_string.get_slice(",",1)+" step: "+arginfo.hint_string.get_slice(",",2); break; - case PROPERTY_HINT_ENUM: hint="Values: "; for(int j=0;j<arginfo.hint_string.get_slice_count(",");j++) { if (j>0) hint+=", "; hint+=arginfo.hint_string.get_slice(",",j)+"="+itos(j); } break; - case PROPERTY_HINT_LENGTH: hint="Length: "+arginfo.hint_string; break; - case PROPERTY_HINT_FLAGS: hint="Values: "; for(int j=0;j<arginfo.hint_string.get_slice_count(",");j++) { if (j>0) hint+=", "; hint+=arginfo.hint_string.get_slice(",",j)+"="+itos(1<<j); } break; - case PROPERTY_HINT_FILE: hint="A file:"; break; - //case PROPERTY_HINT_RESOURCE_TYPE: hint="Type: "+arginfo.hint_string; break; - }; - if (hint!="") - _write_string(f,4,hint); -*/ } c.methods.push_back(method); diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index 12df91a501..b706f2cae6 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -111,18 +111,14 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { Map<String, Ref<Texture> > extension_guess; { - extension_guess["png"] = get_icon("Texture", "EditorIcons"); - extension_guess["jpg"] = get_icon("Texture", "EditorIcons"); - extension_guess["tex"] = get_icon("Texture", "EditorIcons"); - extension_guess["atlastex"] = get_icon("Texture", "EditorIcons"); - extension_guess["dds"] = get_icon("Texture", "EditorIcons"); + extension_guess["png"] = get_icon("ImageTexture", "EditorIcons"); + extension_guess["jpg"] = get_icon("ImageTexture", "EditorIcons"); + extension_guess["atlastex"] = get_icon("AtlasTexture", "EditorIcons"); extension_guess["scn"] = get_icon("PackedScene", "EditorIcons"); extension_guess["tscn"] = get_icon("PackedScene", "EditorIcons"); - extension_guess["xml"] = get_icon("PackedScene", "EditorIcons"); - extension_guess["xscn"] = get_icon("PackedScene", "EditorIcons"); - extension_guess["material"] = get_icon("Material", "EditorIcons"); - extension_guess["shd"] = get_icon("Shader", "EditorIcons"); + extension_guess["shader"] = get_icon("Shader", "EditorIcons"); extension_guess["gd"] = get_icon("GDScript", "EditorIcons"); + extension_guess["vs"] = get_icon("VisualScript", "EditorIcons"); } Ref<Texture> generic_extension = get_icon("Object", "EditorIcons"); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index b9fb532c4a..2180742bbb 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -76,9 +76,9 @@ void EditorAudioBus::_notification(int p_what) { disabled_vu = get_icon("BusVuFrozen", "EditorIcons"); - Color solo_color = Color::html(EditorSettings::get_singleton()->is_dark_theme() ? "#ffe337" : "#ffeb70"); - Color mute_color = Color::html(EditorSettings::get_singleton()->is_dark_theme() ? "#ff2929" : "#ff7070"); - Color bypass_color = Color::html(EditorSettings::get_singleton()->is_dark_theme() ? "#22ccff" : "#70deff"); + Color solo_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1.0, 0.89, 0.22) : Color(1.0, 0.92, 0.44); + Color mute_color = EditorSettings::get_singleton()->is_dark_theme() ? Color(1.0, 0.16, 0.16) : Color(1.0, 0.44, 0.44); + 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_icon("AudioBusSolo", "EditorIcons")); solo->add_color_override("icon_color_pressed", solo_color); diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h index 8781e6ff6c..113adb57c1 100644 --- a/editor/editor_audio_buses.h +++ b/editor/editor_audio_buses.h @@ -233,6 +233,13 @@ private: render_db_value = n.render_db_value; } + _FORCE_INLINE_ AudioNotch operator=(const EditorAudioMeterNotches::AudioNotch &n) { + relative_position = n.relative_position; + db_value = n.db_value; + render_db_value = n.render_db_value; + return *this; + } + _FORCE_INLINE_ AudioNotch() {} }; diff --git a/editor/editor_builders.py b/editor/editor_builders.py index 19c5e0b924..910c53e2ff 100644 --- a/editor/editor_builders.py +++ b/editor/editor_builders.py @@ -63,8 +63,8 @@ def make_fonts_header(target, source, env): g.write("static const int _font_" + name + "_size = " + str(len(buf)) + ";\n") g.write("static const unsigned char _font_" + name + "[] = {\n") - for i in range(len(buf)): - g.write("\t" + byte_to_str(buf[i]) + ",\n") + for j in range(len(buf)): + g.write("\t" + byte_to_str(buf[j]) + ",\n") g.write("};\n") @@ -97,8 +97,8 @@ def make_translations_header(target, source, env): name = os.path.splitext(os.path.basename(sorted_paths[i]))[0] g.write("static const unsigned char _translation_" + name + "_compressed[] = {\n") - for i in range(len(buf)): - g.write("\t" + byte_to_str(buf[i]) + ",\n") + for j in range(len(buf)): + g.write("\t" + byte_to_str(buf[j]) + ",\n") g.write("};\n") diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index bebd5b2412..ed262d9c4f 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -34,6 +34,7 @@ #include "core/io/resource_loader.h" #include "core/io/resource_saver.h" #include "core/io/zip_io.h" +#include "core/math/crypto_core.h" #include "core/os/file_access.h" #include "core/project_settings.h" #include "core/script_language.h" @@ -43,7 +44,6 @@ #include "editor_node.h" #include "editor_settings.h" #include "scene/resources/resource_format_text.h" -#include "thirdparty/misc/md5.h" static int _get_pad(int p_alignment, int p_n) { @@ -323,13 +323,11 @@ Error EditorExportPlatform::_save_pack_file(void *p_userdata, const String &p_pa } { - MD5_CTX ctx; - MD5Init(&ctx); - MD5Update(&ctx, (unsigned char *)p_data.ptr(), p_data.size()); - MD5Final(&ctx); + unsigned char hash[16]; + CryptoCore::md5(p_data.ptr(), p_data.size(), hash); sd.md5.resize(16); for (int i = 0; i < 16; i++) { - sd.md5.write[i] = ctx.digest[i]; + sd.md5.write[i] = hash[i]; } } @@ -901,7 +899,7 @@ Error EditorExportPlatform::_add_shared_object(void *p_userdata, const SharedObj return OK; } -Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files) { +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); @@ -923,9 +921,34 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c pd.file_ofs.sort(); //do sort, so we can do binary search later - FileAccess *f = FileAccess::open(p_path, FileAccess::WRITE); - ERR_FAIL_COND_V(!f, ERR_CANT_CREATE); - f->store_32(0x43504447); //GDPK + FileAccess *f; + int64_t embed_pos = 0; + if (!p_embed) { + // Regular output to separate PCK file + f = FileAccess::open(p_path, FileAccess::WRITE); + ERR_FAIL_COND_V(!f, ERR_CANT_CREATE); + } else { + // Append to executable + f = FileAccess::open(p_path, FileAccess::READ_WRITE); + ERR_FAIL_COND_V(!f, ERR_FILE_CANT_OPEN); + + f->seek_end(); + embed_pos = f->get_position(); + + if (r_embedded_start) { + *r_embedded_start = embed_pos; + } + + // Ensure embedded PCK starts at a 64-bit multiple + int pad = f->get_position() % 8; + for (int i = 0; i < pad; i++) { + f->store_8(0); + } + } + + int64_t pck_start_pos = f->get_position(); + + f->store_32(0x43504447); //GDPC f->store_32(1); //pack version f->store_32(VERSION_MAJOR); f->store_32(VERSION_MINOR); @@ -937,29 +960,29 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c f->store_32(pd.file_ofs.size()); //amount of files - size_t header_size = f->get_position(); + int64_t header_size = f->get_position(); //precalculate header size for (int i = 0; i < pd.file_ofs.size(); i++) { header_size += 4; // size of path string (32 bits is enough) - uint32_t string_len = pd.file_ofs[i].path_utf8.length(); + int string_len = pd.file_ofs[i].path_utf8.length(); header_size += string_len + _get_pad(4, string_len); ///size of path string header_size += 8; // offset to file _with_ header size included header_size += 8; // size of file header_size += 16; // md5 } - size_t header_padding = _get_pad(PCK_PADDING, header_size); + int header_padding = _get_pad(PCK_PADDING, header_size); for (int i = 0; i < pd.file_ofs.size(); i++) { - uint32_t string_len = pd.file_ofs[i].path_utf8.length(); - uint32_t pad = _get_pad(4, string_len); - ; + int string_len = pd.file_ofs[i].path_utf8.length(); + int pad = _get_pad(4, string_len); + f->store_32(string_len + pad); f->store_buffer((const uint8_t *)pd.file_ofs[i].path_utf8.get_data(), string_len); - for (uint32_t j = 0; j < pad; j++) { + for (int j = 0; j < pad; j++) { f->store_8(0); } @@ -968,7 +991,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c f->store_buffer(pd.file_ofs[i].md5.ptr(), 16); //also save md5 for file } - for (uint32_t j = 0; j < header_padding; j++) { + for (int i = 0; i < header_padding; i++) { f->store_8(0); } @@ -994,7 +1017,23 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c memdelete(ftmp); - f->store_32(0x43504447); //GDPK + if (p_embed) { + // Ensure embedded data ends at a 64-bit multiple + int64_t embed_end = f->get_position() - embed_pos + 12; + int pad = embed_end % 8; + for (int i = 0; i < pad; i++) { + f->store_8(0); + } + + int64_t pck_size = f->get_position() - pck_start_pos; + f->store_64(pck_size); + f->store_32(0x43504447); //GDPC + + if (r_embedded_size) { + *r_embedded_size = f->get_position() - embed_pos; + } + } + memdelete(f); return OK; @@ -1401,6 +1440,7 @@ void EditorExportPlatformPC::get_export_options(List<ExportOption> *r_options) { r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/no_bptc_fallbacks"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/64_bits"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "binary_format/embed_pck"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE), "")); } @@ -1518,12 +1558,33 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); Error err = da->copy(template_path, p_path, get_chmod_flags()); + memdelete(da); + if (err == OK) { - String pck_path = p_path.get_basename() + ".pck"; + String pck_path; + if (p_preset->get("binary_format/embed_pck")) { + pck_path = p_path; + } else { + pck_path = p_path.get_basename() + ".pck"; + } Vector<SharedObject> so_files; - err = save_pack(p_preset, pck_path, &so_files); + int64_t embedded_pos; + int64_t embedded_size; + err = save_pack(p_preset, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size); + if (err == OK && p_preset->get("binary_format/embed_pck")) { + + if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) { + EditorNode::get_singleton()->show_warning(TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB.")); + return ERR_UNAVAILABLE; + } + + FixUpEmbeddedPckFunc fixup_func = get_fixup_embedded_pck_func(); + if (fixup_func) { + err = fixup_func(p_path, embedded_pos, embedded_size); + } + } if (err == OK && !so_files.empty()) { //if shared object files, copy them @@ -1531,10 +1592,10 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr for (int i = 0; i < so_files.size() && err == OK; i++) { err = da->copy(so_files[i].path, p_path.get_base_dir().plus_file(so_files[i].path.get_file())); } + memdelete(da); } } - memdelete(da); return err; } @@ -1605,9 +1666,20 @@ void EditorExportPlatformPC::set_chmod_flags(int p_flags) { chmod_flags = p_flags; } +EditorExportPlatformPC::FixUpEmbeddedPckFunc EditorExportPlatformPC::get_fixup_embedded_pck_func() const { + + return fixup_embedded_pck_func; +} + +void EditorExportPlatformPC::set_fixup_embedded_pck_func(FixUpEmbeddedPckFunc p_fixup_embedded_pck_func) { + + fixup_embedded_pck_func = p_fixup_embedded_pck_func; +} + EditorExportPlatformPC::EditorExportPlatformPC() { chmod_flags = -1; + fixup_embedded_pck_func = NULL; } /////////////////////// diff --git a/editor/editor_export.h b/editor/editor_export.h index 7c01abe0e9..3152e249bd 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -240,7 +240,7 @@ public: Error export_project_files(const Ref<EditorExportPreset> &p_preset, EditorExportSaveFunction p_func, void *p_udata, EditorExportSaveSharedObject p_so_func = NULL); - Error save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files = NULL); + Error save_pack(const Ref<EditorExportPreset> &p_preset, const String &p_path, Vector<SharedObject> *p_so_files = NULL, bool p_embed = false, int64_t *r_embedded_start = NULL, int64_t *r_embedded_size = NULL); Error save_zip(const Ref<EditorExportPreset> &p_preset, const String &p_path); virtual bool poll_devices() { return false; } @@ -391,6 +391,10 @@ class EditorExportPlatformPC : public EditorExportPlatform { GDCLASS(EditorExportPlatformPC, EditorExportPlatform); +public: + typedef Error (*FixUpEmbeddedPckFunc)(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size); + +private: Ref<ImageTexture> logo; String name; String os_name; @@ -405,6 +409,8 @@ class EditorExportPlatformPC : public EditorExportPlatform { int chmod_flags; + FixUpEmbeddedPckFunc fixup_embedded_pck_func; + public: virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features); @@ -436,6 +442,9 @@ public: int get_chmod_flags() const; void set_chmod_flags(int p_flags); + FixUpEmbeddedPckFunc get_fixup_embedded_pck_func() const; + void set_fixup_embedded_pck_func(FixUpEmbeddedPckFunc p_fixup_embedded_pck_func); + EditorExportPlatformPC(); }; diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index d1f765a312..d81a1dbd77 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -444,6 +444,7 @@ void EditorHelp::_update_doc() { class_desc->pop(); class_desc->add_newline(); + class_desc->push_font(doc_code_font); class_desc->push_indent(1); class_desc->push_table(2); class_desc->set_table_column_expand(1, 1); @@ -509,6 +510,7 @@ void EditorHelp::_update_doc() { class_desc->pop(); //table class_desc->pop(); + class_desc->pop(); // font class_desc->add_newline(); class_desc->add_newline(); } @@ -1348,39 +1350,39 @@ static void _add_text_to_rt(const String &p_bbcode, RichTextLabel *p_rt) { if (col.begins_with("#")) color = Color::html(col); else if (col == "aqua") - color = Color::html("#00FFFF"); + color = Color(0, 1, 1); else if (col == "black") - color = Color::html("#000000"); + color = Color(0, 0, 0); else if (col == "blue") - color = Color::html("#0000FF"); + color = Color(0, 0, 1); else if (col == "fuchsia") - color = Color::html("#FF00FF"); + color = Color(1, 0, 1); else if (col == "gray" || col == "grey") - color = Color::html("#808080"); + color = Color(0.5, 0.5, 0.5); else if (col == "green") - color = Color::html("#008000"); + color = Color(0, 0.5, 0); else if (col == "lime") - color = Color::html("#00FF00"); + color = Color(0, 1, 0); else if (col == "maroon") - color = Color::html("#800000"); + color = Color(0.5, 0, 0); else if (col == "navy") - color = Color::html("#000080"); + color = Color(0, 0, 0.5); else if (col == "olive") - color = Color::html("#808000"); + color = Color(0.5, 0.5, 0); else if (col == "purple") - color = Color::html("#800080"); + color = Color(0.5, 0, 0.5); else if (col == "red") - color = Color::html("#FF0000"); + color = Color(1, 0, 0); else if (col == "silver") - color = Color::html("#C0C0C0"); + color = Color(0.75, 0.75, 0.75); else if (col == "teal") - color = Color::html("#008008"); + color = Color(0, 0.5, 0.5); else if (col == "white") - color = Color::html("#FFFFFF"); + color = Color(1, 1, 1); else if (col == "yellow") - color = Color::html("#FFFF00"); + color = Color(1, 1, 0); else - color = Color(0, 0, 0, 1); //base_color; + color = Color(0, 0, 0); //base_color; p_rt->push_color(color); pos = brk_end + 1; diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index 4ec24c76f2..fbfc999dbf 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -337,7 +337,7 @@ bool EditorHelpSearch::Runner::_phase_match_classes() { if (term.length() > 1) { if (search_flags & SEARCH_METHODS) for (int i = 0; i < class_doc.methods.size(); i++) { - String method_name = search_flags & SEARCH_CASE_SENSITIVE ? class_doc.methods[i].name : class_doc.methods[i].name.to_lower(); + String method_name = (search_flags & SEARCH_CASE_SENSITIVE) ? class_doc.methods[i].name : class_doc.methods[i].name.to_lower(); if (method_name.find(term) > -1 || (term.begins_with(".") && method_name.begins_with(term.right(1))) || (term.ends_with("(") && method_name.ends_with(term.left(term.length() - 1).strip_edges())) || @@ -405,7 +405,7 @@ bool EditorHelpSearch::Runner::_phase_member_items() { ClassMatch &match = iterator_match->value(); - TreeItem *parent = search_flags & SEARCH_SHOW_HIERARCHY ? class_items[match.doc->name] : root_item; + TreeItem *parent = (search_flags & SEARCH_SHOW_HIERARCHY) ? class_items[match.doc->name] : root_item; for (int i = 0; i < match.methods.size(); i++) _create_method_item(parent, match.doc, match.methods[i]); for (int i = 0; i < match.signals.size(); i++) diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 865ffd1baa..3183f1ae97 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -222,7 +222,7 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) { _editor_select(EDITOR_SCRIPT); } else if (ED_IS_SHORTCUT("editor/editor_help", p_event)) { emit_signal("request_help_search", ""); - } else if (ED_IS_SHORTCUT("editor/editor_assetlib", p_event)) { + } else if (ED_IS_SHORTCUT("editor/editor_assetlib", p_event) && StreamPeerSSL::is_available()) { _editor_select(EDITOR_ASSETLIB); } else if (ED_IS_SHORTCUT("editor/editor_next", p_event)) { _editor_select_next(); @@ -238,185 +238,183 @@ void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) { void EditorNode::_notification(int p_what) { - if (p_what == NOTIFICATION_EXIT_TREE) { - - editor_data.save_editor_external_data(); - FileAccess::set_file_close_fail_notify_callback(NULL); - log->deinit(); // do not get messages anymore - } - if (p_what == NOTIFICATION_PROCESS) { - - if (opening_prev && !confirmation->is_visible()) - opening_prev = false; + switch (p_what) { + case NOTIFICATION_PROCESS: { + if (opening_prev && !confirmation->is_visible()) + opening_prev = false; - if (unsaved_cache != (saved_version != editor_data.get_undo_redo().get_version())) { + if (unsaved_cache != (saved_version != editor_data.get_undo_redo().get_version())) { - unsaved_cache = (saved_version != editor_data.get_undo_redo().get_version()); - _update_title(); - } + unsaved_cache = (saved_version != editor_data.get_undo_redo().get_version()); + _update_title(); + } - if (last_checked_version != editor_data.get_undo_redo().get_version()) { - _update_scene_tabs(); - last_checked_version = editor_data.get_undo_redo().get_version(); - } + if (last_checked_version != editor_data.get_undo_redo().get_version()) { + _update_scene_tabs(); + last_checked_version = editor_data.get_undo_redo().get_version(); + } - // update the animation frame of the update spinner - uint64_t frame = Engine::get_singleton()->get_frames_drawn(); - uint32_t tick = OS::get_singleton()->get_ticks_msec(); + // update the animation frame of the update spinner + uint64_t frame = Engine::get_singleton()->get_frames_drawn(); + uint32_t tick = OS::get_singleton()->get_ticks_msec(); - if (frame != update_spinner_step_frame && (tick - update_spinner_step_msec) > (1000 / 8)) { + if (frame != update_spinner_step_frame && (tick - update_spinner_step_msec) > (1000 / 8)) { - update_spinner_step++; - if (update_spinner_step >= 8) - update_spinner_step = 0; + update_spinner_step++; + if (update_spinner_step >= 8) + update_spinner_step = 0; - update_spinner_step_msec = tick; - update_spinner_step_frame = frame + 1; + update_spinner_step_msec = tick; + update_spinner_step_frame = frame + 1; - // update the icon itself only when the spinner is visible - if (EditorSettings::get_singleton()->get("interface/editor/show_update_spinner")) { - update_spinner->set_icon(gui_base->get_icon("Progress" + itos(update_spinner_step + 1), "EditorIcons")); + // update the icon itself only when the spinner is visible + if (EditorSettings::get_singleton()->get("interface/editor/show_update_spinner")) { + update_spinner->set_icon(gui_base->get_icon("Progress" + itos(update_spinner_step + 1), "EditorIcons")); + } } - } - editor_selection->update(); + editor_selection->update(); - scene_root->set_size_override(true, Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"))); + scene_root->set_size_override(true, Size2(ProjectSettings::get_singleton()->get("display/window/size/width"), ProjectSettings::get_singleton()->get("display/window/size/height"))); - ResourceImporterTexture::get_singleton()->update_imports(); - } - if (p_what == NOTIFICATION_ENTER_TREE) { + ResourceImporterTexture::get_singleton()->update_imports(); + } break; - Engine::get_singleton()->set_editor_hint(true); + case NOTIFICATION_ENTER_TREE: { + Engine::get_singleton()->set_editor_hint(true); - OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec"))); - get_tree()->get_root()->set_usage(Viewport::USAGE_2D_NO_SAMPLING); //reduce memory usage - get_tree()->get_root()->set_disable_3d(true); - get_tree()->get_root()->set_as_audio_listener(false); - get_tree()->get_root()->set_as_audio_listener_2d(false); - get_tree()->set_auto_accept_quit(false); - get_tree()->connect("files_dropped", this, "_dropped_files"); + OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec"))); + get_tree()->get_root()->set_usage(Viewport::USAGE_2D_NO_SAMPLING); //reduce memory usage + get_tree()->get_root()->set_disable_3d(true); + get_tree()->get_root()->set_as_audio_listener(false); + get_tree()->get_root()->set_as_audio_listener_2d(false); + get_tree()->set_auto_accept_quit(false); + get_tree()->connect("files_dropped", this, "_dropped_files"); - /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ - } + /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ + } break; - if (p_what == NOTIFICATION_EXIT_TREE) { + case NOTIFICATION_EXIT_TREE: { + editor_data.save_editor_external_data(); + FileAccess::set_file_close_fail_notify_callback(NULL); + log->deinit(); // do not get messages anymore + editor_data.clear_edited_scenes(); + } break; - editor_data.clear_edited_scenes(); - } - if (p_what == NOTIFICATION_READY) { + case NOTIFICATION_READY: { - VisualServer::get_singleton()->viewport_set_hide_scenario(get_scene_root()->get_viewport_rid(), true); - VisualServer::get_singleton()->viewport_set_hide_canvas(get_scene_root()->get_viewport_rid(), true); - VisualServer::get_singleton()->viewport_set_disable_environment(get_viewport()->get_viewport_rid(), true); + VisualServer::get_singleton()->viewport_set_hide_scenario(get_scene_root()->get_viewport_rid(), true); + VisualServer::get_singleton()->viewport_set_hide_canvas(get_scene_root()->get_viewport_rid(), true); + VisualServer::get_singleton()->viewport_set_disable_environment(get_viewport()->get_viewport_rid(), true); - feature_profile_manager->notify_changed(); + feature_profile_manager->notify_changed(); - if (!main_editor_buttons[EDITOR_3D]->is_visible()) { //may be hidden due to feature profile - _editor_select(EDITOR_2D); - } else { - _editor_select(EDITOR_3D); - } + if (!main_editor_buttons[EDITOR_3D]->is_visible()) { //may be hidden due to feature profile + _editor_select(EDITOR_2D); + } else { + _editor_select(EDITOR_3D); + } - _update_debug_options(); + _update_debug_options(); - /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ - } + /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ + } break; - if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) { + case MainLoop::NOTIFICATION_WM_FOCUS_IN: { - // Restore the original FPS cap after focusing back on the editor - OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec"))); + // Restore the original FPS cap after focusing back on the editor + OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/low_processor_mode_sleep_usec"))); - EditorFileSystem::get_singleton()->scan_changes(); - } + EditorFileSystem::get_singleton()->scan_changes(); + } break; - if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_OUT) { + case MainLoop::NOTIFICATION_WM_FOCUS_OUT: { - // Set a low FPS cap to decrease CPU/GPU usage while the editor is unfocused - OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec"))); - } + // Set a low FPS cap to decrease CPU/GPU usage while the editor is unfocused + OS::get_singleton()->set_low_processor_usage_mode_sleep_usec(int(EDITOR_GET("interface/editor/unfocused_low_processor_mode_sleep_usec"))); + } break; - if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST) { + case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: { - _menu_option_confirm(FILE_QUIT, false); - } + _menu_option_confirm(FILE_QUIT, false); + } break; - if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) { - scene_tabs->set_tab_close_display_policy((bool(EDITOR_GET("interface/scene_tabs/always_show_close_button")) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); - Ref<Theme> theme = create_editor_theme(theme_base->get_theme()); + case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { + scene_tabs->set_tab_close_display_policy((bool(EDITOR_GET("interface/scene_tabs/always_show_close_button")) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY)); + Ref<Theme> theme = create_editor_theme(theme_base->get_theme()); - theme_base->set_theme(theme); - gui_base->set_theme(theme); + theme_base->set_theme(theme); + gui_base->set_theme(theme); - gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles")); - scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles")); - bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer")); - scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles")); - scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles")); + gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles")); + scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles")); + bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer")); + scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles")); + scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles")); - file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); - project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); - debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); - settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); - help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); + help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles")); - if (EDITOR_GET("interface/scene_tabs/resize_if_many_tabs")) { - scene_tabs->set_min_width(int(EDITOR_GET("interface/scene_tabs/minimum_width")) * EDSCALE); - } else { - scene_tabs->set_min_width(0); - } - _update_scene_tabs(); + if (EDITOR_GET("interface/scene_tabs/resize_if_many_tabs")) { + scene_tabs->set_min_width(int(EDITOR_GET("interface/scene_tabs/minimum_width")) * EDSCALE); + } else { + scene_tabs->set_min_width(0); + } + _update_scene_tabs(); - recent_scenes->set_as_minsize(); + recent_scenes->set_as_minsize(); - // debugger area - if (ScriptEditor::get_singleton()->get_debugger()->is_visible()) - bottom_panel->add_style_override("panel", gui_base->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")); + // debugger area + if (ScriptEditor::get_singleton()->get_debugger()->is_visible()) + bottom_panel->add_style_override("panel", gui_base->get_stylebox("BottomPanelDebuggerOverride", "EditorStyles")); - // update_icons - for (int i = 0; i < singleton->main_editor_buttons.size(); i++) { + // update_icons + for (int i = 0; i < singleton->main_editor_buttons.size(); i++) { - ToolButton *tb = singleton->main_editor_buttons[i]; - EditorPlugin *p_editor = singleton->editor_table[i]; - Ref<Texture> icon = p_editor->get_icon(); + ToolButton *tb = singleton->main_editor_buttons[i]; + EditorPlugin *p_editor = singleton->editor_table[i]; + Ref<Texture> icon = p_editor->get_icon(); - if (icon.is_valid()) { - tb->set_icon(icon); - } else if (singleton->gui_base->has_icon(p_editor->get_name(), "EditorIcons")) { - tb->set_icon(singleton->gui_base->get_icon(p_editor->get_name(), "EditorIcons")); + if (icon.is_valid()) { + tb->set_icon(icon); + } else if (singleton->gui_base->has_icon(p_editor->get_name(), "EditorIcons")) { + tb->set_icon(singleton->gui_base->get_icon(p_editor->get_name(), "EditorIcons")); + } } - } - _build_icon_type_cache(); + _build_icon_type_cache(); - play_button->set_icon(gui_base->get_icon("MainPlay", "EditorIcons")); - play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons")); - play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons")); - pause_button->set_icon(gui_base->get_icon("Pause", "EditorIcons")); - stop_button->set_icon(gui_base->get_icon("Stop", "EditorIcons")); + play_button->set_icon(gui_base->get_icon("MainPlay", "EditorIcons")); + play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons")); + play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons")); + pause_button->set_icon(gui_base->get_icon("Pause", "EditorIcons")); + stop_button->set_icon(gui_base->get_icon("Stop", "EditorIcons")); - prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons")); - distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons")); - scene_tab_add->set_icon(gui_base->get_icon("Add", "EditorIcons")); + prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons")); + distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons")); + scene_tab_add->set_icon(gui_base->get_icon("Add", "EditorIcons")); - // clear_button->set_icon(gui_base->get_icon("Close", "EditorIcons")); don't have access to that node. needs to become a class property - dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons")); - dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); + // clear_button->set_icon(gui_base->get_icon("Close", "EditorIcons")); don't have access to that node. needs to become a class property + dock_tab_move_left->set_icon(theme->get_icon("Back", "EditorIcons")); + dock_tab_move_right->set_icon(theme->get_icon("Forward", "EditorIcons")); - PopupMenu *p = help_menu->get_popup(); - p->set_item_icon(p->get_item_index(HELP_SEARCH), gui_base->get_icon("HelpSearch", "EditorIcons")); - p->set_item_icon(p->get_item_index(HELP_DOCS), gui_base->get_icon("Instance", "EditorIcons")); - p->set_item_icon(p->get_item_index(HELP_QA), gui_base->get_icon("Instance", "EditorIcons")); - p->set_item_icon(p->get_item_index(HELP_ISSUES), gui_base->get_icon("Instance", "EditorIcons")); - p->set_item_icon(p->get_item_index(HELP_COMMUNITY), gui_base->get_icon("Instance", "EditorIcons")); - p->set_item_icon(p->get_item_index(HELP_ABOUT), gui_base->get_icon("Godot", "EditorIcons")); + PopupMenu *p = help_menu->get_popup(); + p->set_item_icon(p->get_item_index(HELP_SEARCH), gui_base->get_icon("HelpSearch", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_DOCS), gui_base->get_icon("Instance", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_QA), gui_base->get_icon("Instance", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_ISSUES), gui_base->get_icon("Instance", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_COMMUNITY), gui_base->get_icon("Instance", "EditorIcons")); + p->set_item_icon(p->get_item_index(HELP_ABOUT), gui_base->get_icon("Godot", "EditorIcons")); - _update_update_spinner(); - } + _update_update_spinner(); + } break; - if (p_what == Control::NOTIFICATION_RESIZED) { - _update_scene_tabs(); + case Control::NOTIFICATION_RESIZED: { + _update_scene_tabs(); + } break; } } @@ -2485,7 +2483,16 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { bool was_visible = OS::get_singleton()->is_console_visible(); OS::get_singleton()->set_console_visible(!was_visible); EditorSettings::get_singleton()->set_setting("interface/editor/hide_console_window", !was_visible); + } break; + case EDITOR_SCREENSHOT: { + + screenshot_timer->start(); + } break; + case EDITOR_OPEN_SCREENSHOT: { + bool is_checked = settings_menu->get_popup()->is_item_checked(settings_menu->get_popup()->get_item_index(EDITOR_OPEN_SCREENSHOT)); + settings_menu->get_popup()->set_item_checked(settings_menu->get_popup()->get_item_index(EDITOR_OPEN_SCREENSHOT), !is_checked); + EditorSettings::get_singleton()->set_project_metadata("screenshot_options", "open_screenshot", !is_checked); } break; case SETTINGS_PICK_MAIN_SCENE: { @@ -2540,6 +2547,30 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) { } } +void EditorNode::_request_screenshot() { + _screenshot(); +} + +void EditorNode::_screenshot(bool p_use_utc) { + String name = "editor_screenshot_" + OS::get_singleton()->get_iso_date_time(p_use_utc).replace(":", "") + ".png"; + NodePath path = String("user://") + name; + _save_screenshot(path); + if (EditorSettings::get_singleton()->get_project_metadata("screenshot_options", "open_screenshot", true)) { + OS::get_singleton()->shell_open(String("file://") + ProjectSettings::get_singleton()->globalize_path(path)); + } +} + +void EditorNode::_save_screenshot(NodePath p_path) { + + Viewport *viewport = EditorInterface::get_singleton()->get_editor_viewport()->get_viewport(); + viewport->set_clear_mode(Viewport::CLEAR_MODE_ONLY_NEXT_FRAME); + Ref<Image> img = viewport->get_texture()->get_data(); + img->flip_y(); + viewport->set_clear_mode(Viewport::CLEAR_MODE_ALWAYS); + Error error = img->save_png(p_path); + ERR_FAIL_COND(error != OK); +} + void EditorNode::_tool_menu_option(int p_idx) { switch (tool_menu->get_item_id(p_idx)) { case TOOLS_ORPHAN_RESOURCES: { @@ -2589,6 +2620,13 @@ void EditorNode::_exit_editor() { exiting = true; resource_preview->stop(); //stop early to avoid crashes _save_docks(); + + // Dim the editor window while it's quitting to make it clearer that it's busy. + // No transition is applied, as the effect needs to be visible immediately + float c = 1.0f - float(EDITOR_GET("interface/editor/dim_amount")); + Color dim_color = Color(c, c, c); + gui_base->set_modulate(dim_color); + get_tree()->quit(); } @@ -3673,6 +3711,11 @@ void EditorNode::show_warning(const String &p_text, const String &p_title) { warning->popup_centered_minsize(); } +void EditorNode::_copy_warning(const String &p_str) { + + OS::get_singleton()->set_clipboard(warning->get_text()); +} + void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) { Ref<InputEventMouse> me = p_input; @@ -4927,18 +4970,18 @@ void EditorNode::dim_editor(bool p_dimming) { static int dim_count = 0; bool dim_ui = EditorSettings::get_singleton()->get("interface/editor/dim_editor_on_dialog_popup"); if (p_dimming) { - if (dim_ui) { - if (dim_count == 0) { - _start_dimming(true); - } - dim_count++; + if (dim_ui && dim_count == 0) { + _start_dimming(true); } + dim_count++; } else { if (dim_count == 1) { _start_dimming(false); - dim_count = 0; - } else if (dim_ui && dim_count > 0) { + } + if (dim_count > 0) { dim_count--; + } else { + ERR_PRINT("Undimmed before dimming!"); } } } @@ -5057,10 +5100,11 @@ void EditorNode::_feature_profile_changed() { main_editor_buttons[EDITOR_3D]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D)); main_editor_buttons[EDITOR_SCRIPT]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT)); - main_editor_buttons[EDITOR_ASSETLIB]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB)); + if (StreamPeerSSL::is_available()) + main_editor_buttons[EDITOR_ASSETLIB]->set_visible(!profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB)); if ((profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D) && singleton->main_editor_buttons[EDITOR_3D]->is_pressed()) || (profile->is_feature_disabled(EditorFeatureProfile::FEATURE_SCRIPT) && singleton->main_editor_buttons[EDITOR_SCRIPT]->is_pressed()) || - (profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB) && singleton->main_editor_buttons[EDITOR_ASSETLIB]->is_pressed())) { + (StreamPeerSSL::is_available() && profile->is_feature_disabled(EditorFeatureProfile::FEATURE_ASSET_LIB) && singleton->main_editor_buttons[EDITOR_ASSETLIB]->is_pressed())) { _editor_select(EDITOR_2D); } } else { @@ -5073,7 +5117,8 @@ void EditorNode::_feature_profile_changed() { filesystem_dock->set_visible(true); main_editor_buttons[EDITOR_3D]->set_visible(true); main_editor_buttons[EDITOR_SCRIPT]->set_visible(true); - main_editor_buttons[EDITOR_ASSETLIB]->set_visible(true); + if (StreamPeerSSL::is_available()) + main_editor_buttons[EDITOR_ASSETLIB]->set_visible(true); } _update_dock_slots_visibility(); @@ -5150,6 +5195,8 @@ void EditorNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_inherit_imported"), &EditorNode::_inherit_imported); ClassDB::bind_method(D_METHOD("_dim_timeout"), &EditorNode::_dim_timeout); + ClassDB::bind_method("_copy_warning", &EditorNode::_copy_warning); + ClassDB::bind_method(D_METHOD("_resources_reimported"), &EditorNode::_resources_reimported); ClassDB::bind_method(D_METHOD("_bottom_panel_raise_toggled"), &EditorNode::_bottom_panel_raise_toggled); @@ -5160,6 +5207,10 @@ void EditorNode::_bind_methods() { ClassDB::bind_method(D_METHOD("_resources_changed"), &EditorNode::_resources_changed); ClassDB::bind_method(D_METHOD("_feature_profile_changed"), &EditorNode::_feature_profile_changed); + ClassDB::bind_method("_screenshot", &EditorNode::_screenshot); + ClassDB::bind_method("_request_screenshot", &EditorNode::_request_screenshot); + ClassDB::bind_method("_save_screenshot", &EditorNode::_save_screenshot); + ADD_SIGNAL(MethodInfo("play_pressed")); ADD_SIGNAL(MethodInfo("pause_pressed")); ADD_SIGNAL(MethodInfo("stop_pressed")); @@ -5747,7 +5798,9 @@ EditorNode::EditorNode() { feature_profile_manager->connect("current_feature_profile_changed", this, "_feature_profile_changed"); warning = memnew(AcceptDialog); + warning->add_button(TTR("Copy Text"), true, "copy"); gui_base->add_child(warning); + warning->connect("custom_action", this, "_copy_warning"); ED_SHORTCUT("editor/next_tab", TTR("Next tab"), KEY_MASK_CMD + KEY_TAB); ED_SHORTCUT("editor/prev_tab", TTR("Previous tab"), KEY_MASK_CMD + KEY_MASK_SHIFT + KEY_TAB); @@ -5886,6 +5939,16 @@ EditorNode::EditorNode() { editor_layouts->connect("id_pressed", this, "_layout_menu_option"); p->add_submenu_item(TTR("Editor Layout"), "Layouts"); #ifdef OSX_ENABLED + p->add_shortcut(ED_SHORTCUT("editor/take_screenshot", TTR("Take Screenshot"), KEY_MASK_CMD | KEY_F12), EDITOR_SCREENSHOT); +#else + p->add_shortcut(ED_SHORTCUT("editor/take_screenshot", TTR("Take Screenshot"), KEY_MASK_CTRL | KEY_F12), EDITOR_SCREENSHOT); +#endif + p->set_item_tooltip(p->get_item_count() - 1, TTR("Screenshots are stored in the Editor Data/Settings Folder.")); + p->add_check_shortcut(ED_SHORTCUT("editor/open_screenshot", TTR("Automatically Open Screenshots")), EDITOR_OPEN_SCREENSHOT); + bool is_open_screenshot = EditorSettings::get_singleton()->get_project_metadata("screenshot_options", "open_screenshot", true); + p->set_item_checked(p->get_item_count() - 1, is_open_screenshot); + p->set_item_tooltip(p->get_item_count() - 1, TTR("Open in an external image editor.")); +#ifdef OSX_ENABLED p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_CMD | KEY_MASK_CTRL | KEY_F), SETTINGS_TOGGLE_FULLSCREEN); #else p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11), SETTINGS_TOGGLE_FULLSCREEN); @@ -6209,7 +6272,7 @@ EditorNode::EditorNode() { file_export_lib->set_title(TTR("Export Library")); file_export_lib->set_mode(EditorFileDialog::MODE_SAVE_FILE); file_export_lib->connect("file_selected", this, "_dialog_action"); - file_export_lib_merge = memnew(CheckButton); + file_export_lib_merge = memnew(CheckBox); file_export_lib_merge->set_text(TTR("Merge With Existing")); file_export_lib_merge->set_pressed(true); file_export_lib->get_vbox()->add_child(file_export_lib_merge); @@ -6477,6 +6540,13 @@ EditorNode::EditorNode() { ED_SHORTCUT("editor/editor_assetlib", TTR("Open Asset Library")); ED_SHORTCUT("editor/editor_next", TTR("Open the next Editor")); ED_SHORTCUT("editor/editor_prev", TTR("Open the previous Editor")); + + screenshot_timer = memnew(Timer); + screenshot_timer->set_one_shot(true); + screenshot_timer->set_wait_time(settings_menu->get_popup()->get_submenu_popup_delay() + 0.1f); + screenshot_timer->connect("timeout", this, "_request_screenshot"); + add_child(screenshot_timer); + screenshot_timer->set_owner(get_owner()); } EditorNode::~EditorNode() { diff --git a/editor/editor_node.h b/editor/editor_node.h index 8222f6213b..5dabe529f9 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -199,6 +199,9 @@ private: SETTINGS_HELP, SCENE_TAB_CLOSE, + EDITOR_SCREENSHOT, + EDITOR_OPEN_SCREENSHOT, + HELP_SEARCH, HELP_DOCS, HELP_QA, @@ -280,6 +283,8 @@ private: ToolButton *search_button; TextureProgress *audio_vu; + Timer *screenshot_timer; + PluginConfigDialog *plugin_config_dialog; RichTextLabel *load_errors; @@ -325,7 +330,7 @@ private: EditorFileDialog *file_export; EditorFileDialog *file_export_lib; EditorFileDialog *file_script; - CheckButton *file_export_lib_merge; + CheckBox *file_export_lib_merge; LineEdit *file_export_password; String current_path; MenuButton *update_spinner; @@ -448,6 +453,11 @@ private: void _menu_option(int p_option); void _menu_confirm_current(); void _menu_option_confirm(int p_option, bool p_confirmed); + + void _request_screenshot(); + void _screenshot(bool p_use_utc = false); + void _save_screenshot(NodePath p_path); + void _tool_menu_option(int p_idx); void _update_debug_options(); @@ -646,6 +656,7 @@ private: protected: void _notification(int p_what); + static void _bind_methods(); protected: @@ -771,6 +782,8 @@ public: void show_accept(const String &p_text, const String &p_title); void show_warning(const String &p_text, const String &p_title = "Warning!"); + void _copy_warning(const String &p_str); + Error export_preset(const String &p_preset, const String &p_path, bool p_debug, const String &p_password, bool p_quit_after = false); static void register_editor_types(); diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp index 90d6c3a983..c2a845653e 100644 --- a/editor/editor_plugin.cpp +++ b/editor/editor_plugin.cpp @@ -220,7 +220,7 @@ EditorSelection *EditorInterface::get_selection() { return EditorNode::get_singleton()->get_editor_selection(); } -EditorSettings *EditorInterface::get_editor_settings() { +Ref<EditorSettings> EditorInterface::get_editor_settings() { return EditorSettings::get_singleton(); } diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h index ec369bbdbb..75c230adb7 100644 --- a/editor/editor_plugin.h +++ b/editor/editor_plugin.h @@ -87,7 +87,7 @@ public: EditorSelection *get_selection(); //EditorImportExport *get_import_export(); - EditorSettings *get_editor_settings(); + Ref<EditorSettings> get_editor_settings(); EditorResourcePreview *get_resource_previewer(); EditorFileSystem *get_resource_file_system(); diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp index 9cf36f162d..471742948f 100644 --- a/editor/editor_profiler.cpp +++ b/editor/editor_profiler.cpp @@ -340,7 +340,7 @@ void EditorProfiler::_update_plot() { } } - wr = PoolVector<uint8_t>::Write(); + wr.release(); Ref<Image> img; img.instance(); diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index a49f9489e1..347699c632 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -183,16 +183,20 @@ void EditorPropertyArray::_property_changed(const String &p_prop, Variant p_valu void EditorPropertyArray::_change_type(Object *p_button, int p_index) { Button *button = Object::cast_to<Button>(p_button); - + changing_type_idx = p_index; Rect2 rect = button->get_global_rect(); change_type->set_as_minsize(); change_type->set_global_position(rect.position + rect.size - Vector2(change_type->get_combined_minimum_size().x, 0)); change_type->popup(); - changing_type_idx = p_index; } void EditorPropertyArray::_change_type_menu(int p_index) { + if (p_index == Variant::VARIANT_MAX) { + _remove_pressed(changing_type_idx); + return; + } + Variant value; Variant::CallError ce; value = Variant::construct(Variant::Type(p_index), NULL, 0, ce); @@ -204,6 +208,7 @@ void EditorPropertyArray::_change_type_menu(int p_index) { if (array.get_type() == Variant::ARRAY) { array = array.call("duplicate"); //dupe, so undo/redo works better } + object->set_array(array); update_property(); } @@ -356,21 +361,27 @@ void EditorPropertyArray::update_property() { prop->set_selectable(false); prop->connect("property_changed", this, "_property_changed"); prop->connect("object_id_selected", this, "_object_id_selected"); - if (array.get_type() == Variant::ARRAY) { - HBoxContainer *hb = memnew(HBoxContainer); - vbox->add_child(hb); - hb->add_child(prop); - prop->set_h_size_flags(SIZE_EXPAND_FILL); - - if (subtype == Variant::NIL) { - Button *edit = memnew(Button); - edit->set_icon(get_icon("Edit", "EditorIcons")); - hb->add_child(edit); - edit->connect("pressed", this, "_change_type", varray(edit, i + offset)); - } + prop->set_h_size_flags(SIZE_EXPAND_FILL); + + HBoxContainer *hb = memnew(HBoxContainer); + + vbox->add_child(hb); + hb->add_child(prop); + bool is_untyped_array = array.get_type() == Variant::ARRAY && subtype == Variant::NIL; + + if (is_untyped_array) { + + Button *edit = memnew(Button); + edit->set_icon(get_icon("Edit", "EditorIcons")); + hb->add_child(edit); + edit->connect("pressed", this, "_change_type", varray(edit, i + offset)); } else { - vbox->add_child(prop); + + Button *remove = memnew(Button); + remove->set_icon(get_icon("Remove", "EditorIcons")); + remove->connect("pressed", this, "_remove_pressed", varray(i + offset)); + hb->add_child(remove); } prop->update_property(); @@ -388,8 +399,21 @@ void EditorPropertyArray::update_property() { #endif } -void EditorPropertyArray::_notification(int p_what) { +void EditorPropertyArray::_remove_pressed(int p_index) { + Variant array = object->get_array(); + array.call("remove", p_index); + + if (array.get_type() == Variant::ARRAY) { + array = array.call("duplicate"); + } + + emit_changed(get_edited_property(), array, "", false); + object->set_array(array); + update_property(); +} + +void EditorPropertyArray::_notification(int p_what) { if (p_what == NOTIFICATION_ENTER_TREE || p_what == NOTIFICATION_THEME_CHANGED) { } } @@ -476,6 +500,7 @@ void EditorPropertyArray::_bind_methods() { ClassDB::bind_method("_change_type", &EditorPropertyArray::_change_type); ClassDB::bind_method("_change_type_menu", &EditorPropertyArray::_change_type_menu); ClassDB::bind_method("_object_id_selected", &EditorPropertyArray::_object_id_selected); + ClassDB::bind_method("_remove_pressed", &EditorPropertyArray::_remove_pressed); } EditorPropertyArray::EditorPropertyArray() { @@ -498,11 +523,13 @@ EditorPropertyArray::EditorPropertyArray() { change_type = memnew(PopupMenu); add_child(change_type); change_type->connect("id_pressed", this, "_change_type_menu"); - changing_type_idx = -1; + for (int i = 0; i < Variant::VARIANT_MAX; i++) { String type = Variant::get_type_name(Variant::Type(i)); change_type->add_item(type, i); } + change_type->add_separator(); + change_type->add_item(TTR("Remove Item"), Variant::VARIANT_MAX); changing_type_idx = -1; subtype = Variant::NIL; @@ -995,7 +1022,7 @@ EditorPropertyDictionary::EditorPropertyDictionary() { change_type = memnew(PopupMenu); add_child(change_type); change_type->connect("id_pressed", this, "_change_type_menu"); - changing_type_idx = -1; + for (int i = 0; i < Variant::VARIANT_MAX; i++) { String type = Variant::get_type_name(Variant::Type(i)); change_type->add_item(type, i); diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h index 18519c754a..2fe7c07d56 100644 --- a/editor/editor_properties_array_dict.h +++ b/editor/editor_properties_array_dict.h @@ -105,6 +105,7 @@ class EditorPropertyArray : public EditorProperty { void _change_type_menu(int p_index); void _object_id_selected(const String &p_property, ObjectID p_id); + void _remove_pressed(int p_index); protected: static void _bind_methods(); diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp index f2e4d1086b..327e61cea3 100644 --- a/editor/editor_resource_preview.cpp +++ b/editor/editor_resource_preview.cpp @@ -50,7 +50,7 @@ bool EditorResourcePreviewGenerator::handles(const String &p_type) const { ERR_FAIL_V(false); } -Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from, const Size2 p_size) const { +Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from, const Size2 &p_size) const { if (get_script_instance() && get_script_instance()->has_method("generate")) { return get_script_instance()->call("generate", p_from, p_size); @@ -59,7 +59,7 @@ Ref<Texture> EditorResourcePreviewGenerator::generate(const RES &p_from, const S ERR_FAIL_V(Ref<Texture>()); } -Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path, const Size2 p_size) const { +Ref<Texture> EditorResourcePreviewGenerator::generate_from_path(const String &p_path, const Size2 &p_size) const { if (get_script_instance() && get_script_instance()->has_method("generate_from_path")) { return get_script_instance()->call("generate_from_path", p_path, p_size); diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h index e0fd54c924..ad4136e9ab 100644 --- a/editor/editor_resource_preview.h +++ b/editor/editor_resource_preview.h @@ -45,8 +45,8 @@ protected: public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; - virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 &p_size) const; + virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 &p_size) const; virtual bool generate_small_preview_automatically() const; virtual bool can_generate_small_preview() const; diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index 4bd68a593f..e4e32b2ce0 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -37,7 +37,7 @@ EditorRun::Status EditorRun::get_status() const { return status; } -Error EditorRun::run(const String &p_scene, const String p_custom_args, const List<String> &p_breakpoints) { +Error EditorRun::run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints) { List<String> args; diff --git a/editor/editor_run.h b/editor/editor_run.h index c27c8a05c8..9127c62030 100644 --- a/editor/editor_run.h +++ b/editor/editor_run.h @@ -51,7 +51,7 @@ private: public: Status get_status() const; - Error run(const String &p_scene, const String p_custom_args, const List<String> &p_breakpoints); + Error run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints); void run_native_notify() { status = STATUS_PLAY; } void stop(); diff --git a/editor/editor_sectioned_inspector.cpp b/editor/editor_sectioned_inspector.cpp index e7019e4ef6..ad6b280b6d 100644 --- a/editor/editor_sectioned_inspector.cpp +++ b/editor/editor_sectioned_inspector.cpp @@ -144,8 +144,9 @@ void SectionedInspector::_section_selected() { if (!sections->get_selected()) return; - filter->set_section(sections->get_selected()->get_metadata(0), sections->get_selected()->get_children() == NULL); - inspector->set_property_prefix(String(sections->get_selected()->get_metadata(0)) + "/"); + selected_category = sections->get_selected()->get_metadata(0); + filter->set_section(selected_category, sections->get_selected()->get_children() == NULL); + inspector->set_property_prefix(selected_category + "/"); } void SectionedInspector::set_current_section(const String &p_section) { @@ -197,8 +198,13 @@ void SectionedInspector::edit(Object *p_object) { filter->set_edited(p_object); inspector->edit(filter); - if (sections->get_root()->get_children()) { - sections->get_root()->get_children()->select(0); + TreeItem *first_item = sections->get_root(); + if (first_item) { + while (first_item->get_children()) + first_item = first_item->get_children(); + + first_item->select(0); + selected_category = first_item->get_metadata(0); } } else { @@ -208,7 +214,6 @@ void SectionedInspector::edit(Object *p_object) { void SectionedInspector::update_category_list() { - String selected_category = get_current_section(); sections->clear(); Object *o = ObjectDB::get_instance(obj); @@ -224,6 +229,10 @@ void SectionedInspector::update_category_list() { TreeItem *root = sections->create_item(); section_map[""] = root; + String filter; + if (search_box) + filter = search_box->get_text(); + for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { PropertyInfo pi = E->get(); @@ -236,9 +245,6 @@ void SectionedInspector::update_category_list() { if (pi.name.find(":") != -1 || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path" || pi.name == "resource_local_to_scene" || pi.name.begins_with("_global_script")) continue; - if (search_box && search_box->get_text() != String() && pi.name.findn(search_box->get_text()) == -1) - continue; - int sp = pi.name.find("/"); if (sp == -1) pi.name = "global/" + pi.name; @@ -246,6 +252,9 @@ void SectionedInspector::update_category_list() { Vector<String> sectionarr = pi.name.split("/"); String metasection; + if (!filter.empty() && !filter.is_subsequence_ofi(sectionarr[sectionarr.size() - 1].capitalize())) + continue; + int sc = MIN(2, sectionarr.size() - 1); for (int i = 0; i < sc; i++) { diff --git a/editor/editor_sectioned_inspector.h b/editor/editor_sectioned_inspector.h index c32f23890f..4395e9bb27 100644 --- a/editor/editor_sectioned_inspector.h +++ b/editor/editor_sectioned_inspector.h @@ -50,6 +50,8 @@ class SectionedInspector : public HSplitContainer { EditorInspector *inspector; LineEdit *search_box; + String selected_category; + static void _bind_methods(); void _section_selected(); diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp index ecc63b1a8d..2c0449398e 100644 --- a/editor/editor_settings.cpp +++ b/editor/editor_settings.cpp @@ -354,9 +354,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { hints["interface/theme/preset"] = PropertyInfo(Variant::STRING, "interface/theme/preset", PROPERTY_HINT_ENUM, "Default,Alien,Arc,Godot 2,Grey,Light,Solarized (Dark),Solarized (Light),Custom", PROPERTY_USAGE_DEFAULT); _initial_set("interface/theme/icon_and_font_color", 0); hints["interface/theme/icon_and_font_color"] = PropertyInfo(Variant::INT, "interface/theme/icon_and_font_color", PROPERTY_HINT_ENUM, "Auto,Dark,Light", PROPERTY_USAGE_DEFAULT); - _initial_set("interface/theme/base_color", Color::html("#323b4f")); + _initial_set("interface/theme/base_color", Color(0.2, 0.23, 0.31)); hints["interface/theme/base_color"] = PropertyInfo(Variant::COLOR, "interface/theme/base_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT); - _initial_set("interface/theme/accent_color", Color::html("#699ce8")); + _initial_set("interface/theme/accent_color", Color(0.41, 0.61, 0.91)); hints["interface/theme/accent_color"] = PropertyInfo(Variant::COLOR, "interface/theme/accent_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT); _initial_set("interface/theme/contrast", 0.25); hints["interface/theme/contrast"] = PropertyInfo(Variant::REAL, "interface/theme/contrast", PROPERTY_HINT_RANGE, "0.01, 1, 0.01"); @@ -505,10 +505,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) { _initial_set("editors/grid_map/pick_distance", 5000.0); // 3D - _initial_set("editors/3d/primary_grid_color", Color::html("909090")); + _initial_set("editors/3d/primary_grid_color", Color(0.56, 0.56, 0.56)); hints["editors/3d/primary_grid_color"] = PropertyInfo(Variant::COLOR, "editors/3d/primary_grid_color", PROPERTY_HINT_COLOR_NO_ALPHA, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); - _initial_set("editors/3d/secondary_grid_color", Color::html("606060")); + _initial_set("editors/3d/secondary_grid_color", Color(0.38, 0.38, 0.38)); hints["editors/3d/secondary_grid_color"] = PropertyInfo(Variant::COLOR, "editors/3d/secondary_grid_color", PROPERTY_HINT_COLOR_NO_ALPHA, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED); _initial_set("editors/3d/grid_size", 50); @@ -648,32 +648,32 @@ void EditorSettings::_load_default_text_editor_theme() { bool dark_theme = is_dark_theme(); - _initial_set("text_editor/highlighting/symbol_color", Color::html("badfff")); - _initial_set("text_editor/highlighting/keyword_color", Color::html("ffffb3")); - _initial_set("text_editor/highlighting/base_type_color", Color::html("a4ffd4")); - _initial_set("text_editor/highlighting/engine_type_color", Color::html("83d3ff")); - _initial_set("text_editor/highlighting/comment_color", Color::html("676767")); - _initial_set("text_editor/highlighting/string_color", Color::html("ef6ebe")); - _initial_set("text_editor/highlighting/background_color", dark_theme ? Color::html("3b000000") : Color::html("#323b4f")); - _initial_set("text_editor/highlighting/completion_background_color", Color::html("2C2A32")); - _initial_set("text_editor/highlighting/completion_selected_color", Color::html("434244")); - _initial_set("text_editor/highlighting/completion_existing_color", Color::html("21dfdfdf")); - _initial_set("text_editor/highlighting/completion_scroll_color", Color::html("ffffff")); - _initial_set("text_editor/highlighting/completion_font_color", Color::html("aaaaaa")); - _initial_set("text_editor/highlighting/text_color", Color::html("aaaaaa")); - _initial_set("text_editor/highlighting/line_number_color", Color::html("66aaaaaa")); - _initial_set("text_editor/highlighting/safe_line_number_color", Color::html("99aac8aa")); - _initial_set("text_editor/highlighting/caret_color", Color::html("aaaaaa")); - _initial_set("text_editor/highlighting/caret_background_color", Color::html("000000")); - _initial_set("text_editor/highlighting/text_selected_color", Color::html("000000")); - _initial_set("text_editor/highlighting/selection_color", Color::html("5a699ce8")); + _initial_set("text_editor/highlighting/symbol_color", Color(0.73, 0.87, 1.0)); + _initial_set("text_editor/highlighting/keyword_color", Color(1.0, 1.0, 0.7)); + _initial_set("text_editor/highlighting/base_type_color", Color(0.64, 1.0, 0.83)); + _initial_set("text_editor/highlighting/engine_type_color", Color(0.51, 0.83, 1.0)); + _initial_set("text_editor/highlighting/comment_color", Color(0.4, 0.4, 0.4)); + _initial_set("text_editor/highlighting/string_color", Color(0.94, 0.43, 0.75)); + _initial_set("text_editor/highlighting/background_color", dark_theme ? Color(0.0, 0.0, 0.0, 0.23) : Color(0.2, 0.23, 0.31)); + _initial_set("text_editor/highlighting/completion_background_color", Color(0.17, 0.16, 0.2)); + _initial_set("text_editor/highlighting/completion_selected_color", Color(0.26, 0.26, 0.27)); + _initial_set("text_editor/highlighting/completion_existing_color", Color(0.13, 0.87, 0.87, 0.87)); + _initial_set("text_editor/highlighting/completion_scroll_color", Color(1, 1, 1)); + _initial_set("text_editor/highlighting/completion_font_color", Color(0.67, 0.67, 0.67)); + _initial_set("text_editor/highlighting/text_color", Color(0.67, 0.67, 0.67)); + _initial_set("text_editor/highlighting/line_number_color", Color(0.67, 0.67, 0.67, 0.4)); + _initial_set("text_editor/highlighting/safe_line_number_color", Color(0.67, 0.78, 0.67, 0.6)); + _initial_set("text_editor/highlighting/caret_color", Color(0.67, 0.67, 0.67)); + _initial_set("text_editor/highlighting/caret_background_color", Color(0, 0, 0)); + _initial_set("text_editor/highlighting/text_selected_color", Color(0, 0, 0)); + _initial_set("text_editor/highlighting/selection_color", Color(0.41, 0.61, 0.91, 0.35)); _initial_set("text_editor/highlighting/brace_mismatch_color", Color(1, 0.2, 0.2)); _initial_set("text_editor/highlighting/current_line_color", Color(0.3, 0.5, 0.8, 0.15)); _initial_set("text_editor/highlighting/line_length_guideline_color", Color(0.3, 0.5, 0.8, 0.1)); _initial_set("text_editor/highlighting/word_highlighted_color", Color(0.8, 0.9, 0.9, 0.15)); - _initial_set("text_editor/highlighting/number_color", Color::html("EB9532")); - _initial_set("text_editor/highlighting/function_color", Color::html("66a2ce")); - _initial_set("text_editor/highlighting/member_variable_color", Color::html("e64e59")); + _initial_set("text_editor/highlighting/number_color", Color(0.92, 0.58, 0.2)); + _initial_set("text_editor/highlighting/function_color", Color(0.4, 0.64, 0.81)); + _initial_set("text_editor/highlighting/member_variable_color", Color(0.9, 0.31, 0.35)); _initial_set("text_editor/highlighting/mark_color", Color(1.0, 0.4, 0.4, 0.4)); _initial_set("text_editor/highlighting/bookmark_color", Color(0.08, 0.49, 0.98)); _initial_set("text_editor/highlighting/breakpoint_color", Color(0.8, 0.8, 0.4, 0.2)); @@ -1579,6 +1579,8 @@ void EditorSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("get_recent_dirs"), &EditorSettings::get_recent_dirs); ADD_SIGNAL(MethodInfo("settings_changed")); + + BIND_CONSTANT(NOTIFICATION_EDITOR_SETTINGS_CHANGED); } EditorSettings::EditorSettings() { diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index ff38b4b650..4eceb09792 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -257,44 +257,44 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Please, use alphabet order if you've added new theme here(After "Default" and "Custom") if (preset == "Default") { - preset_accent_color = Color::html("#699ce8"); - preset_base_color = Color::html("#323b4f"); + preset_accent_color = Color(0.41, 0.61, 0.91); + preset_base_color = Color(0.2, 0.23, 0.31); preset_contrast = default_contrast; } else if (preset == "Custom") { accent_color = EDITOR_GET("interface/theme/accent_color"); base_color = EDITOR_GET("interface/theme/base_color"); contrast = EDITOR_GET("interface/theme/contrast"); } else if (preset == "Alien") { - preset_accent_color = Color::html("#1bfe99"); - preset_base_color = Color::html("#2f373f"); + preset_accent_color = Color(0.11, 1.0, 0.6); + preset_base_color = Color(0.18, 0.22, 0.25); preset_contrast = 0.25; } else if (preset == "Arc") { - preset_accent_color = Color::html("#5294e2"); - preset_base_color = Color::html("#383c4a"); + preset_accent_color = Color(0.32, 0.58, 0.89); + preset_base_color = Color(0.22, 0.24, 0.29); preset_contrast = 0.25; } else if (preset == "Godot 2") { - preset_accent_color = Color::html("#86ace2"); - preset_base_color = Color::html("#3C3A44"); + preset_accent_color = Color(0.53, 0.67, 0.89); + preset_base_color = Color(0.24, 0.23, 0.27); preset_contrast = 0.25; } else if (preset == "Grey") { - preset_accent_color = Color::html("#b8e4ff"); - preset_base_color = Color::html("#3d3d3d"); + preset_accent_color = Color(0.72, 0.89, 1.0); + preset_base_color = Color(0.24, 0.24, 0.24); preset_contrast = 0.2; } else if (preset == "Light") { - preset_accent_color = Color::html("#2070ff"); - preset_base_color = Color::html("#ffffff"); + preset_accent_color = Color(0.13, 0.44, 1.0); + preset_base_color = Color(1, 1, 1); preset_contrast = 0.08; } else if (preset == "Solarized (Dark)") { - preset_accent_color = Color::html("#268bd2"); - preset_base_color = Color::html("#073642"); + preset_accent_color = Color(0.15, 0.55, 0.82); + preset_base_color = Color(0.03, 0.21, 0.26); preset_contrast = 0.23; } else if (preset == "Solarized (Light)") { - preset_accent_color = Color::html("#268bd2"); - preset_base_color = Color::html("#fdf6e3"); + preset_accent_color = Color(0.15, 0.55, 0.82); + preset_base_color = Color(0.99, 0.96, 0.89); preset_contrast = 0.06; } else { // Default - preset_accent_color = Color::html("#699ce8"); - preset_base_color = Color::html("#323b4f"); + preset_accent_color = Color(0.41, 0.61, 0.91); + preset_base_color = Color(0.2, 0.23, 0.31); preset_contrast = default_contrast; } @@ -1088,14 +1088,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.7); // editor main color - const Color main_color = Color::html(dark_theme ? "#57b3ff" : "#0480ff"); + const Color main_color = dark_theme ? Color(0.34, 0.7, 1.0) : Color(0.02, 0.5, 1.0); - const Color symbol_color = Color::html("#5792ff").linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3); - const Color keyword_color = Color::html("#ff7185"); - const Color basetype_color = Color::html(dark_theme ? "#42ffc2" : "#00c161"); + const Color symbol_color = Color(0.34, 0.57, 1.0).linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3); + const Color keyword_color = Color(1.0, 0.44, 0.52); + const Color basetype_color = dark_theme ? Color(0.26, 1.0, 0.76) : Color(0.0, 0.76, 0.38); const Color type_color = basetype_color.linear_interpolate(mono_color, dark_theme ? 0.7 : 0.5); const Color comment_color = dim_color; - const Color string_color = Color::html(dark_theme ? "#ffd942" : "#ffd118").linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3); + const Color string_color = (dark_theme ? Color(1.0, 0.85, 0.26) : Color(1.0, 0.82, 0.09)).linear_interpolate(mono_color, dark_theme ? 0.5 : 0.3); const Color te_background_color = dark_theme ? background_color : base_color; const Color completion_background_color = dark_theme ? base_color : background_color; diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 9301d8c1a4..8e332ad20e 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -163,7 +163,7 @@ Vector<String> FileSystemDock::_compute_uncollapsed_paths() { return uncollapsed_paths; } -void FileSystemDock::_update_tree(const Vector<String> p_uncollapsed_paths, bool p_uncollapse_root, bool p_select_in_favorites) { +void FileSystemDock::_update_tree(const Vector<String> &p_uncollapsed_paths, bool p_uncollapse_root, bool p_select_in_favorites) { // Recreate the tree tree->clear(); @@ -812,7 +812,7 @@ void FileSystemDock::_update_file_list(bool p_keep_selection) { } } -void FileSystemDock::_select_file(const String p_path, bool p_select_in_favorites) { +void FileSystemDock::_select_file(const String &p_path, bool p_select_in_favorites) { String fpath = p_path; if (fpath.ends_with("/")) { if (fpath != "res://") { @@ -1298,7 +1298,7 @@ void FileSystemDock::_rename_operation_confirm() { _try_move_item(to_rename, new_path, file_renames, folder_renames); int current_tab = editor->get_current_tab(); - + _save_scenes_after_move(file_renames); // save scenes before updating _update_dependencies_after_move(file_renames); _update_resource_paths_after_move(file_renames); _update_project_settings_after_move(file_renames); @@ -1324,14 +1324,14 @@ void FileSystemDock::_duplicate_operation_confirm() { return; } - String new_path; String base_dir = to_duplicate.path.get_base_dir(); - if (to_duplicate.is_file) { - new_path = base_dir.plus_file(new_name); - } else { - new_path = base_dir.substr(0, base_dir.find_last("/")).plus_file(new_name); + // get_base_dir() returns "some/path" if the original path was "some/path/", so work it around. + if (to_duplicate.path.ends_with("/")) { + base_dir = base_dir.get_base_dir(); } + String new_path = base_dir.plus_file(new_name); + //Present a more user friendly warning for name conflict DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (da->file_exists(new_path) || da->dir_exists(new_path)) { @@ -1407,7 +1407,7 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw if (is_moved) { int current_tab = editor->get_current_tab(); - + _save_scenes_after_move(file_renames); //save scenes before updating _update_dependencies_after_move(file_renames); _update_resource_paths_after_move(file_renames); _update_project_settings_after_move(file_renames); @@ -1502,7 +1502,7 @@ void FileSystemDock::_file_list_rmb_option(int p_option) { _file_option(p_option, selected); } -void FileSystemDock::_file_option(int p_option, const Vector<String> p_selected) { +void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected) { // The first one should be the active item switch (p_option) { diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 76f92665db..6de370ad29 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -175,7 +175,7 @@ private: Ref<Texture> _get_tree_item_icon(EditorFileSystemDirectory *p_dir, int p_idx); bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir, Vector<String> &uncollapsed_paths, bool p_select_in_favorites); Vector<String> _compute_uncollapsed_paths(); - void _update_tree(const Vector<String> p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false, bool p_select_in_favorites = false); + void _update_tree(const Vector<String> &p_uncollapsed_paths = Vector<String>(), bool p_uncollapse_root = false, bool p_select_in_favorites = false); void _navigate_to_path(const String &p_path, bool p_select_in_favorites = false); void _file_list_gui_input(Ref<InputEvent> p_event); @@ -188,7 +188,7 @@ private: void _tree_toggle_collapsed(); - void _select_file(const String p_path, bool p_select_in_favorites = false); + void _select_file(const String &p_path, bool p_select_in_favorites = false); void _tree_activate_file(); void _file_list_activate_file(int p_idx); void _file_multi_selected(int p_index, bool p_selected); @@ -221,7 +221,7 @@ private: void _tree_rmb_option(int p_option); void _file_list_rmb_option(int p_option); - void _file_option(int p_option, const Vector<String> p_selected); + void _file_option(int p_option, const Vector<String> &p_selected); void _fw_history(); void _bw_history(); diff --git a/editor/icons/icon_vulkan.svg b/editor/icons/icon_vulkan.svg deleted file mode 100644 index 1d5fed0305..0000000000 --- a/editor/icons/icon_vulkan.svg +++ /dev/null @@ -1,127 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="svg2" - width="48" - height="16" - viewBox="0 0 47.999999 16" - sodipodi:docname="icon_vulkan.svg" - inkscape:version="0.92.3 (2405546, 2018-03-11)"> - <metadata - id="metadata8"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title /> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs6" /> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1853" - inkscape:window-height="1016" - id="namedview4" - showgrid="false" - inkscape:zoom="10.24" - inkscape:cx="9.4970674" - inkscape:cy="11.192118" - inkscape:window-x="67" - inkscape:window-y="27" - inkscape:window-maximized="1" - inkscape:current-layer="g8" /> - <path - style="fill:#000000;stroke-width:1.06666672" - d="" - id="path819" - inkscape:connector-curvature="0" /> - <path - style="fill:#000000;stroke-width:1.06666672" - d="" - id="path817" - inkscape:connector-curvature="0" /> - <g - transform="matrix(0.04333868,0,0,0.04333868,-4.0493236,-3.7704963)" - id="g8"> - <path - inkscape:connector-curvature="0" - d="m 724.1,432.41989 h -40.6 c 0,0 0,-99 0,-129.7 13,7.2 30.1,20.5 40.6,33.3 z" - id="path10" - style="fill:#e6555a;fill-opacity:1" /> - <g - id="g12" - style="fill:#e6555a;fill-opacity:1" - transform="translate(0,47.319882)"> - <path - inkscape:connector-curvature="0" - d="m 381.8,385.1 h -50.6 l -66,-204 h 46 l 45.4,143.5 h 0.6 l 46,-143.5 h 46.3 z" - id="path14" - style="fill:#e6555a;fill-opacity:1" /> - <path - inkscape:connector-curvature="0" - d="M 585.5,385.1 H 546.9 V 364.5 H 546 c -5.1,8.6 -11.8,14.8 -20,18.6 -8.2,3.8 -16.6,5.7 -25.1,5.7 -10.9,0 -19.8,-1.4 -26.7,-4.3 -7,-2.9 -12.4,-6.9 -16.4,-12.1 -4,-5.2 -6.8,-11.6 -8.4,-19.1 -1.6,-7.5 -2.4,-15.9 -2.4,-25 v -90.9 h 40.6 v 83.4 c 0,12.2 1.9,21.3 5.7,27.3 3.8,6 10.6,9 20.3,9 11,0 19.1,-3.3 24,-9.9 5,-6.6 7.4,-17.4 7.4,-32.4 v -77.4 h 40.6 v 147.7 z" - id="path16" - style="fill:#e6555a;fill-opacity:1" /> - </g> - <polygon - points="730.8,296.2 730.7,290.5 781.9,237.3 829.9,237.3 774.2,291.6 836.2,385.1 787,385.1 " - id="polygon18" - style="fill:#e6555a;fill-opacity:1" - transform="translate(0,47.319882)" /> - <path - inkscape:connector-curvature="0" - d="m 843.6,330.11989 c 0.6,-9.5 3,-17.4 7.2,-23.7 4.2,-6.3 9.5,-11.3 16,-15.1 6.5,-3.8 13.8,-6.5 21.9,-8.1 8.1,-1.6 16.2,-2.4 24.4,-2.4 7.4,0 15,0.5 22.6,1.6 7.6,1.1 14.6,3.1 20.9,6.1 6.3,3.1 11.4,7.3 15.4,12.7 4,5.4 6,12.6 6,21.6 v 76.9 c 0,6.7 0.4,13.1 1.1,19.1 0.8,6.1 2.1,10.7 4,13.7 h -41.2 c -0.8,-2.3 -1.4,-4.6 -1.9,-7 -0.5,-2.4 -0.8,-4.8 -1,-7.3 -6.5,6.7 -14.1,11.3 -22.9,14 -8.8,2.7 -17.7,4 -26.9,4 -7,0 -13.6,-0.9 -19.7,-2.6 -6.1,-1.7 -11.4,-4.4 -16,-8 -4.6,-3.6 -8.2,-8.2 -10.7,-13.7 -2.6,-5.5 -3.9,-12.1 -3.9,-19.7 0,-8.4 1.5,-15.3 4.4,-20.7 3,-5.4 6.8,-9.8 11.4,-13 4.7,-3.2 10,-5.7 16,-7.3 6,-1.6 12,-2.9 18.1,-3.9 6.1,-0.9 12.1,-1.7 18,-2.3 5.9,-0.6 11.1,-1.4 15.7,-2.6 4.6,-1.1 8.2,-2.8 10.9,-5 2.7,-2.2 3.9,-5.4 3.7,-9.6 0,-4.4 -0.7,-7.9 -2.2,-10.4 -1.4,-2.6 -3.3,-4.6 -5.7,-6 -2.4,-1.4 -5.1,-2.4 -8.3,-2.9 -3.1,-0.5 -6.5,-0.7 -10.1,-0.7 -8,0 -14.3,1.7 -18.9,5.1 -4.6,3.4 -7.2,9.1 -8,17.1 h -40.3 z m 93.8,30 c -1.7,1.5 -3.9,2.7 -6.4,3.6 -2.6,0.9 -5.3,1.6 -8.3,2.2 -2.9,0.6 -6,1 -9.3,1.4 -3.2,0.4 -6.5,0.9 -9.7,1.4 -3,0.6 -6,1.3 -9,2.3 -3,1 -5.5,2.2 -7.7,3.9 -2.2,1.6 -4,3.7 -5.3,6.1 -1.3,2.5 -2,5.6 -2,9.4 0,3.6 0.7,6.7 2,9.1 1.3,2.5 3.1,4.4 5.4,5.9 2.3,1.4 5,2.4 8,3 3.1,0.6 6.2,0.9 9.4,0.9 8,0 14.2,-1.3 18.6,-4 4.4,-2.7 7.6,-5.9 9.7,-9.6 2.1,-3.7 3.4,-7.5 3.9,-11.3 0.5,-3.8 0.7,-6.9 0.7,-9.1 z" - id="path20" - style="fill:#e6555a;fill-opacity:1" /> - <path - inkscape:connector-curvature="0" - d="m 1004.2,284.61989 h 38.6 v 20.6 h 0.9 c 5.1,-8.6 11.8,-14.8 20,-18.7 8.2,-3.9 16.6,-5.9 25.1,-5.9 10.9,0 19.8,1.5 26.7,4.4 7,3 12.4,7.1 16.4,12.3 4,5.2 6.8,11.6 8.4,19.1 1.6,7.5 2.4,15.9 2.4,25 v 90.9 h -40.6 v -83.4 c 0,-12.2 -1.9,-21.3 -5.7,-27.3 -3.8,-6 -10.6,-9 -20.3,-9 -11,0 -19,3.3 -24,9.9 -5,6.6 -7.4,17.4 -7.4,32.4 v 77.4 h -40.6 v -147.7 z" - id="path22" - style="fill:#e6555a;fill-opacity:1" /> - <g - id="g24" - style="fill:#e6555a;fill-opacity:1" - transform="translate(0,47.319882)"> - <path - inkscape:connector-curvature="0" - d="M 612.4,211.8 V 385 H 653 V 234.2 c -13.1,-8 -26.6,-15.5 -40.6,-22.4 z" - id="path26" - style="fill:#e6555a;fill-opacity:1" /> - </g> - <path - inkscape:connector-curvature="0" - d="m 198.4,266.51989 c 23.5,-68.9 164.2,-94.2 314.1,-56.4 90,22.6 163.5,66.5 211.5,109.9 -21.7,-57.6 -127.3,-139.6 -272.8,-167.7 -164.5,-31.8 -326.7,-3.9 -346.8,69.1 -14.5,52.7 49.2,114.5 147.7,156.7 -44.3,-35.8 -65.8,-76 -53.7,-111.6 z" - id="path28" - style="fill:#e6555a;fill-opacity:1" /> - <g - id="g30" - style="fill:#e6555a;fill-opacity:1" - transform="translate(0,47.319882)"> - <path - inkscape:connector-curvature="0" - d="M 724.2,247.6 V 181 h -40.6 v 20.2 c 17.3,15.5 31,31.2 40.6,46.4 z" - id="path32" - style="fill:#e6555a;fill-opacity:1" /> - </g> - </g> -</svg> diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index 2bfc77325f..bc507e91b2 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -30,6 +30,7 @@ #include "editor_scene_importer_gltf.h" #include "core/io/json.h" +#include "core/math/crypto_core.h" #include "core/math/math_defs.h" #include "core/os/file_access.h" #include "core/os/os.h" @@ -37,7 +38,6 @@ #include "scene/3d/mesh_instance.h" #include "scene/animation/animation_player.h" #include "scene/resources/surface_tool.h" -#include "thirdparty/misc/base64.h" uint32_t EditorSceneImporterGLTF::get_import_flags() const { @@ -279,7 +279,8 @@ static Vector<uint8_t> _parse_base64_uri(const String &uri) { Vector<uint8_t> buf; buf.resize(strlen / 4 * 3 + 1 + 1); - int len = base64_decode((char *)buf.ptr(), (char *)substr.get_data(), strlen); + size_t len = 0; + ERR_FAIL_COND_V(CryptoCore::b64_decode(buf.ptrw(), buf.size(), &len, (unsigned char *)substr.get_data(), strlen) != OK, Vector<uint8_t>()); buf.resize(len); diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp index 1787a3b88d..e728dbac31 100644 --- a/editor/import/resource_importer_wav.cpp +++ b/editor/import/resource_importer_wav.cpp @@ -62,6 +62,10 @@ String ResourceImporterWAV::get_resource_type() const { bool ResourceImporterWAV::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { + if (p_option == "force/max_rate_hz" && !bool(p_options["force/max_rate"])) { + return false; + } + return true; } @@ -77,7 +81,7 @@ void ResourceImporterWAV::get_import_options(List<ImportOption> *r_options, int r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/8_bit"), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/mono"), false)); - r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/max_rate"), false)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/max_rate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false)); r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "force/max_rate_hz", PROPERTY_HINT_EXP_RANGE, "11025,192000,1"), 44100)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "edit/trim"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "edit/normalize"), true)); diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp index 2931678c80..574b47d770 100644 --- a/editor/plugins/abstract_polygon_2d_editor.cpp +++ b/editor/plugins/abstract_polygon_2d_editor.cpp @@ -349,7 +349,6 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) Vector<Vector2> vertices2 = _get_polygon(insert.polygon); pre_move_edit = vertices2; - printf("setting pre_move_edit\n"); edited_point = PosVertex(insert.polygon, insert.vertex + 1, xform.affine_inverse().xform(insert.pos)); vertices2.insert(edited_point.vertex, edited_point.pos); selected_point = edited_point; @@ -367,7 +366,6 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) if (closest.valid()) { - printf("setting pre_move_edit\n"); pre_move_edit = _get_polygon(closest.polygon); edited_point = PosVertex(closest, xform.affine_inverse().xform(closest.pos)); selected_point = closest; @@ -612,7 +610,7 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl Vector2 point = xform.xform(p); Vector2 next_point = xform.xform(p2); - p_overlay->draw_line(point, next_point, col, 2 * EDSCALE); + p_overlay->draw_line(point, next_point, col, Math::round(2 * EDSCALE), true); } } @@ -636,7 +634,7 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl p2 = points[(i + 1) % n_points] + offset; const Vector2 next_point = xform.xform(p2); - p_overlay->draw_line(point, next_point, col, 2 * EDSCALE); + p_overlay->draw_line(point, next_point, col, Math::round(2 * EDSCALE), true); } } diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp index 65282ccfc2..574f906cfa 100644 --- a/editor/plugins/animation_blend_tree_editor_plugin.cpp +++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp @@ -878,9 +878,7 @@ void AnimationNodeBlendTreeEditor::edit(const Ref<AnimationNode> &p_node) { blend_tree->disconnect("removed_from_graph", this, "_removed_from_graph"); } - if (p_node.is_valid()) { - blend_tree = p_node; - } + blend_tree = p_node; if (blend_tree.is_null()) { hide(); diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp index 2c1da3c10b..28dc5bf5c8 100644 --- a/editor/plugins/animation_tree_editor_plugin.cpp +++ b/editor/plugins/animation_tree_editor_plugin.cpp @@ -115,6 +115,8 @@ void AnimationTreeEditor::edit_path(const Vector<String> &p_path) { button_path.push_back(p_path[i]); } + edited_path = button_path; + for (int i = 0; i < editors.size(); i++) { if (editors[i]->can_edit(node)) { editors[i]->edit(node); @@ -126,10 +128,9 @@ void AnimationTreeEditor::edit_path(const Vector<String> &p_path) { } } else { current_root = 0; + edited_path = button_path; } - edited_path = button_path; - _update_path(); } diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp index 1503258ff5..16f24c3c3a 100644 --- a/editor/plugins/asset_library_editor_plugin.cpp +++ b/editor/plugins/asset_library_editor_plugin.cpp @@ -403,54 +403,60 @@ void EditorAssetLibraryItemDownload::configure(const String &p_title, int p_asse void EditorAssetLibraryItemDownload::_notification(int p_what) { - if (p_what == NOTIFICATION_PROCESS) { + switch (p_what) { - // Make the progress bar visible again when retrying the download - progress->set_modulate(Color(1, 1, 1, 1)); + case NOTIFICATION_READY: { - if (download->get_downloaded_bytes() > 0) { - progress->set_max(download->get_body_size()); - progress->set_value(download->get_downloaded_bytes()); - } + add_style_override("panel", get_stylebox("panel", "TabContainer")); + } break; + case NOTIFICATION_PROCESS: { - int cstatus = download->get_http_client_status(); + // Make the progress bar visible again when retrying the download. + progress->set_modulate(Color(1, 1, 1, 1)); - if (cstatus == HTTPClient::STATUS_BODY) { - if (download->get_body_size() > 0) { - status->set_text( - vformat( - TTR("Downloading (%s / %s)..."), - String::humanize_size(download->get_downloaded_bytes()), - String::humanize_size(download->get_body_size()))); - } else { - // Total file size is unknown, so it cannot be displayed - status->set_text(TTR("Downloading...")); + if (download->get_downloaded_bytes() > 0) { + progress->set_max(download->get_body_size()); + progress->set_value(download->get_downloaded_bytes()); } - } - if (cstatus != prev_status) { - switch (cstatus) { + int cstatus = download->get_http_client_status(); + + if (cstatus == HTTPClient::STATUS_BODY) { + if (download->get_body_size() > 0) { + status->set_text(vformat( + TTR("Downloading (%s / %s)..."), + String::humanize_size(download->get_downloaded_bytes()), + String::humanize_size(download->get_body_size()))); + } else { + // Total file size is unknown, so it cannot be displayed. + status->set_text(TTR("Downloading...")); + } + } - case HTTPClient::STATUS_RESOLVING: { - status->set_text(TTR("Resolving...")); - progress->set_max(1); - progress->set_value(0); - } break; - case HTTPClient::STATUS_CONNECTING: { - status->set_text(TTR("Connecting...")); - progress->set_max(1); - progress->set_value(0); - } break; - case HTTPClient::STATUS_REQUESTING: { - status->set_text(TTR("Requesting...")); - progress->set_max(1); - progress->set_value(0); - } break; - default: { + if (cstatus != prev_status) { + switch (cstatus) { + + case HTTPClient::STATUS_RESOLVING: { + status->set_text(TTR("Resolving...")); + progress->set_max(1); + progress->set_value(0); + } break; + case HTTPClient::STATUS_CONNECTING: { + status->set_text(TTR("Connecting...")); + progress->set_max(1); + progress->set_value(0); + } break; + case HTTPClient::STATUS_REQUESTING: { + status->set_text(TTR("Requesting...")); + progress->set_max(1); + progress->set_value(0); + } break; + default: { + } } + prev_status = cstatus; } - prev_status = cstatus; - } + } break; } } void EditorAssetLibraryItemDownload::_close() { @@ -531,7 +537,7 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() { hb2->add_spacer(); install = memnew(Button); - install->set_text(TTR("Install")); + install->set_text(TTR("Install...")); install->set_disabled(true); install->connect("pressed", this, "_install"); @@ -564,6 +570,7 @@ EditorAssetLibraryItemDownload::EditorAssetLibraryItemDownload() { void EditorAssetLibrary::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_READY: { error_tr->set_texture(get_icon("Error", "EditorIcons")); @@ -573,14 +580,12 @@ void EditorAssetLibrary::_notification(int p_what) { error_label->raise(); } break; - case NOTIFICATION_VISIBILITY_CHANGED: { if (is_visible()) { - _repository_changed(0); // Update when shown for the first time + _repository_changed(0); // Update when shown for the first time. } } break; - case NOTIFICATION_PROCESS: { HTTPClient::Status s = request->get_http_client_status(); @@ -619,6 +624,7 @@ void EditorAssetLibrary::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { library_scroll_bg->add_style_override("panel", get_stylebox("bg", "Tree")); + downloads_scroll->add_style_override("bg", get_stylebox("bg", "Tree")); error_tr->set_texture(get_icon("Error", "EditorIcons")); reverse->set_icon(get_icon("Sort", "EditorIcons")); filter->set_right_icon(get_icon("Search", "EditorIcons")); @@ -1238,9 +1244,6 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const description->connect("confirmed", this, "_install_asset"); description->configure(r["title"], r["asset_id"], category_map[r["category_id"]], r["category_id"], r["author"], r["author_id"], r["cost"], r["version"], r["version_string"], r["description"], r["download_url"], r["browse_url"], r["download_hash"]); - /*item->connect("asset_selected",this,"_select_asset"); - item->connect("author_selected",this,"_select_author"); - item->connect("category_selected",this,"_category_selected");*/ if (r.has("icon_url") && r["icon_url"] != "") { _request_image(description->get_instance_id(), r["icon_url"], IMAGE_QUEUE_ICON, 0); @@ -1390,19 +1393,16 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) { reverse = memnew(ToolButton); reverse->set_toggle_mode(true); reverse->connect("toggled", this, "_rerun_search"); - //reverse->set_text(TTR("Reverse")); + reverse->set_tooltip(TTR("Reverse sorting.")); search_hb2->add_child(reverse); search_hb2->add_child(memnew(VSeparator)); - //search_hb2->add_spacer(); - search_hb2->add_child(memnew(Label(TTR("Category:") + " "))); categories = memnew(OptionButton); categories->add_item(TTR("All")); search_hb2->add_child(categories); categories->set_h_size_flags(SIZE_EXPAND_FILL); - //search_hb2->add_spacer(); categories->connect("item_selected", this, "_rerun_search"); search_hb2->add_child(memnew(VSeparator)); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index e0e9d4af52..d4eab888cc 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -860,20 +860,47 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve Ref<InputEventMouseButton> b = p_event; Ref<InputEventMouseMotion> m = p_event; - // Start dragging a guide if (drag_type == DRAG_NONE) { - if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { - if (show_guides && show_rulers && EditorNode::get_singleton()->get_edited_scene()) { - Transform2D xform = viewport_scrollable->get_transform() * transform; - // Retrieve the guide lists - Array vguides; - if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) { - vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_"); + if (show_guides && show_rulers && EditorNode::get_singleton()->get_edited_scene()) { + Transform2D xform = viewport_scrollable->get_transform() * transform; + // Retrieve the guide lists + Array vguides; + if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_vertical_guides_")) { + vguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_vertical_guides_"); + } + Array hguides; + if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) { + hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_"); + } + + // Hover over guides + float minimum = 1e20; + is_hovering_h_guide = false; + is_hovering_v_guide = false; + + if (m.is_valid() && m->get_position().x < RULER_WIDTH) { + // Check if we are hovering an existing horizontal guide + for (int i = 0; i < hguides.size(); i++) { + if (ABS(xform.xform(Point2(0, hguides[i])).y - m->get_position().y) < MIN(minimum, 8)) { + is_hovering_h_guide = true; + is_hovering_v_guide = false; + break; + } } - Array hguides; - if (EditorNode::get_singleton()->get_edited_scene()->has_meta("_edit_horizontal_guides_")) { - hguides = EditorNode::get_singleton()->get_edited_scene()->get_meta("_edit_horizontal_guides_"); + + } else if (m.is_valid() && m->get_position().y < RULER_WIDTH) { + // Check if we are hovering an existing vertical guide + for (int i = 0; i < vguides.size(); i++) { + if (ABS(xform.xform(Point2(vguides[i], 0)).x - m->get_position().x) < MIN(minimum, 8)) { + is_hovering_v_guide = true; + is_hovering_h_guide = false; + break; + } } + } + + // Start dragging a guide + if (b.is_valid() && b->get_button_index() == BUTTON_LEFT && b->is_pressed()) { // Press button if (b->get_position().x < RULER_WIDTH && b->get_position().y < RULER_WIDTH) { @@ -883,7 +910,6 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve return true; } else if (b->get_position().x < RULER_WIDTH) { // Check if we drag an existing horizontal guide - float minimum = 1e20; dragged_guide_index = -1; for (int i = 0; i < hguides.size(); i++) { if (ABS(xform.xform(Point2(0, hguides[i])).y - b->get_position().y) < MIN(minimum, 8)) { @@ -901,7 +927,6 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve return true; } else if (b->get_position().y < RULER_WIDTH) { // Check if we drag an existing vertical guide - float minimum = 1e20; dragged_guide_index = -1; for (int i = 0; i < vguides.size(); i++) { if (ABS(xform.xform(Point2(vguides[i], 0)).x - b->get_position().x) < MIN(minimum, 8)) { @@ -956,14 +981,14 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve // Adds a new vertical guide if (dragged_guide_index >= 0) { vguides[dragged_guide_index] = edited.x; - undo_redo->create_action(TTR("Move vertical guide")); + undo_redo->create_action(TTR("Move Vertical Guide")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides); undo_redo->add_undo_method(viewport, "update"); undo_redo->commit_action(); } else { vguides.push_back(edited.x); - undo_redo->create_action(TTR("Create new vertical guide")); + undo_redo->create_action(TTR("Create Vertical Guide")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides); undo_redo->add_undo_method(viewport, "update"); @@ -972,7 +997,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve } else { if (dragged_guide_index >= 0) { vguides.remove(dragged_guide_index); - undo_redo->create_action(TTR("Remove vertical guide")); + undo_redo->create_action(TTR("Remove Vertical Guide")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides); undo_redo->add_undo_method(viewport, "update"); @@ -985,14 +1010,14 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve // Adds a new horizontal guide if (dragged_guide_index >= 0) { hguides[dragged_guide_index] = edited.y; - undo_redo->create_action(TTR("Move horizontal guide")); + undo_redo->create_action(TTR("Move Horizontal Guide")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides); undo_redo->add_undo_method(viewport, "update"); undo_redo->commit_action(); } else { hguides.push_back(edited.y); - undo_redo->create_action(TTR("Create new horizontal guide")); + undo_redo->create_action(TTR("Create Horizontal Guide")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides); undo_redo->add_undo_method(viewport, "update"); @@ -1001,7 +1026,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve } else { if (dragged_guide_index >= 0) { hguides.remove(dragged_guide_index); - undo_redo->create_action(TTR("Remove horizontal guide")); + undo_redo->create_action(TTR("Remove Horizontal Guide")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", prev_hguides); undo_redo->add_undo_method(viewport, "update"); @@ -1015,7 +1040,7 @@ bool CanvasItemEditor::_gui_input_rulers_and_guides(const Ref<InputEvent> &p_eve // Adds a new horizontal guide a new vertical guide vguides.push_back(edited.x); hguides.push_back(edited.y); - undo_redo->create_action(TTR("Create new horizontal and vertical guides")); + undo_redo->create_action(TTR("Create Horizontal and Vertical Guides")); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", vguides); undo_redo->add_do_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_horizontal_guides_", hguides); undo_redo->add_undo_method(EditorNode::get_singleton()->get_edited_scene(), "set_meta", "_edit_vertical_guides_", prev_vguides); @@ -2221,8 +2246,6 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { //printf("Plugin\n"); } else if ((accepted = _gui_input_open_scene_on_double_click(p_event))) { //printf("Open scene on double click\n"); - } else if ((accepted = _gui_input_anchors(p_event))) { - //printf("Anchors\n"); } else if ((accepted = _gui_input_scale(p_event))) { //printf("Set scale\n"); } else if ((accepted = _gui_input_pivot(p_event))) { @@ -2233,6 +2256,8 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { //printf("Rotate\n"); } else if ((accepted = _gui_input_move(p_event))) { //printf("Move\n"); + } else if ((accepted = _gui_input_anchors(p_event))) { + //printf("Anchors\n"); } else if ((accepted = _gui_input_select(p_event))) { //printf("Selection\n"); } else { @@ -2268,14 +2293,17 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { break; case DRAG_LEFT: case DRAG_RIGHT: + case DRAG_V_GUIDE: c = CURSOR_HSIZE; break; case DRAG_TOP: case DRAG_BOTTOM: + case DRAG_H_GUIDE: c = CURSOR_VSIZE; break; case DRAG_TOP_LEFT: case DRAG_BOTTOM_RIGHT: + case DRAG_DOUBLE_GUIDE: c = CURSOR_FDIAGSIZE; break; case DRAG_TOP_RIGHT: @@ -2288,6 +2316,12 @@ void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) { default: break; } + + if (is_hovering_h_guide) + c = CURSOR_VSIZE; + else if (is_hovering_v_guide) + c = CURSOR_HSIZE; + viewport->set_default_cursor_shape(c); // Grab focus @@ -2351,7 +2385,7 @@ void CanvasItemEditor::_draw_guides() { if (drag_type == DRAG_V_GUIDE && i == dragged_guide_index) continue; float x = xform.xform(Point2(vguides[i], 0)).x; - viewport->draw_line(Point2(x, 0), Point2(x, viewport->get_size().y), guide_color); + viewport->draw_line(Point2(x, 0), Point2(x, viewport->get_size().y), guide_color, Math::round(EDSCALE)); } } @@ -2361,7 +2395,7 @@ void CanvasItemEditor::_draw_guides() { if (drag_type == DRAG_H_GUIDE && i == dragged_guide_index) continue; float y = xform.xform(Point2(0, hguides[i])).y; - viewport->draw_line(Point2(0, y), Point2(viewport->get_size().x, y), guide_color); + viewport->draw_line(Point2(0, y), Point2(viewport->get_size().x, y), guide_color, Math::round(EDSCALE)); } } @@ -2373,14 +2407,14 @@ void CanvasItemEditor::_draw_guides() { Ref<Font> font = get_font("font", "Label"); Size2 text_size = font->get_string_size(str); viewport->draw_string(font, Point2(dragged_guide_pos.x + 10, RULER_WIDTH + text_size.y / 2 + 10), str, text_color); - viewport->draw_line(Point2(dragged_guide_pos.x, 0), Point2(dragged_guide_pos.x, viewport->get_size().y), guide_color); + viewport->draw_line(Point2(dragged_guide_pos.x, 0), Point2(dragged_guide_pos.x, viewport->get_size().y), guide_color, Math::round(EDSCALE)); } if (drag_type == DRAG_DOUBLE_GUIDE || drag_type == DRAG_H_GUIDE) { String str = vformat("%d px", xform.affine_inverse().xform(dragged_guide_pos).y); Ref<Font> font = get_font("font", "Label"); Size2 text_size = font->get_string_size(str); viewport->draw_string(font, Point2(RULER_WIDTH + 10, dragged_guide_pos.y + text_size.y / 2 + 10), str, text_color); - viewport->draw_line(Point2(0, dragged_guide_pos.y), Point2(viewport->get_size().x, dragged_guide_pos.y), guide_color); + viewport->draw_line(Point2(0, dragged_guide_pos.y), Point2(viewport->get_size().x, dragged_guide_pos.y), guide_color, Math::round(EDSCALE)); } } @@ -2435,14 +2469,14 @@ void CanvasItemEditor::_draw_rulers() { for (int i = Math::ceil(first.x); i < last.x; i++) { Point2 position = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0)); if (i % (major_subdivision * minor_subdivision) == 0) { - viewport->draw_line(Point2(position.x, 0), Point2(position.x, RULER_WIDTH), graduation_color); + viewport->draw_line(Point2(position.x, 0), Point2(position.x, RULER_WIDTH), graduation_color, Math::round(EDSCALE)); float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(i, 0)).x; viewport->draw_string(font, Point2(position.x + 2, font->get_height()), vformat(((int)val == val) ? "%d" : "%.1f", val), font_color); } else { if (i % minor_subdivision == 0) { - viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.33), Point2(position.x, RULER_WIDTH), graduation_color); + viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.33), Point2(position.x, RULER_WIDTH), graduation_color, Math::round(EDSCALE)); } else { - viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.75), Point2(position.x, RULER_WIDTH), graduation_color); + viewport->draw_line(Point2(position.x, RULER_WIDTH * 0.75), Point2(position.x, RULER_WIDTH), graduation_color, Math::round(EDSCALE)); } } } @@ -2452,7 +2486,7 @@ void CanvasItemEditor::_draw_rulers() { for (int i = Math::ceil(first.y); i < last.y; i++) { Point2 position = (transform * ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i)); if (i % (major_subdivision * minor_subdivision) == 0) { - viewport->draw_line(Point2(0, position.y), Point2(RULER_WIDTH, position.y), graduation_color); + viewport->draw_line(Point2(0, position.y), Point2(RULER_WIDTH, position.y), graduation_color, Math::round(EDSCALE)); float val = (ruler_transform * major_subdivide * minor_subdivide).xform(Point2(0, i)).y; Transform2D text_xform = Transform2D(-Math_PI / 2.0, Point2(font->get_height(), position.y - 2)); @@ -2462,9 +2496,9 @@ void CanvasItemEditor::_draw_rulers() { } else { if (i % minor_subdivision == 0) { - viewport->draw_line(Point2(RULER_WIDTH * 0.33, position.y), Point2(RULER_WIDTH, position.y), graduation_color); + viewport->draw_line(Point2(RULER_WIDTH * 0.33, position.y), Point2(RULER_WIDTH, position.y), graduation_color, Math::round(EDSCALE)); } else { - viewport->draw_line(Point2(RULER_WIDTH * 0.75, position.y), Point2(RULER_WIDTH, position.y), graduation_color); + viewport->draw_line(Point2(RULER_WIDTH * 0.75, position.y), Point2(RULER_WIDTH, position.y), graduation_color, Math::round(EDSCALE)); } } } @@ -2495,7 +2529,7 @@ void CanvasItemEditor::_draw_grid() { if (i == 0) last_cell = cell; if (last_cell != cell) - viewport->draw_line(Point2(i, 0), Point2(i, s.height), grid_color); + viewport->draw_line(Point2(i, 0), Point2(i, s.height), grid_color, Math::round(EDSCALE)); last_cell = cell; } } @@ -2506,7 +2540,7 @@ void CanvasItemEditor::_draw_grid() { if (i == 0) last_cell = cell; if (last_cell != cell) - viewport->draw_line(Point2(0, i), Point2(s.width, i), grid_color); + viewport->draw_line(Point2(0, i), Point2(s.width, i), grid_color, Math::round(EDSCALE)); last_cell = cell; } } @@ -2601,7 +2635,13 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) { line_starts[i] = Vector2::linear_interpolate(corners_pos[i], corners_pos[(i + 1) % 4], anchor_val); line_ends[i] = Vector2::linear_interpolate(corners_pos[(i + 3) % 4], corners_pos[(i + 2) % 4], anchor_val); snapped = anchors_values[i] == 0.0 || anchors_values[i] == 0.5 || anchors_values[i] == 1.0; - viewport->draw_line(line_starts[i], line_ends[i], snapped ? color_snapped : color_base, (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) ? 2 : 1); + int line_width; + if (i == dragged_anchor || (i + 3) % 4 == dragged_anchor) { + line_width = 2; + } else { + line_width = 1; + } + viewport->draw_line(line_starts[i], line_ends[i], snapped ? color_snapped : color_base, Math::round(line_width * EDSCALE)); } // Display the percentages next to the lines @@ -2646,7 +2686,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) { start = Vector2(node_pos_in_parent[0], Math::lerp(node_pos_in_parent[1], node_pos_in_parent[3], ratio)); end = start - Vector2(control->get_margin(MARGIN_LEFT), 0); _draw_margin_at_position(control->get_margin(MARGIN_LEFT), parent_transform.xform((start + end) / 2), MARGIN_TOP); - viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); + viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, Math::round(EDSCALE)); break; default: break; @@ -2661,7 +2701,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) { start = Vector2(node_pos_in_parent[2], Math::lerp(node_pos_in_parent[3], node_pos_in_parent[1], ratio)); end = start - Vector2(control->get_margin(MARGIN_RIGHT), 0); _draw_margin_at_position(control->get_margin(MARGIN_RIGHT), parent_transform.xform((start + end) / 2), MARGIN_BOTTOM); - viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); + viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, Math::round(EDSCALE)); break; default: break; @@ -2676,7 +2716,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) { start = Vector2(Math::lerp(node_pos_in_parent[0], node_pos_in_parent[2], ratio), node_pos_in_parent[1]); end = start - Vector2(0, control->get_margin(MARGIN_TOP)); _draw_margin_at_position(control->get_margin(MARGIN_TOP), parent_transform.xform((start + end) / 2), MARGIN_LEFT); - viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); + viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, Math::round(EDSCALE)); break; default: break; @@ -2691,7 +2731,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) { start = Vector2(Math::lerp(node_pos_in_parent[2], node_pos_in_parent[0], ratio), node_pos_in_parent[3]); end = start - Vector2(0, control->get_margin(MARGIN_BOTTOM)); _draw_margin_at_position(control->get_margin(MARGIN_BOTTOM), parent_transform.xform((start + end) / 2), MARGIN_RIGHT); - viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, 1); + viewport->draw_line(parent_transform.xform(start), parent_transform.xform(end), color_base, Math::round(EDSCALE)); break; default: break; @@ -2710,7 +2750,7 @@ void CanvasItemEditor::_draw_control_helpers(Control *control) { case DRAG_MOVE: if (control->get_rotation() != 0.0 || control->get_scale() != Vector2(1, 1)) { Rect2 rect = Rect2(Vector2(node_pos_in_parent[0], node_pos_in_parent[1]), control->get_size()); - viewport->draw_rect(parent_transform.xform(rect), color_base, false); + viewport->draw_rect(parent_transform.xform(rect), color_base, false, Math::round(EDSCALE)); } break; default: @@ -2751,7 +2791,7 @@ void CanvasItemEditor::_draw_selection() { }; for (int i = 0; i < 4; i++) { - viewport->draw_line(pre_drag_endpoints[i], pre_drag_endpoints[(i + 1) % 4], pre_drag_color, 2); + viewport->draw_line(pre_drag_endpoints[i], pre_drag_endpoints[(i + 1) % 4], pre_drag_color, Math::round(2 * EDSCALE), true); } } else { viewport->draw_texture(previous_position_icon, (pre_drag_xform.xform(Point2()) - (previous_position_icon->get_size() / 2)).floor()); @@ -2773,7 +2813,7 @@ void CanvasItemEditor::_draw_selection() { Color c = Color(1, 0.6, 0.4, 0.7); for (int i = 0; i < 4; i++) { - viewport->draw_line(endpoints[i], endpoints[(i + 1) % 4], c, 2); + viewport->draw_line(endpoints[i], endpoints[(i + 1) % 4], c, Math::round(2 * EDSCALE), true); } } else { @@ -2853,18 +2893,16 @@ void CanvasItemEditor::_draw_selection() { } } - //scale_factor *= zoom; - viewport->draw_set_transform_matrix(simple_xform); Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); Color x_axis_color(1.0, 0.4, 0.4, 0.6); viewport->draw_rect(x_handle_rect, x_axis_color); - viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), x_axis_color); + viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), x_axis_color, Math::round(EDSCALE), true); Rect2 y_handle_rect = Rect2(-5 * EDSCALE, -(scale_factor.y + 10) * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); Color y_axis_color(0.4, 1.0, 0.4, 0.6); viewport->draw_rect(y_handle_rect, y_axis_color); - viewport->draw_line(Point2(), Point2(0, -scale_factor.y * EDSCALE), y_axis_color); + viewport->draw_line(Point2(), Point2(0, -scale_factor.y * EDSCALE), y_axis_color, Math::round(EDSCALE), true); viewport->draw_set_transform_matrix(viewport->get_transform()); } diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index a46682d494..2a85b20424 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -371,6 +371,8 @@ private: List<CanvasItem *> drag_selection; int dragged_guide_index; Point2 dragged_guide_pos; + bool is_hovering_h_guide; + bool is_hovering_v_guide; bool updating_value_dialog; diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp index 87cb0d04a2..8cf09406c7 100644 --- a/editor/plugins/collision_polygon_editor_plugin.cpp +++ b/editor/plugins/collision_polygon_editor_plugin.cpp @@ -346,8 +346,10 @@ bool Polygon3DEditor::forward_spatial_gui_input(Camera *p_camera, const Ref<Inpu snap_ignore = false; } - if (!snap_ignore) { - cpoint = CanvasItemEditor::get_singleton()->snap_point(cpoint); + if (!snap_ignore && SpatialEditor::get_singleton()->is_snap_enabled()) { + cpoint = cpoint.snapped(Vector2( + SpatialEditor::get_singleton()->get_translate_snap(), + SpatialEditor::get_singleton()->get_translate_snap())); } edited_point_pos = cpoint; diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index d2d2b8f130..5d3cef4c34 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -715,7 +715,7 @@ void CurveEditor::_draw() { if (_hover_point != -1) { const Color hover_color = line_color; Vector2 pos = curve.get_point_position(_hover_point); - stroke_rect(Rect2(get_view_pos(pos), Vector2(1, 1)).grow(_hover_radius), hover_color); + draw_rect(Rect2(get_view_pos(pos), Vector2(1, 1)).grow(_hover_radius), hover_color, false, Math::round(EDSCALE)); } // Help text @@ -726,23 +726,6 @@ void CurveEditor::_draw() { } } -// TODO That should be part of the drawing API... -void CurveEditor::stroke_rect(Rect2 rect, Color color) { - - // a---b - // | | - // c---d - Vector2 a(rect.position); - Vector2 b(rect.position.x + rect.size.x, rect.position.y); - Vector2 c(rect.position.x, rect.position.y + rect.size.y); - Vector2 d(rect.position + rect.size); - - draw_line(a, b, color, Math::round(EDSCALE)); - draw_line(b, d, color, Math::round(EDSCALE)); - draw_line(d, c, color, Math::round(EDSCALE)); - draw_line(c, a, color, Math::round(EDSCALE)); -} - void CurveEditor::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &CurveEditor::on_gui_input); ClassDB::bind_method(D_METHOD("_on_preset_item_selected"), &CurveEditor::on_preset_item_selected); @@ -783,7 +766,7 @@ bool CurvePreviewGenerator::handles(const String &p_type) const { return p_type == "Curve"; } -Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, const Size2 p_size) const { +Ref<Texture> CurvePreviewGenerator::generate(const Ref<Resource> &p_from, const Size2 &p_size) const { Ref<Curve> curve_ref = p_from; ERR_FAIL_COND_V(curve_ref.is_null(), Ref<Texture>()); diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h index be774a9696..9071146863 100644 --- a/editor/plugins/curve_editor_plugin.h +++ b/editor/plugins/curve_editor_plugin.h @@ -97,8 +97,6 @@ private: void _draw(); - void stroke_rect(Rect2 rect, Color color); - private: Transform2D _world_to_view; @@ -142,7 +140,7 @@ class CurvePreviewGenerator : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const Ref<Resource> &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate(const Ref<Resource> &p_from, const Size2 &p_size) const; }; #endif // CURVE_EDITOR_PLUGIN_H diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp index 285823d95a..c8ffc2744a 100644 --- a/editor/plugins/editor_preview_plugins.cpp +++ b/editor/plugins/editor_preview_plugins.cpp @@ -82,7 +82,7 @@ bool EditorTexturePreviewPlugin::generate_small_preview_automatically() const { return true; } -Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { +Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { Ref<Image> img; Ref<AtlasTexture> atex = p_from; @@ -148,7 +148,7 @@ bool EditorImagePreviewPlugin::handles(const String &p_type) const { return p_type == "Image"; } -Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { +Ref<Texture> EditorImagePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { Ref<Image> img = p_from; @@ -196,7 +196,7 @@ bool EditorBitmapPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "BitMap"); } -Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { +Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { Ref<BitMap> bm = p_from; @@ -263,12 +263,12 @@ bool EditorPackedScenePreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "PackedScene"); } -Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { +Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { return generate_from_path(p_from->get_path(), p_size); } -Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path, const Size2 p_size) const { +Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const { String temp_path = EditorSettings::get_singleton()->get_cache_dir(); String cache_base = ProjectSettings::get_singleton()->globalize_path(p_path).md5_text(); @@ -321,7 +321,7 @@ bool EditorMaterialPreviewPlugin::generate_small_preview_automatically() const { return true; } -Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { +Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { Ref<Material> material = p_from; ERR_FAIL_COND_V(material.is_null(), Ref<Texture>()); @@ -487,7 +487,7 @@ bool EditorScriptPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Script"); } -Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { +Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { Ref<Script> scr = p_from; if (scr.is_null()) @@ -609,7 +609,7 @@ bool EditorAudioStreamPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "AudioStream"); } -Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { +Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { Ref<AudioStream> stream = p_from; ERR_FAIL_COND_V(stream.is_null(), Ref<Texture>()); @@ -676,7 +676,7 @@ Ref<Texture> EditorAudioStreamPreviewPlugin::generate(const RES &p_from, const S } } - imgdata = PoolVector<uint8_t>::Write(); + imgdata.release(); //post_process_preview(img); Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture)); @@ -706,7 +706,7 @@ bool EditorMeshPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh } -Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { +Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { Ref<Mesh> mesh = p_from; ERR_FAIL_COND_V(mesh.is_null(), Ref<Texture>()); @@ -827,7 +827,7 @@ bool EditorFontPreviewPlugin::handles(const String &p_type) const { return ClassDB::is_parent_class(p_type, "DynamicFontData"); } -Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 p_size) const { +Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path, const Size2 &p_size) const { Ref<DynamicFontData> SampledFont; SampledFont.instance(); @@ -882,7 +882,7 @@ Ref<Texture> EditorFontPreviewPlugin::generate_from_path(const String &p_path, c return ptex; } -Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from, const Size2 p_size) const { +Ref<Texture> EditorFontPreviewPlugin::generate(const RES &p_from, const Size2 &p_size) const { String path = p_from->get_path(); if (!FileAccess::exists(path)) { diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h index 12d693b10a..71a6c0fc08 100644 --- a/editor/plugins/editor_preview_plugins.h +++ b/editor/plugins/editor_preview_plugins.h @@ -41,7 +41,7 @@ class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; virtual bool generate_small_preview_automatically() const; - virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 &p_size) const; EditorTexturePreviewPlugin(); }; @@ -52,7 +52,7 @@ class EditorImagePreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; virtual bool generate_small_preview_automatically() const; - virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 &p_size) const; EditorImagePreviewPlugin(); }; @@ -63,7 +63,7 @@ class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; virtual bool generate_small_preview_automatically() const; - virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 &p_size) const; EditorBitmapPreviewPlugin(); }; @@ -72,8 +72,8 @@ class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; - virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 &p_size) const; + virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 &p_size) const; EditorPackedScenePreviewPlugin(); }; @@ -102,7 +102,7 @@ protected: public: virtual bool handles(const String &p_type) const; virtual bool generate_small_preview_automatically() const; - virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 &p_size) const; EditorMaterialPreviewPlugin(); ~EditorMaterialPreviewPlugin(); @@ -111,7 +111,7 @@ public: class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 &p_size) const; EditorScriptPreviewPlugin(); }; @@ -119,7 +119,7 @@ public: class EditorAudioStreamPreviewPlugin : public EditorResourcePreviewGenerator { public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 &p_size) const; EditorAudioStreamPreviewPlugin(); }; @@ -146,7 +146,7 @@ protected: public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 &p_size) const; EditorMeshPreviewPlugin(); ~EditorMeshPreviewPlugin(); @@ -169,8 +169,8 @@ protected: public: virtual bool handles(const String &p_type) const; - virtual Ref<Texture> generate(const RES &p_from, const Size2 p_size) const; - virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 p_size) const; + virtual Ref<Texture> generate(const RES &p_from, const Size2 &p_size) const; + virtual Ref<Texture> generate_from_path(const String &p_path, const Size2 &p_size) const; EditorFontPreviewPlugin(); ~EditorFontPreviewPlugin(); diff --git a/editor/plugins/multimesh_editor_plugin.cpp b/editor/plugins/multimesh_editor_plugin.cpp index cae705a697..d59efe49e7 100644 --- a/editor/plugins/multimesh_editor_plugin.cpp +++ b/editor/plugins/multimesh_editor_plugin.cpp @@ -144,7 +144,7 @@ void MultiMeshEditor::_populate() { } } - w = PoolVector<Face3>::Write(); + w.release(); PoolVector<Face3> faces = geometry; ERR_EXPLAIN(TTR("Parent has no solid faces to populate.")); diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp index f05e7d65d3..75d31459e8 100644 --- a/editor/plugins/particles_editor_plugin.cpp +++ b/editor/plugins/particles_editor_plugin.cpp @@ -197,7 +197,7 @@ void ParticlesEditorBase::_node_selected(const NodePath &p_path) { } } - w = PoolVector<Face3>::Write(); + w.release(); emission_dialog->popup_centered(Size2(300, 130)); } diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp index 88dc258c5f..1ae5acc5ff 100644 --- a/editor/plugins/path_editor_plugin.cpp +++ b/editor/plugins/path_editor_plugin.cpp @@ -95,6 +95,7 @@ void PathSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_p Vector3 ray_from = p_camera->project_ray_origin(p_point); Vector3 ray_dir = p_camera->project_ray_normal(p_point); + // Setting curve point positions if (p_idx < c->get_point_count()) { Plane p(gt.xform(original), p_camera->get_transform().basis.get_axis(2)); @@ -126,6 +127,7 @@ void PathSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_p Vector3 inters; + // Setting curve in/out positions if (p.intersects_ray(ray_from, ray_dir, &inters)) { if (!PathEditorPlugin::singleton->is_handle_clicked()) { @@ -135,9 +137,13 @@ void PathSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_p } Vector3 local = gi.xform(inters) - base; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + float snap = SpatialEditor::get_singleton()->get_translate_snap(); + local.snap(Vector3(snap, snap, snap)); + } + if (t == 0) { c->set_point_in(idx, local); - if (PathEditorPlugin::singleton->mirror_angle_enabled()) c->set_point_out(idx, PathEditorPlugin::singleton->mirror_length_enabled() ? -local : (-local.normalized() * orig_out_length)); } else { diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp index 712b1a0ae4..59004a08c0 100644 --- a/editor/plugins/polygon_2d_editor_plugin.cpp +++ b/editor/plugins/polygon_2d_editor_plugin.cpp @@ -1001,7 +1001,7 @@ void Polygon2DEditor::_uv_draw() { if (i == 0) last_cell = cell; if (last_cell != cell) - uv_edit_draw->draw_line(Point2(i, 0), Point2(i, s.height), grid_color); + uv_edit_draw->draw_line(Point2(i, 0), Point2(i, s.height), grid_color, Math::round(EDSCALE)); last_cell = cell; } } @@ -1012,7 +1012,7 @@ void Polygon2DEditor::_uv_draw() { if (i == 0) last_cell = cell; if (last_cell != cell) - uv_edit_draw->draw_line(Point2(0, i), Point2(s.width, i), grid_color); + uv_edit_draw->draw_line(Point2(0, i), Point2(s.width, i), grid_color, Math::round(EDSCALE)); last_cell = cell; } } @@ -1074,7 +1074,7 @@ void Polygon2DEditor::_uv_draw() { int next = uv_draw_max > 0 ? (i + 1) % uv_draw_max : 0; if (i < uv_draw_max && uv_drag && uv_move_current == UV_MODE_EDIT_POINT && EDITOR_DEF("editors/poly_editor/show_previous_outline", true)) { - uv_edit_draw->draw_line(mtx.xform(points_prev[i]), mtx.xform(points_prev[next]), prev_color, 2 * EDSCALE); + uv_edit_draw->draw_line(mtx.xform(points_prev[i]), mtx.xform(points_prev[next]), prev_color, Math::round(EDSCALE), true); } Vector2 next_point = uvs[next]; @@ -1082,7 +1082,7 @@ void Polygon2DEditor::_uv_draw() { next_point = uv_create_to; } if (i < uv_draw_max /*&& polygons.size() == 0 && polygon_create.size() == 0*/) { //if using or creating polygons, do not show outline (will show polygons instead) - uv_edit_draw->draw_line(mtx.xform(uvs[i]), mtx.xform(next_point), poly_line_color, 2 * EDSCALE); + uv_edit_draw->draw_line(mtx.xform(uvs[i]), mtx.xform(next_point), poly_line_color, Math::round(EDSCALE), true); } rect.expand_to(mtx.basis_xform(uvs[i])); @@ -1103,7 +1103,7 @@ void Polygon2DEditor::_uv_draw() { if (idx_next < 0 || idx_next >= uvs.size()) continue; - uv_edit_draw->draw_line(mtx.xform(uvs[idx]), mtx.xform(uvs[idx_next]), polygon_line_color, 2 * EDSCALE); + uv_edit_draw->draw_line(mtx.xform(uvs[idx]), mtx.xform(uvs[idx_next]), polygon_line_color, Math::round(EDSCALE), true); } if (points.size() >= 3) { uv_edit_draw->draw_polygon(polypoints, polygon_fill_color); @@ -1115,7 +1115,7 @@ void Polygon2DEditor::_uv_draw() { if (weight_r.ptr()) { Vector2 draw_pos = mtx.xform(uvs[i]); float weight = weight_r[i]; - uv_edit_draw->draw_rect(Rect2(draw_pos - Vector2(2, 2) * EDSCALE, Vector2(5, 5) * EDSCALE), Color(weight, weight, weight, 1.0)); + uv_edit_draw->draw_rect(Rect2(draw_pos - Vector2(2, 2) * EDSCALE, Vector2(5, 5) * EDSCALE), Color(weight, weight, weight, 1.0), Math::round(EDSCALE)); } else { if (i < uv_draw_max) { uv_edit_draw->draw_texture(handle, mtx.xform(uvs[i]) - handle->get_size() * 0.5); @@ -1129,21 +1129,10 @@ void Polygon2DEditor::_uv_draw() { for (int i = 0; i < polygon_create.size(); i++) { Vector2 from = uvs[polygon_create[i]]; Vector2 to = (i + 1) < polygon_create.size() ? uvs[polygon_create[i + 1]] : uv_create_to; - uv_edit_draw->draw_line(mtx.xform(from), mtx.xform(to), polygon_line_color, 2); + uv_edit_draw->draw_line(mtx.xform(from), mtx.xform(to), polygon_line_color, Math::round(EDSCALE), true); } } -#if 0 - PoolVector<int> splits = node->get_splits(); - - for (int i = 0; i < splits.size(); i += 2) { - int idx_from = splits[i]; - int idx_to = splits[i + 1]; - if (idx_from < 0 || idx_to >= uvs.size()) - continue; - uv_edit_draw->draw_line(mtx.xform(uvs[idx_from]), mtx.xform(uvs[idx_to]), poly_line_color, 2); - } -#endif if (uv_mode == UV_MODE_PAINT_WEIGHT || uv_mode == UV_MODE_CLEAR_WEIGHT) { NodePath bone_path; @@ -1182,8 +1171,8 @@ void Polygon2DEditor::_uv_draw() { Transform2D endpoint_xform = bone_xform * n->get_transform(); Color color = current ? Color(1, 1, 1) : Color(0.5, 0.5, 0.5); - uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), Color(0, 0, 0), current ? 5 : 4); - uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), color, current ? 3 : 2); + uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), Color(0, 0, 0), Math::round((current ? 5 : 4) * EDSCALE)); + uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), color, Math::round((current ? 3 : 2) * EDSCALE)); } if (!found_child) { @@ -1192,8 +1181,8 @@ void Polygon2DEditor::_uv_draw() { Transform2D endpoint_xform = bone_xform * Transform2D(0, Vector2(bone->get_default_length(), 0)); Color color = current ? Color(1, 1, 1) : Color(0.5, 0.5, 0.5); - uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), Color(0, 0, 0), current ? 5 : 4); - uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), color, current ? 3 : 2); + uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), Color(0, 0, 0), Math::round((current ? 5 : 4) * EDSCALE)); + uv_edit_draw->draw_line(mtx.xform(bone_xform.get_origin()), mtx.xform(endpoint_xform.get_origin()), color, Math::round((current ? 3 : 2) * EDSCALE)); } } } diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index f705970d79..438621115b 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -646,19 +646,20 @@ void ScriptTextEditor::_validate_script() { void ScriptTextEditor::_update_bookmark_list() { - bookmarks_menu->get_popup()->clear(); + bookmarks_menu->clear(); + bookmarks_menu->set_size(Size2(1, 1)); - bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); - bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL); - bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT); - bookmarks_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); + bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_bookmark"), BOOKMARK_TOGGLE); + bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_bookmarks"), BOOKMARK_REMOVE_ALL); + bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_bookmark"), BOOKMARK_GOTO_NEXT); + bookmarks_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_bookmark"), BOOKMARK_GOTO_PREV); Array bookmark_list = code_editor->get_text_edit()->get_bookmarks_array(); if (bookmark_list.size() == 0) { return; } - bookmarks_menu->get_popup()->add_separator(); + bookmarks_menu->add_separator(); for (int i = 0; i < bookmark_list.size(); i++) { String line = code_editor->get_text_edit()->get_line(bookmark_list[i]).strip_edges(); @@ -667,17 +668,17 @@ void ScriptTextEditor::_update_bookmark_list() { line = line.substr(0, 50); } - bookmarks_menu->get_popup()->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\""); - bookmarks_menu->get_popup()->set_item_metadata(bookmarks_menu->get_popup()->get_item_count() - 1, bookmark_list[i]); + bookmarks_menu->add_item(String::num((int)bookmark_list[i] + 1) + " - \"" + line + "\""); + bookmarks_menu->set_item_metadata(bookmarks_menu->get_item_count() - 1, bookmark_list[i]); } } void ScriptTextEditor::_bookmark_item_pressed(int p_idx) { if (p_idx < 4) { // Any item before the separator. - _edit_option(bookmarks_menu->get_popup()->get_item_id(p_idx)); + _edit_option(bookmarks_menu->get_item_id(p_idx)); } else { - code_editor->goto_line(bookmarks_menu->get_popup()->get_item_metadata(p_idx)); + code_editor->goto_line(bookmarks_menu->get_item_metadata(p_idx)); } } @@ -772,13 +773,13 @@ void ScriptEditor::_update_modified_scripts_for_external_editor(Ref<Script> p_fo } } -void ScriptTextEditor::_code_complete_scripts(void *p_ud, const String &p_code, List<String> *r_options, bool &r_force) { +void ScriptTextEditor::_code_complete_scripts(void *p_ud, const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_force) { ScriptTextEditor *ste = (ScriptTextEditor *)p_ud; ste->_code_complete_script(p_code, r_options, r_force); } -void ScriptTextEditor::_code_complete_script(const String &p_code, List<String> *r_options, bool &r_force) { +void ScriptTextEditor::_code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_force) { if (color_panel->is_visible_in_tree()) return; Node *base = get_tree()->get_edited_scene_root(); @@ -792,6 +793,44 @@ void ScriptTextEditor::_code_complete_script(const String &p_code, List<String> } } +void ScriptTextEditor::_update_breakpoint_list() { + + breakpoints_menu->clear(); + breakpoints_menu->set_size(Size2(1, 1)); + + breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_breakpoint"), DEBUG_TOGGLE_BREAKPOINT); + breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_breakpoints"), DEBUG_REMOVE_ALL_BREAKPOINTS); + breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_breakpoint"), DEBUG_GOTO_NEXT_BREAKPOINT); + breakpoints_menu->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_breakpoint"), DEBUG_GOTO_PREV_BREAKPOINT); + + Array breakpoint_list = code_editor->get_text_edit()->get_breakpoints_array(); + if (breakpoint_list.size() == 0) { + return; + } + + breakpoints_menu->add_separator(); + + for (int i = 0; i < breakpoint_list.size(); i++) { + String line = code_editor->get_text_edit()->get_line(breakpoint_list[i]).strip_edges(); + // Limit the size of the line if too big. + if (line.length() > 50) { + line = line.substr(0, 50); + } + + breakpoints_menu->add_item(String::num((int)breakpoint_list[i] + 1) + " - \"" + line + "\""); + breakpoints_menu->set_item_metadata(breakpoints_menu->get_item_count() - 1, breakpoint_list[i]); + } +} + +void ScriptTextEditor::_breakpoint_item_pressed(int p_idx) { + + if (p_idx < 4) { // Any item before the separator. + _edit_option(breakpoints_menu->get_item_id(p_idx)); + } else { + code_editor->goto_line(breakpoints_menu->get_item_metadata(p_idx)); + } +} + void ScriptTextEditor::_breakpoint_toggled(int p_row) { ScriptEditor::get_singleton()->get_debugger()->set_breakpoint(script->get_path(), p_row + 1, code_editor->get_text_edit()->is_line_set_as_breakpoint(p_row)); @@ -1298,6 +1337,8 @@ void ScriptTextEditor::_bind_methods() { ClassDB::bind_method("_update_bookmark_list", &ScriptTextEditor::_update_bookmark_list); ClassDB::bind_method("_bookmark_item_pressed", &ScriptTextEditor::_bookmark_item_pressed); ClassDB::bind_method("_load_theme_settings", &ScriptTextEditor::_load_theme_settings); + ClassDB::bind_method("_update_breakpoint_list", &ScriptTextEditor::_update_breakpoint_list); + ClassDB::bind_method("_breakpoint_item_pressed", &ScriptTextEditor::_breakpoint_item_pressed); ClassDB::bind_method("_breakpoint_toggled", &ScriptTextEditor::_breakpoint_toggled); ClassDB::bind_method("_lookup_connections", &ScriptTextEditor::_lookup_connections); ClassDB::bind_method("_update_connected_methods", &ScriptTextEditor::_update_connected_methods); @@ -1705,11 +1746,6 @@ ScriptTextEditor::ScriptTextEditor() { edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/auto_indent"), EDIT_AUTO_INDENT); edit_menu->get_popup()->connect("id_pressed", this, "_edit_option"); edit_menu->get_popup()->add_separator(); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/toggle_breakpoint"), DEBUG_TOGGLE_BREAKPOINT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/remove_all_breakpoints"), DEBUG_REMOVE_ALL_BREAKPOINTS); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_next_breakpoint"), DEBUG_GOTO_NEXT_BREAKPOINT); - edit_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_text_editor/goto_previous_breakpoint"), DEBUG_GOTO_PREV_BREAKPOINT); - edit_menu->get_popup()->add_separator(); PopupMenu *convert_case = memnew(PopupMenu); convert_case->set_name("convert_case"); @@ -1749,13 +1785,26 @@ ScriptTextEditor::ScriptTextEditor() { edit_hb->add_child(edit_menu); - bookmarks_menu = memnew(MenuButton); - edit_hb->add_child(bookmarks_menu); - bookmarks_menu->set_text(TTR("Bookmarks")); - bookmarks_menu->set_switch_on_hover(true); + MenuButton *goto_menu = memnew(MenuButton); + edit_hb->add_child(goto_menu); + goto_menu->set_text(TTR("Go To")); + goto_menu->set_switch_on_hover(true); + + bookmarks_menu = memnew(PopupMenu); + bookmarks_menu->set_name("Bookmarks"); + goto_menu->get_popup()->add_child(bookmarks_menu); + goto_menu->get_popup()->add_submenu_item(TTR("Bookmarks"), "Bookmarks"); _update_bookmark_list(); bookmarks_menu->connect("about_to_show", this, "_update_bookmark_list"); - bookmarks_menu->get_popup()->connect("index_pressed", this, "_bookmark_item_pressed"); + bookmarks_menu->connect("index_pressed", this, "_bookmark_item_pressed"); + + breakpoints_menu = memnew(PopupMenu); + breakpoints_menu->set_name("Breakpoints"); + goto_menu->get_popup()->add_child(breakpoints_menu); + goto_menu->get_popup()->add_submenu_item(TTR("Breakpoints"), "Breakpoints"); + _update_breakpoint_list(); + breakpoints_menu->connect("about_to_show", this, "_update_breakpoint_list"); + breakpoints_menu->connect("index_pressed", this, "_breakpoint_item_pressed"); quick_open = memnew(ScriptEditorQuickOpen); add_child(quick_open); diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h index f83f1ea759..9a2a514a6e 100644 --- a/editor/plugins/script_text_editor.h +++ b/editor/plugins/script_text_editor.h @@ -70,7 +70,8 @@ class ScriptTextEditor : public ScriptEditorBase { MenuButton *edit_menu; MenuButton *search_menu; - MenuButton *bookmarks_menu; + PopupMenu *bookmarks_menu; + PopupMenu *breakpoints_menu; PopupMenu *highlighter_menu; PopupMenu *context_menu; @@ -142,13 +143,17 @@ class ScriptTextEditor : public ScriptEditorBase { }; protected: - static void _code_complete_scripts(void *p_ud, const String &p_code, List<String> *r_options, bool &r_force); + void _update_breakpoint_list(); + void _breakpoint_item_pressed(int p_idx); void _breakpoint_toggled(int p_row); void _validate_script(); // No longer virtual. void _update_bookmark_list(); void _bookmark_item_pressed(int p_idx); - void _code_complete_script(const String &p_code, List<String> *r_options, bool &r_force); + + static void _code_complete_scripts(void *p_ud, const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_force); + void _code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options, bool &r_force); + void _load_theme_settings(); void _set_theme_for_script(); void _show_warnings_panel(bool p_show); diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp index 04d13f0027..994c542187 100644 --- a/editor/plugins/shader_editor_plugin.cpp +++ b/editor/plugins/shader_editor_plugin.cpp @@ -190,7 +190,7 @@ void ShaderTextEditor::_check_shader_mode() { } } -void ShaderTextEditor::_code_complete_script(const String &p_code, List<String> *r_options) { +void ShaderTextEditor::_code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options) { _check_shader_mode(); diff --git a/editor/plugins/shader_editor_plugin.h b/editor/plugins/shader_editor_plugin.h index f01e39189f..8e55a1ad70 100644 --- a/editor/plugins/shader_editor_plugin.h +++ b/editor/plugins/shader_editor_plugin.h @@ -53,7 +53,7 @@ protected: static void _bind_methods(); virtual void _load_theme_settings(); - virtual void _code_complete_script(const String &p_code, List<String> *r_options); + virtual void _code_complete_script(const String &p_code, List<ScriptCodeCompletionOption> *r_options); public: virtual void _validate_script(); diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 7f7ae8f273..a593a92b97 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -283,7 +283,8 @@ void SpatialEditorViewport::_select_clicked(bool p_append, bool p_single) { node = node->get_parent(); } - _select(selected, clicked_wants_append, true); + if (!_is_node_locked(selected)) + _select(selected, clicked_wants_append, true); } void SpatialEditorViewport::_select(Node *p_node, bool p_append, bool p_single) { @@ -513,7 +514,7 @@ void SpatialEditorViewport::_select_region() { for (int i = 0; i < instances.size(); i++) { Spatial *sp = Object::cast_to<Spatial>(ObjectDB::get_instance(instances[i])); - if (!sp) + if (!sp && _is_node_locked(sp)) continue; Node *item = Object::cast_to<Node>(sp); @@ -536,6 +537,8 @@ void SpatialEditorViewport::_select_region() { if (selected.find(item) != -1) continue; + if (_is_node_locked(Object::cast_to<Spatial>(item))) continue; + Ref<EditorSpatialGizmo> seg = sp->get_gizmo(); if (!seg.is_valid()) @@ -833,7 +836,9 @@ void SpatialEditorViewport::_surface_focus_exit() { view_menu->set_disable_shortcuts(true); } - +bool SpatialEditorViewport ::_is_node_locked(const Node *p_node) { + return p_node->has_meta("_edit_lock_") && p_node->get_meta("_edit_lock_"); +} void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) { _find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->get_shift()); @@ -2348,23 +2353,6 @@ void SpatialEditorViewport::_notification(int p_what) { } } -// TODO That should be part of the drawing API... -static void stroke_rect(CanvasItem &ci, Rect2 rect, Color color, real_t width = 1.0) { - - // a---b - // | | - // c---d - Vector2 a(rect.position); - Vector2 b(rect.position.x + rect.size.x, rect.position.y); - Vector2 c(rect.position.x, rect.position.y + rect.size.y); - Vector2 d(rect.position + rect.size); - - ci.draw_line(a, b, color, width); - ci.draw_line(b, d, color, width); - ci.draw_line(d, c, color, width); - ci.draw_line(c, a, color, width); -} - static void draw_indicator_bar(Control &surface, real_t fill, Ref<Texture> icon) { // Adjust bar size from control height @@ -2379,7 +2367,7 @@ static void draw_indicator_bar(Control &surface, real_t fill, Ref<Texture> icon) // Draw both neutral dark and bright colors to account this surface.draw_rect(r, Color(1, 1, 1, 0.2)); surface.draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6)); - stroke_rect(surface, r.grow(1), Color(0, 0, 0, 0.7)); + surface.draw_rect(r.grow(1), Color(0, 0, 0, 0.7), false, Math::round(EDSCALE)); Vector2 icon_size = icon->get_size(); Vector2 icon_pos = Vector2(r.position.x - (icon_size.x - r.size.x) / 2, r.position.y + r.size.y + 2); @@ -2460,7 +2448,7 @@ void SpatialEditorViewport::_draw() { draw_rect = Rect2(Vector2(), s).clip(draw_rect); - stroke_rect(*surface, draw_rect, Color(0.6, 0.6, 0.1, 0.5), 2.0); + surface->draw_rect(draw_rect, Color(0.6, 0.6, 0.1, 0.5), false, Math::round(2 * EDSCALE)); } else { @@ -3207,7 +3195,7 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const return point + offset; } -AABB SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, const AABB p_bounds) { +AABB SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, const AABB &p_bounds) { AABB bounds = p_bounds; for (int i = 0; i < p_parent->get_child_count(); i++) { Spatial *child = Object::cast_to<Spatial>(p_parent->get_child(i)); @@ -6048,7 +6036,6 @@ void EditorSpatialGizmoPlugin::create_icon_material(const String &p_name, const void EditorSpatialGizmoPlugin::create_handle_material(const String &p_name, bool p_billboard) { Ref<SpatialMaterial> handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); - handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial)); handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true); handle_material->set_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true); Ref<Texture> handle_t = SpatialEditor::get_singleton()->get_icon("Editor3DHandle", "EditorIcons"); diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h index 3bddc6d6d4..1a32d6e047 100644 --- a/editor/plugins/spatial_editor_plugin.h +++ b/editor/plugins/spatial_editor_plugin.h @@ -119,7 +119,7 @@ public: void set_spatial_node(Spatial *p_node); Spatial *get_spatial_node() const { return spatial_node; } - EditorSpatialGizmoPlugin *get_plugin() const { return gizmo_plugin; } + Ref<EditorSpatialGizmoPlugin> get_plugin() const { return gizmo_plugin; } Vector3 get_handle_pos(int p_idx) const; bool intersect_frustum(const Camera *p_camera, const Vector<Plane> &p_frustum); bool intersect_ray(Camera *p_camera, const Point2 &p_point, Vector3 &r_pos, Vector3 &r_normal, int *r_gizmo_handle = NULL, bool p_sec_first = false); @@ -364,7 +364,7 @@ private: Camera *preview; bool previewing_cinema; - + bool _is_node_locked(const Node *p_node); void _preview_exited_scene(); void _toggle_camera_preview(bool); void _toggle_cinema_preview(bool); @@ -376,7 +376,7 @@ private: Point2i _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const; Vector3 _get_instance_position(const Point2 &p_pos) const; - static AABB _calculate_spatial_bounds(const Spatial *p_parent, const AABB p_bounds); + static AABB _calculate_spatial_bounds(const Spatial *p_parent, const AABB &p_bounds); void _create_preview(const Vector<String> &files) const; void _remove_preview(); bool _cyclical_dependency_exists(const String &p_target_scene_path, Node *p_desired_node); diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp index 8f58fbd6ab..cb48b5eaa5 100644 --- a/editor/plugins/texture_region_editor_plugin.cpp +++ b/editor/plugins/texture_region_editor_plugin.cpp @@ -1021,15 +1021,21 @@ bool TextureRegionEditorPlugin::handles(Object *p_object) const { return p_object->is_class("Sprite") || p_object->is_class("Sprite3D") || p_object->is_class("NinePatchRect") || p_object->is_class("StyleBoxTexture") || p_object->is_class("AtlasTexture"); } +void TextureRegionEditorPlugin::_editor_visiblity_changed() { + manually_hidden = !region_editor->is_visible_in_tree(); +} + void TextureRegionEditorPlugin::make_visible(bool p_visible) { if (p_visible) { texture_region_button->show(); - if (region_editor->is_stylebox() || region_editor->is_atlas_texture() || region_editor->is_ninepatch() || (region_editor->get_sprite() && region_editor->get_sprite()->is_region()) || (region_editor->get_sprite_3d() && region_editor->get_sprite_3d()->is_region()) || texture_region_button->is_pressed()) { + bool is_node_configured = region_editor->is_stylebox() || region_editor->is_atlas_texture() || region_editor->is_ninepatch() || (region_editor->get_sprite() && region_editor->get_sprite()->is_region()) || (region_editor->get_sprite_3d() && region_editor->get_sprite_3d()->is_region()); + if ((is_node_configured && !manually_hidden) || texture_region_button->is_pressed()) { editor->make_bottom_panel_item_visible(region_editor); } } else { if (region_editor->is_visible_in_tree()) { editor->hide_bottom_panel(); + manually_hidden = false; } texture_region_button->hide(); region_editor->edit(NULL); @@ -1076,12 +1082,18 @@ void TextureRegionEditorPlugin::set_state(const Dictionary &p_state) { } } +void TextureRegionEditorPlugin::_bind_methods() { + ClassDB::bind_method(D_METHOD("_editor_visiblity_changed"), &TextureRegionEditorPlugin::_editor_visiblity_changed); +} + TextureRegionEditorPlugin::TextureRegionEditorPlugin(EditorNode *p_node) { + manually_hidden = false; editor = p_node; - region_editor = memnew(TextureRegionEditor(p_node)); + region_editor = memnew(TextureRegionEditor(p_node)); region_editor->set_custom_minimum_size(Size2(0, 200) * EDSCALE); region_editor->hide(); + region_editor->connect("visibility_changed", this, "_editor_visiblity_changed"); texture_region_button = p_node->add_bottom_panel_item(TTR("TextureRegion"), region_editor); texture_region_button->hide(); diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h index a49e0fb96c..4eb84ae176 100644 --- a/editor/plugins/texture_region_editor_plugin.h +++ b/editor/plugins/texture_region_editor_plugin.h @@ -145,10 +145,16 @@ public: class TextureRegionEditorPlugin : public EditorPlugin { GDCLASS(TextureRegionEditorPlugin, EditorPlugin); + bool manually_hidden; Button *texture_region_button; TextureRegionEditor *region_editor; EditorNode *editor; +protected: + static void _bind_methods(); + + void _editor_visiblity_changed(); + public: virtual String get_name() const { return "TextureRegion"; } bool has_main_screen() const { return false; } diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 6e47d82847..766890242f 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -281,7 +281,7 @@ void TileMapEditor::_finish_undo() { undo_redo->commit_action(); } -void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i p_autotile_coord) { +void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord) { ERR_FAIL_COND(!node); @@ -693,7 +693,7 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era return preview ? bucket_cache : points; } -void TileMapEditor::_fill_points(const PoolVector<Vector2> p_points, const Dictionary &p_op) { +void TileMapEditor::_fill_points(const PoolVector<Vector2> &p_points, const Dictionary &p_op) { int len = p_points.size(); PoolVector<Vector2>::Read pr = p_points.read(); @@ -711,7 +711,7 @@ void TileMapEditor::_fill_points(const PoolVector<Vector2> p_points, const Dicti node->update_dirty_bitmask(); } -void TileMapEditor::_erase_points(const PoolVector<Vector2> p_points) { +void TileMapEditor::_erase_points(const PoolVector<Vector2> &p_points) { int len = p_points.size(); PoolVector<Vector2>::Read pr = p_points.read(); @@ -754,7 +754,7 @@ void TileMapEditor::_erase_selection() { } } -void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i p_autotile_coord, const Transform2D &p_xform) { +void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord, const Transform2D &p_xform) { Ref<Texture> t = node->get_tileset()->tile_get_texture(p_cell); @@ -782,8 +782,9 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p r.position += (r.size + Vector2(spacing, spacing)) * offset; } Size2 sc = p_xform.get_scale(); - /* For a future CheckBox to Center Texture: - Size2 cell_size = node->get_cell_size(); */ + Size2 cell_size = node->get_cell_size(); + bool centered_texture = node->is_centered_textures_enabled(); + bool compatibility_mode_enabled = node->is_compatibility_mode_enabled(); Rect2 rect = Rect2(); rect.position = node->map_to_world(p_point) + node->get_cell_draw_offset(); @@ -793,13 +794,24 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p rect.size = r.size; } + if (compatibility_mode_enabled && !centered_texture) { + if (rect.size.y > rect.size.x) { + if ((p_flip_h && (p_flip_v || p_transpose)) || (p_flip_v && !p_transpose)) + tile_ofs.y += rect.size.y - rect.size.x; + } else if (rect.size.y < rect.size.x) { + if ((p_flip_v && (p_flip_h || p_transpose)) || (p_flip_h && !p_transpose)) + tile_ofs.x += rect.size.x - rect.size.y; + } + } + if (p_transpose) { SWAP(tile_ofs.x, tile_ofs.y); - /* For a future CheckBox to Center Texture: - rect.position.x += cell_size.x / 2 - rect.size.y / 2; - rect.position.y += cell_size.y / 2 - rect.size.x / 2; - } else { - rect.position += cell_size / 2 - rect.size / 2; */ + if (centered_texture) { + rect.position.x += cell_size.x / 2 - rect.size.y / 2; + rect.position.y += cell_size.y / 2 - rect.size.x / 2; + } + } else if (centered_texture) { + rect.position += cell_size / 2 - rect.size / 2; } if (p_flip_h) { @@ -812,7 +824,44 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p tile_ofs.y *= -1.0; } - rect.position += tile_ofs; + if (compatibility_mode_enabled && !centered_texture) { + if (node->get_tile_origin() == TileMap::TILE_ORIGIN_TOP_LEFT) { + + rect.position += tile_ofs; + } else if (node->get_tile_origin() == TileMap::TILE_ORIGIN_BOTTOM_LEFT) { + + rect.position += tile_ofs; + + if (p_transpose) { + if (p_flip_h) + rect.position.x -= cell_size.x; + else + rect.position.x += cell_size.x; + } else { + if (p_flip_v) + rect.position.y -= cell_size.y; + else + rect.position.y += cell_size.y; + } + + } else if (node->get_tile_origin() == TileMap::TILE_ORIGIN_CENTER) { + + rect.position += tile_ofs; + + if (p_flip_h) + rect.position.x -= cell_size.x / 2; + else + rect.position.x += cell_size.x / 2; + + if (p_flip_v) + rect.position.y -= cell_size.y / 2; + else + rect.position.y += cell_size.y / 2; + } + } else { + rect.position += tile_ofs; + } + rect.position = p_xform.xform(rect.position); rect.size *= sc; @@ -826,7 +875,7 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p } } -void TileMapEditor::_draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i p_autotile_coord, const Transform2D &p_xform) { +void TileMapEditor::_draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord, const Transform2D &p_xform) { PoolVector<Vector2> points = _bucket_fill(p_point, false, true); PoolVector<Vector2>::Read pr = points.read(); @@ -1418,15 +1467,28 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) { return true; } - if (ED_IS_SHORTCUT("tile_map_editor/mirror_x", p_event)) { - flip_h = !flip_h; - _update_palette(); + if (ED_IS_SHORTCUT("tile_map_editor/rotate_left", p_event)) { + _rotate(-1); CanvasItemEditor::get_singleton()->update_viewport(); return true; } - if (ED_IS_SHORTCUT("tile_map_editor/mirror_y", p_event)) { - flip_v = !flip_v; - _update_palette(); + if (ED_IS_SHORTCUT("tile_map_editor/rotate_right", p_event)) { + _rotate(1); + CanvasItemEditor::get_singleton()->update_viewport(); + return true; + } + if (ED_IS_SHORTCUT("tile_map_editor/flip_horizontal", p_event)) { + _flip_horizontal(); + CanvasItemEditor::get_singleton()->update_viewport(); + return true; + } + if (ED_IS_SHORTCUT("tile_map_editor/flip_vertical", p_event)) { + _flip_vertical(); + CanvasItemEditor::get_singleton()->update_viewport(); + return true; + } + if (ED_IS_SHORTCUT("tile_map_editor/clear_transform", p_event)) { + _clear_transform(); CanvasItemEditor::get_singleton()->update_viewport(); return true; } @@ -1868,8 +1930,6 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { ED_SHORTCUT("tile_map_editor/erase_selection", TTR("Erase Selection"), KEY_DELETE); ED_SHORTCUT("tile_map_editor/find_tile", TTR("Find Tile"), KEY_MASK_CMD + KEY_F); ED_SHORTCUT("tile_map_editor/transpose", TTR("Transpose"), KEY_T); - ED_SHORTCUT("tile_map_editor/mirror_x", TTR("Mirror X"), KEY_A); - ED_SHORTCUT("tile_map_editor/mirror_y", TTR("Mirror Y"), KEY_S); HBoxContainer *tool_hb = memnew(HBoxContainer); add_child(tool_hb); @@ -1995,30 +2055,35 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { rotate_left_button->set_tooltip(TTR("Rotate Left")); rotate_left_button->set_focus_mode(FOCUS_NONE); rotate_left_button->connect("pressed", this, "_rotate", varray(-1)); + rotate_left_button->set_shortcut(ED_SHORTCUT("tile_map_editor/rotate_left", TTR("Rotate Left"), KEY_A)); tool_hb->add_child(rotate_left_button); rotate_right_button = memnew(ToolButton); rotate_right_button->set_tooltip(TTR("Rotate Right")); rotate_right_button->set_focus_mode(FOCUS_NONE); rotate_right_button->connect("pressed", this, "_rotate", varray(1)); + rotate_right_button->set_shortcut(ED_SHORTCUT("tile_map_editor/rotate_right", TTR("Rotate Right"), KEY_S)); tool_hb->add_child(rotate_right_button); flip_horizontal_button = memnew(ToolButton); flip_horizontal_button->set_tooltip(TTR("Flip Horizontally")); flip_horizontal_button->set_focus_mode(FOCUS_NONE); flip_horizontal_button->connect("pressed", this, "_flip_horizontal"); + flip_horizontal_button->set_shortcut(ED_SHORTCUT("tile_map_editor/flip_horizontal", TTR("Flip Horizontally"), KEY_X)); tool_hb->add_child(flip_horizontal_button); flip_vertical_button = memnew(ToolButton); flip_vertical_button->set_tooltip(TTR("Flip Vertically")); flip_vertical_button->set_focus_mode(FOCUS_NONE); flip_vertical_button->connect("pressed", this, "_flip_vertical"); + flip_vertical_button->set_shortcut(ED_SHORTCUT("tile_map_editor/flip_vertical", TTR("Flip Vertically"), KEY_Z)); tool_hb->add_child(flip_vertical_button); clear_transform_button = memnew(ToolButton); clear_transform_button->set_tooltip(TTR("Clear Transform")); clear_transform_button->set_focus_mode(FOCUS_NONE); clear_transform_button->connect("pressed", this, "_clear_transform"); + clear_transform_button->set_shortcut(ED_SHORTCUT("tile_map_editor/clear_transform", TTR("Clear Transform"), KEY_W)); tool_hb->add_child(clear_transform_button); clear_transform_button->set_disabled(true); diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h index 3f0abd1e6e..3331fb971f 100644 --- a/editor/plugins/tile_map_editor_plugin.h +++ b/editor/plugins/tile_map_editor_plugin.h @@ -169,14 +169,14 @@ class TileMapEditor : public VBoxContainer { PoolVector<Vector2> _bucket_fill(const Point2i &p_start, bool erase = false, bool preview = false); - void _fill_points(const PoolVector<Vector2> p_points, const Dictionary &p_op); - void _erase_points(const PoolVector<Vector2> p_points); + void _fill_points(const PoolVector<Vector2> &p_points, const Dictionary &p_op); + void _erase_points(const PoolVector<Vector2> &p_points); void _select(const Point2i &p_from, const Point2i &p_to); void _erase_selection(); - void _draw_cell(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i p_autotile_coord, const Transform2D &p_xform); - void _draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i p_autotile_coord, const Transform2D &p_xform); + void _draw_cell(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord, const Transform2D &p_xform); + void _draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i &p_autotile_coord, const Transform2D &p_xform); void _clear_bucket_cache(); void _update_copydata(); @@ -200,7 +200,7 @@ class TileMapEditor : public VBoxContainer { void _start_undo(const String &p_action); void _finish_undo(); void _create_set_cell_undo_redo(const Vector2 &p_vec, const CellOp &p_cell_old, const CellOp &p_cell_new); - void _set_cell(const Point2i &p_pos, Vector<int> p_values, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false, const Point2i p_autotile_coord = Point2()); + void _set_cell(const Point2i &p_pos, Vector<int> p_values, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false, const Point2i &p_autotile_coord = Point2()); void _canvas_mouse_enter(); void _canvas_mouse_exit(); diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp index 35cfdf15be..f135becf5f 100644 --- a/editor/plugins/tile_set_editor_plugin.cpp +++ b/editor/plugins/tile_set_editor_plugin.cpp @@ -1491,7 +1491,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { w[i] = current_shape[i] - shape_anchor; } - w = PoolVector<Vector2>::Write(); + w.release(); undo_redo->create_action(TTR("Edit Occlusion Polygon")); undo_redo->add_do_method(edited_occlusion_shape.ptr(), "set_polygon", polygon); @@ -1514,7 +1514,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) { indices.push_back(i); } - w = PoolVector<Vector2>::Write(); + w.release(); undo_redo->create_action(TTR("Edit Navigation Polygon")); undo_redo->add_do_method(edited_navigation_shape.ptr(), "set_vertices", polygon); @@ -1833,7 +1833,7 @@ Vector<Vector2> TileSetEditor::_get_edited_shape_points() { return _get_collision_shape_points(edited_collision_shape); } -void TileSetEditor::_set_edited_shape_points(const Vector<Vector2> points) { +void TileSetEditor::_set_edited_shape_points(const Vector<Vector2> &points) { Ref<ConvexPolygonShape2D> convex = edited_collision_shape; Ref<ConcavePolygonShape2D> concave = edited_collision_shape; if (convex.is_valid()) { @@ -2785,7 +2785,7 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) { w[i] = current_shape[i] - shape_anchor; } - w = PoolVector<Vector2>::Write(); + w.release(); shape->set_polygon(polygon); undo_redo->create_action(TTR("Create Occlusion Polygon")); @@ -2813,7 +2813,7 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) { indices.push_back(i); } - w = PoolVector<Vector2>::Write(); + w.release(); shape->set_vertices(polygon); shape->add_polygon(indices); diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h index 04e8d65155..69ad8205a4 100644 --- a/editor/plugins/tile_set_editor_plugin.h +++ b/editor/plugins/tile_set_editor_plugin.h @@ -201,7 +201,7 @@ private: void _on_grid_snap_toggled(bool p_val); Vector<Vector2> _get_collision_shape_points(const Ref<Shape2D> &p_shape); Vector<Vector2> _get_edited_shape_points(); - void _set_edited_shape_points(const Vector<Vector2> points); + void _set_edited_shape_points(const Vector<Vector2> &points); void _update_tile_data(); void _update_toggle_shape_button(); void _select_next_tile(); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index e1929d7489..cd8e36f68b 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -184,6 +184,11 @@ void VisualShaderEditor::_update_options_menu() { int item_count2 = 0; bool is_first_item = true; + Color unsupported_color = get_color("error_color", "Editor"); + Color supported_color = get_color("warning_color", "Editor"); + + static bool low_driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES2"; + int current_func = -1; if (!visual_shader.is_null()) { @@ -239,6 +244,10 @@ void VisualShaderEditor::_update_options_menu() { if ((add_options[i].func == current_func || add_options[i].func == -1) && _is_available(add_options[i].mode)) { ++item_count2; TreeItem *item = members->create_item(sub_category); + if (add_options[i].highend && low_driver) + item->set_custom_color(0, unsupported_color); + else if (add_options[i].highend) + item->set_custom_color(0, supported_color); item->set_text(0, add_options[i].name); if (is_first_item) { item->select(0); @@ -271,6 +280,10 @@ void VisualShaderEditor::_update_options_menu() { if ((add_options[i].func == current_func || add_options[i].func == -1) && _is_available(add_options[i].mode)) { ++item_count; TreeItem *item = members->create_item(category); + if (add_options[i].highend && low_driver) + item->set_custom_color(0, unsupported_color); + else if (add_options[i].highend) + item->set_custom_color(0, supported_color); item->set_text(0, add_options[i].name); switch (add_options[i].return_type) { case VisualShaderNode::PORT_TYPE_SCALAR: @@ -365,10 +378,10 @@ void VisualShaderEditor::_update_graph() { } static const Color type_color[4] = { - Color::html("#61daf4"), // scalar - Color::html("#d67dee"), // vector - Color::html("#8da6f0"), // boolean - Color::html("#f6a86e") // transform + Color(0.38, 0.85, 0.96), // scalar + Color(0.84, 0.49, 0.93), // vector + Color(0.55, 0.65, 0.94), // boolean + Color(0.96, 0.66, 0.43) // transform }; List<VisualShader::Connection> connections; @@ -529,6 +542,9 @@ void VisualShaderEditor::_update_graph() { button->set_custom_minimum_size(Size2(30, 0) * EDSCALE); button->connect("draw", this, "_draw_color_over_button", varray(button, default_value)); } break; + case Variant::BOOL: { + button->set_text(((bool)default_value) ? "true" : "false"); + } break; case Variant::INT: case Variant::REAL: { button->set_text(String::num(default_value, 4)); @@ -1150,6 +1166,18 @@ void VisualShaderEditor::_add_node(int p_idx, int p_op_idx) { input->set_input_name(add_options[p_idx].sub_func_str); } + VisualShaderNodeIs *is = Object::cast_to<VisualShaderNodeIs>(vsn); + + if (is) { + is->set_function((VisualShaderNodeIs::Function)p_op_idx); + } + + VisualShaderNodeCompare *cmp = Object::cast_to<VisualShaderNodeCompare>(vsn); + + if (cmp) { + cmp->set_function((VisualShaderNodeCompare::Function)p_op_idx); + } + VisualShaderNodeColorOp *colorOp = Object::cast_to<VisualShaderNodeColorOp>(vsn); if (colorOp) { @@ -1395,7 +1423,7 @@ void VisualShaderEditor::_node_selected(Object *p_node) { //EditorNode::get_singleton()->push_item(vsnode.ptr(), "", true); } -void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> p_event) { +void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; @@ -1711,7 +1739,11 @@ void VisualShaderEditor::_member_selected() { if (item != NULL && item->has_meta("id")) { members_dialog->get_ok()->set_disabled(false); - node_desc->set_text(add_options[item->get_meta("id")].description); + if (add_options[item->get_meta("id")].highend) { + node_desc->set_text(TTR("(GLES3 only)") + " " + add_options[item->get_meta("id")].description); // TODO: change it to (Vulkan Only) when its ready + } else { + node_desc->set_text(add_options[item->get_meta("id")].description); + } } else { members_dialog->get_ok()->set_disabled(true); node_desc->set_text(""); @@ -2039,33 +2071,47 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ColorConstant", "Color", "Variables", "VisualShaderNodeColorConstant", TTR("Color constant."), -1, VisualShaderNode::PORT_TYPE_COLOR)); add_options.push_back(AddOption("ColorUniform", "Color", "Variables", "VisualShaderNodeColorUniform", TTR("Color uniform."), -1, VisualShaderNode::PORT_TYPE_COLOR)); - // BOOLEAN + // CONDITIONAL + const String &compare_func_desc = TTR("Returns the boolean result of %s comparison between two parameters."); + + add_options.push_back(AddOption("Equal", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Equal (==)")), VisualShaderNodeCompare::FUNC_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("GreaterThan", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than (>)")), VisualShaderNodeCompare::FUNC_GREATER_THAN, VisualShaderNode::PORT_TYPE_BOOLEAN)); + add_options.push_back(AddOption("GreaterThanEqual", "Conditional", "Functions", "VisualShaderNodeCompare", vformat(compare_func_desc, TTR("Greater Than or Equal (>=)")), VisualShaderNodeCompare::FUNC_GREATER_THAN_EQUAL, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("If", "Conditional", "Functions", "VisualShaderNodeIf", TTR("Returns an associated vector if the provided scalars are equal, greater or less."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("IsInf", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between INF and a scalar parameter."), VisualShaderNodeIs::FUNC_IS_INF, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, -1, -1, true)); + add_options.push_back(AddOption("IsNaN", "Conditional", "Functions", "VisualShaderNodeIs", TTR("Returns the boolean result of the comparison between NaN and a scalar parameter."), VisualShaderNodeIs::FUNC_IS_NAN, VisualShaderNode::PORT_TYPE_BOOLEAN, -1, -1, -1, true)); + 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("Compare", "Conditional", "Common", "VisualShaderNodeCompare", TTR("Returns the boolean result of the contains the result of 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, -1, -1, -1, true)); + add_options.push_back(AddOption("BooleanConstant", "Conditional", "Variables", "VisualShaderNodeBooleanConstant", TTR("Boolean constant."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN)); add_options.push_back(AddOption("BooleanUniform", "Conditional", "Variables", "VisualShaderNodeBooleanUniform", TTR("Boolean uniform."), -1, VisualShaderNode::PORT_TYPE_BOOLEAN)); // INPUT // SPATIAL-FOR-ALL - const String input_param_shader_modes = "'%s' input parameter for all shader modes."; - add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "camera"), "camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "inv_camera"), "inv_camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "inv_projection"), "inv_projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Normal", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Projection", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "camera"), "projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("ViewportSize", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "viewport_size"), "viewport_size", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("World", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); + const String input_param_shader_modes = TTR("'%s' input parameter for all shader modes."); + add_options.push_back(AddOption("Camera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("InvCamera", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_camera"), "inv_camera", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("InvProjection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "inv_projection"), "inv_projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Normal", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Projection", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "camera"), "projection", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("ViewportSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "viewport_size"), "viewport_size", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("World", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, -1, Shader::MODE_SPATIAL)); // CANVASITEM-FOR-ALL - add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("TexturePixelSize", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "texture_pixel_size"), "texture_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(TTR(input_param_shader_modes), "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Alpha", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Color", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("TexturePixelSize", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "texture_pixel_size"), "texture_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Time", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, -1, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("UV", "Input", "All", "VisualShaderNodeInput", vformat(input_param_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, -1, Shader::MODE_CANVAS_ITEM)); ///////////////// @@ -2073,88 +2119,88 @@ VisualShaderEditor::VisualShaderEditor() { // SPATIAL INPUTS - const String input_param_for_vertex_and_fragment_shader_modes = "'%s' input parameter for vertex and fragment shader modes."; - const String input_param_for_fragment_and_light_shader_modes = "'%s' input parameter for fragment and light shader modes."; - const String input_param_for_fragment_shader_mode = "'%s' input parameter for fragment shader mode."; - const String input_param_for_light_shader_mode = "'%s' input parameter for light shader mode."; - const String input_param_for_vertex_shader_mode = "'%s' input parameter for vertex shader mode."; - const String input_param_for_vertex_and_fragment_shader_mode = "'%s' input parameter for vertex and fragment shader mode."; - - add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_and_light_shader_modes), "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_shader_mode), "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_shader_mode), "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Side", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_shader_mode), "side"), "side", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("UV", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("UV2", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_and_light_shader_modes), "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); - - add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "albedo"), "albedo", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "attenuation"), "attenuation", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "diffuse"), "diffuse", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_and_light_shader_modes), "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "light"), "light", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Roughness", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "roughness"), "roughness", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "specular"), "specular", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Transmission", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "transmission"), "transmission", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_and_light_shader_modes), "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); - - add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("ModelView", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "modelview"), "modelview", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_mode), "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("UV", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("UV2", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); - add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); + const String input_param_for_vertex_and_fragment_shader_modes = TTR("'%s' input parameter for vertex and fragment shader modes."); + const String input_param_for_fragment_and_light_shader_modes = TTR("'%s' input parameter for fragment and light shader modes."); + const String input_param_for_fragment_shader_mode = TTR("'%s' input parameter for fragment shader mode."); + const String input_param_for_light_shader_mode = TTR("'%s' input parameter for light shader mode."); + const String input_param_for_vertex_shader_mode = TTR("'%s' input parameter for vertex shader mode."); + const String input_param_for_vertex_and_fragment_shader_mode = TTR("'%s' input parameter for vertex and fragment shader mode."); + + add_options.push_back(AddOption("Alpha", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Binormal", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Color", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Side", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "side"), "side", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Tangent", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("UV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("UV2", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Vertex", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("View", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_SPATIAL)); + + add_options.push_back(AddOption("Albedo", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "albedo"), "albedo", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Attenuation", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "attenuation"), "attenuation", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Diffuse", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "diffuse"), "diffuse", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Light", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light"), "light", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Roughness", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "roughness"), "roughness", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Specular", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "specular"), "specular", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Transmission", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "transmission"), "transmission", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("View", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "view"), "view", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); + + add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Binormal", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "binormal"), "binormal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("ModelView", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "modelview"), "modelview", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Tangent", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_mode, "tangent"), "tangent", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("UV", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv"), "uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("UV2", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "uv2"), "uv2", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); + add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_SPATIAL)); // CANVASITEM INPUTS - add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_and_light_shader_modes), "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("LightPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "light_pass"), "light_pass", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_and_light_shader_modes), "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("ScreenPixelSize", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_shader_mode), "screen_pixel_size"), "screen_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_and_light_shader_modes), "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM)); - - add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_and_light_shader_modes), "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("LightAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "light_alpha"), "light_alpha", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("LightHeight", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "light_height"), "light_height", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("LightUV", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "light_uv"), "light_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("LightVector", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "light_vec"), "light_vec", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("PointCoord", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_and_light_shader_modes), "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("ScreenUV", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_fragment_and_light_shader_modes), "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("ShadowColor", "Input", "Light", "VisualShaderNodeInput", vformat(TTR(input_param_for_light_shader_mode), "shadow_color"), "shadow_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); - - add_options.push_back(AddOption("Extra", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "extra"), "extra", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("LightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_and_fragment_shader_modes), "light_pass"), "light_pass", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Projection", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "projection"), "projection", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); - add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("FragCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightPass", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "light_pass"), "light_pass", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("PointCoord", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("ScreenPixelSize", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_shader_mode, "screen_pixel_size"), "screen_pixel_size", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("ScreenUV", "Input", "Fragment", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT, Shader::MODE_CANVAS_ITEM)); + + add_options.push_back(AddOption("FragCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "fragcoord"), "fragcoord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightAlpha", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_alpha"), "light_alpha", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_color"), "light_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightHeight", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_height"), "light_height", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_uv"), "light_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightVector", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "light_vec"), "light_vec", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Normal", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "normal"), "normal", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("PointCoord", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "point_coord"), "point_coord", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("ScreenUV", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_fragment_and_light_shader_modes, "screen_uv"), "screen_uv", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("ShadowColor", "Input", "Light", "VisualShaderNodeInput", vformat(input_param_for_light_shader_mode, "shadow_color"), "shadow_color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_LIGHT, Shader::MODE_CANVAS_ITEM)); + + add_options.push_back(AddOption("Extra", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "extra"), "extra", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("LightPass", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_and_fragment_shader_modes, "light_pass"), "light_pass", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("PointSize", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "point_size"), "point_size", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Projection", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "projection"), "projection", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("Vertex", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "vertex"), "vertex", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); + add_options.push_back(AddOption("World", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "world"), "world", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_CANVAS_ITEM)); // PARTICLES INPUTS - add_options.push_back(AddOption("Active", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Custom", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("CustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Delta", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("EmissionTransform", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Index", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("LifeTime", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Restart", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Time", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Transform", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); - add_options.push_back(AddOption("Velocity", "Input", "Vertex", "VisualShaderNodeInput", vformat(TTR(input_param_for_vertex_shader_mode), "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Active", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "active"), "active", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Alpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "alpha"), "alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Color", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "color"), "color", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Custom", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom"), "custom", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("CustomAlpha", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "custom_alpha"), "custom_alpha", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Delta", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "delta"), "delta", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("EmissionTransform", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "emission_transform"), "emission_transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Index", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "index"), "index", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("LifeTime", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "lifetime"), "lifetime", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Restart", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "restart"), "restart", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Time", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "time"), "time", VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Transform", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "transform"), "transform", VisualShaderNode::PORT_TYPE_TRANSFORM, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); + add_options.push_back(AddOption("Velocity", "Input", "Vertex", "VisualShaderNodeInput", vformat(input_param_for_vertex_shader_mode, "velocity"), "velocity", VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_VERTEX, Shader::MODE_PARTICLES)); // SCALAR @@ -2176,16 +2222,16 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Abs", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the absolute value of the parameter."), VisualShaderNodeScalarFunc::FUNC_ABS, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("ACos", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the arc-cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ACOS, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ACosH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("ACosH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true)); add_options.push_back(AddOption("ASin", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the arc-sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ASIN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ASinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("(GLES3 only) Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("ASinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true)); add_options.push_back(AddOption("ATan", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeScalarOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true)); add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeScalarFunc::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("Cos", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_COS, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("(GLES3 only) Returns the hyperbolic cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("CosH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic cosine of the parameter."), VisualShaderNodeScalarFunc::FUNC_COSH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true)); add_options.push_back(AddOption("Degrees", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeScalarFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Exp", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Base-e Exponential."), VisualShaderNodeScalarFunc::FUNC_EXP, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Exp2", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Base-2 Exponential."), VisualShaderNodeScalarFunc::FUNC_EXP2, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -2202,18 +2248,18 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Pow", "Scalar", "Functions", "VisualShaderNodeScalarOp", TTR("Returns the value of the first parameter raised to the power of the second."), VisualShaderNodeScalarOp::OP_POW, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Radians", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Converts a quantity in degrees to radians."), VisualShaderNodeScalarFunc::FUNC_RADIANS, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Reciprocal", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("1.0 / scalar"), VisualShaderNodeScalarFunc::FUNC_RECIPROCAL, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Round", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("(GLES3 only) Finds the nearest integer to the parameter."), VisualShaderNodeScalarFunc::FUNC_ROUND, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("RoundEven", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("(GLES3 only) Finds the nearest even integer to the parameter."), VisualShaderNodeScalarFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Round", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest integer to the parameter."), VisualShaderNodeScalarFunc::FUNC_ROUND, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true)); + add_options.push_back(AddOption("RoundEven", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the nearest even integer to the parameter."), VisualShaderNodeScalarFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true)); add_options.push_back(AddOption("Saturate", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Clamps the value between 0.0 and 1.0."), VisualShaderNodeScalarFunc::FUNC_SATURATE, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Sign", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Extracts the sign of the parameter."), VisualShaderNodeScalarFunc::FUNC_SIGN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Sin", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SIN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("(GLES3 only) Returns the hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("SinH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic sine of the parameter."), VisualShaderNodeScalarFunc::FUNC_SINH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true)); add_options.push_back(AddOption("Sqrt", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the square root of the parameter."), VisualShaderNodeScalarFunc::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 then '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", "VisualShaderNodeScalarOp", TTR("Step function( scalar(edge), scalar(x) ).\n\nReturns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0."), VisualShaderNodeScalarOp::OP_STEP, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Tan", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TAN, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("(GLES3 only) Returns the hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("(GLES3 only) Finds the truncated value of the parameter."), VisualShaderNodeScalarFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("TanH", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Returns the hyperbolic tangent of the parameter."), VisualShaderNodeScalarFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true)); + add_options.push_back(AddOption("Trunc", "Scalar", "Functions", "VisualShaderNodeScalarFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeScalarFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true)); add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeScalarOp", TTR("Adds scalar to scalar."), VisualShaderNodeScalarOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeScalarOp", TTR("Divides scalar by scalar."), VisualShaderNodeScalarOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR)); @@ -2229,20 +2275,21 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubeMap", TTR("Perform the cubic texture lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR)); add_options.push_back(AddOption("Texture", "Textures", "Functions", "VisualShaderNodeTexture", TTR("Perform the texture lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR)); - add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubeMapUniform", TTR("Cubic texture uniform."), -1, VisualShaderNode::PORT_TYPE_COLOR)); - add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform."), -1, VisualShaderNode::PORT_TYPE_COLOR)); + add_options.push_back(AddOption("CubeMapUniform", "Textures", "Variables", "VisualShaderNodeCubeMapUniform", TTR("Cubic texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR)); + add_options.push_back(AddOption("TextureUniform", "Textures", "Variables", "VisualShaderNodeTextureUniform", TTR("2D texture uniform lookup."), -1, VisualShaderNode::PORT_TYPE_COLOR)); + add_options.push_back(AddOption("TextureUniformTriplanar", "Textures", "Variables", "VisualShaderNodeTextureUniformTriplanar", TTR("2D texture uniform lookup with triplanar."), -1, VisualShaderNode::PORT_TYPE_COLOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, Shader::MODE_SPATIAL)); // TRANSFORM add_options.push_back(AddOption("TransformFunc", "Transform", "Common", "VisualShaderNodeTransformFunc", TTR("Transform function."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("OuterProduct", "Transform", "Composition", "VisualShaderNodeOuterProduct", TTR("(GLES3 only) Calculate the outer product of a pair of vectors.\n\nOuterProduct 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'."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("OuterProduct", "Transform", "Composition", "VisualShaderNodeOuterProduct", TTR("Calculate the outer product of a pair of vectors.\n\nOuterProduct 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'."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, -1, -1, true)); add_options.push_back(AddOption("TransformCompose", "Transform", "Composition", "VisualShaderNodeTransformCompose", TTR("Composes transform from four vectors."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("TransformDecompose", "Transform", "Composition", "VisualShaderNodeTransformDecompose", TTR("Decomposes transform to four vectors."))); - add_options.push_back(AddOption("Determinant", "Transform", "Functions", "VisualShaderNodeDeterminant", TTR("(GLES3 only) Calculates the determinant of a transform."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Inverse", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("(GLES3 only) Calculates the inverse of a transform."), VisualShaderNodeTransformFunc::FUNC_INVERSE, VisualShaderNode::PORT_TYPE_TRANSFORM)); - add_options.push_back(AddOption("Transpose", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("(GLES3 only) Calculates the transpose of a transform."), VisualShaderNodeTransformFunc::FUNC_TRANSPOSE, VisualShaderNode::PORT_TYPE_TRANSFORM)); + add_options.push_back(AddOption("Determinant", "Transform", "Functions", "VisualShaderNodeDeterminant", TTR("Calculates the determinant of a transform."), -1, VisualShaderNode::PORT_TYPE_SCALAR, -1, -1, -1, true)); + add_options.push_back(AddOption("Inverse", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the inverse of a transform."), VisualShaderNodeTransformFunc::FUNC_INVERSE, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, -1, -1, true)); + add_options.push_back(AddOption("Transpose", "Transform", "Functions", "VisualShaderNodeTransformFunc", TTR("Calculates the transpose of a transform."), VisualShaderNodeTransformFunc::FUNC_TRANSPOSE, VisualShaderNode::PORT_TYPE_TRANSFORM, -1, -1, -1, true)); add_options.push_back(AddOption("TransformMult", "Transform", "Operators", "VisualShaderNodeTransformMult", TTR("Multiplies transform by transform."), -1, VisualShaderNode::PORT_TYPE_TRANSFORM)); add_options.push_back(AddOption("TransformVectorMult", "Transform", "Operators", "VisualShaderNodeTransformVecMult", TTR("Multiplies vector by transform."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -2260,23 +2307,23 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Abs", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the absolute value of the parameter."), VisualShaderNodeVectorFunc::FUNC_ABS, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("ACos", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ACOS, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("(GLES3 only) Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("ACosH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ACOSH, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true)); add_options.push_back(AddOption("ASin", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ASIN, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("(GLES3 only) Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("ASinH", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_ASINH, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true)); add_options.push_back(AddOption("ATan", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_VECTOR)); 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("(GLES3 only) Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_ATANH, 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, -1, -1, -1, true)); 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("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("(GLES3 only) Returns the hyperbolic cosine of the parameter."), VisualShaderNodeVectorFunc::FUNC_COSH, 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, -1, -1, -1, true)); add_options.push_back(AddOption("Cross", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Calculates the cross product of two vectors."), VisualShaderNodeVectorOp::OP_CROSS, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Degrees", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in radians to degrees."), VisualShaderNodeVectorFunc::FUNC_DEGREES, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Distance", "Vector", "Functions", "VisualShaderNodeVectorDistance", TTR("Returns the distance between two points."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Dot", "Vector", "Functions", "VisualShaderNodeDotProduct", TTR("Calculates the dot product of two vectors."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Exp", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-e Exponential."), VisualShaderNodeVectorFunc::FUNC_EXP, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Exp2", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Base-2 Exponential."), VisualShaderNodeVectorFunc::FUNC_EXP2, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("Returns a 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."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("FaceForward", "Vector", "Functions", "VisualShaderNodeFaceForward", TTR("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."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Floor", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer less than or equal to the parameter."), VisualShaderNodeVectorFunc::FUNC_FLOOR, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Fract", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Computes the fractional part of the argument."), VisualShaderNodeVectorFunc::FUNC_FRAC, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -2292,22 +2339,22 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Pow", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the value of the first parameter raised to the power of the second."), VisualShaderNodeVectorOp::OP_POW, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Radians", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Converts a quantity in degrees to radians."), VisualShaderNodeVectorFunc::FUNC_RADIANS, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Reciprocal", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("1.0 / vector"), VisualShaderNodeVectorFunc::FUNC_RECIPROCAL, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns a vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns a vector that points in the direction of refraction."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("(GLES3 only) Finds the nearest integer to the parameter."), VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("(GLES3 only) Finds the nearest even integer to the parameter."), VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Reflect", "Vector", "Functions", "VisualShaderNodeVectorOp", TTR("Returns the vector that points in the direction of reflection ( a : incident vector, b : normal vector )."), VisualShaderNodeVectorOp::OP_REFLECT, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Refract", "Vector", "Functions", "VisualShaderNodeVectorRefract", TTR("Returns the vector that points in the direction of refraction."), -1, VisualShaderNode::PORT_TYPE_VECTOR)); + add_options.push_back(AddOption("Round", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest integer to the parameter."), VisualShaderNodeVectorFunc::FUNC_ROUND, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true)); + add_options.push_back(AddOption("RoundEven", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the nearest even integer to the parameter."), VisualShaderNodeVectorFunc::FUNC_ROUNDEVEN, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true)); add_options.push_back(AddOption("Saturate", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Clamps the value between 0.0 and 1.0."), VisualShaderNodeVectorFunc::FUNC_SATURATE, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Sign", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Extracts the sign of the parameter."), VisualShaderNodeVectorFunc::FUNC_SIGN, VisualShaderNode::PORT_TYPE_VECTOR)); 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("(GLES3 only) Returns the hyperbolic sine of the parameter."), VisualShaderNodeVectorFunc::FUNC_SINH, 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, -1, -1, -1, true)); 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 then '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 then '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 then '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 then 'edge' and otherwise 1.0."), -1, 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("(GLES3 only) Returns the hyperbolic tangent of the parameter."), VisualShaderNodeVectorFunc::FUNC_TANH, VisualShaderNode::PORT_TYPE_VECTOR)); - add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("(GLES3 only) Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, 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, -1, -1, -1, true)); + add_options.push_back(AddOption("Trunc", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Finds the truncated value of the parameter."), VisualShaderNodeVectorFunc::FUNC_TRUNC, VisualShaderNode::PORT_TYPE_VECTOR, -1, -1, -1, true)); add_options.push_back(AddOption("Add", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Adds vector to vector."), VisualShaderNodeVectorOp::OP_ADD, VisualShaderNode::PORT_TYPE_VECTOR)); add_options.push_back(AddOption("Divide", "Vector", "Operators", "VisualShaderNodeVectorOp", TTR("Divides vector by vector."), VisualShaderNodeVectorOp::OP_DIV, VisualShaderNode::PORT_TYPE_VECTOR)); @@ -2323,15 +2370,15 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Expression", "Special", "", "VisualShaderNodeExpression", TTR("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."))); add_options.push_back(AddOption("Fresnel", "Special", "", "VisualShaderNodeFresnel", TTR("Returns falloff based on the dot product of surface normal and view direction of camera (pass associated inputs to it)."), -1, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("ScalarDerivativeFunc", "Special", "Common", "VisualShaderNodeScalarDerivativeFunc", TTR("(GLES3 only) (Fragment/Light mode only) Scalar derivative function."), -1, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT)); - add_options.push_back(AddOption("VectorDerivativeFunc", "Special", "Common", "VisualShaderNodeVectorDerivativeFunc", TTR("(GLES3 only) (Fragment/Light mode only) Vector derivative function."), -1, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT)); + add_options.push_back(AddOption("ScalarDerivativeFunc", "Special", "Common", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) Scalar derivative function."), -1, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true)); + add_options.push_back(AddOption("VectorDerivativeFunc", "Special", "Common", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) Vector derivative function."), -1, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true)); - add_options.push_back(AddOption("DdX", "Special", "Derivative", "VisualShaderNodeVectorDerivativeFunc", TTR("(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), VisualShaderNodeVectorDerivativeFunc::FUNC_X, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT)); - add_options.push_back(AddOption("DdXS", "Special", "Derivative", "VisualShaderNodeScalarDerivativeFunc", TTR("(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using local differencing."), VisualShaderNodeScalarDerivativeFunc::FUNC_X, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT)); - add_options.push_back(AddOption("DdY", "Special", "Derivative", "VisualShaderNodeVectorDerivativeFunc", TTR("(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), VisualShaderNodeVectorDerivativeFunc::FUNC_Y, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT)); - add_options.push_back(AddOption("DdYS", "Special", "Derivative", "VisualShaderNodeScalarDerivativeFunc", TTR("(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using local differencing."), VisualShaderNodeScalarDerivativeFunc::FUNC_Y, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT)); - add_options.push_back(AddOption("Sum", "Special", "Derivative", "VisualShaderNodeVectorDerivativeFunc", TTR("(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), VisualShaderNodeVectorDerivativeFunc::FUNC_SUM, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT)); - add_options.push_back(AddOption("SumS", "Special", "Derivative", "VisualShaderNodeScalarDerivativeFunc", TTR("(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and 'y'."), VisualShaderNodeScalarDerivativeFunc::FUNC_SUM, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT)); + add_options.push_back(AddOption("DdX", "Special", "Derivative", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'x' using local differencing."), VisualShaderNodeVectorDerivativeFunc::FUNC_X, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true)); + add_options.push_back(AddOption("DdXS", "Special", "Derivative", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) (Scalar) Derivative in 'x' using local differencing."), VisualShaderNodeScalarDerivativeFunc::FUNC_X, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true)); + add_options.push_back(AddOption("DdY", "Special", "Derivative", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Derivative in 'y' using local differencing."), VisualShaderNodeVectorDerivativeFunc::FUNC_Y, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true)); + add_options.push_back(AddOption("DdYS", "Special", "Derivative", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) (Scalar) Derivative in 'y' using local differencing."), VisualShaderNodeScalarDerivativeFunc::FUNC_Y, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true)); + add_options.push_back(AddOption("Sum", "Special", "Derivative", "VisualShaderNodeVectorDerivativeFunc", TTR("(Fragment/Light mode only) (Vector) Sum of absolute derivative in 'x' and 'y'."), VisualShaderNodeVectorDerivativeFunc::FUNC_SUM, VisualShaderNode::PORT_TYPE_VECTOR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true)); + add_options.push_back(AddOption("SumS", "Special", "Derivative", "VisualShaderNodeScalarDerivativeFunc", TTR("(Fragment/Light mode only) (Scalar) Sum of absolute derivative in 'x' and 'y'."), VisualShaderNodeScalarDerivativeFunc::FUNC_SUM, VisualShaderNode::PORT_TYPE_SCALAR, VisualShader::TYPE_FRAGMENT | VisualShader::TYPE_LIGHT, -1, -1, true)); ///////////////////////////////////////////////////////////////////// diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h index fa72b5ec29..100bc53d00 100644 --- a/editor/plugins/visual_shader_editor_plugin.h +++ b/editor/plugins/visual_shader_editor_plugin.h @@ -103,8 +103,9 @@ class VisualShaderEditor : public VBoxContainer { int return_type; int func; float value; + bool highend; - AddOption(const String &p_name = String(), const String &p_category = String(), const String &p_sub_category = String(), const String &p_type = String(), const String &p_description = String(), int p_sub_func = -1, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1) { + AddOption(const String &p_name = String(), const String &p_category = String(), const String &p_sub_category = String(), const String &p_type = String(), const String &p_description = String(), int p_sub_func = -1, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) { name = p_name; type = p_type; category = p_category; @@ -115,9 +116,10 @@ class VisualShaderEditor : public VBoxContainer { mode = p_mode; func = p_func; value = p_value; + highend = p_highend; } - AddOption(const String &p_name, const String &p_category, const String &p_sub_category, const String &p_type, const String &p_description, const String &p_sub_func, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1) { + AddOption(const String &p_name, const String &p_category, const String &p_sub_category, const String &p_type, const String &p_description, const String &p_sub_func, int p_return_type = -1, int p_mode = -1, int p_func = -1, float p_value = -1, bool p_highend = false) { name = p_name; type = p_type; category = p_category; @@ -128,6 +130,7 @@ class VisualShaderEditor : public VBoxContainer { mode = p_mode; func = p_func; value = p_value; + highend = p_highend; } }; @@ -198,7 +201,7 @@ class VisualShaderEditor : public VBoxContainer { void _node_resized(const Vector2 &p_new_size, int p_type, int p_node); void _preview_select_port(int p_node, int p_port); - void _graph_gui_input(const Ref<InputEvent> p_event); + void _graph_gui_input(const Ref<InputEvent> &p_event); void _member_filter_changed(const String &p_text); void _sbox_input(const Ref<InputEvent> &p_ie); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 4b3d468a61..e013aae164 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -765,6 +765,7 @@ public: set_title(TTR("Install Project:") + " " + zip_title); get_ok()->set_text(TTR("Install & Edit")); + project_name->set_text(zip_title); name_container->show(); install_path_container->hide(); rasterizer_container->hide(); diff --git a/editor/rename_dialog.cpp b/editor/rename_dialog.cpp index 40343cf908..cc9e14975f 100644 --- a/editor/rename_dialog.cpp +++ b/editor/rename_dialog.cpp @@ -131,7 +131,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und vbc_substitute->set_name(TTR("Substitute")); tabc_features->add_child(vbc_substitute); - cbut_substitute = memnew(CheckButton); + cbut_substitute = memnew(CheckBox); cbut_substitute->set_text(TTR("Substitute")); vbc_substitute->add_child(cbut_substitute); @@ -246,7 +246,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und vbc_regex->set_custom_minimum_size(Size2(0, feature_min_height)); tabc_features->add_child(vbc_regex); - cbut_regex = memnew(CheckButton); + cbut_regex = memnew(CheckBox); cbut_regex->set_text(TTR("Regular Expressions")); vbc_regex->add_child(cbut_regex); @@ -258,7 +258,7 @@ RenameDialog::RenameDialog(SceneTreeEditor *p_scene_tree_editor, UndoRedo *p_und vbc_process->set_custom_minimum_size(Size2(0, feature_min_height)); tabc_features->add_child(vbc_process); - cbut_process = memnew(CheckButton); + cbut_process = memnew(CheckBox); cbut_process->set_text(TTR("Post-Process")); vbc_process->add_child(cbut_process); diff --git a/editor/rename_dialog.h b/editor/rename_dialog.h index 4e0fab6a9f..9f0fbf66a1 100644 --- a/editor/rename_dialog.h +++ b/editor/rename_dialog.h @@ -32,7 +32,6 @@ #define RENAME_DIALOG_H #include "scene/gui/check_box.h" -#include "scene/gui/check_button.h" #include "scene/gui/dialogs.h" #include "scene/gui/option_button.h" #include "scene/gui/spin_box.h" @@ -75,9 +74,9 @@ class RenameDialog : public ConfirmationDialog { TabContainer *tabc_features; - CheckButton *cbut_substitute; - CheckButton *cbut_regex; - CheckButton *cbut_process; + CheckBox *cbut_substitute; + CheckBox *cbut_regex; + CheckBox *cbut_process; CheckBox *chk_per_level_counter; Button *but_insert_name; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index e5ce834d79..c43d164078 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -89,6 +89,8 @@ void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) { _tool_selected(TOOL_NEW); } else if (ED_IS_SHORTCUT("scene_tree/instance_scene", p_event)) { _tool_selected(TOOL_INSTANCE); + } else if (ED_IS_SHORTCUT("scene_tree/expand_collapse_all", p_event)) { + _tool_selected(TOOL_EXPAND_COLLAPSE); } else if (ED_IS_SHORTCUT("scene_tree/change_node_type", p_event)) { _tool_selected(TOOL_REPLACE); } else if (ED_IS_SHORTCUT("scene_tree/duplicate", p_event)) { @@ -370,12 +372,33 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { quick_open->set_title(TTR("Instance Child Scene")); } break; + case TOOL_EXPAND_COLLAPSE: { + + if (!scene_tree->get_selected()) + break; + + Tree *tree = scene_tree->get_scene_tree(); + TreeItem *selected_item = tree->get_selected(); + + if (!selected_item) + selected_item = tree->get_root(); + + bool collapsed = _is_collapsed_recursive(selected_item); + _set_collapsed_recursive(selected_item, !collapsed); + + tree->ensure_cursor_is_visible(); + + } break; case TOOL_REPLACE: { if (!profile_allow_editing) { break; } - create_dialog->popup_create(false, true, scene_tree->get_selected()->get_class()); + + Node *selected = scene_tree->get_selected(); + if (selected) + create_dialog->popup_create(false, true, selected->get_class()); + } break; case TOOL_ATTACH_SCRIPT: { @@ -418,6 +441,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } } } + script_create_dialog->connect("script_created", this, "_script_created"); + script_create_dialog->connect("popup_hide", this, "_script_creation_closed"); + script_create_dialog->set_inheritance_base_type("Node"); script_create_dialog->config(inherits, path); script_create_dialog->popup_centered(); @@ -547,10 +573,13 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { Node *dupsingle = NULL; List<Node *> editable_children; - for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + selection.sort_custom<Node::Comparator>(); + + for (List<Node *>::Element *E = selection.back(); E; E = E->prev()) { Node *node = E->get(); Node *parent = node->get_parent(); + Node *selection_tail = _get_selection_group_tail(node, selection); List<Node *> owned; node->get_owned_by(node->get_owner(), &owned); @@ -568,7 +597,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { dup->set_name(parent->validate_child_name(dup)); - editor_data->get_undo_redo().add_do_method(parent, "add_child_below_node", node, dup); + editor_data->get_undo_redo().add_do_method(parent, "add_child_below_node", selection_tail, dup); for (List<Node *>::Element *F = owned.front(); F; F = F->next()) { if (!duplimap.has(F->get())) { @@ -576,7 +605,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { continue; } Node *d = duplimap[F->get()]; - editor_data->get_undo_redo().add_do_method(d, "set_owner", node->get_owner()); + editor_data->get_undo_redo().add_do_method(d, "set_owner", selection_tail->get_owner()); } editor_data->get_undo_redo().add_do_method(editor_selection, "add_node", dup); editor_data->get_undo_redo().add_undo_method(parent, "remove_child", dup); @@ -998,6 +1027,17 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) { } } +void SceneTreeDock::_node_collapsed(Object *p_obj) { + + TreeItem *ti = Object::cast_to<TreeItem>(p_obj); + if (!ti) + return; + + if (Input::get_singleton()->is_key_pressed(KEY_SHIFT)) { + _set_collapsed_recursive(ti, ti->is_collapsed()); + } +} + void SceneTreeDock::_notification(int p_what) { switch (p_what) { @@ -1030,6 +1070,7 @@ void SceneTreeDock::_notification(int p_what) { filter->set_clear_button_enabled(true); EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", this, "_selection_changed"); + scene_tree->get_scene_tree()->connect("item_collapsed", this, "_node_collapsed"); // create_root_dialog HBoxContainer *top_row = memnew(HBoxContainer); @@ -1623,6 +1664,52 @@ void SceneTreeDock::_do_reparent(Node *p_new_parent, int p_position_in_parent, V editor_data->get_undo_redo().commit_action(); } +bool SceneTreeDock::_is_collapsed_recursive(TreeItem *p_item) const { + + bool is_branch_collapsed = false; + + List<TreeItem *> needs_check; + needs_check.push_back(p_item); + + while (!needs_check.empty()) { + + TreeItem *item = needs_check.back()->get(); + needs_check.pop_back(); + + TreeItem *child = item->get_children(); + is_branch_collapsed = item->is_collapsed() && child; + + if (is_branch_collapsed) { + break; + } + while (child) { + needs_check.push_back(child); + child = child->get_next(); + } + } + return is_branch_collapsed; +} + +void SceneTreeDock::_set_collapsed_recursive(TreeItem *p_item, bool p_collapsed) { + + List<TreeItem *> to_collapse; + to_collapse.push_back(p_item); + + while (!to_collapse.empty()) { + + TreeItem *item = to_collapse.back()->get(); + to_collapse.pop_back(); + + item->set_collapsed(p_collapsed); + + TreeItem *child = item->get_children(); + while (child) { + to_collapse.push_back(child); + child = child->get_next(); + } + } +} + void SceneTreeDock::_script_created(Ref<Script> p_script) { List<Node *> selected = editor_selection->get_selected_node_list(); @@ -1646,6 +1733,11 @@ void SceneTreeDock::_script_created(Ref<Script> p_script) { _update_script_button(); } +void SceneTreeDock::_script_creation_closed() { + script_create_dialog->disconnect("script_created", this, "_script_created"); + script_create_dialog->disconnect("popup_hide", this, "_script_creation_closed"); +} + void SceneTreeDock::_toggle_editable_children_from_selection() { List<Node *> selection = editor_selection->get_selected_node_list(); @@ -1800,6 +1892,23 @@ void SceneTreeDock::_selection_changed() { _update_script_button(); } +Node *SceneTreeDock::_get_selection_group_tail(Node *p_node, List<Node *> p_list) { + + Node *tail = p_node; + Node *parent = tail->get_parent(); + + for (int i = p_node->get_position_in_parent(); i < parent->get_child_count(); i++) { + Node *sibling = parent->get_child(i); + + if (p_list.find(sibling)) + tail = sibling; + else + break; + } + + return tail; +} + void SceneTreeDock::_create() { if (current_option == TOOL_NEW) { @@ -2141,23 +2250,20 @@ void SceneTreeDock::_script_dropped(String p_file, NodePath p_to) { void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) { - Vector<Node *> nodes; - Node *to_node; - - for (int i = 0; i < p_nodes.size(); i++) { - Node *n = get_node((p_nodes[i])); - if (n) { - nodes.push_back(n); - } - } + List<Node *> selection = editor_selection->get_selected_node_list(); - if (nodes.size() == 0) - return; + if (selection.empty()) + return; //nothing to reparent - to_node = get_node(p_to); + Node *to_node = get_node(p_to); if (!to_node) return; + Vector<Node *> nodes; + for (List<Node *>::Element *E = selection.front(); E; E = E->next()) { + nodes.push_back(E->get()); + } + int to_pos = -1; _normalize_drop(to_node, to_pos, p_type); @@ -2237,8 +2343,10 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) { menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW); menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE); - menu->add_separator(); } + menu->add_icon_shortcut(get_icon("Collapse", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/expand_collapse_all"), TOOL_EXPAND_COLLAPSE); + menu->add_separator(); + existing_script = selected->get_script(); } @@ -2505,6 +2613,7 @@ void SceneTreeDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_node_selected"), &SceneTreeDock::_node_selected); ClassDB::bind_method(D_METHOD("_node_renamed"), &SceneTreeDock::_node_renamed); ClassDB::bind_method(D_METHOD("_script_created"), &SceneTreeDock::_script_created); + ClassDB::bind_method(D_METHOD("_script_creation_closed"), &SceneTreeDock::_script_creation_closed); ClassDB::bind_method(D_METHOD("_load_request"), &SceneTreeDock::_load_request); ClassDB::bind_method(D_METHOD("_script_open_request"), &SceneTreeDock::_script_open_request); ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &SceneTreeDock::_unhandled_key_input); @@ -2515,6 +2624,7 @@ void SceneTreeDock::_bind_methods() { ClassDB::bind_method(D_METHOD("_node_prerenamed"), &SceneTreeDock::_node_prerenamed); ClassDB::bind_method(D_METHOD("_import_subscene"), &SceneTreeDock::_import_subscene); ClassDB::bind_method(D_METHOD("_selection_changed"), &SceneTreeDock::_selection_changed); + ClassDB::bind_method(D_METHOD("_node_collapsed"), &SceneTreeDock::_node_collapsed); ClassDB::bind_method(D_METHOD("_new_scene_from"), &SceneTreeDock::_new_scene_from); ClassDB::bind_method(D_METHOD("_nodes_dragged"), &SceneTreeDock::_nodes_dragged); ClassDB::bind_method(D_METHOD("_files_dropped"), &SceneTreeDock::_files_dropped); @@ -2554,6 +2664,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel ED_SHORTCUT("scene_tree/batch_rename", TTR("Batch Rename"), KEY_MASK_CMD | KEY_F2); ED_SHORTCUT("scene_tree/add_child_node", TTR("Add Child Node"), KEY_MASK_CMD | KEY_A); ED_SHORTCUT("scene_tree/instance_scene", TTR("Instance Child Scene")); + ED_SHORTCUT("scene_tree/expand_collapse_all", TTR("Expand/Collapse All")); ED_SHORTCUT("scene_tree/change_node_type", TTR("Change Type")); ED_SHORTCUT("scene_tree/attach_script", TTR("Attach Script")); ED_SHORTCUT("scene_tree/extend_script", TTR("Extend Script")); @@ -2571,7 +2682,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel button_add = memnew(ToolButton); button_add->connect("pressed", this, "_tool_selected", make_binds(TOOL_NEW, false)); - button_add->set_tooltip(TTR("Add/Create a New Node")); + button_add->set_tooltip(TTR("Add/Create a New Node.")); button_add->set_shortcut(ED_GET_SHORTCUT("scene_tree/add_child_node")); filter_hbc->add_child(button_add); @@ -2660,7 +2771,6 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel script_create_dialog = memnew(ScriptCreateDialog); script_create_dialog->set_inheritance_base_type("Node"); add_child(script_create_dialog); - script_create_dialog->connect("script_created", this, "_script_created"); reparent_dialog = memnew(ReparentDialog); add_child(reparent_dialog); diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index b645c22295..8a2b237b8b 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -60,6 +60,7 @@ class SceneTreeDock : public VBoxContainer { TOOL_NEW, TOOL_INSTANCE, + TOOL_EXPAND_COLLAPSE, TOOL_RENAME, TOOL_BATCH_RENAME, TOOL_REPLACE, @@ -116,6 +117,7 @@ class SceneTreeDock : public VBoxContainer { HBoxContainer *tool_hbc; void _tool_selected(int p_tool, bool p_confirm_override = false); + void _node_collapsed(Object *p_obj); EditorData *editor_data; EditorSelection *editor_selection; @@ -152,6 +154,9 @@ class SceneTreeDock : public VBoxContainer { void _node_reparent(NodePath p_path, bool p_keep_global_xform); void _do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform); + bool _is_collapsed_recursive(TreeItem *p_item) const; + void _set_collapsed_recursive(TreeItem *p_item, bool p_collapsed); + void _set_owners(Node *p_owner, const Array &p_nodes); enum ReplaceOwnerMode { @@ -170,6 +175,7 @@ class SceneTreeDock : public VBoxContainer { void _node_selected(); void _node_renamed(); void _script_created(Ref<Script> p_script); + void _script_creation_closed(); void _delete_confirm(); @@ -189,6 +195,7 @@ class SceneTreeDock : public VBoxContainer { bool _validate_no_foreign(); void _selection_changed(); void _update_script_button(); + Node *_get_selection_group_tail(Node *p_node, List<Node *> p_list); void _fill_path_renames(Vector<StringName> base_path, Vector<StringName> new_base_path, Node *p_node, List<Pair<NodePath, NodePath> > *p_renames); diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp index ff188a00d3..c1a14685b0 100644 --- a/editor/scene_tree_editor.cpp +++ b/editor/scene_tree_editor.cpp @@ -70,7 +70,8 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i } } else if (p_id == BUTTON_SCRIPT) { RefPtr script = n->get_script(); - if (!script.is_null()) + Ref<Script> script_typed = script; + if (!script_typed.is_null()) emit_signal("open_script", script); } else if (p_id == BUTTON_VISIBILITY) { @@ -210,7 +211,8 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { if (connect_to_script_mode) { Color accent = get_color("accent_color", "Editor"); - if (!p_node->get_script().is_null()) { + Ref<Script> script = p_node->get_script(); + if (!script.is_null()) { //has script item->add_button(0, get_icon("Script", "EditorIcons"), BUTTON_SCRIPT); } else { @@ -290,8 +292,8 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) { if (!p_node->is_connected("script_changed", this, "_node_script_changed")) p_node->connect("script_changed", this, "_node_script_changed", varray(p_node)); - if (!p_node->get_script().is_null()) { - Ref<Script> script = p_node->get_script(); + Ref<Script> script = p_node->get_script(); + if (!script.is_null()) { item->add_button(0, get_icon("Script", "EditorIcons"), BUTTON_SCRIPT, false, TTR("Open Script:") + " " + script->get_path()); } @@ -1164,6 +1166,8 @@ void SceneTreeDialog::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { connect("confirmed", this, "_select"); + filter->set_right_icon(get_icon("Search", "EditorIcons")); + filter->set_clear_button_enabled(true); } break; case NOTIFICATION_EXIT_TREE: { disconnect("confirmed", this, "_select"); @@ -1187,20 +1191,37 @@ void SceneTreeDialog::_select() { } } +void SceneTreeDialog::_filter_changed(const String &p_filter) { + + tree->set_filter(p_filter); +} + void SceneTreeDialog::_bind_methods() { ClassDB::bind_method("_select", &SceneTreeDialog::_select); ClassDB::bind_method("_cancel", &SceneTreeDialog::_cancel); + ClassDB::bind_method(D_METHOD("_filter_changed"), &SceneTreeDialog::_filter_changed); + ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::NODE_PATH, "path"))); } SceneTreeDialog::SceneTreeDialog() { set_title(TTR("Select a Node")); + VBoxContainer *vbc = memnew(VBoxContainer); + add_child(vbc); + + filter = memnew(LineEdit); + filter->set_h_size_flags(SIZE_EXPAND_FILL); + filter->set_placeholder(TTR("Filter nodes")); + filter->add_constant_override("minimum_spaces", 0); + filter->connect("text_changed", this, "_filter_changed"); + vbc->add_child(filter); tree = memnew(SceneTreeEditor(false, false, true)); - add_child(tree); + tree->set_v_size_flags(SIZE_EXPAND_FILL); tree->get_scene_tree()->connect("item_activated", this, "_select"); + vbc->add_child(tree); } SceneTreeDialog::~SceneTreeDialog() { diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h index 68642910e8..61cb59ce6f 100644 --- a/editor/scene_tree_editor.h +++ b/editor/scene_tree_editor.h @@ -171,10 +171,12 @@ class SceneTreeDialog : public ConfirmationDialog { SceneTreeEditor *tree; //Button *select; //Button *cancel; + LineEdit *filter; void update_tree(); void _select(); void _cancel(); + void _filter_changed(const String &p_filter); protected: void _notification(int p_what); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index ffa221edaf..ed9a24311d 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -126,7 +126,7 @@ bool ScriptCreateDialog::_validate_class(const String &p_string) { return false; // no start with number plz } - bool valid_char = (p_string[i] >= '0' && p_string[i] <= '9') || (p_string[i] >= 'a' && p_string[i] <= 'z') || (p_string[i] >= 'A' && p_string[i] <= 'Z') || p_string[i] == '_'; + bool valid_char = (p_string[i] >= '0' && p_string[i] <= '9') || (p_string[i] >= 'a' && p_string[i] <= 'z') || (p_string[i] >= 'A' && p_string[i] <= 'Z') || p_string[i] == '_' || p_string[i] == '.'; if (!valid_char) return false; @@ -286,8 +286,8 @@ void ScriptCreateDialog::_create_new() { } } - hide(); emit_signal("script_created", scr); + hide(); } void ScriptCreateDialog::_load_exist() { @@ -300,8 +300,8 @@ void ScriptCreateDialog::_load_exist() { return; } - hide(); emit_signal("script_created", p_script.get_ref_ptr()); + hide(); } void ScriptCreateDialog::_lang_changed(int l) { @@ -528,7 +528,7 @@ void ScriptCreateDialog::_update_dialog() { if (has_named_classes) { if (is_new_script_created) { class_name->set_editable(true); - class_name->set_placeholder(TTR("Allowed: a-z, A-Z, 0-9 and _")); + class_name->set_placeholder(TTR("Allowed: a-z, A-Z, 0-9, _ and .")); class_name->set_placeholder_alpha(0.3); } else { class_name->set_editable(false); @@ -742,8 +742,8 @@ ScriptCreateDialog::ScriptCreateDialog() { /* Built-in Script */ - internal = memnew(CheckButton); - internal->set_h_size_flags(0); + internal = memnew(CheckBox); + internal->set_text(TTR("On")); internal->connect("pressed", this, "_built_in_pressed"); internal_label = memnew(Label(TTR("Built-in Script"))); internal_label->set_align(Label::ALIGN_RIGHT); diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h index 61f87f5732..288b8f604b 100644 --- a/editor/script_create_dialog.h +++ b/editor/script_create_dialog.h @@ -33,7 +33,7 @@ #include "editor/editor_file_dialog.h" #include "editor/editor_settings.h" -#include "scene/gui/check_button.h" +#include "scene/gui/check_box.h" #include "scene/gui/dialogs.h" #include "scene/gui/grid_container.h" #include "scene/gui/line_edit.h" @@ -57,7 +57,7 @@ class ScriptCreateDialog : public ConfirmationDialog { LineEdit *file_path; Button *path_button; EditorFileDialog *file_browse; - CheckButton *internal; + CheckBox *internal; Label *internal_label; VBoxContainer *path_vb; AcceptDialog *alert; diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index fe6d9dd8c7..cbfd0f3742 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -873,6 +873,10 @@ void LightSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Geometry::get_closest_points_between_segments(Vector3(), Vector3(0, 0, -4096), s[0], s[1], ra, rb); float d = -ra.z; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0) d = 0; @@ -885,6 +889,10 @@ void LightSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, if (cp.intersects_ray(ray_from, ray_dir, &inters)) { float r = inters.distance_to(gt.origin); + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + r = Math::stepify(r, SpatialEditor::get_singleton()->get_translate_snap()); + } + light->set_param(Light::PARAM_RANGE, r); } } @@ -1257,6 +1265,10 @@ void CameraSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(0, 0, -1), Vector3(4096, 0, -1), s[0], s[1], ra, rb); float d = ra.x * 2.0; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0) d = 0; @@ -2310,6 +2322,9 @@ void VisibilityNotifierGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx]; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5; notifier->set_aabb(aabb); @@ -2319,6 +2334,10 @@ void VisibilityNotifierGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx] - ofs[p_idx]; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; //resize @@ -2444,7 +2463,6 @@ void ParticlesGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Ca Particles *particles = Object::cast_to<Particles>(p_gizmo->get_spatial_node()); Transform gt = particles->get_global_transform(); - //gt.orthonormalize(); Transform gi = gt.affine_inverse(); bool move = p_idx >= 3; @@ -2467,6 +2485,9 @@ void ParticlesGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Ca Geometry::get_closest_points_between_segments(ofs - axis * 4096, ofs + axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx]; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5; particles->set_visibility_aabb(aabb); @@ -2476,6 +2497,10 @@ void ParticlesGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Ca Geometry::get_closest_points_between_segments(ofs, ofs + axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx] - ofs[p_idx]; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; //resize @@ -2619,6 +2644,10 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); float d = ra[p_idx]; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; @@ -2641,8 +2670,11 @@ void ReflectionProbeGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i Vector3 ra, rb; Geometry::get_closest_points_between_segments(origin - axis * 16384, origin + axis * 16384, sg[0], sg[1], ra, rb); - float d = ra[p_idx]; - d += 0.25; + // Adjust the actual position to account for the gizmo handle position + float d = ra[p_idx] + 0.25; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } origin[p_idx] = d; probe->set_origin_offset(origin); @@ -2780,7 +2812,6 @@ void GIProbeGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Came GIProbe *probe = Object::cast_to<GIProbe>(p_gizmo->get_spatial_node()); Transform gt = probe->get_global_transform(); - //gt.orthonormalize(); Transform gi = gt.affine_inverse(); Vector3 extents = probe->get_extents(); @@ -2796,6 +2827,10 @@ void GIProbeGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Came Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); float d = ra[p_idx]; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; @@ -2945,7 +2980,6 @@ void BakedIndirectLightGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int BakedLightmap *baker = Object::cast_to<BakedLightmap>(p_gizmo->get_spatial_node()); Transform gt = baker->get_global_transform(); - //gt.orthonormalize(); Transform gi = gt.affine_inverse(); Vector3 extents = baker->get_extents(); @@ -2961,6 +2995,10 @@ void BakedIndirectLightGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), axis * 16384, sg[0], sg[1], ra, rb); float d = ra[p_idx]; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; @@ -3158,6 +3196,10 @@ void CollisionShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, i Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb); float d = ra.x; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; @@ -3170,6 +3212,10 @@ void CollisionShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, i Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), Vector3(0, 0, 4096), sg[0], sg[1], ra, rb); float d = ra.z; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; @@ -3184,6 +3230,10 @@ void CollisionShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, i Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx]; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; @@ -3202,6 +3252,11 @@ void CollisionShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, i float d = axis.dot(ra); if (p_idx == 1) d -= cs2->get_radius(); + + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; @@ -3219,6 +3274,9 @@ void CollisionShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, i Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); float d = axis.dot(ra); + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } if (d < 0.001) d = 0.001; diff --git a/editor/translations/af.po b/editor/translations/af.po index 120a87db58..9cce062127 100644 --- a/editor/translations/af.po +++ b/editor/translations/af.po @@ -455,6 +455,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Dupliseer Seleksie" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -636,6 +646,10 @@ msgstr "Gaan na Reël" msgid "Line Number:" msgstr "Reël Nommer:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Geen Pasmaats" @@ -685,7 +699,7 @@ msgstr "Zoem Uit" msgid "Reset Zoom" msgstr "Herset Zoem" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -796,6 +810,11 @@ msgid "Connect" msgstr "Koppel" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Seine:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Koppel '%s' aan '%s'" @@ -968,7 +987,8 @@ msgid "Owners Of:" msgstr "Eienaars van:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Verwyder geselekteerde lêers uit die projek? (geen ontdoen)" #: editor/dependency_editor.cpp @@ -1349,7 +1369,7 @@ msgstr "Ongeldige naam. Dit moet nie met bestaande enjin klasname bots nie." #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" "Ongeldige naam. Dit moet nie met bestaande ingeboude tiepename bots nie." @@ -1527,6 +1547,10 @@ msgstr "" msgid "Template file not found:" msgstr "Sjabloon lêer nie gevind nie:\n" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1555,7 +1579,7 @@ msgid "Node Dock" msgstr "Nodus Naam:" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1615,7 +1639,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1630,7 +1654,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Skep Vouer" #: editor/editor_feature_profile.cpp @@ -1654,13 +1678,9 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Deursoek Klasse" +msgid "Available Profiles:" +msgstr "Eienskappe" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2708,10 +2728,31 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Wissel Modus" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -2818,15 +2859,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "Deurlopend" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -3016,7 +3058,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3116,20 +3158,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3644,6 +3686,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5278,6 +5321,13 @@ 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 "" @@ -6204,10 +6254,20 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Eienskappe" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Eienskappe" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "" @@ -6446,18 +6506,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Skep" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -8045,51 +8109,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8097,203 +8117,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9945,6 +9789,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Vervang Alles" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9973,8 +9822,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Skep Nuwe" #: editor/scene_tree_dock.cpp msgid "" @@ -10219,7 +10069,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10623,56 +10473,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "Kon nie vouer skep nie." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "Skep Intekening" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11262,7 +11062,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11311,7 +11111,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11321,7 +11121,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11388,14 +11188,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11474,7 +11281,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11503,6 +11310,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11537,8 +11348,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11549,7 +11360,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11565,7 +11378,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11576,7 +11389,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11613,7 +11428,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Koppel '%s' aan '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11627,7 +11442,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11639,7 +11454,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11652,10 +11471,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11669,18 +11493,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11723,6 +11547,10 @@ msgid "Input" 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 "" @@ -11742,6 +11570,18 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "Kon nie vouer skep nie." + +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "Skep Intekening" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Deursoek Klasse" + #~ msgid "Path to Node:" #~ msgstr "Pad na Nodus:" diff --git a/editor/translations/ar.po b/editor/translations/ar.po index 9a045680e5..5f9f0aee4c 100644 --- a/editor/translations/ar.po +++ b/editor/translations/ar.po @@ -27,12 +27,13 @@ # Ibraheem Tawfik <tawfikibraheem@gmail.com>, 2019. # DiscoverSquishy <noaimi@discoversquishy.me>, 2019. # ButterflyOfFire <ButterflyOfFire@protonmail.com>, 2019. +# PhoenixHO <oussamahaddouche0@gmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" -"Last-Translator: ButterflyOfFire <ButterflyOfFire@protonmail.com>\n" +"PO-Revision-Date: 2019-07-09 10:47+0000\n" +"Last-Translator: PhoenixHO <oussamahaddouche0@gmail.com>\n" "Language-Team: Arabic <https://hosted.weblate.org/projects/godot-engine/" "godot/ar/>\n" "Language: ar\n" @@ -41,7 +42,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 ? 4 : 5;\n" -"X-Generator: Weblate 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -102,7 +103,7 @@ msgstr "الوقت:" #: editor/animation_bezier_editor.cpp #, fuzzy msgid "Value:" -msgstr "إسم جديد:" +msgstr "القيمة:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -454,11 +455,27 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"هذا الانيميشن ينتمي الى مشهد مستورد، لذا ÙØ¥Ù† أي تغييرات ÙÙŠ المسارات " +"المستوردة لن يتم ØÙظها.\n" +"\n" +"لتشغيل الامكانية Ù„Ø¥Ø¶Ø§ÙØ© مسارات خاصة، انتقل إلى إعدادات استيراد المشهد واضبط " +"\"Animation > Storage\" إلى \"Files\"ØŒ شغل \"Animation > Keep Custom Tracks" +"\"ØŒ ثم ..." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "ØªØØ¯ÙŠØ¯ الوضع" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "Ùقط قم بتبين المقاطع من العقد (Nodes) Ø§Ù„Ù…ØØ¯Ø¯Ø© ÙÙŠ الشجرة." @@ -635,6 +652,10 @@ msgstr "إذهب إلي الخط" msgid "Line Number:" msgstr "رقم الخط:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "لا مطابقة" @@ -684,7 +705,7 @@ msgstr "إبعاد" msgid "Reset Zoom" msgstr "إرجاع التكبير" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "ØªØØ°ÙŠØ±Ø§Øª" @@ -797,6 +818,11 @@ msgid "Connect" msgstr "وصل" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "الإشارات:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "وصل '%s' إلي '%s'" @@ -963,7 +989,8 @@ msgid "Owners Of:" msgstr "ملاك:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Ø¥Ù…Ø³Ø Ø§Ù„Ù…Ù„ÙØ§Øª Ø§Ù„Ù…ØØ¯Ø¯Ø© من المشروع؟ (لا رجعة)" #: editor/dependency_editor.cpp @@ -1336,7 +1363,7 @@ msgstr "إسم غير ØµØ§Ù„ØØŒ يجب أن لا يتصادم مع أسم ÙØµÙ #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "إسم غير ØµØ§Ù„ØØŒ يجب أن لا يتصادم مع الأسماء المبنية تلقائياً الموجودة." #: editor/editor_autoload_settings.cpp @@ -1515,6 +1542,10 @@ msgstr "قالب الإصدار المخصص ليس موجود." 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 #, fuzzy msgid "3D Editor" @@ -1546,7 +1577,7 @@ msgstr "وضع Ø§Ù„ØªØØ±ÙŠÙƒ" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "نظام Ø§Ù„Ù…Ù„ÙØ§Øª" #: editor/editor_feature_profile.cpp @@ -1607,7 +1638,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1622,7 +1653,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "النسخة Ø§Ù„ØØ§Ù„ية:" #: editor/editor_feature_profile.cpp @@ -1646,13 +1677,9 @@ msgid "Export" msgstr "تصدير" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Ø¥Ø¨ØØ« ÙÙŠ الأصناÙ" +msgid "Available Profiles:" +msgstr "خصائص:" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2066,7 +2093,7 @@ msgstr "أخلاء الخرج" #: editor/editor_node.cpp msgid "Project export failed with error code %d." -msgstr "تصدير المشروع ÙØ´Ù„, رمز الخطأ % d." +msgstr "تصدير المشروع ÙØ´Ù„, رمز الخطأ %d." #: editor/editor_node.cpp msgid "Imported resources can't be saved." @@ -2751,11 +2778,35 @@ msgid "Editor Layout" msgstr "نسق Ø§Ù„Ù…ÙØ¹Ø¯Ù„" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "ØÙظ المشهد" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "إعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù„" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "ÙØªØ ÙÙŠ Ø§Ù„Ù…ÙØ¹Ø¯Ù„ التالي" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "إلغاء/ØªÙØ¹ÙŠÙ„ وضع الشاشة الكاملة" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "أظهر المود" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "إعدادات Ø§Ù„Ù…ÙØ¹Ø¯Ù„" @@ -2866,15 +2917,18 @@ msgid "Spins when the editor window redraws." msgstr "يدور ØÙŠÙ†Ù…ا Ù†Ø§ÙØ°Ø© Ø§Ù„Ù…ÙØ¹Ø¯Ù„ يتم إعادة دهانة!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "ØªØØ¯ÙŠØ« دائماً" +#, fuzzy +msgid "Update Continuously" +msgstr "متواصل" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "ØªØØ¯ÙŠØ« التغييرات" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "تعطيل دوار Ø§Ù„ØªØØ¯ÙŠØ«" #: editor/editor_node.cpp @@ -3069,7 +3123,7 @@ msgstr "الوقت" msgid "Calls" msgstr "ندائات" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3169,6 +3223,11 @@ 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 #, fuzzy msgid "New Key:" msgstr "إسم جديد:" @@ -3182,11 +3241,6 @@ msgstr "إسم جديد:" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3707,6 +3761,7 @@ msgid "Nodes not in Group" msgstr "Ø¥Ø¶Ø§ÙØ© إلي مجموعة" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5385,6 +5440,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "إعادة تشغيل (ثواني):" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Ø¥Ù…Ø³Ø Ù‚Ù†Ø§Ø¹ الانبعاث" @@ -6333,10 +6396,20 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 +#, fuzzy +msgid "Filter methods" +msgstr "وضع Ø§Ù„Ù…ÙØµÙÙŠ:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "ترتيب" @@ -6576,18 +6649,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Ù…Ø³Ø Ø§Ù„Ù†Ù‚Ø§Ø·" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -8225,51 +8302,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8278,203 +8311,27 @@ msgid "Input parameter." msgstr "الكبس إلي الطÙÙ„" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10143,6 +10000,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "طوي الكل" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10173,8 +10035,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "إنشاء %s جديد" #: editor/scene_tree_dock.cpp msgid "" @@ -10428,7 +10291,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10845,55 +10708,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "إنشاء الØÙ„..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "لا يمكن إنشاء Ø§Ù„ØØ¯." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "ÙØ´Ù„ ØÙظ الØÙ„." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "تم" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "ÙØ´Ù„ إنشاء مشروع C#‎." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "إنشاء ØÙ„ C#‎" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "بناء المشروع" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "إظهار Ø§Ù„Ù…Ù„ÙØ§Øª" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11480,8 +11294,9 @@ 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 " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "ليتم إظهار الأطر (اللقطات) ÙÙŠ الAnimatedSprite (النقوش Ø§Ù„Ù…ØªØØ±ÙƒØ©), يجب تكوين " @@ -11534,7 +11349,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11544,7 +11359,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11611,14 +11426,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11695,10 +11517,13 @@ 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!" +"shape resource for it." msgstr "" +"يجب تزويد ال CollisionShape2D Ø¨Ø¥ØØ¯Ù‰ الأشكال (من نوع Shape2D) لتعمل بالشكل " +"المطلوب. الرجاء تكوين Ùˆ ضبط الشكل لها اولا!" #: scene/3d/collision_shape.cpp msgid "" @@ -11726,6 +11551,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11760,8 +11589,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11772,7 +11601,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11787,10 +11618,13 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" +"ليتم إظهار الأطر (اللقطات) ÙÙŠ الAnimatedSprite (النقوش Ø§Ù„Ù…ØªØØ±ÙƒØ©), يجب تكوين " +"مصدر لها من نوع SpriteFrames Ùˆ ضبط خاصية الFrames (الأطر) بها." #: scene/3d/vehicle_body.cpp msgid "" @@ -11799,7 +11633,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11837,7 +11673,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "قطع إتصال'%s' من '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11851,7 +11687,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "شجرة Ø§Ù„ØØ±ÙƒØ© خاطئة." #: scene/animation/animation_tree_player.cpp @@ -11863,7 +11699,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11877,10 +11717,15 @@ msgstr "أض٠اللون Ø§Ù„ØØ§Ù„ÙŠ كإعداد مسبق" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11894,18 +11739,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11948,6 +11793,11 @@ msgid "Input" msgstr "إدخال" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "مصدر غير ØµØ§Ù„Ø Ù„ØªØ¸Ù„ÙŠÙ„." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "مصدر غير ØµØ§Ù„Ø Ù„ØªØ¸Ù„ÙŠÙ„." @@ -11967,6 +11817,38 @@ msgstr "يمكن تعيين المتغيرات Ùقط ÙÙŠ الذروة ." msgid "Constants cannot be modified." msgstr "" +#~ msgid "Generating solution..." +#~ msgstr "إنشاء الØÙ„..." + +#~ msgid "Failed to create solution." +#~ msgstr "لا يمكن إنشاء Ø§Ù„ØØ¯." + +#~ msgid "Failed to save solution." +#~ msgstr "ÙØ´Ù„ ØÙظ الØÙ„." + +#~ msgid "Done" +#~ msgstr "تم" + +#~ msgid "Failed to create C# project." +#~ msgstr "ÙØ´Ù„ إنشاء مشروع C#‎." + +#~ msgid "Create C# solution" +#~ msgstr "إنشاء ØÙ„ C#‎" + +#~ msgid "Build Project" +#~ msgstr "بناء المشروع" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "إظهار Ø§Ù„Ù…Ù„ÙØ§Øª" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Ø¥Ø¨ØØ« ÙÙŠ الأصناÙ" + +#~ msgid "Update Always" +#~ msgstr "ØªØØ¯ÙŠØ« دائماً" + #~ msgid "Path to Node:" #~ msgstr "مسار العقدة:" diff --git a/editor/translations/bg.po b/editor/translations/bg.po index cf26258550..7e37605159 100644 --- a/editor/translations/bg.po +++ b/editor/translations/bg.po @@ -457,6 +457,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Избиране на вÑичко" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Избиране на вÑичко" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -636,6 +646,10 @@ msgstr "Отиди на Ред" msgid "Line Number:" msgstr "Ðомер на Реда:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "ÐÑма СъвпадениÑ" @@ -686,7 +700,7 @@ msgstr "Отдалечи" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -794,6 +808,11 @@ msgid "Connect" msgstr "Свържи" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "ÐаÑтройки на редактора" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Свържи '%s' Ñ '%s'" @@ -956,7 +975,8 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Премахни Ñелектираните файлове от проекта? (необратимо)" #: editor/dependency_editor.cpp @@ -1323,7 +1343,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1497,6 +1517,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1528,7 +1552,7 @@ msgid "Node Dock" msgstr "Режим на ПремеÑтване" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1587,7 +1611,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1602,7 +1626,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Избиране на текущата папка" #: editor/editor_feature_profile.cpp @@ -1625,13 +1649,9 @@ msgid "Export" msgstr "ИзнаÑÑне" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "ТърÑи КлаÑове" +msgid "Available Profiles:" +msgstr "ПоÑтавÑне на възелите" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2681,11 +2701,34 @@ msgid "Editor Layout" msgstr "" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Запазване на Ñцената" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "ÐаÑтройки на редактора" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "Покажи Любими" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "ÐаÑтройки на редактора" @@ -2794,15 +2837,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "ОбновÑвай Винаги" +msgid "Update Continuously" +msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2995,7 +3038,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3094,6 +3137,11 @@ 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 "" @@ -3106,11 +3154,6 @@ msgstr "СтойноÑÑ‚" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3629,6 +3672,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp #, fuzzy msgid "Filter nodes" msgstr "ПоÑтавÑне на възелите" @@ -5302,6 +5346,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "Ðвтоматично РеÑтартиране:" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6224,11 +6276,21 @@ msgid "Find Next" msgstr "Ðамери Ðапред" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 #, fuzzy +msgid "Filter methods" +msgstr "ПоÑтавÑне на възелите" + +#: editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Sort" msgstr "Подреждане:" @@ -6467,20 +6529,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +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 "Изтрий Ред" @@ -8100,51 +8166,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8152,203 +8174,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10025,6 +9871,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "ЗатварÑне на вÑичко" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10056,8 +9907,9 @@ msgid "Delete (No Confirm)" msgstr "МолÑ, потвърдете..." #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Създай нови възли." #: editor/scene_tree_dock.cpp msgid "" @@ -10310,7 +10162,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Грешки" @@ -10735,57 +10587,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "ÐеуÑпешно Ñъздаване на папка." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "Проект" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Преглед на файловете" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11378,8 +11179,9 @@ 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 " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "За да може AnimatedSprite да показва кадри, първо трÑбва да му Ñе даде " @@ -11441,8 +11243,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "ТеÑктура Ñ Ð½ÑƒÐ¶Ð½Ð°Ñ‚Ð° форма на Ñветлината трÑбва да бъде дадена в параметъра " @@ -11456,7 +11259,8 @@ msgstr "" "да работи тази ÑÑнка." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "ЗатъмнÑващиÑÑ‚ многоъгълник е празен. МолÑ, нариÑувайте един." #: scene/2d/navigation_polygon.cpp @@ -11529,14 +11333,25 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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, и Ñ‚.н. за да им дадете форма." + #: scene/2d/visibility_notifier_2d.cpp msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11613,10 +11428,13 @@ 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!" +"shape resource for it." msgstr "" +"За да работи CollisionShape2D, е нужно да му Ñе даде форма. МолÑ, Ñъздайте " +"му Shape2D реÑурÑ." #: scene/3d/collision_shape.cpp msgid "" @@ -11644,6 +11462,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11679,8 +11501,8 @@ msgstr "PathFollow2D работи Ñамо когато е наÑледник н #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11692,7 +11514,9 @@ msgstr "" #: scene/3d/remote_transform.cpp #, fuzzy -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "Параметърът 'Path' трÑбва да Ñочи към дейÑтвителен възел Particles2D, за да " "работи." @@ -11709,10 +11533,13 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" +"За да може AnimatedSprite да показва кадри, първо трÑбва да му Ñе даде " +"SpriteFrames реÑÑƒÑ€Ñ Ð² парамертъра 'Frames'." #: scene/3d/vehicle_body.cpp msgid "" @@ -11721,7 +11548,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11756,7 +11585,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11768,7 +11597,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11780,7 +11609,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11793,10 +11626,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11810,18 +11648,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11864,6 +11702,10 @@ msgid "Input" 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 "" @@ -11883,6 +11725,25 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "ÐеуÑпешно Ñъздаване на папка." + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "Проект" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "Преглед на файловете" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "ТърÑи КлаÑове" + +#~ msgid "Update Always" +#~ msgstr "ОбновÑвай Винаги" + #~ msgid "Delete selected files?" #~ msgstr "Изтрий избраните файлове?" diff --git a/editor/translations/bn.po b/editor/translations/bn.po index 83d7a9b527..00182447f2 100644 --- a/editor/translations/bn.po +++ b/editor/translations/bn.po @@ -474,6 +474,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "সবগà§à¦²à¦¿ বাছাই করà§à¦¨" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "কোনোটাই নিরà§à¦¬à¦¾à¦šà¦¨ করবেন না" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -656,6 +665,10 @@ msgstr "লাইন-ঠযান" msgid "Line Number:" msgstr "লাইন নামà§à¦¬à¦¾à¦°:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "কোনো মিল নেই" @@ -705,7 +718,7 @@ msgstr "সংকà§à¦šà¦¿à¦¤ করà§à¦¨ (জà§à¦®à§ আউট)" msgid "Reset Zoom" msgstr "সমà§à¦ªà§à¦°à¦¸à¦¾à¦°à¦¨/সংকোচন অপসারণ করà§à¦¨ (রিসেট জà§à¦®à§)" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp #, fuzzy msgid "Warnings" msgstr "সতরà§à¦•তা" @@ -819,6 +832,11 @@ msgid "Connect" msgstr "সংযোগ" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "সিগনà§à¦¯à¦¾à¦²à¦¸/সংকেতসমূহ:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "'%s' à¦à¦° সাথে '%s' সংযà§à¦•à§à¦¤ করà§à¦¨" @@ -993,7 +1011,8 @@ msgid "Owners Of:" msgstr "সà§à¦¬à¦¤à§à¦¬à¦¾à¦§à¦¿à¦•ারীসমূহ:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "নিরà§à¦¬à¦¾à¦šà¦¿à¦¤ ফাইলসমূহ পà§à¦°à¦•লà§à¦ª হতে অপসারণ করবেন? (অফেরৎযোগà§à¦¯)" #: editor/dependency_editor.cpp @@ -1375,7 +1394,7 @@ msgstr "" #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" "অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ নাম। নামটি অবশà§à¦¯à¦‡ বিদà§à¦¯à¦®à¦¾à¦¨ পূরà§à¦¬à¦¨à¦¿à¦°à§à¦®à¦¿à¦¤ ধরণের নামের সাথে পরমà§à¦ªà¦°à¦¬à¦¿à¦°à§‡à¦¾à¦§à§€ " "হতে পারবে না।" @@ -1560,6 +1579,10 @@ msgstr "সà§à¦¬à¦¨à¦¿à¦°à§à¦®à¦¿à¦¤ রিলিস (release) পà§à¦¯à¦¾à¦• msgid "Template file not found:" msgstr "টেমপà§à¦²à§‡à¦Ÿ ফাইল পাওয়া যায়নি:\n" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1592,7 +1615,7 @@ msgstr "মোড (Mode) সরান" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "ফাইলসিসà§à¦Ÿà§‡à¦®" #: editor/editor_feature_profile.cpp @@ -1654,7 +1677,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1669,7 +1692,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "বরà§à¦¤à¦®à¦¾à¦¨ দৃশà§à¦¯" #: editor/editor_feature_profile.cpp @@ -1694,16 +1717,11 @@ msgstr "à¦à¦•à§à¦¸à¦ªà§‹à¦°à§à¦Ÿ" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "উপসà§à¦¥à¦¿à¦¤ নোডসমূহ:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "কà§à¦²à¦¾à¦¸à§‡à¦° অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "বরà§à¦£à¦¨à¦¾:" @@ -2849,11 +2867,35 @@ msgid "Editor Layout" msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡à¦° লেআউট/নকশা" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "অরà§à¦¥à¦ªà§‚রà§à¦¨!" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡à¦° সেটিংস" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡ খà§à¦²à§à¦¨" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "পূরà§à¦£-পরà§à¦¦à¦¾ অদলবদল/টগল করà§à¦¨" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "CanvasItem দৃশà§à¦¯à¦®à¦¾à¦¨à¦¤à¦¾ টগল করà§à¦¨" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡à¦° সেটিংস" @@ -2966,15 +3008,18 @@ msgid "Spins when the editor window redraws." msgstr "à¦à¦¡à¦¿à¦Ÿà¦°à§‡à¦° পà§à¦¨-অঙà§à¦•নে à¦à¦Ÿà¦¿ ঘূরà§à¦£à¦¨ করে!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "সরà§à¦¬à¦¦à¦¾ হাল-নাগাদ করà§à¦¨" +#, fuzzy +msgid "Update Continuously" +msgstr "অবিচà§à¦›à¦¿à¦¨à§à¦¨/নিরবচà§à¦›à¦¿à¦¨à§à¦¨" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "পরিবরà§à¦¤à¦¨à¦¸à¦®à§‚হ হাল-নাগাদ করà§à¦¨" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "হাল-নাগাদকারী ঘূরà§à¦£à¦• নিষà§à¦•à§à¦°à¦¿à§Ÿ করà§à¦¨" #: editor/editor_node.cpp @@ -3180,7 +3225,7 @@ msgstr "সময়:" msgid "Calls" msgstr "ডাকà§à¦¨ (Call)" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "চালà§" @@ -3288,6 +3333,11 @@ 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 #, fuzzy msgid "New Key:" msgstr "নতà§à¦¨ নাম:" @@ -3301,11 +3351,6 @@ msgstr "নতà§à¦¨ নাম:" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "বসà§à¦¤à§ অপসারণ করà§à¦¨" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3589,7 +3634,7 @@ msgstr "ফেবরিট/পà§à¦°à¦¿à¦¯à¦¼-সমূহ:" #: editor/filesystem_dock.cpp msgid "Cannot navigate to '%s' as it has not been found in the file system!" -msgstr "'% s' তে নেà¦à¦¿à¦—েট করা যাবে না কারণ à¦à¦Ÿà¦¿ ফাইল সিসà§à¦Ÿà§‡à¦®à§‡ পাওয়া যায়নি!" +msgstr "'%s' তে নেà¦à¦¿à¦—েট করা যাবে না কারণ à¦à¦Ÿà¦¿ ফাইল সিসà§à¦Ÿà§‡à¦®à§‡ পাওয়া যায়নি!" #: editor/filesystem_dock.cpp #, fuzzy @@ -3872,6 +3917,7 @@ msgid "Nodes not in Group" msgstr "গà§à¦°à§à¦ª/দলে যোগ করà§à¦¨" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp #, fuzzy msgid "Filter nodes" msgstr "ফিলà§à¦Ÿà¦¾à¦°à¦¸à¦®à§‚হ" @@ -3978,11 +4024,11 @@ msgstr "সংরকà§à¦·à¦¿à¦¤ হচà§à¦›à§‡..." #: editor/import_dock.cpp msgid "Set as Default for '%s'" -msgstr "'% s' à¦à¦° জনà§à¦¯ ডিফলà§à¦Ÿ হিসাবে সেট করà§à¦¨" +msgstr "'%s' à¦à¦° জনà§à¦¯ ডিফলà§à¦Ÿ হিসাবে সেট করà§à¦¨" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "'% s' à¦à¦° জনà§à¦¯ ডিফলà§à¦Ÿ কà§à¦²à¦¿à§Ÿà¦¾à¦° করà§à¦¨" +msgstr "'%s' à¦à¦° জনà§à¦¯ ডিফলà§à¦Ÿ কà§à¦²à¦¿à§Ÿà¦¾à¦° করà§à¦¨" #: editor/import_dock.cpp #, fuzzy @@ -5600,6 +5646,14 @@ msgid "Load Emission Mask" msgstr "Emission Mask লোড করà§à¦¨" #: 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 +#, fuzzy +msgid "Restart" +msgstr "পà§à¦¨à¦°à¦¾à¦°à¦®à§à¦ (সেঃ):" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Emission Mask পরিসà§à¦•ার করà§à¦¨" @@ -6578,11 +6632,21 @@ msgid "Find Next" msgstr "পরবরà§à¦¤à§€ খà§à¦à¦œà§à¦¨" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 #, fuzzy +msgid "Filter methods" +msgstr "ফিলà§à¦Ÿà¦¾à¦°à¦¸à¦®à§‚হ" + +#: editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Sort" msgstr "সাজান:" @@ -6829,20 +6893,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +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 #, fuzzy msgid "Delete Line" @@ -8403,7 +8471,7 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy msgid "Set Input Default Port" -msgstr "'% s' à¦à¦° জনà§à¦¯ ডিফলà§à¦Ÿ হিসাবে সেট করà§à¦¨" +msgstr "'%s' à¦à¦° জনà§à¦¯ ডিফলà§à¦Ÿ হিসাবে সেট করà§à¦¨" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8537,51 +8605,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8590,203 +8614,27 @@ msgid "Input parameter." msgstr "ধারক/বাহক পরà§à¦¯à¦¨à§à¦¤ বিসà§à¦¤à§ƒà¦¤ করà§à¦¨" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9973,7 +9821,7 @@ msgstr "পà§à¦°à¦ªà¦¾à¦°à§à¦Ÿà¦¿:" #: editor/project_settings_editor.cpp msgid "Setting '%s' is internal, and it can't be deleted." -msgstr "'% s' সেটিংটি অà¦à§à¦¯à¦¨à§à¦¤à¦°à§€à¦£, à¦à¦¬à¦‚ à¦à¦Ÿà¦¿ মোছা যাবে না।" +msgstr "'%s' সেটিংটি অà¦à§à¦¯à¦¨à§à¦¤à¦°à§€à¦£, à¦à¦¬à¦‚ à¦à¦Ÿà¦¿ মোছা যাবে না।" #: editor/project_settings_editor.cpp #, fuzzy @@ -10540,6 +10388,11 @@ msgid "Add Child Node" msgstr "শীষà§à¦¯ নোড তৈরি করà§à¦¨" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "কলাপà§à¦¸ করà§à¦¨" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "ধরণ পরিবরà§à¦¤à¦¨ করà§à¦¨" @@ -10571,7 +10424,8 @@ msgid "Delete (No Confirm)" msgstr "অপসারণ করà§à¦¨ (নিশà§à¦šà§Ÿà¦¤à¦¾à¦•রণ নেই)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "অপসারণ করà§à¦¨ (নিশà§à¦šà§Ÿà¦¤à¦¾à¦•রণ নেই)" #: editor/scene_tree_dock.cpp @@ -10855,7 +10709,7 @@ msgstr "ফà§à¦°à§‡à¦®à¦¸à¦®à§‚হ সà§à¦¤à§‚প করà§à¦¨" msgid "Pick one or more items from the list to display the graph." msgstr "গà§à¦°à¦¾à¦« পà§à¦°à¦¦à¦°à§à¦¶à¦¨ করতে তালিকা থেকে à¦à¦• বা à¦à¦•াধিক আইটেম বাছাই করà§à¦¨à¥¤" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "সমসà§à¦¯à¦¾à¦¸à¦®à§‚হ" @@ -11291,62 +11145,6 @@ msgstr "ইনà§à¦¸à¦Ÿà§à¦¯à¦¾à¦¨à§à¦¸:" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Generating solution..." -msgstr "ওকটà§à¦°à§€ (octree) গঠনবিনà§à¦¯à¦¾à¦¸ তৈরি করা হচà§à¦›à§‡" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "পà§à¦°à¦¾à¦¨à§à¦¤à¦°à§‡à¦–া তৈরি করা সমà§à¦à¦¬ হয়নি!" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to save solution." -msgstr "রিসোরà§à¦¸ লোড বà§à¦¯à¦°à§à¦¥ হয়েছে।" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Done" -msgstr "সমà§à¦ªà¦¨à§à¦¨ হয়েছে!" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create C# project." -msgstr "রিসোরà§à¦¸ লোড বà§à¦¯à¦°à§à¦¥ হয়েছে।" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "মনো" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "পà§à¦°à¦¾à¦¨à§à¦¤à¦°à§‡à¦–া তৈরি করà§à¦¨" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "নতà§à¦¨ পà§à¦°à¦•লà§à¦ª" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "ফাইল" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11980,8 +11778,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "সà§à¦ªà§à¦²à§à¦¯à¦¾à¦¶ পরà§à¦¦à¦¾à¦° (splash screen) ছবির অগà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯ মাতà§à¦°à¦¾ (৬২০x৩০০ হতে হবে)।" #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "AnimatedSprite দà§à¦¬à¦¾à¦°à¦¾ ফà§à¦°à§‡à¦® দেখাতে SpriteFrames রিসোরà§à¦¸ অবশà§à¦¯à¦‡ তৈরি করতে হবে " @@ -12041,8 +11840,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "অবশà§à¦¯à¦‡ লাইটের আকৃতি সহ à¦à¦•টি গঠন 'texture' à¦à¦° বৈশিষà§à¦Ÿà§à¦¯à§‡ হিসেবে পà§à¦°à¦¦à¦¾à¦¨ করতে হবে।" @@ -12054,7 +11854,8 @@ msgstr "" "Occluder à¦à¦° পà§à¦°à¦à¦¾à¦¬ ফেলতে à¦à¦•টি occluder বহà§à¦à§à¦œ নিরà§à¦§à¦¾à¦°à¦£ করা (বা, আà¦à¦•া) আবশà§à¦¯à¦•।" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "à¦à¦‡ occluder à¦à¦° জনà§à¦¯ occluder পলিগনটি খালি। অনà§à¦—à§à¦°à¦¹ করে à¦à¦•টি পলিগন আà¦à¦•à§à¦¨!" #: scene/2d/navigation_polygon.cpp @@ -12126,16 +11927,28 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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, ইতà§à¦¯à¦¾à¦¦à¦¿à¦•ে আকার দিতে " +"অনà§à¦—à§à¦°à¦¹ করে তা শà§à¦§à§à¦®à¦¾à¦¤à§à¦° তাদের অংশ হিসেবে বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨à¥¤" + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D সরà§à¦¬à§‹à¦¤à§à¦¤à¦® কারà§à¦¯à¦•র হয় যখন সমà§à¦ªà¦¾à¦¦à¦¿à¦¤ দৃশà§à¦¯ মূল দৃশà§à¦¯ হিসেবে সরাসরি " "বà§à¦¯à¦¬à¦¹à§ƒà¦¤ হয়।" #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -12221,9 +12034,10 @@ msgstr "" "শà§à¦§à§à¦®à¦¾à¦¤à§à¦° তাদের অংশ হিসেবে বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨à¥¤" #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "সফলà§à¦à¦¾à¦¬à§‡ কাজ করতে CollisionShape à¦à¦° à¦à¦•টি আকৃতি পà§à¦°à§Ÿà§‹à¦œà¦¨à¥¤ অনà§à¦—à§à¦°à¦¹ করে তার জনà§à¦¯ à¦à¦•টি " "আকৃতি তৈরি করà§à¦¨!" @@ -12255,6 +12069,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -12294,8 +12112,8 @@ msgstr "PathFollow2D à¦à¦•মাতà§à¦° Path2D à¦à¦° অংশ হিসেà #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -12306,7 +12124,10 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "Path à¦à¦° দিক অবশà§à¦¯à¦‡ à¦à¦•টি কারà§à¦¯à¦•র Spatial নোডের à¦à¦° দিকে নিরà§à¦¦à§‡à¦¶ করাতে হবে।" #: scene/3d/soft_body.cpp @@ -12321,8 +12142,9 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "AnimatedSprite3D দà§à¦¬à¦¾à¦°à¦¾ ফà§à¦°à§‡à¦® দেখাতে SpriteFrames রিসোরà§à¦¸ অবশà§à¦¯à¦‡ তৈরি করতে হবে " @@ -12335,7 +12157,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -12375,7 +12199,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "'%s' à¦à¦° সাথে '%s' সংযà§à¦•à§à¦¤ করà§à¦¨" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -12390,7 +12214,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "অà§à¦¯à¦¾à¦¨à¦¿à¦®à§‡à¦¶à¦¨à§‡à¦° তালিকাটি অকারà§à¦¯à¦•র।" #: scene/animation/animation_tree_player.cpp @@ -12402,9 +12226,12 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -#, fuzzy -msgid "Raw Mode" -msgstr "পà§à¦¯à¦¾à¦¨ মোড" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -12416,10 +12243,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -12431,23 +12263,24 @@ msgid "Please Confirm..." msgstr "অনà§à¦—à§à¦°à¦¹ করে নিশà§à¦šà¦¿à¦¤ করà§à¦¨..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "সাধারণত popups লà§à¦•িয়ে যাবে, যদি আপনি popup() বা popup*() à¦à¦° যেকোনো ফাংশন " "বà§à¦¯à¦¬à¦¹à¦¾à¦° না করেন। যদিও সমà§à¦ªà¦¾à¦¦à¦¨à§‡à¦° কাজে তা গà§à¦°à¦¹à¦¨à¦¯à§‹à¦—à§à¦¯, কিনà§à¦¤à§ চালনার সময় তা লà§à¦•িয়ে " "যাবে।" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -12496,6 +12329,11 @@ msgstr "ইনপà§à¦Ÿ যোগ করà§à¦¨" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "অকারà§à¦¯à¦•র উৎস!" + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "অকারà§à¦¯à¦•র উৎস!" @@ -12515,6 +12353,52 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Generating solution..." +#~ msgstr "ওকটà§à¦°à§€ (octree) গঠনবিনà§à¦¯à¦¾à¦¸ তৈরি করা হচà§à¦›à§‡" + +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "পà§à¦°à¦¾à¦¨à§à¦¤à¦°à§‡à¦–া তৈরি করা সমà§à¦à¦¬ হয়নি!" + +#, fuzzy +#~ msgid "Failed to save solution." +#~ msgstr "রিসোরà§à¦¸ লোড বà§à¦¯à¦°à§à¦¥ হয়েছে।" + +#, fuzzy +#~ msgid "Done" +#~ msgstr "সমà§à¦ªà¦¨à§à¦¨ হয়েছে!" + +#, fuzzy +#~ msgid "Failed to create C# project." +#~ msgstr "রিসোরà§à¦¸ লোড বà§à¦¯à¦°à§à¦¥ হয়েছে।" + +#~ msgid "Mono" +#~ msgstr "মনো" + +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "পà§à¦°à¦¾à¦¨à§à¦¤à¦°à§‡à¦–া তৈরি করà§à¦¨" + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "নতà§à¦¨ পà§à¦°à¦•লà§à¦ª" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "ফাইল" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "কà§à¦²à¦¾à¦¸à§‡à¦° অনà§à¦¸à¦¨à§à¦§à¦¾à¦¨ করà§à¦¨" + +#~ msgid "Update Always" +#~ msgstr "সরà§à¦¬à¦¦à¦¾ হাল-নাগাদ করà§à¦¨" + +#, fuzzy +#~ msgid "Raw Mode" +#~ msgstr "পà§à¦¯à¦¾à¦¨ মোড" + #~ msgid "Path to Node:" #~ msgstr "নোডের পথ:" @@ -13085,9 +12969,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Spatial দৃশà§à¦¯à¦®à¦¾à¦¨à¦¤à¦¾ টগল করà§à¦¨" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "CanvasItem দৃশà§à¦¯à¦®à¦¾à¦¨à¦¤à¦¾ টগল করà§à¦¨" - #~ msgid "Condition" #~ msgstr "শরà§à¦¤ (Condition)" @@ -14013,9 +13894,6 @@ msgstr "" #~ msgid "Images:" #~ msgstr "ছবিসমূহ:" -#~ msgid "Select None" -#~ msgstr "কোনোটাই নিরà§à¦¬à¦¾à¦šà¦¨ করবেন না" - #~ msgid "Group" #~ msgstr "গà§à¦°à§à¦ª" diff --git a/editor/translations/ca.po b/editor/translations/ca.po index f8c7ccaf76..4f12d5f02e 100644 --- a/editor/translations/ca.po +++ b/editor/translations/ca.po @@ -12,7 +12,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" +"PO-Revision-Date: 2019-07-09 10:46+0000\n" "Last-Translator: roger <616steam@gmail.com>\n" "Language-Team: Catalan <https://hosted.weblate.org/projects/godot-engine/" "godot/ca/>\n" @@ -21,7 +21,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -80,9 +80,8 @@ msgid "Time:" msgstr "Temps:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Valor" +msgstr "Valor:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -333,9 +332,8 @@ msgid "Anim Insert Key" msgstr "Insereix una Clau" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Step" -msgstr "Modifica els FPS de l'Animació" +msgstr "Canviar Pas d'Animació" #: editor/animation_track_editor.cpp msgid "Rearrange Tracks" @@ -442,7 +440,17 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Advertiment: Edició d'animació importada" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Selecciona-ho Tot" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Selecciona un Node" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -453,9 +461,8 @@ msgid "Group tracks by node or display them as plain list." msgstr "Agrupa les pistes per node o mostra-les en una llista." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Snap:" -msgstr "Alinear:" +msgstr "Ajustar:" #: editor/animation_track_editor.cpp msgid "Animation step value." @@ -619,6 +626,10 @@ msgstr "Vés a la LÃnia" msgid "Line Number:" msgstr "LÃnia:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Cap Coincidència" @@ -668,7 +679,7 @@ msgstr "Allunya" msgid "Reset Zoom" msgstr "Reinicia el Zoom" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Avisos" @@ -677,38 +688,32 @@ msgid "Line and column numbers." msgstr "Números de lÃnia i columna." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Cal especificar un mètode per al Node objectiu!" +msgstr "S'ha d'especificar el mètode al node de destinació." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"El mètode objectiu no s'ha trobat! Especifiqueu un mètode và lid o adjunteu-" -"li un Script." +"El mètode objectiu no s'ha trobat. Especifiqueu un mètode và lid o adjunteu-" +"li un script." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "Connecta al Node:" +msgstr "Connectar al Node:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "No es pot connectar a l'amfitrió:" +msgstr "Connectar al Script:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Senyals:" +msgstr "Des del Senyal:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "El Node no conté cap geometria." +msgstr "L'escena no conté cap script." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -736,9 +741,8 @@ msgid "Extra Call Arguments:" msgstr "Arguments de Crida addicionals:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Opcions Avançades" +msgstr "Avançat" #: editor/connections_dialog.cpp msgid "Deferred" @@ -748,6 +752,8 @@ msgstr "Diferit" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Difereix el senyal, emmagatzemant-lo en una cua i només disparant-lo en " +"temps d'inactivitat." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -755,12 +761,11 @@ msgstr "Un sol cop" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Desconnecta el senyal després de la seva primera emissió." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Connecta el Senyal: " +msgstr "No es pot connectar el senyal" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -781,6 +786,11 @@ msgid "Connect" msgstr "Connecta" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Senyals:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Connecta '%s' amb '%s'" @@ -802,14 +812,12 @@ msgid "Disconnect" msgstr "Desconnecta" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Connecta el Senyal: " +msgstr "Connectar un Senyal a un Mètode" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Edita la Connexió: " +msgstr "Editar Connexió:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -886,22 +894,20 @@ msgid "Dependencies For:" msgstr "Dependències per a:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" "S'està editant l'Escena '%s'.\n" -"Els canvis s'actualitzaran recarregar." +"Els canvis només tindran efecte quan es recarregui." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" "S'està usant el Recurs '%s'.\n" -"Els canvis s'actualitzaran en recarregar." +"Els canvis només tindran efecte quan es recarregui." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -948,7 +954,8 @@ msgid "Owners Of:" msgstr "Propietaris de:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" "Voleu Eliminar els fitxers seleccionats del projecte? (No es pot desfer!)" @@ -994,9 +1001,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Voleu Eliminar permanentment %d element(s)? (No es pot desfer!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "Dependències" +msgstr "Mostrar Dependències" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1259,7 +1265,7 @@ msgstr "Obre un Disseny de Bus d'Àudio" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "No hi ha cap fitxer '%s'." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1318,13 +1324,11 @@ msgstr "Carà cters và lids:" #: editor/editor_autoload_settings.cpp #, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"El Nom no és và lid. No pot coincidir amb noms de classe del motor ja " -"existents." +msgstr "No pot coincidir amb noms de classe del motor ja existents." #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" "El Nom no és và lid. No pot coincidir amb noms de tipus integrats ja " "existents." @@ -1337,8 +1341,9 @@ msgstr "" "existents." #: editor/editor_autoload_settings.cpp +#, fuzzy msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "Una paraula clau no es pot utilitzar com a nom de cà rrega automà tica." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1369,7 +1374,6 @@ msgid "Rearrange Autoloads" msgstr "Reorganitza AutoCà rregues" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "Camà no và lid." @@ -1424,9 +1428,8 @@ msgid "[unsaved]" msgstr "[no desat]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Elegiu primer un directori base" +msgstr "Si us plau seleccioneu un directori base primer." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1506,25 +1509,25 @@ msgstr "No s'ha trobat cap plantilla de publicació personalitzada." msgid "Template file not found:" msgstr "No s'ha trobat la Plantilla:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Editor" +msgstr "Editor 3D" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Editor d'Scripts" +msgstr "Editor de scripts" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Exportar Biblioteca de Recursos" +msgstr "Biblioteca d'Actius" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Arbre d'Escenes (Nodes):" +msgstr "Edició de l'arbre d'escenes" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1538,90 +1541,81 @@ msgstr "Node mogut" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "Sistema de Fitxers" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Reemplaça-ho Tot (no es pot desfer)" +msgstr "Esborra el perfil '%s'? (no es pot desfer)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "El perfil ha de ser un nom de fitxer và lid i no ha de contenir \".\"" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Ja existeix un Fitxer o Directori amb aquest nom." +msgstr "Ja existeix un perfil amb aquest nom." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Editor Desactivat, Propietats Desactivades)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Només Propietats" +msgstr "(Propietats Desactivades)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Clip Desactivat" +msgstr "(Editor Desactivat)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Descripció de la classe:" +msgstr "Opcions de Classe:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Obre l'Editor Següent" +msgstr "Habilitar l'Editor Contextual" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Propietats:" +msgstr "Propietats Habilitades:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "CaracterÃstiques" +msgstr "CaracterÃstiques Habilitades:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Cerca Classes" +msgstr "Classes Habilitades:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "El format del fitxer '%s' no és và lid, s'ha anul·lat la importació." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"El perfil '%s' ja existeix. Elimineu-lo primer abans d'importar, importació " +"avortada." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Error en carregar la plantilla '%s'" +msgstr "Error en guardar el perfil al camÃ: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Desactivar" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Current Profile" -msgstr "Versió Actual:" +msgid "Current Profile:" +msgstr "Perfil Actual:" #: editor/editor_feature_profile.cpp #, fuzzy msgid "Make Current" -msgstr "Actual:" +msgstr "Fer Actual" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1636,47 +1630,35 @@ msgstr "Importa" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_export.cpp msgid "Export" -msgstr "Exporta" +msgstr "Exportar" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Available Profiles" -msgstr "Nodes disponibles:" +msgid "Available Profiles:" +msgstr "Perfils Disponibles:" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Cerca Classes" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Descripció de la classe" +msgstr "Opcions de Classe" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Nou nom:" +msgstr "Nom del nou perfil:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Esborra l'Àrea" +msgstr "Esborrar Perfil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Project importat" +msgstr "Importar Perfil(s)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Exporta Projecte" +msgstr "Exportar Perfil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "Gestor de Plantilles d'Exportació" +msgstr "Administra els Perfils de CaracterÃstiques de l'Editor" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1791,18 +1773,16 @@ msgid "Next Folder" msgstr "Directori Següent" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Go to parent folder." -msgstr "Vés al directori principal" +msgstr "Anar al directori pare." #: editor/editor_file_dialog.cpp msgid "(Un)favorite current folder." msgstr "Eliminar carpeta actual de preferits." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Commuta Fitxers Ocults" +msgstr "Commutar visibilitat dels fitxers ocults." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1839,6 +1819,8 @@ msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"Hi ha diversos importadors per a diferents tipus apuntant a l'arxiu %s, s'ha " +"avortat la importació" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2013,7 +1995,7 @@ msgstr "Propietat:" #: editor/editor_inspector.cpp msgid "Set" -msgstr "Estableix" +msgstr "Establir" #: editor/editor_inspector.cpp msgid "Set Multiple:" @@ -2100,7 +2082,7 @@ msgstr "Falta '%s' o les seves dependències." #: editor/editor_node.cpp msgid "Error while loading '%s'." -msgstr "S'ha produït un error en carregar '% s'." +msgstr "S'ha produït un error en carregar '%s'." #: editor/editor_node.cpp msgid "Saving Scene" @@ -2178,13 +2160,12 @@ msgstr "" "Referiu-vos a la documentació rellevant sobre la importació d'escenes." #: editor/editor_node.cpp -#, fuzzy 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 "" -"Aquest recurs pertany a una escena instanciada o heretada.\n" -"Els canvis efectuats no es conservaran en desar l'escena." +"Aquest recurs pertany a una escena que va ser instanciada o heretada.\n" +"Els canvis efectuats no es conservaran en desar l'escena actual." #: editor/editor_node.cpp msgid "" @@ -2239,9 +2220,8 @@ msgid "Open Base Scene" msgstr "Obre una Escena Base" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Obertura Rà pida d'Escenes..." +msgstr "Obertura Rà pida..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2373,32 +2353,31 @@ msgstr "" msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." msgstr "" "No s'ha pogut trobar el camp d'Script per al complement a: 'res: // addons /" -"% s'." +"%s'." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." msgstr "Error carregant l'Script complement des del camÃ: '%s'." #: editor/editor_node.cpp -#, fuzzy msgid "" "Unable to load addon script from path: '%s' There seems to be an error in " "the code, please check the syntax." msgstr "" -"No s'ha carregat l'Script d'addon des del camÃ: L'Script '% s' no és en el " -"mode d'Eina." +"No es pot carregar el script d'addon des del camÃ: '%s' Sembla que hi ha un " +"error en el codi, si us plau comproveu la sintaxi." #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' Base type is not EditorPlugin." msgstr "" -"No es pot carregar l'Script complementari: El tipus base de '% s' no és pas " +"No es pot carregar l'Script complementari: El tipus base de '%s' no és pas " "EditorPlugin." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s' Script is not in tool mode." msgstr "" -"No s'ha carregat l'Script d'addon des del camÃ: L'Script '% s' no és en el " +"No s'ha carregat l'Script d'addon des del camÃ: L'Script '%s' no és en el " "mode d'Eina." #: editor/editor_node.cpp @@ -2488,12 +2467,11 @@ msgstr "Tanca les altres pestanyes" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Tancar les Pestanyes a la Dreta" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Tanca-ho Tot" +msgstr "Tancar Totes les Pestanyes" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2627,7 +2605,7 @@ msgstr "Obre el directori de Dades del Projecte" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Instal·lar plantilla de compilació d'Android" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2640,7 +2618,7 @@ msgstr "Depurar" #: editor/editor_node.cpp msgid "Deploy with Remote Debug" -msgstr "Desplega amb Depuració Remota" +msgstr "Desplegar amb Depuració Remota" #: editor/editor_node.cpp msgid "" @@ -2696,7 +2674,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Sync Scene Changes" -msgstr "Sincronitza Canvis en Escenes" +msgstr "Sincronitzar Canvis en Escena" #: editor/editor_node.cpp msgid "" @@ -2712,7 +2690,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Sync Script Changes" -msgstr "Sincronitza Canvis en Scripts" +msgstr "Sincronitzar Canvis en Scripts" #: editor/editor_node.cpp msgid "" @@ -2739,10 +2717,32 @@ msgid "Editor Layout" msgstr "Disseny de l'Editor" #: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "Fer captura de pantalla" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "" +"Les captures de pantalla s'emmagatzemen a la carpeta dades/configuració de " +"l'editor." + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "Obrir automà ticament captures de pantalla" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "Obrir en un editor d'imatges extern." + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Mode Pantalla Completa" #: editor/editor_node.cpp +msgid "Toggle System Console" +msgstr "Commutar la consola del sistema" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Obre el directori de Dades/Configuració de l'Editor" @@ -2755,9 +2755,8 @@ msgid "Open Editor Settings Folder" msgstr "Obre el directori de Configuració de l'Editor" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "Gestor de Plantilles d'Exportació" +msgstr "Administrar CaracterÃstiques de l'Editor" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2850,15 +2849,16 @@ msgid "Spins when the editor window redraws." msgstr "Gira quan la finestra de l'editor es redibuixa." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Actualitza Sempre" +msgid "Update Continuously" +msgstr "Actualitzar contÃnuament" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "Actualitza Canvis" +msgid "Update When Changed" +msgstr "Actualitzar quan es canvia" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Desactiva l'Indicador d'Actualització" #: editor/editor_node.cpp @@ -2888,11 +2888,12 @@ msgstr "No Desis" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." msgstr "" +"Falta la plantilla de construcció d'Android, si us plau instal·leu " +"plantilles pertinents." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Gestor de Plantilles d'Exportació" +msgstr "Administrar Plantilles" #: editor/editor_node.cpp msgid "" @@ -2901,11 +2902,16 @@ msgid "" msgstr "" #: editor/editor_node.cpp +#, fuzzy msgid "" "Android build template is already installed and it won't be overwritten.\n" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"La plantilla de compilació d'Android ja està instal·lada i no se " +"sobreescriurà .\n" +"Elimineu el directori \"Build\" manualment abans de tornar a intentar " +"aquesta operació." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3049,7 +3055,7 @@ msgstr "Temps" msgid "Calls" msgstr "Crides" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Activat" @@ -3149,6 +3155,11 @@ msgid "Page: " msgstr "Pà gina: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Elimina Element" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Nova Clau:" @@ -3160,11 +3171,6 @@ msgstr "Nou Valor:" msgid "Add Key/Value Pair" msgstr "Afegeix una Parella de Clau/Valor" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Elimina Element" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3371,9 +3377,8 @@ msgid "SSL Handshake Error" msgstr "Error en la conformitat de la connexió SSL" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "Descomprimint Recursos" +msgstr "Descomprimint les Fonts de Compilació d'Android" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3392,9 +3397,8 @@ msgid "Remove Template" msgstr "Elimina la Plantilla" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" -msgstr "Selecciona fitxer de plantilla" +msgstr "Seleccioneu un Fitxer de Plantilla" #: editor/export_template_manager.cpp msgid "Export Template Manager" @@ -3451,9 +3455,8 @@ msgid "No name provided." msgstr "Manca Nom." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "El nom conté carà cters que no són và lids" +msgstr "El nom proporcionat conté carà cters invà lids." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3480,28 +3483,24 @@ msgid "Duplicating folder:" msgstr "S'està duplicant el directori:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Nova Escena heretada..." +msgstr "Nova Escena Heretada" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Obre una Escena" +msgstr "Obrir Escenes" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Instà ncia" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" -msgstr "Afegir a preferits" +msgstr "Afegir a Preferits" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "Eliminar dels preferits" +msgstr "Eliminar de Preferits" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." @@ -3549,23 +3548,20 @@ msgid "Rename" msgstr "Reanomena" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Directori Anterior" +msgstr "Carpeta/Fitxer Anterior" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Directori Següent" +msgstr "Carpeta/Fitxer Següent" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "ReAnalitza Sistema de Fitxers" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" -msgstr "Commutar mode dividit" +msgstr "Commutar Mode Dividit" #: editor/filesystem_dock.cpp msgid "Search files" @@ -3614,6 +3610,8 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Inclou els fitxers amb les extensions següents. Afegiu-les o suprimiu-les a " +"la configuració del projecte." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3665,6 +3663,7 @@ msgid "Nodes not in Group" msgstr "Els nodes no es troben en el Grup" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtre els Nodes" @@ -4037,7 +4036,7 @@ msgstr "Selecciona i mou els punts, crea punts fent clic dret." #: 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 "Habilitar ajustament i mostrar quadrÃcula." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4052,9 +4051,8 @@ msgid "Open Animation Node" msgstr "Obre un Node d'Animació" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "El triangle ja existeix" +msgstr "El triangle ja existeix." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4085,9 +4083,8 @@ msgid "No triangles exist, so no blending can take place." msgstr "En no haver-hi cap triangle, no es pot mesclar res." #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Toggle Auto Triangles" -msgstr "Commuta les Globals d'AutoCà rrega" +msgstr "Commutar Auto Triangles" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Create triangles by connecting points." @@ -4158,9 +4155,8 @@ msgid "Delete Node(s)" msgstr "Elimina els Nodes" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Toggle Filter On/Off" -msgstr "Activa/Desactiva la Pista." +msgstr "Commutar Filtre On/Off" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Change Filter" @@ -4173,8 +4169,11 @@ msgstr "" "els noms de les pistes." #: editor/plugins/animation_blend_tree_editor_plugin.cpp +#, fuzzy msgid "Player path set is invalid, so unable to retrieve track names." msgstr "" +"El camà del reproductor assignat no és và lid, de manera que no pot recuperar " +"els noms de les pistes." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/root_motion_editor_plugin.cpp @@ -4182,6 +4181,8 @@ msgid "" "Animation player has no valid root node path, so unable to retrieve track " "names." msgstr "" +"El reproductor d'animació no té cap camà và lid per al node arrel, de manera " +"que no es poden recuperar els noms de les pistes." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp @@ -4199,9 +4200,8 @@ msgid "Edit Filtered Tracks:" msgstr "Editar Pistes Filtrades:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" -msgstr "Habilitar filtració" +msgstr "Habilitar Filtració" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" @@ -4336,9 +4336,8 @@ msgid "Enable Onion Skinning" msgstr "Activa l'Efecte Paper Ceba" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "Efecte Paper Ceba" +msgstr "Opcions Paper Ceba" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4383,7 +4382,7 @@ msgstr "Inclou Gizmos (3D)" #: editor/plugins/animation_player_editor_plugin.cpp #, fuzzy msgid "Pin AnimationPlayer" -msgstr "Enganxa l'Animació" +msgstr "Fixar AnimationPlayer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" @@ -4489,8 +4488,11 @@ msgid "Remove selected node or transition." msgstr "Eliminar el node o transició seleccionats." #: editor/plugins/animation_state_machine_editor.cpp +#, fuzzy msgid "Toggle autoplay this animation on start, restart or seek to zero." msgstr "" +"Commuta auto reproducció d'aquesta animació en iniciar, reiniciar o buscar a " +"zero." #: editor/plugins/animation_state_machine_editor.cpp #, fuzzy @@ -4819,7 +4821,7 @@ msgstr "Previsualització" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" -msgstr "Configura l'Alineament" +msgstr "Configurar Ajustament" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Grid Offset:" @@ -4866,9 +4868,8 @@ msgid "Create new horizontal and vertical guides" msgstr "Crea una guia horitzontal i vertical noves" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move pivot" -msgstr "Mou el Pivot" +msgstr "Moure pivot" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -4930,7 +4931,7 @@ msgstr "Modifica Ancoratges" #: editor/plugins/spatial_editor_plugin.cpp #, fuzzy msgid "Lock Selected" -msgstr "Selecciona una Eina" +msgstr "Bloca el Seleccionat" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -4940,24 +4941,21 @@ msgstr "Elimina Seleccionats" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Copiar Selecció" +msgstr "Agrupar Seleccionat" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Copiar Selecció" +msgstr "Desagrupar Seleccionat" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" msgstr "Enganxa Positura" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" -msgstr "Crea Punts d'Emissió des d'una Malla" +msgstr "Crea Os(sos) Personalitzat(s) a partir de Node(s)" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -4973,7 +4971,6 @@ msgid "Clear IK Chain" msgstr "Esborra la cadena CI" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "" "Warning: Children of a container get their position and size determined only " "by their parent." @@ -5039,75 +5036,70 @@ msgid "Pan Mode" msgstr "Mode d'Escombratge lateral" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Toggle snapping." -msgstr "Activa/Desactiva Alineament" +msgstr "Commutar Ajustament." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Snap" -msgstr "Alinea" +msgstr "Utilitzar Ajustament" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snapping Options" -msgstr "Opcions d'Alineament" +msgstr "Opcions d'Ajustament" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" -msgstr "Alinea-ho amb la graella" +msgstr "Ajustar a la QuadrÃcula" #: editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "Use Rotation Snap" -msgstr "Rotació alineada" +msgstr "Utilitzar Ajustament de Rotació" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Configure Snap..." -msgstr "Configura l'Alineament..." +msgstr "Configurar Ajustament..." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap Relative" -msgstr "Alineament Relatiu" +msgstr "Ajustament Relatiu" #: editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "Use Pixel Snap" -msgstr "Alinea-ho amb els Pixels" +msgstr "Utilitzar Ajustament amb els PÃxels" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" -msgstr "Alineament intel·ligent" +msgstr "Ajustament Intel·ligent" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" -msgstr "Alinea-ho amb el Pare" +msgstr "Ajustar al Pare" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy msgid "Snap to Node Anchor" -msgstr "Alinea-ho amb el node d'ancoratge" +msgstr "Ajustar a l'Àncora del Node" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy msgid "Snap to Node Sides" -msgstr "Alinea-ho amb els costats del node" +msgstr "Ajustar als costats del node" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" -msgstr "Alinea-ho amb el node d'ancoratge" +msgstr "Ajustar al centre del node" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy msgid "Snap to Other Nodes" -msgstr "Alinea-ho amb altres nodes" +msgstr "Ajustar als altres nodes" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" -msgstr "Alinea-ho amb les guies" +msgstr "Ajustar amb les guies" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5138,8 +5130,9 @@ msgid "Show Bones" msgstr "Mostra els Ossos" #: editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "Make Custom Bone(s) from Node(s)" -msgstr "" +msgstr "Fer os(sos) personalitzat(s) a partir de Node(s)" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5189,8 +5182,9 @@ msgid "Frame Selection" msgstr "Enquadra la Selecció" #: editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "Preview Canvas Scale" -msgstr "" +msgstr "Vista prèvia de l'escala del llenç" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -5209,15 +5203,20 @@ msgid "Insert keys (based on mask)." msgstr "Inserir claus (basades en mascara)." #: editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "" "Auto insert keys when objects are translated, rotated on 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 "" +"Inserir claus automà ticament quan els objectes es traslladen, giren o " +"escalen (basat en la mà scara).\n" +"Les claus només s'afegeixen a les pistes existents, no es crearà cap pista " +"nova.\n" +"Les claus s'han d'inserir manualment per primera vegada." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Auto Insert Key" msgstr "Inserir Clau Automà ticament" @@ -5269,9 +5268,8 @@ msgid "Error instancing scene from %s" msgstr "Error en instanciar l'escena des de %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" -msgstr "Modifica el tipus per defecte" +msgstr "Canviar Tipus per Defecte" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -5313,6 +5311,14 @@ msgid "Load Emission Mask" msgstr "Carrega una Mà scara d'Emissió" #: 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 +#, fuzzy +msgid "Restart" +msgstr "Reinicia" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Esborra la Mà scara d'Emissió" @@ -5393,24 +5399,20 @@ msgid "Load Curve Preset" msgstr "Carrega un ajustament per la Corba" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" -msgstr "Afegeix un punt" +msgstr "Afegir Punt" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" -msgstr "Elimina el punt" +msgstr "Elimina Punt" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" -msgstr "Lineal esquerra" +msgstr "Lineal Esquerra" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" -msgstr "Lineal dreta" +msgstr "Lineal Dret" #: editor/plugins/curve_editor_plugin.cpp #, fuzzy @@ -5475,8 +5477,9 @@ msgid "Create Trimesh Static Shape" msgstr "Crea un forma amb una malla de triangles" #: editor/plugins/mesh_instance_editor_plugin.cpp +#, fuzzy msgid "Failed creating shapes!" -msgstr "" +msgstr "Ha fallat la creació de formes!" #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy @@ -5899,9 +5902,8 @@ msgid "Split Segment (in curve)" msgstr "Parteix el Segment (de la Corba)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" -msgstr "Moure unió" +msgstr "Moure Unió" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" @@ -5967,7 +5969,6 @@ msgid "Paint Bone Weights" msgstr "Pintar Pes dels Ossos" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Open Polygon 2D UV editor." msgstr "Obrir editor UV de PolÃgons 2D." @@ -6067,11 +6068,11 @@ msgstr "Configuració de la QuadrÃcula" #: editor/plugins/polygon_2d_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap" -msgstr "Alinea" +msgstr "Ajustar" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Enable Snap" -msgstr "Activa l'Alineament" +msgstr "Activar Ajustament" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid" @@ -6082,22 +6083,18 @@ msgid "Configure Grid:" msgstr "Configurar QuadrÃcula:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Offset X:" msgstr "Desplaçament X de la quadrÃcula:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Offset Y:" -msgstr "Desplaçament Y de la quadrÃcula :" +msgstr "Desplaçament Y de la quadrÃcula:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Step X:" msgstr "Pas X de la quadrÃcula:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Step Y:" msgstr "Pas Y de la quadrÃcula:" @@ -6161,7 +6158,7 @@ msgstr "" #: editor/plugins/root_motion_editor_plugin.cpp #, fuzzy msgid "Path to AnimationPlayer is invalid" -msgstr "L'arbre d'animació no és và lid." +msgstr "El camà cap a l'AnimationPlayer no és và lid" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Files" @@ -6172,7 +6169,6 @@ msgid "Close and save changes?" msgstr "Tancar i desar els canvis?" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error writing TextFile:" msgstr "Error en escriure el Fitxer de Text:" @@ -6205,7 +6201,6 @@ msgid "Error Importing" msgstr "Error en Importar" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "New TextFile..." msgstr "Nou Fitxer de Text..." @@ -6234,7 +6229,6 @@ msgid "Save Theme As..." msgstr "Desa el Tema com a..." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "%s Class Reference" msgstr "Referència de Classe %s" @@ -6244,8 +6238,18 @@ msgid "Find Next" msgstr "Cerca el Següent" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filtra les propietats" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." -msgstr "" +msgstr "Alterna l'ordenació alfabètica de la llista de mètodes." + +#: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Filtra Mode:" #: editor/plugins/script_editor_plugin.cpp msgid "Sort" @@ -6326,7 +6330,7 @@ msgstr "Tanca-ho Tot" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp msgid "Run" -msgstr "Executa" +msgstr "Executar" #: editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" @@ -6358,13 +6362,12 @@ msgid "Debug with External Editor" msgstr "Depurar amb un Editor Extern" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Obre la Documentació en lÃnia" +msgstr "Obrir la documentació en lÃnia de Godot." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" -msgstr "" +msgstr "Sol·licitar Documentació" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -6414,30 +6417,27 @@ msgid "Search Results" msgstr "Resultats de cerca" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "Connecta al Node:" +msgstr "Connexions al mètode:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Origen:" +msgstr "Font" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Senyals" +msgstr "Senyal" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Target" -msgstr "Camà de Destinació:" +msgstr "Objectiu" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "Desconnecta '%s' de '%s'" +msgstr "" +"Falta el mètode de connexió '%s' per al senyal '%s' del node '%s' al node " +"'%s'." #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6445,7 +6445,7 @@ msgstr "LÃnia" #: editor/plugins/script_text_editor.cpp msgid "(ignore)" -msgstr "" +msgstr "(ignorar)" #: editor/plugins/script_text_editor.cpp msgid "Go to Function" @@ -6458,7 +6458,7 @@ msgstr "Només s'hi poden deixar caure Recursos del sistema de fitxers." #: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Lookup Symbol" -msgstr "Completa el SÃmbol" +msgstr "Cercar SÃmbol" #: editor/plugins/script_text_editor.cpp msgid "Pick Color" @@ -6485,20 +6485,24 @@ msgid "Syntax Highlighter" msgstr "Ressaltador de sintaxi" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "Marcadors" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Crea punts." #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Talla" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Selecciona-ho Tot" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Esborra la LÃnia" @@ -6518,22 +6522,20 @@ msgstr "Comentaris" #: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Toggle Bookmark" -msgstr "Vista Lliure" +msgstr "Commutar Marcador" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "Anar al Punt d'Interrupció següent" +msgstr "Anar al marcador següent" #: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Go to Previous Bookmark" -msgstr "Anar al Punt d'Interrupció anterior" +msgstr "Anar al marcador anterior" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "Treu tots els Elements" +msgstr "Suprimir tots els marcadors" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -6564,9 +6566,8 @@ msgid "Convert Indent to Spaces" msgstr "Converteix la Sagnia en Espais" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Convert Indent to Tabs" -msgstr "Converteix el Sagnat en Tabulacions" +msgstr "Convertir Sagnia en Tabulacions" #: editor/plugins/script_text_editor.cpp msgid "Auto Indent" @@ -6610,21 +6611,21 @@ msgid "Contextual Help" msgstr "Ajuda Contextual" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"El disc conté versions més recents dels fitxer següents. \n" -"Quina acció voleu seguir?:" +"Aquest Shader s'ha modificat en el disc.\n" +"Quina acció s'ha de prendre?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" -msgstr "Ombreig" +msgstr "Shader" #: editor/plugins/skeleton_2d_editor_plugin.cpp +#, fuzzy msgid "This skeleton has no bones, create some children Bone2D nodes." -msgstr "" +msgstr "Aquest esquelet no té ossos, crea alguns nodes fill Bone2D." #: editor/plugins/skeleton_2d_editor_plugin.cpp #, fuzzy @@ -6641,32 +6642,31 @@ msgid "Skeleton2D" msgstr "Esquelet2D" #: editor/plugins/skeleton_2d_editor_plugin.cpp +#, fuzzy msgid "Make Rest Pose (From Bones)" -msgstr "" +msgstr "Crear Pose de Repòs (A partir dels Ossos)" #: editor/plugins/skeleton_2d_editor_plugin.cpp #, fuzzy msgid "Set Bones to Rest Pose" -msgstr "Establir els ossos a la postura de descans" +msgstr "Establir els ossos a la postura de repós" #: editor/plugins/skeleton_editor_plugin.cpp -#, fuzzy msgid "Create physical bones" -msgstr "Crea un malla de Navegació" +msgstr "Crear ossos fÃsics" #: editor/plugins/skeleton_editor_plugin.cpp msgid "Skeleton" msgstr "Esquelet" #: editor/plugins/skeleton_editor_plugin.cpp -#, fuzzy msgid "Create physical skeleton" -msgstr "Crea una solució en C#" +msgstr "Crea esquelet fÃsic" #: editor/plugins/skeleton_ik_editor_plugin.cpp #, fuzzy msgid "Play IK" -msgstr "Reprodueix" +msgstr "Reproduir IK" #: editor/plugins/spatial_editor_plugin.cpp msgid "Orthogonal" @@ -6735,7 +6735,7 @@ msgstr "Canvis de Material" #: editor/plugins/spatial_editor_plugin.cpp msgid "Shader Changes" -msgstr "Canvis de Ombreig" +msgstr "Canvis de Shader" #: editor/plugins/spatial_editor_plugin.cpp msgid "Surface Changes" @@ -6903,9 +6903,8 @@ msgid "XForm Dialog" msgstr "Dià leg XForm" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Nodes To Floor" -msgstr "Alinea-ho amb la graella" +msgstr "Ajustar Nodes al Terra" #: editor/plugins/spatial_editor_plugin.cpp msgid "Select Mode (Q)" @@ -6943,7 +6942,7 @@ msgstr "Mode Espai Local (%s)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Mode (%s)" -msgstr "Mode Imant (%s)" +msgstr "Mode d'Ajustament (%s)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom View" @@ -6970,9 +6969,8 @@ msgid "Right View" msgstr "Vista Dreta" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" -msgstr "Vista Perspectiva/Ortogonal" +msgstr "Canviar Vista Perspectiva/Ortogonal" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" @@ -7013,12 +7011,11 @@ msgstr "Vista Lliure" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Transform" -msgstr "Transforma" +msgstr "Transformar" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" -msgstr "Alinea-ho amb la graella" +msgstr "Ajustar Objecte al Terra" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Dialog..." @@ -7051,7 +7048,7 @@ msgstr "4 Vistes" #: editor/plugins/spatial_editor_plugin.cpp #, fuzzy msgid "Gizmos" -msgstr "Mostra els Gizmos" +msgstr "Gizmos" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Origin" @@ -7068,19 +7065,22 @@ msgstr "Configuració" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Settings" -msgstr "Configuració de l'Alineament" +msgstr "Configuració d'Ajustament" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy msgid "Translate Snap:" -msgstr "Translació Alineada:" +msgstr "Ajustament de Translació:" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy msgid "Rotate Snap (deg.):" -msgstr "Rotació Alineada (graus):" +msgstr "Ajustament de Rotació (graus):" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy msgid "Scale Snap (%):" -msgstr "Escala Alineada (%):" +msgstr "Ajustament d'Escala (%):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Viewport Settings" @@ -7127,8 +7127,9 @@ msgid "Post" msgstr "Post" #: editor/plugins/spatial_editor_plugin.cpp +#, fuzzy msgid "Nameless gizmo" -msgstr "" +msgstr "Gizmo sense nom" #: editor/plugins/sprite_editor_plugin.cpp msgid "Create Mesh2D" @@ -7151,11 +7152,12 @@ msgstr "Crea un PolÃgon Oclusor" #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy msgid "Sprite is empty!" -msgstr "El camà per desar és buit!" +msgstr "El Sprite està buit!" #: editor/plugins/sprite_editor_plugin.cpp msgid "Can't convert a sprite using animation frames to mesh." msgstr "" +"No es pot convertir un sprite que utilitza fotogrames d'animació a malla." #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't replace by mesh." @@ -7183,8 +7185,9 @@ msgid "Create CollisionPolygon2D Sibling" msgstr "Crea un PolÃgon de Navegació" #: editor/plugins/sprite_editor_plugin.cpp +#, fuzzy msgid "Invalid geometry, can't create light occluder." -msgstr "" +msgstr "La geometria no és và lida, no es pot crear oclusor de llum." #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7192,9 +7195,8 @@ msgid "Create LightOccluder2D Sibling" msgstr "Crea un PolÃgon Oclusor" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Sprite" -msgstr "SpriteFrames" +msgstr "Sprite" #: editor/plugins/sprite_editor_plugin.cpp msgid "Simplification: " @@ -7215,12 +7217,12 @@ msgstr "Configuració:" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy msgid "No Frames Selected" -msgstr "Enquadra la Selecció" +msgstr "No hi ha Fotogrames Seleccionats" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy msgid "Add %d Frame(s)" -msgstr "Afegeix Fotograma" +msgstr "Afegir %d Fotograma(es)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" @@ -7271,13 +7273,13 @@ msgid "Animation Frames:" msgstr "Fotogrames d'Animació:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Afegeix Nodes des d'Arbre" +msgstr "Afegir Textura des de Fitxer" #: editor/plugins/sprite_frames_editor_plugin.cpp +#, fuzzy msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "Afegir fotogrames des d'una fulla de Sprites" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7298,17 +7300,15 @@ msgstr "Mou (Després)" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy msgid "Select Frames" -msgstr "Fotogrames de la Pila" +msgstr "Seleccionar Fotogrames" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Inverteix horitzontalment" +msgstr "Horitzontal:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "Vèrtexs" +msgstr "Vertical:" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy @@ -7329,13 +7329,12 @@ msgid "Set Region Rect" msgstr "Defineix la Regió Rectangular" #: editor/plugins/texture_region_editor_plugin.cpp -#, fuzzy msgid "Set Margin" -msgstr "Estableix la Nansa" +msgstr "Establir Marge" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Snap Mode:" -msgstr "Mode Imant:" +msgstr "Mode d'ajustament:" #: editor/plugins/texture_region_editor_plugin.cpp #: scene/resources/visual_shader.cpp @@ -7343,12 +7342,13 @@ msgid "None" msgstr "Cap" #: editor/plugins/texture_region_editor_plugin.cpp +#, fuzzy msgid "Pixel Snap" -msgstr "Alinea-ho amb els Pixels" +msgstr "Ajustar amb els PÃxels" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Grid Snap" -msgstr "Alinea-ho a la graella" +msgstr "Ajustar a la quadrÃcula" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Auto Slice" @@ -7363,8 +7363,9 @@ msgid "Step:" msgstr "Pas:" #: editor/plugins/texture_region_editor_plugin.cpp +#, fuzzy msgid "Sep.:" -msgstr "" +msgstr "Sep.:" #: editor/plugins/texture_region_editor_plugin.cpp #, fuzzy @@ -7392,9 +7393,8 @@ msgid "Remove All" msgstr "Treu-los tots" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "Edita el Tema..." +msgstr "Editar Tema" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7423,21 +7423,19 @@ msgstr "Crea a partir del Tema d'Editor actual" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy msgid "Toggle Button" -msgstr "Botó del ratolÃ" +msgstr "Botó de commutació" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Botó Central" +msgstr "Botó Desactivat" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" msgstr "Element" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "Desactivat" +msgstr "Element Desactivat" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -7461,7 +7459,7 @@ msgstr "" #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Submenú" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -7499,13 +7497,13 @@ msgid "Tab 3" msgstr "Pestanya 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "Fills Editables" +msgstr "Element Editable" #: editor/plugins/theme_editor_plugin.cpp +#, fuzzy msgid "Subtree" -msgstr "" +msgstr "Subarbre" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7542,7 +7540,7 @@ msgstr "Elimina la Selecció" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy msgid "Fix Invalid Tiles" -msgstr "Nom no và lid." +msgstr "Arreglar Rajoles no Valides" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp @@ -7551,7 +7549,7 @@ msgstr "Tallar Selecció" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint TileMap" -msgstr "Pinta el TileMap" +msgstr "Pintar Mapa de Rajoles" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Line Draw" @@ -7567,12 +7565,11 @@ msgstr "Cubell de pintura" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase TileMap" -msgstr "Elimina el TileMap" +msgstr "Elimina Mapa de Rajoles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Find Tile" -msgstr "Cerca Tessel·la" +msgstr "Trobar Rajola" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Transpose" @@ -7592,48 +7589,45 @@ msgid "Disable Autotile" msgstr "AutoTiles" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "Edita Filtres" +msgstr "Habilitar Prioritat" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" -msgstr "Pinta Tessel·la" +msgstr "Pinta Rajola" #: editor/plugins/tile_map_editor_plugin.cpp +#, fuzzy msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Maj + RMB: dibuixar una lÃnia\n" +"Maj + Ctrl + RMB: pintar rectangle" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" -msgstr "Tria un Tessel·la" +msgstr "Escollir Rajola" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" -msgstr "Mode de Rotació" +msgstr "Girar a l'Esquerra" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" -msgstr "Gira el PolÃgon" +msgstr "Girar a la Dreta" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Horizontally" -msgstr "Inverteix horitzontalment" +msgstr "Invertir Horitzontalment" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Vertically" -msgstr "Inverteix verticalment" +msgstr "Invertir Verticalment" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" -msgstr "Transforma" +msgstr "Restablir Transformació" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -7658,56 +7652,54 @@ msgid "Next Coordinate" msgstr "Coordenada Següent" #: editor/plugins/tile_set_editor_plugin.cpp +#, fuzzy msgid "Select the next shape, subtile, or Tile." -msgstr "" +msgstr "Seleccioneu la forma, sub-rajola o rajola següent." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Previous Coordinate" msgstr "Coordenada Anterior" #: editor/plugins/tile_set_editor_plugin.cpp +#, fuzzy msgid "Select the previous shape, subtile, or Tile." -msgstr "" +msgstr "Seleccioneu la forma, sub-rajola o rajola anterior." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "Mode d'Execució:" +msgstr "Mode Regió" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "Mode d'Interpolació" +msgstr "Mode Col·lisió" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "Editar PolÃgon d'Oclusió" +msgstr "Mode Oclusió" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "Crea un malla de Navegació" +msgstr "Mode Navegació" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "Bitmask Mode" -msgstr "Mode de Rotació" +msgstr "Mode mà scara de bits" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "Priority Mode" -msgstr "Mode d'Exportació:" +msgstr "Mode Prioritat" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "Icon Mode" -msgstr "Mode d'Escombratge lateral" +msgstr "Mode Icona" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "Z Index Mode" -msgstr "Mode d'Escombratge lateral" +msgstr "Mode Index Z" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7716,12 +7708,12 @@ msgstr "Copiar mà scara de bits." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "Paste bitmask." -msgstr "Enganxa l'Animació" +msgstr "Enganxar mà scara de bits." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "Erase bitmask." -msgstr "Elimina un Punt." +msgstr "Esborrar mà scara de bits." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create a new rectangle." @@ -7739,15 +7731,18 @@ msgstr "Mantenir polÃgon dins de la regió Rect." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Enable snap and show grid (configurable via the Inspector)." msgstr "" +"Habilitar ajustament i mostrar quadrÃcula (configurable a través de " +"l'inspector)." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Display Tile Names (Hold Alt Key)" -msgstr "" +msgstr "Mostrar noms de les rajoles (manteniu pressionada la tecla Alt)" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove selected texture? This will remove all tiles which use it." -msgstr "Elimina l'entrada actual" +msgstr "" +"Eliminar la textura seleccionada? Això eliminarà totes les rajoles que " +"l'utilitzin." #: editor/plugins/tile_set_editor_plugin.cpp msgid "You haven't selected a texture to remove." @@ -7755,7 +7750,7 @@ msgstr "No heu seleccionat una textura per eliminar." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from scene? This will overwrite all current tiles." -msgstr "" +msgstr "Crear des de l'escena? Això sobreescriurà totes les rajoles actuals." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Merge from scene?" @@ -7766,9 +7761,8 @@ msgid "Remove Texture" msgstr "Eliminar Textura" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "%s file(s) were not added because was already on the list." -msgstr "%s fitxer(s) no es van afegir perquè ja estaven en la llista." +msgstr "%s fitxer(s) no s'han afegit perquè ja estaven en la llista." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -7779,14 +7773,16 @@ msgstr "" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "Delete selected Rect." -msgstr "Voleu Esborrar els fitxers seleccionats?" +msgstr "Suprimir Rectangle seleccionat." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "" "Select current edited sub-tile.\n" "Click on another Tile to edit it." -msgstr "Selecciona la sub-tessel·la en edició." +msgstr "" +"Seleccioneu la sub-rajola editada actual.\n" +"Feu clic en una altra rajola per editar-la." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Delete polygon." @@ -7800,8 +7796,10 @@ msgid "" "Shift+LMB: Set wildcard bit.\n" "Click on another Tile to edit it." msgstr "" -"clic Esquerra: activa el bit\n" -"clic Dreta: desactiva el bit." +"Clic Esquerra: activar bit\n" +"Clic Dret: desactivar bit.\n" +"Maj. + Clic Esquerra: Establir valor de bit comodÃ.\n" +"Feu clic en una altra rajola per editar-la." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -7810,41 +7808,43 @@ msgid "" "bindings.\n" "Click on another Tile to edit it." msgstr "" -"Selecciona una sub-tessel·la com a icona. També s'utilitzarà per les " -"assignacions automà tiques no-và lides de l'autotile." +"Seleccioneu la sub-rajola que voleu utilitzar com a icona, també " +"s'utilitzarà en les vinculacions de rajoles automà tiques no và lides.\n" +"Feu clic en una altra rajola per editar-la." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "" "Select sub-tile to change its priority.\n" "Click on another Tile to edit it." -msgstr "Selecciona una sub-tessel·la per a modificar-ne la prioritat." +msgstr "" +"Seleccioneu la sub-rajola per canviar-ne la prioritat.\n" +"Feu clic en una altra rajola per editar-la." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "" "Select sub-tile to change its z index.\n" "Click on another Tile to edit it." -msgstr "Selecciona una sub-tessel·la per a modificar-ne la prioritat." +msgstr "" +"Seleccioneu la sub-rajola per canviar el seu Ãndex z.\n" +"Feu clic en una altra rajola per editar-la." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Set Tile Region" -msgstr "Defineix la Regió Rectangular" +msgstr "Definir Regió de Rajola" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create Tile" -msgstr "Crea un Directori" +msgstr "Crear Rajola" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Set Tile Icon" -msgstr "" +msgstr "Establir icona de la Rajola" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Tile Bitmask" -msgstr "Edita Filtres" +msgstr "Editar mà scara de bits de la rajola" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Collision Polygon" @@ -7859,13 +7859,12 @@ msgid "Edit Navigation Polygon" msgstr "Editar PolÃgon de Navegació" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Paste Tile Bitmask" -msgstr "Enganxa l'Animació" +msgstr "Enganxar mà scara de bits del la rajola" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Clear Tile Bitmask" -msgstr "" +msgstr "Restablir mà scara de bits de la rajola" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -7878,9 +7877,8 @@ msgid "Make Polygon Convex" msgstr "Mou el PolÃgon" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Tile" -msgstr "Elimina la Plantilla" +msgstr "Eliminar Rajola" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove Collision Polygon" @@ -7895,13 +7893,12 @@ msgid "Remove Navigation Polygon" msgstr "Eliminar PolÃgon de Navegació" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Tile Priority" -msgstr "Edita Filtres" +msgstr "Editar Prioritat de la Rajola" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Tile Z Index" -msgstr "" +msgstr "Editar Ãndex Z de la rajola" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create Collision Polygon" @@ -7918,7 +7915,7 @@ msgstr "Aquesta propietat no es pot canviar." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy msgid "TileSet" -msgstr "Tile Set" +msgstr "Conjunt de rajoles" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -7936,13 +7933,12 @@ msgid "Scalar" msgstr "Escala:" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Inspector" +msgstr "Vector" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Booleà " #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -7951,7 +7947,7 @@ msgstr "Afegeix una Entrada" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Afegir port de sortida" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -7991,11 +7987,12 @@ msgstr "Canviar Expressió" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy msgid "Resize VisualShader node" -msgstr "Ombreig" +msgstr "Redimensionar node VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Set Uniform Name" -msgstr "" +msgstr "Definir nom uniforme" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8005,7 +8002,7 @@ msgstr "Establir com a valor Predeterminat per a '%s'" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy msgid "Add Node to Visual Shader" -msgstr "Ombreig" +msgstr "Afegir node al VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Duplicate Nodes" @@ -8016,26 +8013,25 @@ msgid "Delete Nodes" msgstr "Eliminar Nodes" #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Visual Shader Input Type Changed" -msgstr "" +msgstr "El tipus d'entrada VisualShader ha canviat" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Vertex" msgstr "Vèrtex" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Fragment" -msgstr "Arguments:" +msgstr "Fragment" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Light" msgstr "Llum" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "Crea un Node" +msgstr "Crear node Shader" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8044,20 +8040,19 @@ msgstr "Vés a la Funció" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "Operador Color." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "Crea Funció" +msgstr "Funció d'escala de grisos." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "Converteix el vector HSV en equivalent RGB." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "Converteix el vector RGB en un equivalent de HSV." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8069,13 +8064,13 @@ msgid "Burn operator." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Darken operator." -msgstr "" +msgstr "Operador enfosquir." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Difference operator." -msgstr "Només diferencial" +msgstr "Operador diferencial." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." @@ -8086,8 +8081,9 @@ msgid "HardLight operator" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Lighten operator." -msgstr "" +msgstr "Operador Aclarir." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." @@ -8102,9 +8098,8 @@ msgid "SoftLight operator." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color constant." -msgstr "Constant" +msgstr "Constant de color." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8116,11 +8111,14 @@ msgid "" "Returns an associated vector if the provided scalars are equal, greater or " "less." msgstr "" +"Retorna un vector associat si els escalars proporcionats són iguals, majors " +"o menors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided boolean value is true or false." msgstr "" +"Retorna un vector associat si el valor booleà proporcionat és cert o fals." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8132,257 +8130,43 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy -msgid "Input parameter." -msgstr "Alinea-ho amb el Pare" +msgid "'%s' input parameter for all shader modes." +msgstr "parà metre d'entrada 'uv' per a tots els modes shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" +msgid "Input parameter." +msgstr "Parà metre d'entrada." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "parà metre d'entrada 'alpha' per modes shader vèrtex i el fragment." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "parà metre d'entrada 'uv' per a tots els modes shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for fragment shader mode." +msgstr "parà metre d'entrada 'uv' per a tots els modes shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for light shader mode." +msgstr "parà metre d'entrada 'uv' per a tots els modes shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for vertex shader mode." +msgstr "parà metre d'entrada 'uv' per a tots els modes shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "parà metre d'entrada 'alpha' per modes shader vèrtex i el fragment." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8396,157 +8180,158 @@ msgstr "Modifica un operador escalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "Constant E (2,718282). Representa la base del logaritme natural." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "Constant Èpsilon (0,00001). Menor nombre escalar possible." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "Constant pi (1,618034). Proporció à uria." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "Constant Pi/4 (0,785398) o 45 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "Constant Pi/2 (1,570796) o 90 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "Constant Pi (3,141593) o 180 graus." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "Constant tau (6,283185) o 360 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "Constant Sqrt2 (1,414214). Arrel quadrada de 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "Retorna el valor absolut del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "Retorna el l'arc cosinus del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Només GLES3) Retorna el cosinus hiperbòlic invers del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "Retorna l'arc sinus del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "(Només GLES3) Retorna el sinus hiperbòlic invers del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "Retorna l'arc tangent del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "Retorna l'arc tangent dels parà metres." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Només GLES3) Retorna la tangent hiperbòlica inversa del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "Troba l'enter més proper que sigui major o igual que el parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "Restringeix un valor entre dos valors addicionals." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "Retorna el cosinus del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Només GLES3) Retorna el cosinus hiperbòlic del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "Converteix una quantitat en radians a graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "Exponencial en base e." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "Exponencial en base 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "Troba l'enter més proper inferior o igual al parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "Calcula la part fraccional de l'argument." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "Retorna l'invers de l'arrel quadrada del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "Logaritme natural." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "Logaritme en base 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "Retorna el major de dos valors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "Retorna el menor de dos valors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "Interpolació lineal entre dos escalars." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "Retorna el valor oposat del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - escalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." -msgstr "" +msgstr "Retorna el valor del primer parà metre elevat a la potència del segon." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "Converteix una quantitat en graus a radians." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / escalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(Només GLES3) Troba l'enter més proper al parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(Només GLES3) Troba l'enter parell més proper al parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." @@ -8554,19 +8339,19 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "Extreu el signe del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "Retorna el sinus del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(Només GLES3) Retorna el sinus hiperbòlic del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "Retorna l'arrel quadrada del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8586,35 +8371,35 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "Retorna la tangent del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Només GLES3) Retorna la tangent hiperbòlica del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." -msgstr "" +msgstr "(Només GLES3) Troba el valor truncat del parà metre." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "Afegeix escalar a escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "Divideix escalar per escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "Multiplica escalar per escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "Retorna el residu dels dos escalars." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "Resta escalar d'escalar." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8627,12 +8412,14 @@ msgid "Scalar uniform." msgstr "Modificar un Uniforme Escalar" #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "Realitzar la cerca de textures cúbiques." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Perform the texture lookup." -msgstr "" +msgstr "Realitza la cerca de textures." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8647,7 +8434,7 @@ msgstr "Modifica un Uniforme Textura" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy msgid "Transform function." -msgstr "Dià leg de Transformació..." +msgstr "Funció de transformació." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8662,36 +8449,36 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes transform from four vectors." -msgstr "" +msgstr "Compon una transformació a partir de quatre vectors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes transform to four vectors." -msgstr "" +msgstr "Descompon una transformació en quatre vectors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the determinant of a transform." -msgstr "" +msgstr "(Només GLES3) Calcula el determinant d'una transformació." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the inverse of a transform." -msgstr "" +msgstr "(Només GLES3) Calcula l'invers d'una transformació." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the transpose of a transform." -msgstr "" +msgstr "(Només GLES3) Calcula la transposició d'una transformació." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies transform by transform." -msgstr "" +msgstr "Multiplica transformació per transformació." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by transform." -msgstr "" +msgstr "Multiplica vector per transformació." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy msgid "Transform constant." -msgstr "S'ha interromput la Transformació ." +msgstr "Constant de Transformació." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8699,9 +8486,8 @@ msgid "Transform uniform." msgstr "S'ha interromput la Transformació ." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector function." -msgstr "Assignació a funció" +msgstr "Funció vector." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8710,23 +8496,23 @@ msgstr "Modifica un operador vectorial" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "Compon un vector a partir de tres escalars." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "Descompon un vector en tres escalars." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "Calcula el producte creuat de dos vectors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "Retorna la distà ncia entre dos punts." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "Calcula el producte escalar de dos vectors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8738,23 +8524,23 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "Calcula la longitud d'un vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "Interpolació lineal entre dos vectors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." -msgstr "" +msgstr "Calcula el producte normalitzar del vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - vector" -msgstr "" +msgstr "1.0 - vector" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / vector" -msgstr "" +msgstr "1.0 / vector" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8764,7 +8550,7 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns a vector that points in the direction of refraction." -msgstr "" +msgstr "Retorna un vector que apunta en la direcció de la refracció." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8800,23 +8586,23 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." -msgstr "" +msgstr "Afegeix vector al vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "" +msgstr "Divideix vector per vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." -msgstr "" +msgstr "Multiplica vector per vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two vectors." -msgstr "" +msgstr "Retorna el residu dels dos vectors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts vector from vector." -msgstr "" +msgstr "Resta vector al vector." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8829,11 +8615,16 @@ msgid "Vector uniform." msgstr "Modifica un Uniforme Vectorial" #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy 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 "" +"Expressió personalitzada del llenguatge de Shader de Godot, amb una " +"quantitat de ports d'entrada i sortida personalitzats. Això es una una " +"injecció de codi directa en la funció vertex/fragment/light, no lo utilitzau " +"per a escriure les declaracions de la funció dins seu." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8886,18 +8677,16 @@ msgid "" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "VisualShader" -msgstr "Ombreig" +msgstr "VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Edit Visual Property" msgstr "Editar Propietat Visual" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Visual Shader Mode Changed" -msgstr "Canvis de Ombreig" +msgstr "El mode Visual Shader ha canviat" #: editor/project_export.cpp msgid "Runnable" @@ -8935,7 +8724,7 @@ msgstr "alliberat" #: editor/project_export.cpp #, fuzzy msgid "Exporting All" -msgstr "Exportació per a %s" +msgstr "Exportant tot" #: editor/project_export.cpp msgid "The given export path doesn't exist:" @@ -9016,14 +8805,12 @@ msgid "Feature List:" msgstr "Llista de CaracterÃstiques :" #: editor/project_export.cpp -#, fuzzy msgid "Script" -msgstr "Script Nou" +msgstr "Script" #: editor/project_export.cpp -#, fuzzy msgid "Script Export Mode:" -msgstr "Mode d'Exportació:" +msgstr "Mode d'Exportació de Scripts:" #: editor/project_export.cpp msgid "Text" @@ -9078,9 +8865,8 @@ msgid "Please choose an empty folder." msgstr "Selecciona un directori buit." #: editor/project_manager.cpp -#, fuzzy msgid "Please choose a 'project.godot' or '.zip' file." -msgstr "Si us plau seleccioneu un fitxer 'projecte.godot' o '.zip'." +msgstr "Si us plau seleccioneu un fitxer 'project.godot' o '.zip'." #: editor/project_manager.cpp msgid "Directory already contains a Godot project." @@ -9281,52 +9067,50 @@ msgstr "" "Edita el Projecte per inicialitzar-lo." #: editor/project_manager.cpp -#, fuzzy msgid "Are you sure to run %d projects at once?" -msgstr "Esteu segur que voleu executar més d'un projecte de cop?" +msgstr "Esteu segur que voleu executar %d projectes de cop?" #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove %d projects from the list?\n" "The project folders' contents won't be modified." msgstr "" -"Retirar el Projecte de la llista? (El contingut del directori no es " -"modificarà )" +"Eliminar %d projectes de la llista?\n" +"El contingut del directori del projecte no es modificarà ." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove this project from the list?\n" "The project folder's contents won't be modified." msgstr "" -"Retirar el Projecte de la llista? (El contingut del directori no es " -"modificarà )" +"Eliminar aquest projecte de la llista?\n" +"El contingut del directori del projecte no es modificarà ." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove all missing projects from the list? (Folders contents will not be " "modified)" msgstr "" -"Retirar el Projecte de la llista? (El contingut del directori no es " -"modificarà )" +"Eliminar tots els projectes que falten de la llista? (El contingut dels " +"directoris no es modificarà )" #: editor/project_manager.cpp -#, fuzzy msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." msgstr "" -"Canvi de Llengua.\n" -"La interficie s'actualitzarà en iniciar l'editor o administrador." +"L'idioma ha canviat.\n" +"La interfÃcie s'actualitzarà després de reiniciar l'editor o el gestor de " +"projectes." #: editor/project_manager.cpp -#, fuzzy msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." -msgstr "S'examinaran %s directoris a la recerca de projectes. Ho Confirmeu?" +msgstr "" +"Esteu segur que voleu escanejar %s carpetes per als projectes de Godot " +"existents?\n" +"Això pot trigar una estona." #: editor/project_manager.cpp msgid "Project Manager" @@ -9351,7 +9135,7 @@ msgstr "Nou Projecte" #: editor/project_manager.cpp #, fuzzy msgid "Remove Missing" -msgstr "Elimina el punt" +msgstr "Suprimeix els que falten" #: editor/project_manager.cpp msgid "Templates" @@ -9370,13 +9154,12 @@ msgid "Can't run project" msgstr "No es pot executar el projecte" #: editor/project_manager.cpp -#, fuzzy msgid "" "You currently don't have any projects.\n" "Would you like to explore official example projects in the Asset Library?" msgstr "" -"Encara no teniu cap projecte.\n" -"Voleu explorar els projectes d'exemple oficials a la Biblioteca d'Actius?" +"Actualment no teniu cap projecte.\n" +"Us agradaria explorar projectes d'exemple oficials a la biblioteca d'actius?" #: editor/project_settings_editor.cpp msgid "Key " @@ -9395,27 +9178,24 @@ msgid "Mouse Button" msgstr "Botó del ratolÃ" #: editor/project_settings_editor.cpp -#, fuzzy msgid "" "Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'" msgstr "" -"Nom d'acció no và lid. No pot estar buit ni contenir '/', ':', '=', '\\' o " -"'\"'." +"Nom d'acció no và lid. No pot estar buit ni contenir '/', ':', '=', '\\' o " +"'\"'" #: editor/project_settings_editor.cpp -#, fuzzy msgid "An action with the name '%s' already exists." -msgstr "L'Acció '%s' ja existeix!" +msgstr "Ja existeix una acció amb el nom '%s'." #: editor/project_settings_editor.cpp msgid "Rename Input Action Event" msgstr "Reanomena la Incidència de l'Acció d'Entrada" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Change Action deadzone" -msgstr "Modifica el Nom de l'Animació:" +msgstr "Canviar zona morta de l'acció" #: editor/project_settings_editor.cpp msgid "Add Input Action Event" @@ -9630,9 +9410,8 @@ msgid "Override For..." msgstr "Substitutiu per a..." #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -#, fuzzy msgid "The editor must be restarted for changes to take effect." -msgstr "Cal reiniciar el editor per a que els canvis tinguin efecte" +msgstr "Cal reiniciar el editor per a que els canvis tinguin efecte." #: editor/project_settings_editor.cpp msgid "Input Map" @@ -9684,21 +9463,19 @@ msgstr "Remapatges per Llengua:" #: editor/project_settings_editor.cpp msgid "Locale" -msgstr "Localització" +msgstr "Idioma" #: editor/project_settings_editor.cpp msgid "Locales Filter" msgstr "Filtre de Localitzacions" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show All Locales" -msgstr "Mostra totes les Localitzacions" +msgstr "Mostrar tots els idiomes" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show Selected Locales Only" -msgstr "Mostrar només les Localitzacions seleccionades" +msgstr "Mostrar només els idiomes seleccionats" #: editor/project_settings_editor.cpp msgid "Filter mode:" @@ -9786,7 +9563,6 @@ msgid "Suffix" msgstr "Sufix" #: editor/rename_dialog.cpp -#, fuzzy msgid "Advanced Options" msgstr "Opcions Avançades" @@ -9815,13 +9591,12 @@ msgid "Root node name" msgstr "Nom del node arrel" #: editor/rename_dialog.cpp -#, fuzzy msgid "" "Sequential integer counter.\n" "Compare counter options." msgstr "" "Comptador seqüencial d'enters.\n" -"Compara les opcions de comptador." +"Comparar opcions de comptador." #: editor/rename_dialog.cpp msgid "Per Level counter" @@ -9859,7 +9634,6 @@ msgid "Regular Expressions" msgstr "Expressions Regulars" #: editor/rename_dialog.cpp -#, fuzzy msgid "Post-Process" msgstr "Post-Processat" @@ -9981,20 +9755,18 @@ msgid "Can't reparent nodes in inherited scenes, order of nodes can't change." msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Node must belong to the edited scene to become root." msgstr "" "El node ha de pertà nyer a l'escena editada per a convertir-se en arrel." #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Instantiated scenes can't become root" msgstr "Les escenes instanciades no es poden convertir en arrel" #: editor/scene_tree_dock.cpp #, fuzzy msgid "Make node as Root" -msgstr "Entesos!" +msgstr "Convertir node en arrel" #: editor/scene_tree_dock.cpp msgid "Delete Node(s)?" @@ -10052,9 +9824,8 @@ msgid "User Interface" msgstr "InterfÃcie d'usuari" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Other Node" -msgstr "Eliminar Node" +msgstr "Altre Node" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" @@ -10097,7 +9868,6 @@ msgid "Clear Inheritance" msgstr "Elimina l'Herència" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Open Documentation" msgstr "Obrir documentació" @@ -10106,13 +9876,17 @@ msgid "Add Child Node" msgstr "Afegeix un Node Fill" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Col·lapsar tot" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Modifica el Tipus" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Extend Script" -msgstr "Estén l'script" +msgstr "Estendre el script" #: editor/scene_tree_dock.cpp #, fuzzy @@ -10136,7 +9910,8 @@ msgid "Delete (No Confirm)" msgstr "Elimina (Sense Confirmació)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Afegeix/Crea un Node Nou" #: editor/scene_tree_dock.cpp @@ -10178,14 +9953,12 @@ msgid "Unlock Node" msgstr "Selecciona un Node" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Button Group" -msgstr "Botó 7" +msgstr "Grup de botons" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "(Connecting From)" -msgstr "Error en la connexió" +msgstr "(Connectant des de)" #: editor/scene_tree_editor.cpp msgid "Node configuration warning:" @@ -10217,9 +9990,8 @@ msgstr "" "Clic per mostrar el Tauler de Grups." #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Open Script:" -msgstr "Obrir Script" +msgstr "Obrir Script:" #: editor/scene_tree_editor.cpp msgid "" @@ -10268,19 +10040,16 @@ msgid "Select a Node" msgstr "Selecciona un Node" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is empty." -msgstr "El camà és Buit" +msgstr "El camà està buit." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Filename is empty." -msgstr "El nom del fitxer és buit" +msgstr "El nom del fitxer és buit." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is not local." -msgstr "El Camà no és local" +msgstr "El camà no és local." #: editor/script_create_dialog.cpp #, fuzzy @@ -10288,19 +10057,16 @@ msgid "Invalid base path." msgstr "El Camà de base no és và lid" #: editor/script_create_dialog.cpp -#, fuzzy msgid "A directory with the same name exists." -msgstr "Ja existeix un directori amb el mateix nom" +msgstr "Ja existeix un directori amb el mateix nom." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid extension." -msgstr "L'extensió no és và lida" +msgstr "L'extensió no és và lida." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Wrong extension chosen." -msgstr "L'extensió triada no és correcta" +msgstr "L'extensió triada no és correcta." #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" @@ -10319,52 +10085,44 @@ msgid "N/A" msgstr "No Disponible" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Open Script / Choose Location" -msgstr "Obrir Script/Escollir Localització" +msgstr "Obrir Script / Escollir Localització" #: editor/script_create_dialog.cpp msgid "Open Script" msgstr "Obrir Script" #: editor/script_create_dialog.cpp -#, fuzzy msgid "File exists, it will be reused." -msgstr "El fitxer ja existeix i serà reutilitzat" +msgstr "El fitxer ja existeix, es reutilitzarà ." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid class name." -msgstr "El Nom de Classe no és và lid" +msgstr "Nom de classe no và lid." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid inherited parent name or path." -msgstr "El Nom o camà del Pare heretat no és và lid" +msgstr "El nom o camà del pare heretat no és và lid." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script is valid." -msgstr "L'Script és và lid" +msgstr "El script és và lid." #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9 and _" msgstr "Permesos: a-z, a-Z, 0-9 i _" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Built-in script (into scene file)." -msgstr "Script Integrat (en un fitxer d'escena)" +msgstr "Script Integrat (en el fitxer d'escena)." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will create a new script file." -msgstr "Crea un nou Script" +msgstr "Es crearà un nou fitxer de script." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will load an existing script file." -msgstr "Carrega un Script existent" +msgstr "Es carregarà un fitxer de script existent." #: editor/script_create_dialog.cpp msgid "Language" @@ -10407,7 +10165,7 @@ msgstr "Fotogrames de la Pila" msgid "Pick one or more items from the list to display the graph." msgstr "Trieu un o més elements de la llista per mostrar el Graf." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Errors" @@ -10632,8 +10390,9 @@ msgid "GDNativeLibrary" msgstr "GDNativeLibrary" #: modules/gdnative/gdnative_library_singleton_editor.cpp +#, fuzzy msgid "Enabled GDNative Singleton" -msgstr "" +msgstr "Habilitar Singleton GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp #, fuzzy @@ -10820,54 +10579,6 @@ msgstr "Trieu la distà ncia:" msgid "Class name can't be a reserved keyword" msgstr "El nom de la classe no pot ser una paraula clau reservada" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "S'està generant la solució..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "S'està generant el projecte en C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "No s'ha pogut crear la solució." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "No s'ha pogut desar la solució." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Fet" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "No s'ha pogut crear el projecte en C#." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "Sobre el suport de C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Crea una solució en C#" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Muntatges" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Munta el Projecte" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Mostra el Registre" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Final de la traça de la pila d'excepció interna" @@ -11117,9 +10828,8 @@ msgid "Change Input Value" msgstr "Modifica el Valor de l'Entrada" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Resize Comment" -msgstr "Modifica el elementCanvas" +msgstr "Redimensionar comentari" #: modules/visual_script/visual_script_editor.cpp msgid "Can't copy the function node." @@ -11278,20 +10988,24 @@ msgstr "" "El carà cter '%s' no està permès als noms de paquets d'aplicacions Android." #: platform/android/export/export.cpp +#, fuzzy msgid "A digit cannot be the first character in a package segment." -msgstr "" +msgstr "Un dÃgit no pot ser el primer carà cter d'un segment de paquets." #: platform/android/export/export.cpp +#, fuzzy msgid "The character '%s' cannot be the first character in a package segment." msgstr "" +"El carà cter '%s' no pot ser el primer carà cter d'un segment de paquets." #: platform/android/export/export.cpp msgid "The package must have at least one '.' separator." msgstr "El paquet ha de tenir com a mÃnim un separador '. '." #: platform/android/export/export.cpp +#, fuzzy msgid "ADB executable not configured in the Editor Settings." -msgstr "" +msgstr "L'executable ADB no està configurat a la configuració de l'editor." #: platform/android/export/export.cpp msgid "OpenJDK jarsigner not configured in the Editor Settings." @@ -11360,20 +11074,17 @@ msgstr "" #: platform/iphone/export/export.cpp msgid "The character '%s' is not allowed in Identifier." -msgstr "No es permet el carà cter '% s' en l'Identificador." +msgstr "No es permet el carà cter '%s' en l'Identificador." #: platform/iphone/export/export.cpp -#, fuzzy msgid "A digit cannot be the first character in a Identifier segment." -msgstr "Un dÃgit no pot ser el primer carà cter d'un segment Identificador." +msgstr "Un dÃgit no pot ser el primer carà cter en un segment Identificador." #: platform/iphone/export/export.cpp -#, fuzzy msgid "" "The character '%s' cannot be the first character in a Identifier segment." msgstr "" -"El carà cter \"% s\" no pot ser el primer carà cter d'un segment " -"d'Identificador." +"El carà cter '%s' no pot ser el primer carà cter en un segment Identificador." #: platform/iphone/export/export.cpp msgid "The Identifier must have at least one '.' separator." @@ -11424,9 +11135,8 @@ msgid "Using default boot splash image." msgstr "Utilitzant la imatge de presentació per defecte." #: platform/uwp/export/export.cpp -#, fuzzy msgid "Invalid package unique name." -msgstr "El nom exclusiu del paquet no és và lid." +msgstr "El nom únic del paquet no és và lid." #: platform/uwp/export/export.cpp msgid "Invalid product GUID." @@ -11471,8 +11181,9 @@ msgstr "" "620x300." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Un recurs del tipus SpriteFrames s'ha de crear or especificar en la " @@ -11538,8 +11249,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "S'ha de proveir la propietat 'textura' amb una textura amb la forma de la " @@ -11553,7 +11265,8 @@ msgstr "" "(occluder) faci efecte." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "El polÃgon oclusiu és buit. Dibuixeu un polÃgon!" #: scene/2d/navigation_polygon.cpp @@ -11633,16 +11346,29 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 només proporciona formes de col·lisió nodes de derivats de " +"CollisionObject2D. Utilitzeu-lo només per donar una forma a nodes com " +"Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "Un node VisibilityEnable2D funcionarà millor en ser emparentat directament " "amb l'arrel de l'escena." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "El node ARVRCamera requereix un Pare del tipus ARVROrigin" #: scene/3d/arvr_nodes.cpp @@ -11737,9 +11463,10 @@ msgstr "" "StaticBody, RigidBody, KinematicBody, etc." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Cal proveir una forma perquè CollisionShape funcioni. Creeu-li un recurs de " "forma!" @@ -11773,6 +11500,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11813,8 +11544,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11828,7 +11559,10 @@ msgstr "" "Modifica la mida de les Formes de Col. lisió Filles." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "Cal que la propietat Camà assenyali cap a un node Spatial và lid." #: scene/3d/soft_body.cpp @@ -11848,8 +11582,9 @@ msgstr "" "Modifica la mida de les Formes de Col. lisió Filles." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Cal crear o establir un recurs SpriteFrames en la propietat 'Frames' perquè " @@ -11865,8 +11600,10 @@ msgstr "" "Modifica la mida de les Formes de Col·lisió Filles." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment necessita un recurs Ambiental." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11907,7 +11644,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Desconnecta '%s' de '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11922,7 +11659,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "L'arbre d'animació no és và lid." #: scene/animation/animation_tree_player.cpp @@ -11934,11 +11671,14 @@ msgid "Pick a color from the screen." msgstr "Trieu un color de la pantalla." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Mode Cru" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" #: scene/gui/color_picker.cpp -#, fuzzy msgid "Switch between hexadecimal and code values." msgstr "Canviar entre valors hexadecimals i de codi." @@ -11949,10 +11689,15 @@ msgstr "Afegeix el Color actual com a predeterminat" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11964,23 +11709,25 @@ msgid "Please Confirm..." msgstr "Confirmeu..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Les finestres emergents s'oculten per defecte tret que s'invoqui popup() o " "qualsevol de les funcions popup*(). És possible fer-les visibles mentre " "s'edita, però s'ocultaran durant l'execució." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "" #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer fou pensat per treballar-hi amb un sol Control fill.\n" @@ -12028,19 +11775,21 @@ msgid "Invalid font size." msgstr "La mida de la lletra no és và lida." #: scene/resources/visual_shader.cpp -#, fuzzy msgid "Input" -msgstr "Afegeix una Entrada" +msgstr "Entrada" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "Font no và lida pel Shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." -msgstr "La mida de la lletra no és và lida." +msgstr "Font no và lida pel Shader." #: servers/visual/shader_language.cpp -#, fuzzy msgid "Assignment to function." -msgstr "Assignació a funció" +msgstr "Assignació a funció." #: servers/visual/shader_language.cpp msgid "Assignment to uniform." @@ -12054,6 +11803,88 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Generating solution..." +#~ msgstr "S'està generant la solució..." + +#~ msgid "Generating C# project..." +#~ msgstr "S'està generant el projecte en C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "No s'ha pogut crear la solució." + +#~ 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#." + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "Sobre el suport de C#" + +#~ msgid "Create C# solution" +#~ msgstr "Crea una solució en C#" + +#~ msgid "Builds" +#~ msgstr "Muntatges" + +#~ msgid "Build Project" +#~ msgstr "Munta el Projecte" + +#~ msgid "View log" +#~ msgstr "Mostra el Registre" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment necessita un recurs Ambiental." + +#~ msgid "Enabled Classes" +#~ msgstr "Classes Habilitades" + +#~ msgid "Update Always" +#~ msgstr "Actualitza Sempre" + +#~ msgid "'camera' input parameter for all shader modes." +#~ msgstr "parà metre d'entrada 'cà mera' per a tots els modes shader." + +#~ msgid "'inv_camera' input parameter for all shader modes." +#~ msgstr "parà metre d'entrada 'inv_camera' per a tots els modes shader." + +#~ msgid "'inv_projection' input parameter for all shader modes." +#~ msgstr "parà metre d'entrada 'inv_projection' per a tots els modes shader." + +#~ msgid "'normal' input parameter for all shader modes." +#~ msgstr "parà metre d'entrada 'normal' per a tots els modes shader." + +#~ msgid "'projection' input parameter for all shader modes." +#~ msgstr "parà metre d'entrada 'projection' per a tots els modes shader." + +#~ msgid "'time' input parameter for all shader modes." +#~ msgstr "parà metre d'entrada 'time' per a tots els modes shader." + +#~ msgid "'viewport_size' input parameter for all shader modes." +#~ msgstr "parà metre d'entrada 'viewport_size' per a tots els modes shader." + +#~ msgid "'world' input parameter for all shader modes." +#~ msgstr "parà metre d'entrada 'world' per a tots els modes shader." + +#~ msgid "'alpha' input parameter for all shader modes." +#~ msgstr "parà metre d'entrada 'alpha' per a tots els modes shader." + +#~ msgid "'color' input parameter for all shader modes." +#~ msgstr "parà metre d'entrada 'color' per a tots els modes shader." + +#~ msgid "'texture_pixel_size' input parameter for all shader modes." +#~ msgstr "" +#~ "parà metre d'entrada 'texture_pixel_size' per a tots els modes shader." + +#~ msgid "Raw Mode" +#~ msgstr "Mode Cru" + #~ msgid "Path to Node:" #~ msgstr "Camà al Node:" @@ -12610,9 +12441,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Visibilitat dels Espacials" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Visibilitat del CanvasItem" - #~ msgid "Condition" #~ msgstr "Condició" diff --git a/editor/translations/cs.po b/editor/translations/cs.po index 34adfd7652..c9fbafaf13 100644 --- a/editor/translations/cs.po +++ b/editor/translations/cs.po @@ -7,7 +7,7 @@ # Jiri Hysek <contact@jirihysek.com>, 2017. # Josef KuchaÅ™ <josef.kuchar267@gmail.com>, 2018, 2019. # LudÄ›k Novotný <gladosicek@gmail.com>, 2016, 2018. -# Martin Novák <maidx@seznam.cz>, 2017. +# Martin Novák <maidx@seznam.cz>, 2017, 2019. # zxey <r.hozak@seznam.cz>, 2018. # VojtÄ›ch Å amla <auzkok@seznam.cz>, 2018, 2019. # Peeter Angelo <contact@peeterangelo.com>, 2019. @@ -15,8 +15,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-03-16 11:42+0000\n" -"Last-Translator: VojtÄ›ch Å amla <auzkok@seznam.cz>\n" +"PO-Revision-Date: 2019-07-09 10:46+0000\n" +"Last-Translator: Martin Novák <maidx@seznam.cz>\n" "Language-Team: Czech <https://hosted.weblate.org/projects/godot-engine/godot/" "cs/>\n" "Language: cs\n" @@ -24,7 +24,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 3.6-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -36,7 +36,7 @@ msgstr "" #: 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 "Nedostatek bytů pro dekódovánà bytů, nebo Å¡patný formát." +msgstr "Nedostatek bajtů pro dekódovánà bajtů, nebo neplatný formát." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" @@ -44,7 +44,7 @@ msgstr "Neplatný vstup %i (neproÅ¡el) ve výrazu" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" -msgstr "" +msgstr "self nemůže být použito, protože instance je null (neproÅ¡la)" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." @@ -56,11 +56,11 @@ msgstr "Neplatný index typu %s pro základnà typ %s" #: core/math/expression.cpp msgid "Invalid named index '%s' for base type %s" -msgstr "" +msgstr "NeplatnÄ› pojmenovaný index '%s' pro základnà typ %s" #: core/math/expression.cpp msgid "Invalid arguments to construct '%s'" -msgstr "Neplatné argumenty pro konstrukci '%s'" +msgstr "Neplatné argumenty pro zkonstruovánà '%s'" #: core/math/expression.cpp msgid "On call to '%s':" @@ -76,18 +76,16 @@ msgid "Balanced" msgstr "Vyvážený" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Mirror" -msgstr "Zrcadlit X" +msgstr "Zrcadlit" #: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp msgid "Time:" msgstr "ÄŒas:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Hodnota" +msgstr "Hodnota:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -102,14 +100,12 @@ msgid "Delete Selected Key(s)" msgstr "Smazat klÃÄ(e)" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Add Bezier Point" -msgstr "PÅ™idat bod" +msgstr "PÅ™idat bod Bézierovy kÅ™ivky" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Move Bezier Points" -msgstr "PÅ™esunout body" +msgstr "PÅ™esunout body Bézierovy kÅ™ivky" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Duplicate Keys" @@ -173,12 +169,10 @@ msgid "Animation Playback Track" msgstr "Stopa pÅ™ehrávánà animace" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (frames)" -msgstr "Délka animace (v sekundách)" +msgstr "Délka animace (ve snÃmcÃch)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (seconds)" msgstr "Délka animace (v sekundách)" @@ -220,8 +214,9 @@ msgid "Interpolation Mode" msgstr "InterpolaÄnà režim" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" -msgstr "" +msgstr "Režim ovinuté smyÄky (interpolace konce se zaÄátkem ve smyÄce)" #: editor/animation_track_editor.cpp msgid "Remove this track." @@ -266,12 +261,14 @@ msgid "Cubic" msgstr "Kubická" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Clamp Loop Interp" -msgstr "" +msgstr "Režim svorkové smyÄky" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Wrap Loop Interp" -msgstr "" +msgstr "Interpolace ovinutou smyÄkou" #: editor/animation_track_editor.cpp #: editor/plugins/canvas_item_editor_plugin.cpp @@ -352,7 +349,7 @@ msgstr "PÅ™eskupit stopy" #: editor/animation_track_editor.cpp msgid "Transform tracks only apply to Spatial-based nodes." -msgstr "" +msgstr "TransformaÄnà stopy se aplikujà pouze na uzly vycházejÃcà ze Spatial." #: editor/animation_track_editor.cpp msgid "" @@ -372,7 +369,7 @@ msgstr "Stopa animace může odkazovat pouze na uzly AnimationPlayer." #: editor/animation_track_editor.cpp msgid "An animation player can't animate itself, only other players." -msgstr "" +msgstr "PÅ™ehrávaÄ animace nemůže animovat sám sebe, pouze ostatnà pÅ™ehrávaÄe." #: editor/animation_track_editor.cpp msgid "Not possible to add a new track without a root" @@ -384,7 +381,7 @@ msgstr "PÅ™idat Bézierovu stopu" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a key." -msgstr "" +msgstr "Cesta stopy nenà validnÃ, nelze vložit klÃÄ." #: editor/animation_track_editor.cpp msgid "Track is not of type Spatial, can't insert key" @@ -402,7 +399,7 @@ msgstr "PÅ™idat stopu" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a method key." -msgstr "" +msgstr "Cesta stopy nenà validnÃ, nelze vložit klÃÄ metody." #: editor/animation_track_editor.cpp #, fuzzy @@ -430,9 +427,12 @@ msgid "Anim Scale Keys" msgstr "Animace: zmÄ›nit měřÃtko klÃÄů" #: editor/animation_track_editor.cpp +#, fuzzy msgid "" "This option does not work for Bezier editing, as it's only a single track." msgstr "" +"Tato možnost nefunguje s Beziérovými úpravami, protože se jedná pouze o " +"jednu stopu." #: editor/animation_track_editor.cpp msgid "" @@ -449,7 +449,17 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "UpozornÄ›nÃ: Upravuje se importovaná animace" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Vybrat vÅ¡e" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Vybrat uzel" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -460,9 +470,8 @@ msgid "Group tracks by node or display them as plain list." msgstr "Seskupit stopy podle uzlu nebo je zobrazit jako jednoduchý seznam." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Snap:" -msgstr "PÅ™ichytit" +msgstr "PÅ™ichycenÃ:" #: editor/animation_track_editor.cpp msgid "Animation step value." @@ -470,7 +479,7 @@ msgstr "Hodnota animaÄnÃho kroku." #: editor/animation_track_editor.cpp msgid "Seconds" -msgstr "" +msgstr "Sekundy" #: editor/animation_track_editor.cpp msgid "FPS" @@ -627,6 +636,10 @@ msgstr "JÃt na řádek" msgid "Line Number:" msgstr "ÄŒÃslo řádku:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Žádné shody" @@ -658,7 +671,7 @@ msgstr "Pouze výbÄ›r" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Standard" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -676,13 +689,13 @@ msgstr "Oddálit" msgid "Reset Zoom" msgstr "Obnovit původnà pÅ™iblÞenÃ" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "VarovánÃ" #: editor/code_editor.cpp msgid "Line and column numbers." -msgstr "" +msgstr "ÄŒÃsla řádků a sloupců." #: editor/connections_dialog.cpp #, fuzzy @@ -715,7 +728,7 @@ msgstr "Signály:" #: editor/connections_dialog.cpp msgid "Scene does not contain any script." -msgstr "" +msgstr "Scéna neobsahuje žádný skript." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -762,12 +775,11 @@ msgstr "JednorázovÄ›" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Odpojà signál po jeho prvnÃm vyvolánÃ." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "PÅ™ipojit Signál: " +msgstr "PÅ™ipojit Signál" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -788,6 +800,11 @@ msgid "Connect" msgstr "PÅ™ipojit" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signály:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "PÅ™ipojit '%s' k '%s'" @@ -955,7 +972,8 @@ msgid "Owners Of:" msgstr "VlastnÃci:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Odebrat vybrané soubory z projektu? (nelze vrátit zpÄ›t)" #: editor/dependency_editor.cpp @@ -1267,7 +1285,7 @@ msgstr "OtevÅ™Ãt rozloženà Audio Busu" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Neexistuje '%s' soubor." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1331,7 +1349,7 @@ msgstr "Neplatný název. Nesmà kolidovat s existujÃcà názvem tÅ™Ãdy enginu #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" "Neplatný název. Nesmà kolidovat s existujÃcÃm jménem zabudovaného typu." @@ -1343,7 +1361,7 @@ msgstr "" #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "KlÃÄové slovo nemůže být použito jako název pro autoload." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1511,6 +1529,10 @@ msgstr "Vlastnà šablona k uveÅ™ejnÄ›nà nebyla nalezena." msgid "Template file not found:" msgstr "Soubor Å¡ablony nenalezen:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1543,7 +1565,7 @@ msgstr "Uzel pÅ™esunut" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "Souborový systém" #: editor/editor_feature_profile.cpp @@ -1553,7 +1575,7 @@ msgstr "Nahradit vÅ¡echny (bez možnosti vrácenÃ)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "Profil musà být validnà název souboru a nesmà obsahovat '.'" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1562,7 +1584,7 @@ msgstr "Soubor nebo složka s tÃmto názvem již existuje." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Editor zakázán, Vlastnosti zakázány)" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1601,13 +1623,13 @@ msgstr "Hledat tÅ™Ãdy" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Formát souboru '%s' je neplatný, import zruÅ¡en." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." -msgstr "" +msgstr "Profil '%s' již existuje. PÅ™ed importem jej odstraňte, import zruÅ¡en." #: editor/editor_feature_profile.cpp #, fuzzy @@ -1616,11 +1638,11 @@ msgstr "Chyba pÅ™i nahrávánà šablony '%s'" #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "OdznaÄit" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Aktuálnà verze:" #: editor/editor_feature_profile.cpp @@ -1645,16 +1667,11 @@ msgstr "Exportovat" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "Dostupné uzly:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Hledat tÅ™Ãdy" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "Popis tÅ™Ãdy" @@ -1845,6 +1862,8 @@ msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"Existuje vÃcero importérů různých typů odkazujÃcÃch na soubor %s, import " +"zruÅ¡en" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2070,6 +2089,8 @@ msgid "" "This resource can't be saved because it does not belong to the edited scene. " "Make it unique first." msgstr "" +"Tento zdroj nemůže být uložen, protože nenáležà editované scénÄ›. NejdÅ™Ãve z " +"nÄ›j udÄ›lejte unikátnà zdroj." #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Save Resource As..." @@ -2431,6 +2452,8 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"Žádná hlavnà scéna nebyla definována. Vyberte jednu?\n" +"Může být pozdÄ›ji zmÄ›nÄ›no v \"Nastavenà projektu\" v kategorii 'aplikace'." #: editor/editor_node.cpp msgid "" @@ -2727,10 +2750,34 @@ msgid "Editor Layout" msgstr "Rozloženà editoru" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Dává smysl!" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "OtevÅ™Ãt složku s daty a nastavenÃm editoru" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "OtevÅ™Ãt dalšà editor" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Celá obrazovka" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "PÅ™epnout režim rozdÄ›lenÃ" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "OtevÅ™Ãt složku s daty a nastavenÃm editoru" @@ -2838,15 +2885,18 @@ msgid "Spins when the editor window redraws." msgstr "ToÄà se, když se okno editoru pÅ™ekresluje." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Aktualizovat vždy" +#, fuzzy +msgid "Update Continuously" +msgstr "Spojité" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Akualizovat zmÄ›ny" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Vypnout aktualizaÄnà koleÄko" #: editor/editor_node.cpp @@ -3037,7 +3087,7 @@ msgstr "ÄŒas" msgid "Calls" msgstr "VolánÃ" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3139,6 +3189,11 @@ msgid "Page: " msgstr "Strana: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Odstranit položku" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Nový klÃÄ:" @@ -3150,11 +3205,6 @@ msgstr "Nová hodnota:" msgid "Add Key/Value Pair" msgstr "Vložte pár klÃÄ/hodnota" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Odstranit položku" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3658,6 +3708,7 @@ msgid "Nodes not in Group" msgstr "Uzly nejsou ve skupinÄ›" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtrovat uzly" @@ -5277,6 +5328,14 @@ msgid "Load Emission Mask" msgstr "NaÄÃst emisnà masku" #: 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 +#, fuzzy +msgid "Restart" +msgstr "Restartovat nynÃ" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "VyÄistit emisnà masku" @@ -6199,10 +6258,20 @@ msgid "Find Next" msgstr "NajÃt dalÅ¡Ã" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filtrovat vlastnosti" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "PÅ™epnout abecednà řazenà seznamu metod." #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Režim filtru:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "SeÅ™adit" @@ -6439,20 +6508,24 @@ msgid "Syntax Highlighter" msgstr "ZvýrazňovaÄ syntaxe" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +msgstr "VytvoÅ™it body." + #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Vyjmout" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Vybrat vÅ¡e" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Odstranit řádek" @@ -8076,51 +8149,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8129,204 +8158,28 @@ msgid "Input parameter." msgstr "PÅ™ichytit k rodiÄovi" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" +msgid "'%s' input parameter for light shader mode." +msgstr "'%s' vstupnà parametr pro mód svÄ›telného shaderu." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" +msgid "'%s' input parameter for vertex shader mode." +msgstr "'%s' vstupnà parametr pro mód vertexového shaderu." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "'%s' vstupnà parametr pro mód vertexového a fragmentového shaderu." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8340,100 +8193,101 @@ msgstr "ZmÄ›nit skalárnà operátor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "E konstanta (2.718282). Reprezentuje základ pÅ™irozeného logaritmu." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "Epsilon konstanta (0.00001). Nejmenšà možné skalárnà ÄÃslo." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "Phi konstanta (1.618034). Zlatý Å™ez." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "Pi/4 konstanta (0.785398) nebo 45 stupňů." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "Pi/2 konstanta (1.570796) nebo 90 stupňů." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "Pi konstanta (3.141593) nebo 180 stupňů." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "Tau konstanta (6.283185) nebo 360 stupňů." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "Sqrt2 konstanta (1.414214). Druhá odmocnina ze 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "Vrátà absolutnà hodnotu parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "Vrátà arkus kosinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Pouze GLES3) Vrátà inverznà hyperbolický kosinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "Vrátà arkus sinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "(Pouze GLES3) Vrátà inverznà hyperbolický sinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "Vrátà arkus tangent parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "Vrátà arkus tangent parametrů." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Pouze GLES3) Vrátà inverznà hyperbolický tangent parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." msgstr "" +"Nalezne nejbližšà celé ÄÃslo, které je vÄ›tšà nebo stejné jako parametr." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "Omezà hodnotu, aby náležela intervalu dvou hodnot." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "Vrátà kosinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Pouze GLES3) Vrátà hyperbolický kosinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "Konvertuje množstvà v radiánech na stupnÄ›." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "Exponenciál se základem e." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "Exponenciál se základem 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "Nalezne nejbližšà celé ÄÃslo menšà nebo stejné jako parametr." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." @@ -8441,76 +8295,76 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "Vrátà inverznà odmocninu z parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "PÅ™irozený logaritmus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "Logaritmus se základem 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "Vrátà vÄ›tšà ze dvou hodnot." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "Vrátà menšà ze dvou hodnot." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "Lineárnà interpolace mezi dvÄ›ma skaláry." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "Vrátà opaÄnou hodnotu parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - skalár" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." -msgstr "" +msgstr "Vrátà hodnotu prvnÃho parametru umocnÄ›ného druhým." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "Konvertuje množstvà ve stupnÃch na radiány." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / skalár" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(Pouze GLES3) Nalezne nejbližšà celé ÄÃslo k parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(Pouze GLES3) Nalezne nejbližšà sudé celé ÄÃslo k parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "SevÅ™e hodnotu mezi 0.0 a 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "ZÃská znaménko z parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "Vrátà sinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(Pouze GLES3) Vrátà hyperbolický sinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "Vrátà odmocninu parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8530,11 +8384,11 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "Vrátà tangens parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Pouze GLES3) Vrátà hyperbolický tangens parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." @@ -8542,15 +8396,15 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "PÅ™iÄte skalár ke skaláru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "PodÄ›là skalár skalárem." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "Vynásobà skalár skalárem." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." @@ -9995,6 +9849,11 @@ msgid "Add Child Node" msgstr "PÅ™idat podÅ™Ãzený uzel" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Sbalit vÅ¡e" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "ZmÄ›nit typ" @@ -10025,7 +9884,8 @@ msgid "Delete (No Confirm)" msgstr "Odstranit (bez potvrzenÃ)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "PÅ™idat/VytvoÅ™it nový uzel" #: editor/scene_tree_dock.cpp @@ -10282,7 +10142,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Chyby" @@ -10700,54 +10560,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "Název tÅ™Ãdy nemůže být rezervované klÃÄové slovo" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Generovánà řeÅ¡enÃ..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "Generovánà C# projektu..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "NepodaÅ™ilo se vytvoÅ™it Å™eÅ¡enÃ." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "NepodaÅ™ilo se uložit Å™eÅ¡enÃ." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Hotovo" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "VytvoÅ™enà C# projektu selhalo." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "O podpoÅ™e C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "VytvoÅ™it C# Å™eÅ¡enÃ" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "SestavenÃ" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Sestavit projekt" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Zobrazit logy" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11351,8 +11163,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "Neplatné rozmÄ›ry obrázku uvÃtacà obrazovky (mÄ›ly by být 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Aby AnimatedSprite mohl zobrazovat snÃmky, zdroj SpriteFrames musà být " @@ -11418,8 +11231,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "Textura svÄ›tla musà být nastavena vlastnostà 'texture'." @@ -11430,7 +11244,7 @@ msgstr "" "Polygon stÃnÃtka musà být nastaven (nebo namalován), aby stÃnÃtko fungovalo." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11503,16 +11317,29 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 "" +"CollisionPolygon2D sloužà pouze jako kontejner tvarů objektu " +"CollissionObject2D a od nÄ›j odvozených uzlů. Použijte ho pouze jako potomka " +"Area2D, StaticBody2D, RigidBody2D, KinematicBody2D a dalÅ¡Ãch, pro urÄenà " +"jejich tvaru." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D funguje nejlépe, když je nastaven jako rodiÄ editované " "scény." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11599,9 +11426,10 @@ msgstr "" "a KinematicBody, abyste jim dali tvar." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Aby CollisionShape mohl fungovat, musà mu být poskytnut tvar. VytvoÅ™te mu " "prosÃm zdroj tvar!" @@ -11632,6 +11460,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11670,8 +11502,8 @@ msgstr "PathFollow funguje pouze, když je dÃtÄ›tem uzlu Path." #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11683,7 +11515,9 @@ msgstr "" #: scene/3d/remote_transform.cpp #, fuzzy -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "Aby ParticleAttractor2D fungoval, musà vlastnost path ukazovat na platný " "uzel Particles2D." @@ -11702,8 +11536,9 @@ msgstr "" "Změňte mÃsto nÄ›ho velikost koliznÃch tvarů potomků." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Zdroj SpriteFrames musà být vytvoÅ™en nebo nastaven ve vlastnosti 'Frames', " @@ -11718,7 +11553,9 @@ msgstr "" "potomka VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11756,7 +11593,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Odpojit '%s' od '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11770,7 +11607,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "Strom animace je neplatný." #: scene/animation/animation_tree_player.cpp @@ -11782,8 +11619,12 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "RAW mód" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11796,10 +11637,15 @@ msgstr "PÅ™idat aktuálnà barvu jako pÅ™edvolbu" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11811,23 +11657,25 @@ msgid "Please Confirm..." msgstr "PotvrÄte prosÃm..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Popupy budou standardnÄ› skryty, dokud nezavoláte popup() nebo nÄ›kterou z " "popup*() funkcÃ. I když je jejich zviditelnÄ›nà pro úpravu v pořádku, za bÄ›hu " "budou skryty." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Pokud má exp_edit hodnotu true, pak min_value musà být > 0." #: 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11877,6 +11725,11 @@ msgid "Input" msgstr "Vstup" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Neplatný zdroj pro shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Neplatný zdroj pro shader." @@ -11894,7 +11747,53 @@ msgstr "" #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "Konstanty nenà možné upravovat." + +#~ msgid "Generating solution..." +#~ msgstr "Generovánà řeÅ¡enÃ..." + +#~ msgid "Generating C# project..." +#~ msgstr "Generovánà C# projektu..." + +#~ msgid "Failed to create solution." +#~ msgstr "NepodaÅ™ilo se vytvoÅ™it Å™eÅ¡enÃ." + +#~ 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." + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "O podpoÅ™e C#" + +#~ msgid "Create C# solution" +#~ msgstr "VytvoÅ™it C# Å™eÅ¡enÃ" + +#~ msgid "Builds" +#~ msgstr "SestavenÃ" + +#~ msgid "Build Project" +#~ msgstr "Sestavit projekt" + +#~ msgid "View log" +#~ msgstr "Zobrazit logy" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Hledat tÅ™Ãdy" + +#~ msgid "Update Always" +#~ msgstr "Aktualizovat vždy" + +#~ msgid "Raw Mode" +#~ msgstr "RAW mód" #~ msgid "Path to Node:" #~ msgstr "Cesta k uzlu:" diff --git a/editor/translations/da.po b/editor/translations/da.po index ec06bd6fa6..103fc7ef35 100644 --- a/editor/translations/da.po +++ b/editor/translations/da.po @@ -458,6 +458,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Vælg alle" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Vælg Node" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "Vis kun spor fra noder valgt in træ." @@ -634,6 +644,10 @@ msgstr "GÃ¥ til linje" msgid "Line Number:" msgstr "Linjenummer:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Ingen Match" @@ -683,7 +697,7 @@ msgstr "Zoom Ud" msgid "Reset Zoom" msgstr "Nulstil Zoom" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -795,6 +809,11 @@ msgid "Connect" msgstr "Forbind" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signaler:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Forbind '%s' til '%s'" @@ -962,7 +981,8 @@ msgid "Owners Of:" msgstr "Ejere af:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Fjern de valgte filer fra projektet? (ej fortrydes)" #: editor/dependency_editor.cpp @@ -1338,7 +1358,7 @@ msgstr "" #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" "Ugyldigt navn. Det mÃ¥ ikke være i konflikt med eksisterende built-in type " "navn." @@ -1516,6 +1536,10 @@ msgstr "" msgid "Template file not found:" msgstr "Skabelonfil ikke fundet:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1547,7 +1571,7 @@ msgstr "Node Navn:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "Fil System" #: editor/editor_feature_profile.cpp @@ -1609,7 +1633,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1624,7 +1648,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Nuværende version:" #: editor/editor_feature_profile.cpp @@ -1649,16 +1673,11 @@ msgstr "Eksport" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "Tilgængelige Noder:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Søg Classes" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "Klasse beskrivelse" @@ -2746,10 +2765,34 @@ msgid "Editor Layout" msgstr "Redaktør opsætning" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Gem Scene" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Ã…bn redaktør Data/Indstillinger-mappe" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Ã…bn næste Editor" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Skifter fuldskærm" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Skifter Modus" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Ã…bn redaktør Data/Indstillinger-mappe" @@ -2858,15 +2901,18 @@ msgid "Spins when the editor window redraws." msgstr "Snurrer nÃ¥r editor vinduer gentegnes!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Altid Opdater" +#, fuzzy +msgid "Update Continuously" +msgstr "Kontinuerlig" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Opdater Ændringer" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "SlÃ¥ Opdaterings Snurrer Fra" #: editor/editor_node.cpp @@ -3057,7 +3103,7 @@ msgstr "Tid" msgid "Calls" msgstr "Kald" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3156,20 +3202,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3699,6 +3745,7 @@ msgid "Nodes not in Group" msgstr "Føj til Gruppe" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtrer noder" @@ -5363,6 +5410,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "Gem & genstart" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6302,10 +6357,20 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filtrer noder" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Filter mode:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Sorter" @@ -6546,20 +6611,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +msgstr "Slet points" + #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Cut" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Vælg alle" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Fjern Line" @@ -8181,51 +8250,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8233,203 +8258,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10108,6 +9957,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Klap alle sammen" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10138,8 +9992,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Opret Ny %s" #: editor/scene_tree_dock.cpp msgid "" @@ -10396,7 +10251,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10807,60 +10662,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "Fejler med at indlæse ressource." - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to save solution." -msgstr "Fejler med at indlæse ressource." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create C# project." -msgstr "Fejler med at indlæse ressource." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "Opret Abonnement" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "Projekt" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Vis filer" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11465,8 +11266,9 @@ 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 " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "En SpriteFrames ressource skal oprettes eller angives i egenskaben 'Frames' " @@ -11527,8 +11329,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "En tekstur med formen pÃ¥ lyset skal gives til egenskaben 'teksture'." @@ -11540,7 +11343,8 @@ msgstr "" "i kraft." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "Occluder polygon for denne occluder er tom. Tegn venligst en polygon!" #: scene/2d/navigation_polygon.cpp @@ -11614,16 +11418,28 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 tjener kun til at give en kollision figur til en " +"CollisionObject2D afledte node. Du skal kun bruge det som et barn af Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. til at give dem en form." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D fungerer bedst, nÃ¥r det bruges med den redigerede " "scenerod direkte som parent." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11706,9 +11522,10 @@ msgstr "" "StaticBody, RigidBody, KinematicBody, etc. til at give dem en form." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "En figur skal gives for at CollisionShape fungerer. Opret en figur ressource " "til det!" @@ -11739,6 +11556,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11779,8 +11600,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11791,7 +11612,10 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "Stien skal pege pÃ¥ en gyldig fysisk node for at virke." #: scene/3d/soft_body.cpp @@ -11806,8 +11630,9 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "En SpriteFrames ressource skal oprettes eller angivets i egenskaben 'Frames' " @@ -11820,7 +11645,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11860,7 +11687,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Afbryd '%s' fra '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11874,7 +11701,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11886,7 +11713,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11899,10 +11730,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11914,23 +11750,24 @@ msgid "Please Confirm..." msgstr "Bekræft venligst..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Popups er skjulte som standard, medmindre du kalder popup() eller nogen af " "popup*() funktionerne. At gøre dem synlige for redigering er fint, men de " "bliver skjult under afvikling." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11978,6 +11815,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "Ugyldig skriftstørrelse." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "Ugyldig skriftstørrelse." @@ -11997,6 +11839,37 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "Fejler med at indlæse ressource." + +#, fuzzy +#~ msgid "Failed to save solution." +#~ msgstr "Fejler med at indlæse ressource." + +#, fuzzy +#~ msgid "Failed to create C# project." +#~ msgstr "Fejler med at indlæse ressource." + +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "Opret Abonnement" + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "Projekt" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "Vis filer" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Søg Classes" + +#~ msgid "Update Always" +#~ msgstr "Altid Opdater" + #~ msgid "Path to Node:" #~ msgstr "Sti til Node:" diff --git a/editor/translations/de.po b/editor/translations/de.po index f4a51c906c..eac561c855 100644 --- a/editor/translations/de.po +++ b/editor/translations/de.po @@ -40,11 +40,14 @@ # Andreas During <anduring@web.de>, 2019. # Arthur S. Muszynski <artism90@gmail.com>, 2019. # Andreas Binczyk <andreas.binczyk@gmail.com>, 2019. +# Marcus Naschke <marcus.naschke@gmail.com>, 2019. +# datenbauer <d-vaupel@web.de>, 2019. +# Alexander Hausmann <alexander-hausmann+weblate@posteo.de>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-05-27 11:00+0000\n" +"PO-Revision-Date: 2019-07-09 10:46+0000\n" "Last-Translator: So Wieso <sowieso@dukun.de>\n" "Language-Team: German <https://hosted.weblate.org/projects/godot-engine/" "godot/de/>\n" @@ -53,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -65,8 +68,7 @@ msgstr "" #: 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 "" -"Nicht genügend Bytes zum Dekodieren des Byte-Strings oder ungültiges Format." +msgstr "Nicht genügend Bytes zum Dekodieren oder ungültiges Format." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" @@ -74,11 +76,12 @@ msgstr "Ungültige Eingabe %i (nicht übergeben) im Ausdruck" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" -msgstr "'self' kann nicht benutzt werden da die Instanz null ist (ungültig)" +msgstr "" +"'self' kann nicht benutzt werden, da die Instanz null ist (nicht übergeben)" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." -msgstr "Ungültige Operanden für Operator %s: %s und %s." +msgstr "Ungültige Operanden für Operator %s, %s und %s." #: core/math/expression.cpp msgid "Invalid index of type %s for base type %s" @@ -114,9 +117,8 @@ msgid "Time:" msgstr "Zeit:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Wert" +msgstr "Wert:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -471,10 +473,28 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Diese Animation gehört zu einer importierten Szene, Änderungen an " +"importierten Spuren werden nicht gespeichert.\n" +"\n" +"Um neue Spuren hinzufügen zu können muss unter den Importeinstellungen\n" +"„Animation > Storage“ zu „Files“ gesetzt und „Animation > Keep Custom " +"Tracks“ aktiviert werden.\n" +"Danach ist die Szene erneut zu importieren.\n" +"Alternativ kann eine Importeinstllung benutzt werden welche Animationen in " +"separate Dateien importiert." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Achtung: Es wird eine importierte Animation bearbeitet" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Alles auswählen" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "Nichts auswählen" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -650,6 +670,10 @@ msgstr "Gehe zu Zeile" msgid "Line Number:" msgstr "Zeilennummer:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Keine Übereinstimmungen" @@ -699,7 +723,7 @@ msgstr "Verkleinern" msgid "Reset Zoom" msgstr "Vergrößerung zurücksetzen" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Warnungen" @@ -708,38 +732,32 @@ msgid "Line and column numbers." msgstr "Zeilen- und Spaltennummern." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Im Ziel-Node muss eine Methode angegeben werden!" +msgstr "Methode des Ziel-Nodes muss angegeben werden." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Zielmethode nicht gefunden! Bitte eine gültige Methode angeben oder ein " +"Zielmethode nicht gefunden. Bitte eine gültige Methode angeben oder ein " "Skript dem Ziel-Node anhängen." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" msgstr "Mit Node verbinden:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Kann nicht zu Host verbinden:" +msgstr "Mit Skript verbinden:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Signale:" +msgstr "Durch Signal:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "Knoten enthält keine Geometrie." +msgstr "Szene enthält kein einziges Skript." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -767,9 +785,8 @@ msgid "Extra Call Arguments:" msgstr "Zusätzliche Aufrufparameter:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Erweiterte Einstellungen" +msgstr "Erweitert" #: editor/connections_dialog.cpp msgid "Deferred" @@ -779,6 +796,8 @@ msgstr "Verzögert" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Schiebt das Signal auf, speichert es in einer Warteschlange und sendet es " +"erst in einer Ruhephase." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -786,12 +805,11 @@ msgstr "Einmalig" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Trenne das Signal nach seiner ersten Emission." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Signal verbinden: " +msgstr "Signal kann nicht verbunden werden" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -812,6 +830,11 @@ msgid "Connect" msgstr "Verbinden" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signale:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Verbinde ‚%s‘ mit ‚%s‘" @@ -833,14 +856,12 @@ msgid "Disconnect" msgstr "Trennen" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Signal verbinden: " +msgstr "Ein Signal mit einer Methode verbinden" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Verbindung bearbeiten: " +msgstr "Verbindung bearbeiten:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -916,7 +937,6 @@ msgid "Dependencies For:" msgstr "Abhängigkeiten für:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." @@ -925,7 +945,6 @@ msgstr "" "Änderungen werden erst wirksam, wenn die Szene neu geladen wird." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." @@ -978,7 +997,8 @@ msgid "Owners Of:" msgstr "Besitzer von:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" "Ausgewählte Dateien aus dem Projekt löschen? (Kann nicht rückgängig gemacht " "werden)" @@ -1027,9 +1047,8 @@ msgstr "" "%d Datei(en) dauerhaft entfernen? (Kann nicht rückgängig gemacht werden)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "Abhängigkeiten" +msgstr "Abhängigkeiten aufzeigen" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1293,7 +1312,7 @@ msgstr "Öffne Audiobus-Layout" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Datei ‚%s‘ existiert nicht." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1350,29 +1369,20 @@ msgid "Valid characters:" msgstr "Gültige Zeichen:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"Ungültiger Name. Darf nicht mit existierenden Klassennamen der Engine " -"übereinstimmen." +msgstr "Darf nicht mit existierenden Klassennamen der Engine übereinstimmen." #: editor/editor_autoload_settings.cpp -#, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "" -"Ungültiger Name. Darf nicht mit existierenden eingebauten Typnamen " -"übereinstimmen." +msgid "Must not collide with an existing built-in type name." +msgstr "Darf nicht mit existierenden eingebauten Typnamen übereinstimmen." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." -msgstr "" -"Ungültiger Name. Darf nicht mit Namen existierender globaler Konstanten " -"übereinstimmen." +msgstr "Darf nicht mit Namen existierender globaler Konstanten übereinstimmen." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "Schlüsselwörter können nicht als Autoload-Namen genutzt werden." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1403,7 +1413,6 @@ msgid "Rearrange Autoloads" msgstr "Autoloads neu anordnen" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "Ungültiger Pfad." @@ -1458,9 +1467,8 @@ msgid "[unsaved]" msgstr "[ungespeichert]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Zuerst ein Wurzelverzeichnis setzen" +msgstr "Zuerst ein Wurzelverzeichnis auswählen." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1543,122 +1551,110 @@ msgstr "Selbst konfigurierte Release-Exportvorlage nicht gefunden." msgid "Template file not found:" msgstr "Vorlagendatei nicht gefunden:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Editor" +msgstr "3D-Editor" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Skripteditor öffnen" +msgstr "Skripteditor" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Öffne Nutzerinhaltesammlung" +msgstr "Nutzerinhaltesammlung" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Szenenbaum (Nodes):" +msgstr "Szenenbaum-Bearbeitung" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Import" +msgstr "Importleiste" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "Node verschoben" +msgstr "Node-Leiste" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Filesystem Dock" -msgstr "Dateisystem" +msgid "FileSystem and Import Docks" +msgstr "Dateisystem- und Import-Leiste" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Alle ersetzen (nicht rückgängig)" +msgstr "Profil ‚%s‘ löschen? (unumkehrbar)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" msgstr "" +"Das Profil muss ein gültiger Dateiname sein der keinen Punkt ‚.‘ enthält" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Es existiert bereits eine Datei oder ein Ordner mit diesem Namen." +msgstr "Ein Profil mit diesem Namen existiert bereits." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Editor deaktiviert, Einstellungen deaktiviert)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Nur Eigenschaften" +msgstr "(Einstellungen deaktiviert)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Einrasten deaktiviert" +msgstr "(Editor deaktiviert)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Klassenbeschreibung:" +msgstr "Klassen-Optionen:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Nächsten Editor öffnen" +msgstr "Kontextsensitiven Editor aktivieren" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Eigenschaften:" +msgstr "Aktivierte Eigenschaften:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "Funktionen" +msgstr "Aktivierte Funktionen:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Klassen suchen" +msgstr "Aktivierte Klassen:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Datei ‚%s‘ ist ungültig, Import wurde abgebrochen." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"Profil ‚%s‘ existiert bereits. Es muss erst entfernt werden bevor es " +"importiert werden kann, Import wurde abgebrochen." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Fehler beim Laden der Vorlage ‚%s‘" +msgstr "Fehler beim Speichern des Profils im Pfad: ‚%s‘." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Deaktivieren" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Current Profile" -msgstr "Aktuelle Version:" +msgid "Current Profile:" +msgstr "Aktuelles Profil:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Laufend:" +msgstr "Als aktuell auswählen" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1676,44 +1672,32 @@ msgid "Export" msgstr "Exportieren" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Available Profiles" -msgstr "Verfügbare Nodes:" - -#: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Klassen suchen" +msgid "Available Profiles:" +msgstr "Verfügbare Profile:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Klassenbeschreibung" +msgstr "Klassen-Optionen" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Neuer Name:" +msgstr "Neuer Profilname:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Bereich entfernen" +msgstr "Profil löschen" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Importiertes Projekt" +msgstr "Profil(e) importieren" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Projekt exportieren" +msgstr "Profil exportieren" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "Verwalte Exportvorlagen" +msgstr "Verwalte Editorfunktionenprofile" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1836,9 +1820,8 @@ msgid "(Un)favorite current folder." msgstr "Gegenwärtigen Ordner (de)favorisieren." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Versteckte Dateien ein- und ausblenden" +msgstr "Versteckte Dateien ein- oder ausblenden." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1875,6 +1858,8 @@ msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"Mehrere Importer verschiedener Typen zeigen zu Datei ‚%s‘, Import wurde " +"abgebrochen" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2220,13 +2205,12 @@ msgstr "" "Die Dokumentation zum Szenenimport beschreibt den nötigen Arbeitsablauf." #: editor/editor_node.cpp -#, fuzzy 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 "" "Diese Ressource gehört zu einer instantiierten oder geerbten Szene.\n" -"Änderungen an der Ressource werden beim Speichern der Szene nicht " +"Änderungen an der Ressource werden beim Speichern der aktuellen Szene nicht " "mitgespeichert." #: editor/editor_node.cpp @@ -2239,7 +2223,6 @@ msgstr "" "durchgeführt werden." #: editor/editor_node.cpp -#, fuzzy 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" @@ -2251,13 +2234,12 @@ msgstr "" "Die Dokumentation zum Szenenimport beschreibt den nötigen Arbeitsablauf." #: editor/editor_node.cpp -#, fuzzy 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 "" -"Dies ist ein Fern-Objekt, die Änderungen an ihm werden nicht gespeichert.\n" +"Dies ist ein Fern-Objekt, Änderungen an ihm werden nicht gespeichert.\n" "Die Dokumentation zum Debugging beschreibt den nötigen Arbeitsablauf." #: editor/editor_node.cpp @@ -2283,9 +2265,8 @@ msgid "Open Base Scene" msgstr "Basisszene öffnen" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Schnell Szenen öffnen..." +msgstr "Schnell öffnen..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2379,7 +2360,7 @@ msgstr "Editor verlassen?" #: editor/editor_node.cpp msgid "Open Project Manager?" -msgstr "Projektverwaltung öffnen?" +msgstr "Aktuelles Projekt schließen und zur Projektverwaltung zurückkehren?" #: editor/editor_node.cpp msgid "Save & Quit" @@ -2533,12 +2514,11 @@ msgstr "Andere Tabs schließen" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Tabs rechts schließen" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Alle schließen" +msgstr "Alle Tabs schließen" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2672,11 +2652,11 @@ msgstr "Projektdatenordner öffnen" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Android-Build-Vorlage installieren" #: editor/editor_node.cpp msgid "Quit to Project List" -msgstr "Verlasse zur Projektverwaltung" +msgstr "Zur Projektverwaltung zurückkehren" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp @@ -2784,25 +2764,45 @@ msgid "Editor Layout" msgstr "Editorlayout" #: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "Bildschirmfoto erstellen" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "" +"Bildschirmfotos werden im „Editor Data/Settings“-Verzeichnis gespeichert." + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "Bildschirmfotos automatisch öffnen" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "In externem Bildbearbeitungsprogramm öffnen." + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Vollbildmodus umschalten" #: editor/editor_node.cpp +msgid "Toggle System Console" +msgstr "Systemkonsole umschalten" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Editordaten-/Einstellungenordner öffnen" #: editor/editor_node.cpp msgid "Open Editor Data Folder" -msgstr "Editor-Dateiverzeichnis öffnen" +msgstr "Editordateiverzeichnis öffnen" #: editor/editor_node.cpp msgid "Open Editor Settings Folder" msgstr "Editoreinstellungenordner öffnen" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "Verwalte Exportvorlagen" +msgstr "Editorfunktionen verwalten" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2827,7 +2827,7 @@ msgstr "Internetdokumentation" #: editor/editor_node.cpp msgid "Q&A" -msgstr "Fragen&Antworten" +msgstr "Fragen & Antworten" #: editor/editor_node.cpp msgid "Issue Tracker" @@ -2895,16 +2895,16 @@ msgid "Spins when the editor window redraws." msgstr "Dreht sich, wenn das Editorfenster neu gezeichnet wird." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Immer aktualisieren" +msgid "Update Continuously" +msgstr "Fortlaufend aktualisieren" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "Änderungen aktualisieren" +msgid "Update When Changed" +msgstr "Bei Änderungen aktualisieren" #: editor/editor_node.cpp -msgid "Disable Update Spinner" -msgstr "Update-Anzeigerad deaktivieren" +msgid "Hide Update Spinner" +msgstr "Aktualisierungsanzeigerad ausblenden" #: editor/editor_node.cpp msgid "FileSystem" @@ -2933,17 +2933,20 @@ msgstr "Nicht speichern" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." msgstr "" +"Android-Build-Vorlage fehlt, Installation relevanter Vorlagen erforderlich." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Verwalte Exportvorlagen" +msgstr "Vorlagen verwalten" #: editor/editor_node.cpp msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"Dies wird das Android-Projekt für eigene Builds installieren.\n" +"Hinweis: Um es zu benutzen muss es in den jeweiligen Exportvoreinstellungen " +"aktivierten werden." #: editor/editor_node.cpp msgid "" @@ -2951,6 +2954,10 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"Android-Build-Vorlage wurde bereits installiert und wird nicht " +"überschrieben.\n" +"Zur Ausführung dieses Befehls muss das „build“-Verzeichnis manuell gelöscht " +"werden." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3094,7 +3101,7 @@ msgstr "Zeit" msgid "Calls" msgstr "Aufrufe" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "An" @@ -3201,6 +3208,11 @@ msgid "Page: " msgstr "Seite: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Entferne Element" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Neuer Schlüssel:" @@ -3212,11 +3224,6 @@ msgstr "Neuer Wert:" msgid "Add Key/Value Pair" msgstr "Schlüssel-Wert-Paar hinzufügen" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Entferne Element" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3423,9 +3430,8 @@ msgid "SSL Handshake Error" msgstr "SSL-Handshake-Fehler" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "Inhalte werden entpackt" +msgstr "Android-Build-Quellen werden entpackt" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3444,9 +3450,8 @@ msgid "Remove Template" msgstr "Entferne Vorlage" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" -msgstr "Vorlagendatei wählen" +msgstr "Vorlagendatei auswählen" #: editor/export_template_manager.cpp msgid "Export Template Manager" @@ -3506,9 +3511,8 @@ msgid "No name provided." msgstr "Kein Name angegeben." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "Angegebener Name enthält ungültige Zeichen" +msgstr "Angegebener Name enthält ungültige Zeichen." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3535,26 +3539,22 @@ msgid "Duplicating folder:" msgstr "Dupliziere Ordner:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Neue geerbte Szene..." +msgstr "Neue geerbte Szene" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Szene öffnen" +msgstr "Szenen öffnen" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Instanz" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" msgstr "Zu Favoriten hinzufügen" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" msgstr "Aus Favoriten entfernen" @@ -3604,21 +3604,18 @@ msgid "Rename" msgstr "Umbenennen" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Vorheriger Ordner" +msgstr "Vorherige(r) Ordner/Datei" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Nächster Ordner" +msgstr "Nächste(r) Ordner/Datei" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "Dateisystem erneut einlesen" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" msgstr "Geteilten Modus umschalten" @@ -3673,6 +3670,8 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Dateien mit den folgenden Endungen werden hinzugefügt. In den " +"Projekteinstellungen änderbar." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3724,6 +3723,7 @@ msgid "Nodes not in Group" msgstr "Nodes nicht in der Gruppe" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Nodes filtern" @@ -4113,9 +4113,8 @@ msgid "Open Animation Node" msgstr "Animations-Node öffnen" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "Dreieck existiert bereits" +msgstr "Dreieck existiert bereits." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4261,7 +4260,6 @@ msgid "Edit Filtered Tracks:" msgstr "Gefilterte Spuren bearbeiten:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" msgstr "Filtern aktivieren" @@ -4397,9 +4395,8 @@ msgid "Enable Onion Skinning" msgstr "Zwiebelhaut aktivieren" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "Zwiebelhaut" +msgstr "Zwiebelhaut-Einstellugen" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4967,6 +4964,8 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Wenn aktiviert ändert das Verschieben von Control-Nodes ihre Anker anstatt " +"ihre Ausmaße." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -4982,41 +4981,35 @@ msgstr "Ankerpunkte ändern" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "Werkzeugauswahl" +msgstr "Auswahl sperren" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "Ausgewähltes löschen" +msgstr "Auswahl entsperren" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Auswahl kopieren" +msgstr "Auswahl gruppieren" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Auswahl kopieren" +msgstr "Auswahl entgruppieren" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" msgstr "Pose einfügen" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" msgstr "Erstelle eigenständige(n) Knochen aus Node(s)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "Pose zurücksetzen" +msgstr "Knochen löschen" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -5105,7 +5098,6 @@ msgid "Snapping Options" msgstr "Einrasteinstellungen" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" msgstr "Am Gitter einrasten" @@ -5127,37 +5119,30 @@ msgid "Use Pixel Snap" msgstr "Pixelraster benutzen" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" msgstr "Intelligentes Einrasten" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" msgstr "An Elternobjekt einrasten" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" msgstr "Am Node-Anker einrasten" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" msgstr "An Node-Seiten einrasten" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" msgstr "Am Node-Mittelpunkt einrasten" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" msgstr "An anderen Nodes einrasten" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" msgstr "An Hilfslinien einrasten" @@ -5241,9 +5226,8 @@ msgid "Frame Selection" msgstr "Auswahl einrahmen" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Preview Canvas Scale" -msgstr "Zeige Atlas-Vorschau" +msgstr "Leinwandskalierung vorschauen" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -5299,9 +5283,8 @@ msgid "Divide grid step by 2" msgstr "Gitterstufe halbieren" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Pan View" -msgstr "Sicht von hinten" +msgstr "Sicht verschieben" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" @@ -5326,7 +5309,6 @@ msgid "Error instancing scene from %s" msgstr "Fehler beim Instanziieren von %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" msgstr "Standardtyp ändern" @@ -5370,6 +5352,13 @@ msgid "Load Emission Mask" msgstr "Emissionsmaske laden" #: 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 "Neustarten" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Emissionsmaske leeren" @@ -5415,14 +5404,12 @@ msgid "Create Emission Points From Node" msgstr "Erzeuge Emissionspunkte aus Node" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "Flach0" +msgstr "Flach 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "Flach1" +msgstr "Flach 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -5449,27 +5436,22 @@ msgid "Load Curve Preset" msgstr "Kurvenvorlage laden" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" msgstr "Punkt hinzufügen" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" msgstr "Punkt entfernen" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" msgstr "Links linear" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" msgstr "Rechts linear" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" msgstr "Vorlage laden" @@ -5526,18 +5508,16 @@ msgid "This doesn't work on scene root!" msgstr "Das geht nicht an der Wurzel der Szene!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Trimesh-Form erzeugen" +msgstr "Trimesh-Statische-Form erzeugen" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "Form-Erstellung fehlgeschlagen!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "Konvexe Form erstellen" +msgstr "Konvexe Form(en) erstellen" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -5594,9 +5574,8 @@ msgid "Create Trimesh Collision Sibling" msgstr "Trimesh-Kollisionselement erzeugen" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Collision Sibling(s)" -msgstr "Konvexes Kollisionselement erzeugen" +msgstr "Konvexe(s) Kollisionselement(e) erzeugen" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." @@ -5958,7 +5937,6 @@ msgid "Split Segment (in curve)" msgstr "Segment aufteilen (in Kurve)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" msgstr "Gelenk verschieben" @@ -6293,10 +6271,18 @@ msgid "Find Next" msgstr "Finde Nächstes" #: editor/plugins/script_editor_plugin.cpp +msgid "Filter scripts" +msgstr "Skripte filtern" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "Alphabetische Sortierung der Methodenliste umschalten." #: editor/plugins/script_editor_plugin.cpp +msgid "Filter methods" +msgstr "Methoden filtern" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Sortiere" @@ -6407,18 +6393,17 @@ msgid "Debug with External Editor" msgstr "Mit externem Editor debuggen" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Öffne Godot-Referenzdokumentation" +msgstr "Godot-Onlinedokumentation öffnen." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" msgstr "Dokumentation anfragen" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "Die Godot-Dokumentation durch Meinungsäußerung verbessern" +msgstr "" +"Mithelfen die Godot-Dokumentation durch Meinungsäußerungen zu verbessern." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6463,29 +6448,26 @@ msgid "Search Results" msgstr "Suchergebnisse" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "Mit Node verbinden:" +msgstr "Verbindungen mit Methode:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Quelle:" +msgstr "Quelle" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Signale" +msgstr "Signal" #: editor/plugins/script_text_editor.cpp msgid "Target" msgstr "Ziel" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "Nichts ist mit dem Eingang ‚%s‘ von Node ‚%s‘ verbunden." +msgstr "" +"Fehlende verbundene Methode ‚%s‘ für Signal ‚%s‘ von Node ‚%s‘ zu Node ‚%s‘." #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6532,20 +6514,24 @@ msgid "Syntax Highlighter" msgstr "Syntaxhervorhebung" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "Lesezeichen" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Punkte erstellen." #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Ausschneiden" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Alles auswählen" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Zeile löschen" @@ -6563,24 +6549,20 @@ msgid "Toggle Comment" msgstr "Kommentar umschalten" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "Freie Kamera umschalten" +msgstr "Lesezeichen umschalten" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "Springe zum nächsten Haltepunkt" +msgstr "Springe zum nächsten Lesezeichen" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Previous Bookmark" -msgstr "Springe zum vorigen Haltepunkt" +msgstr "Springe zum vorigen Lesezeichen" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "Alle Elemente entfernen" +msgstr "Alle Lesezeichen entfernen" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -6656,13 +6638,12 @@ msgid "Contextual Help" msgstr "Kontexthilfe" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"Die folgenden Dateien wurden im Dateisystem verändert.\n" -"Wie soll weiter vorgegangen werden?:" +"Dieser Shader wurde im Dateisystem verändert.\n" +"Wie soll weiter vorgegangen werden?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -7010,9 +6991,8 @@ msgid "Right View" msgstr "Sicht von rechts" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" -msgstr "Wechsle zwischen perspektivischer und orthogonaler Sicht" +msgstr "Zwischen perspektivischer und orthogonaler Sicht wechseln" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" @@ -7056,7 +7036,6 @@ msgid "Transform" msgstr "Transformation" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" msgstr "Objekt am Boden einrasten" @@ -7248,14 +7227,12 @@ msgid "Settings:" msgstr "Einstellungen:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "Auswahl einrahmen" +msgstr "Keine Frames ausgewählt" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "Frame hinzufügen" +msgstr "%d Frame(s) hinzufügen" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" @@ -7306,13 +7283,12 @@ msgid "Animation Frames:" msgstr "Animationsbilder:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Textur(en) zu TileSet hinzufügen." +msgstr "Textur aus Datei hinzufügen" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "Frame aus Sprite-Sheet hinzufügen" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7331,29 +7307,24 @@ msgid "Move (After)" msgstr "Dahinter bewegen" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "Aufrufsverlauf" +msgstr "Frames auswählen" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Horizontal spiegeln" +msgstr "Horizontal:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "Vertices" +msgstr "Vertikal:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "Alles auswählen" +msgstr "Alle Frames aus/ab-wählen" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "Von Szene erstellen" +msgstr "Frames aus Sprite-Sheet erzeugen" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" @@ -7425,9 +7396,8 @@ msgid "Remove All" msgstr "Alles entfernen" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "Thema bearbeiten..." +msgstr "Thema bearbeiten" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7454,23 +7424,20 @@ msgid "Create From Current Editor Theme" msgstr "Aus derzeitigem Editor-Thema erstellen" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Toggle Button" -msgstr "Maustaste" +msgstr "Knopf umschalten" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Mittlere Taste" +msgstr "Deaktivierter Knopf" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" msgstr "Element" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "Deaktiviert" +msgstr "Deaktiviertes Objekt" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -7490,21 +7457,19 @@ msgstr "Markiertes Element der Auswahl" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "Ben. Trenner" #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Untermenü" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "Element" +msgstr "Element 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "Element" +msgstr "Element 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -7515,9 +7480,8 @@ msgid "Many" msgstr "Viele" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled LineEdit" -msgstr "Deaktiviert" +msgstr "Deaktiviertes LineEdit" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -7532,13 +7496,12 @@ msgid "Tab 3" msgstr "Tab 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "bearbeitbare Unterobjekte" +msgstr "Bearbeitbares Element" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "Unterbaum" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7618,14 +7581,12 @@ msgid "Mirror Y" msgstr "Y-Koordinaten spiegeln" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "Autokacheln" +msgstr "Autokacheln deaktivieren" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "Kachelpriorität bearbeiten" +msgstr "Priorität aktivieren" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7636,35 +7597,32 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Umsch+RMT: Linie zeichnen\n" +"Umsch+Strg+RMT: Rechteck einfärben" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" msgstr "Wähle Kachel" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" msgstr "Nach links rotieren" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" msgstr "Nach rechts rotieren" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Horizontally" -msgstr "Horizontal spiegeln" +msgstr "Horizontal umdrehen" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Vertically" -msgstr "Vertikal spiegeln" +msgstr "Vertikal umdrehen" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" -msgstr "Transform löschen" +msgstr "Transform leeren" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Add Texture(s) to TileSet." @@ -7699,44 +7657,36 @@ msgid "Select the previous shape, subtile, or Tile." msgstr "Die vorherige Form oder Kachel auswählen." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "Ausführungsmodus:" +msgstr "Bereichsmodus" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "Interpolationsmodus" +msgstr "Kollisionsmodus" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "Occlusion-Polygon bearbeiten" +msgstr "Verschlussmodus" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "Navigations-Mesh erzeugen" +msgstr "Navigationsmodus" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "Rotationsmodus" +msgstr "Bitmaskenmodus" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "Export-Modus:" +msgstr "Prioritätsmodus" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "Schwenkmodus" +msgstr "Symbolmodus" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "Schwenkmodus" +msgstr "Z-Indexmodus" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7823,15 +7773,15 @@ msgid "Delete polygon." msgstr "Polygon löschen." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy 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 "" -"LMT: Bit anstellen.\n" -"RMT: Bit ausstellen.\n" +"LMT: Bit setzen.\n" +"RMT: Bit löschen.\n" +"Umsch+LMT: Wildcard-Bit setzen.\n" "Auf andere Kachel klicken um diese zu bearbeiten." #: editor/plugins/tile_set_editor_plugin.cpp @@ -7945,77 +7895,64 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input +" -msgstr "Eingang hinzufügen" +msgstr "Eingang hinzufügen +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add output +" -msgstr "Eingang hinzufügen" +msgstr "Ausgang hinzufügen +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "Skalierung:" +msgstr "Skalar" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Inspektor" +msgstr "Vektor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Boolean" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "Eingang hinzufügen" +msgstr "Eingangsschnittstelle hinzufügen" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Ausgangsschnittstelle hinzufügen" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "Standardtyp ändern" +msgstr "Eingangsschnittstellentyp ändern" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "Standardtyp ändern" +msgstr "Ausgangsschnittstellentyp ändern" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "Ändere Eingabename" +msgstr "Eingangsschnittstellenname ändern" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "Ändere Eingabename" +msgstr "Ausgangsschnittstellenname ändern" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "Punkt entfernen" +msgstr "Eingangsschnittstelle entfernen" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "Punkt entfernen" +msgstr "Ausgangsschnittstelle entfernen" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "Ausdruck ändern" +msgstr "Ausdruck eintragen" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "VisualShader" +msgstr "VisualShader-Nodegröße anpassen" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" @@ -8054,540 +7991,316 @@ msgid "Light" msgstr "Licht" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "Erzeuge Node" +msgstr "Shader-Node erzeugen" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "Springe zu Funktion" +msgstr "Farbfunktion." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "Farboperator." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "Funktion erstellen" +msgstr "Graustufenfunktion." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "Wandelt HSV-Vektor in RGB-Gegenwert um." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "Wandelt RGB-Vektor in HSV-Gegenwert um." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "Funktion umbenennen" +msgstr "Sepiafunktion." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "Brenn-Operator." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "Verdunkel-Operator." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Difference operator." -msgstr "nur Unterschiede" +msgstr "Differenz-Operator." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." -msgstr "" +msgstr "Umgehungsoperator." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "HardLight operator" -msgstr "" +msgstr "Hartlicht-Operator" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." -msgstr "" +msgstr "Erhell-Operator." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." -msgstr "" +msgstr "Überlagerungsoperator." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Screen operator." -msgstr "" +msgstr "Bildschirm-Opertor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "SoftLight operator." -msgstr "" +msgstr "Weichlicht-Operator." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color constant." -msgstr "Konstant" +msgstr "Farbkonstante." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color uniform." -msgstr "Transform löschen" +msgstr "Farb-Uniform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided scalars are equal, greater or " "less." msgstr "" +"Gibt einen geeigneten Vektor zurück je nach dem ob die übergebenen Skalare " +"gleich, größer oder kleiner sind." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided boolean value is true or false." msgstr "" +"Gibt einen geeigneten Vektor zurück je nach dem ob der übergebene Wert wahr " +"oder falsch ist." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Boolean constant." -msgstr "Ändere Vektorkonstante" +msgstr "Boolean-Konstante." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean uniform." -msgstr "" +msgstr "Boolean-Uniform." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" +msgid "'%s' input parameter for all shader modes." +msgstr "‚%s‘-Eingabeparameter für alle Shadermodi." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Input parameter." -msgstr "An Elternobjekt einrasten" +msgstr "Eingabeparameter." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "‚%s‘-Eingabeparameter für Vertex- und Fragment-Shadermodus." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "‚%s‘-Eingabeparameter für Fragment- und Light-Shadermodus." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for fragment shader mode." +msgstr "‚%s‘-Eingabeparameter für Fragment-Shadermodus." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" +msgid "'%s' input parameter for light shader mode." +msgstr "‚%s‘-Eingabeparameter für Light-Shadermodus." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for vertex shader mode." +msgstr "‚%s‘-Eingabeparameter für Vertex-Shadermodus." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "‚%s‘-Eingabeparameter für Vertex- und Fragment-Shadermodus." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar function." -msgstr "Ändere skalare Funktion" +msgstr "Skalarfunktion." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar operator." -msgstr "Ändere skalaren Operator" +msgstr "Skalaroperator." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "Konstante E (2.718282). Basis des natürlichen Logarithmus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "Konstante Epsilon (0.00001). Kleinstmöglicher skalarer Wert." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "Konstante Phi (1.618034). Goldener Schnitt." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "Konstante Pi/4 (0.785398) oder 45 Grad." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "Konstante Pi/2 (1.570796) oder 90 Grad." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "Konstante Pi (3.141593) oder 180 Grad." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "Konstante Tau (6.283185) oder 360 Grad." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "Konstante Sqrt2 (1.414214). Quadratwurzel aus 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "Gibt den absoluten Betrag des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "Gibt den Arkuskosinus des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." msgstr "" +"(Nur GLES3) Gibt den inversen hyperbolischen Kosinus des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "Gibt den Arkussinus des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." msgstr "" +"(Nur GLES3) Gibt den inversen hyperbolischen Sinus des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "Gibt den Arkustangens des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "Gibt den Arkuskosinus2 der Parameter zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." msgstr "" +"(Nur GLES3) Gibt den inversen hyperbolischen Tangens des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "Gibt die nächste Ganzzahl größer gleich dem Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "Schränkt den Wert auf das Intervall zweier Werte ein." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "Gibt den Kosinus des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Nur GLES3) Gibt den hyperbolischen Kosinus des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "Wandelt einen Wert von Bogenmaß zu Grad um." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "Basis-e exponentiell." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "Basis-2 exponentiell." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "Gibt die nächste Ganzzahl kleiner gleich dem Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "Berechnet den Bruchteil des Parameters." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "Gibt die inverse Quadratwurzel des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "Natürlicher Logarithmus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "Basis-2 Logarithmus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "Gibt den größeren zweier Parameter zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "Gibt den kleineren zweier Parameter zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "Lineare Interpolation zwischen zwei Skalaren." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "Gibt den inversen Wert des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - Skalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." -msgstr "" +msgstr "Gibt den ersten Parameter hoch den Zweiten zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "Wandelt einen Wert von Grad zu Bogenmaß um." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / Skalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(nur GLES3) Gibt die nächste Ganzzahl vom Parameter zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(nur GLES3) Gibt die nächste gerade Ganzzahl vom Parameter zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "Schränkt den Wert auf das Intervall von 0.0 bis 1.0 ein." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "Extrahiert das Vorzeichen des Parameters." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "Gibt den Sinus des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(nur GLES3) Gibt den hyperbolischen Sinus des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "Gibt die Quadratwurzel des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8597,6 +8310,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"Weichschrittfunktion ( Skalar(Kante0), Skalar(Kante1), Skalar(x) ).\n" +"\n" +"Gibt 0.0 zurück falls ‚x‘ kleiner als ‚Kante0‘, gibt 1.0 zurück falls ‚x‘ " +"größer ‚Kante1‘. Ansonsten wird ein durch Hermite-Polynome interpolierter " +"Wert zwischen 0.0 und 1.0 zurück gegeben." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8604,71 +8322,69 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Schrittfunktion ( Skalar(Kante), Skalar(x) ).\n" +"\n" +"Gibt 0.0 zurück falls ‚x‘ kleiner als ‚Kante‘, ansonsten 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "Gibt den Tangens des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(nur GLES3) Gibt den hyperbolischen Tangens des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." -msgstr "" +msgstr "(Nur GLES3) Gibt den abgeschnittenen Wert des Parameters zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "Addiert Skalar zu Skalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "Teilt Skalar durch Skalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "Multipliziert Skalar mit Skalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "Gibt den Rest der Division zweier Skalare zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "Subtrahiert ein Skalar von einen anderem." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar constant." -msgstr "Ändere skalare Konstante" +msgstr "Skalarkonstante." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar uniform." -msgstr "Ändere Skalar-Uniform" +msgstr "Skalar-Uniform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "Kubisches Texturfinden ausführen." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the texture lookup." -msgstr "" +msgstr "Texturfinden ausführen." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Cubic texture uniform." -msgstr "Ändere Textur-Uniform" +msgstr "Kubisches Textur-Uniform." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "2D texture uniform." -msgstr "Ändere Textur-Uniform" +msgstr "2D-Textur-Uniform." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform function." -msgstr "Transformationsdialog..." +msgstr "Transformierungsfunktion." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8680,74 +8396,77 @@ msgid "" "whose number of rows is the number of components in 'c' and whose number of " "columns is the number of components in 'r'." msgstr "" +"(nur GLES3) Berechnet das äußere Produkt zweier Vektoren.\n" +"\n" +"Führt eine Matrixmultiplikation des ersten Parameters ‚c‘ (interpretiert als " +"Spaltenvektor = Matrix aus einer Spalte) mit dem zweiten Parameter " +"‚r‘ (interpretiert als Zeilenvektor = Matrix aus einer Zeile) aus und gibt " +"eine Matrix zurück die aus ‚cn‘ Zeilen und ‚rn‘ Spalten besteht, wobei ‚cn‘ " +"und ‚rn‘ die Anzahl der Komponenten von ‚c‘ und ‚r‘ sind." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes transform from four vectors." -msgstr "" +msgstr "Erstellt Transform aus vier Vektoren." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes transform to four vectors." -msgstr "" +msgstr "Extrahiert vier Vektoren aus Transform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the determinant of a transform." -msgstr "" +msgstr "(nur GLES3) Berechnet die Determinante eines Transforms." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the inverse of a transform." -msgstr "" +msgstr "(nur GLES3) Invertiert ein Transform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the transpose of a transform." -msgstr "" +msgstr "(nur GLES3) Transponiert ein Transform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies transform by transform." -msgstr "" +msgstr "Multipliziert Transform mit Transform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by transform." -msgstr "" +msgstr "Multipliziert Vektor mit Transform." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform constant." -msgstr "Transformation abgebrochen." +msgstr "Transformkonstante." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform uniform." -msgstr "Transformation abgebrochen." +msgstr "Transform-Uniform." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector function." -msgstr "Zuweisung an Funktion." +msgstr "Vektorfunktion." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector operator." -msgstr "Ändere Vektoroperator" +msgstr "Vektoroperator." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "Formt Vektor aus drei Skalaren." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "Extrahiert drei Skalare aus Vektor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "Berechnet das Kreuzprodukt zweier Vektoren." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "Gibt die Distanz zwischen zwei Punkten zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "Berechnet das Skalarprodukt aus zwei Vektoren." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8756,36 +8475,43 @@ msgid "" "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 "" +"Gibt einen Vektor zurück der in die gleiche Richtung wie ein Referenzvektor " +"zeigt. Die Funktion benötigt drei Vektorparameter: N, der auszurichtende " +"Vektor, E, der Einfallsvektor und Nref, der Referenzvektor. Ist das " +"Skalarprodukt aus E und Nref kleiner als null wird N zurückgegeben, " +"ansonsten -N." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "Berechnet die Länge eines Vektors." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "Lineare Interpolation zwischen zwei Vektoren." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." -msgstr "" +msgstr "Berechnet den normierten Vektor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - vector" -msgstr "" +msgstr "1.0 - Vektor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / vector" -msgstr "" +msgstr "1.0 / Vektor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns a vector that points in the direction of reflection ( a : incident " "vector, b : normal vector )." msgstr "" +"Berechnet den Vektor der in die Richtung einer Reflektion zeigt (a: " +"Einfallsvektor, b: Normalenvektor)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns a vector that points in the direction of refraction." -msgstr "" +msgstr "Berechnet den Vektor der in Richtung einer Brechung zeigt." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8795,6 +8521,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"Weiche Stufenfunktion ( Vektor(Kante0), Vektor(Kante1), Vektor(x) ).\n" +"\n" +"Gibt 0.0 zurück falls ‚x‘ kleiner als ‚Kante0‘, gibt 1.0 zurück falls ‚x‘ " +"größer als ‚Kante1‘. Ansonsten wird ein durch Hermite-Polynome " +"interpolierter Wert zwischen 0.0 und 1.0 zurückgegeben." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8804,6 +8535,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"Weiche Stufenfunktion ( Skalar(Kante0), Skalar(Kante1), Vektor(x) ).\n" +"\n" +"Gibt 0.0 zurück falls ‚x‘ kleiner als ‚Kante0‘, gibt 1.0 zurück falls ‚x‘ " +"größer als ‚Kante1‘. Ansonsten wird ein durch Hermite-Polynome " +"interpolierter Wert zwischen 0.0 und 1.0 zurückgegeben." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8811,6 +8547,9 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Stufenfunktion ( Vektor(Kante), Vektor(x) ).\n" +"\n" +"Gibt 0.0 zurück falls ‚x‘ kleiner als ‚Kante‘, ansonsten 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8818,36 +8557,37 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Stufenfunktion ( Skalar(Kante), Vektor(x) ).\n" +"\n" +"Gibt 0.0 zurück falls ‚x‘ kleiner als ‚Kante‘, ansonsten 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." -msgstr "" +msgstr "Addiert Vektor zu Vektor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "" +msgstr "Teilt Vektor durch Vektor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." -msgstr "" +msgstr "Multipliziert Vektor mit Vektor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two vectors." -msgstr "" +msgstr "Gibt den Rest einer Division zweier Vektoren zurück." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts vector from vector." -msgstr "" +msgstr "Subtrahiert Vektor von Vektor." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector constant." -msgstr "Ändere Vektorkonstante" +msgstr "Vektorkonstante." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector uniform." -msgstr "Zuweisung an Uniform." +msgstr "Vektor-Uniform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8855,56 +8595,77 @@ msgid "" "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 "" +"Ein selbst festgelegter Shader-Sprachausdruck mit eigens festgelegten Ein- " +"und Ausgangsschnittstellen. Dieser Code wird direkt in eine Vertex-, " +"Fragment- oder Light-Funktion kopiert, Funktionsdeklarationen können hier " +"nicht verwendet werden." #: 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 "" +"Gibt den Fresnelabfall abgeleitet aus dem Skalarprodukt aus " +"Oberflächennormalenvektor und Kamerablickrichtung zurück (zugeordnete " +"Eingänge müssen übergeben werden)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function." msgstr "" +"(nur GLES3) (nur für Fragment-/Light-Modus) Skalare Ableitungsfunktion." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function." msgstr "" +"(nur GLES3) (nur für Fragment-/Light-Modus) Vektorielle Ableitungsfunktion." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using " "local differencing." msgstr "" +"(nur GLES3) (nur für Fragment-/Light-Modus) (Vektor) Lokale differenzielle " +"Ableitung in ‚x‘-Richtung." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using " "local differencing." msgstr "" +"(nur GLES3) (nur für Fragment-/Light-Modus) (Skalar) Lokale differenzielle " +"Ableitung in ‚x‘-Richtung." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using " "local differencing." msgstr "" +"(nur GLES3) (nur für Fragment-/Light-Modus) (Vektor) Lokale differenzielle " +"Ableitung in ‚y‘-Richtung." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using " "local differencing." msgstr "" +"(nur GLES3) (nur für Fragment-/Light-Modus) (Skalar) Lokale differenzielle " +"Ableitung in ‚y‘-Richtung." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(nur GLES3) (nur für Fragment-/Light-Modus) (Vektor) Summe der absoluten " +"Ableitungen in ‚x‘- und ‚y‘-Richtung." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(nur GLES3) (nur für Fragment-/Light-Modus) (Skalar) Summe der absoluten " +"Ableitungen in ‚x‘- und ‚y‘-Richtung." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "VisualShader" @@ -9246,7 +9007,6 @@ msgid "Are you sure to open more than one project?" msgstr "Sollen wirklich mehrere Projekte geöffnet werden?" #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file does not specify the version of Godot " "through which it was created.\n" @@ -9258,18 +9018,17 @@ msgid "" "Warning: You won't be able to open the project with previous versions of the " "engine anymore." msgstr "" -"Die folgenden Projekteinstellungsdatei enthält keine Information darüber, " -"mit welcher Version von Godot sie erstellt wurde.\n" +"Die folgende Projekteinstellungsdatei enthält keine Information darüber, mit " +"welcher Version von Godot sie erstellt wurde.\n" "\n" "%s\n" "\n" -"Wenn Sie mit dem Öffnen fortfahren, wird die Datei in das aktuelle " -"Konfigurationsdateiformat von Godot konvertiert.\n" +"Sollte das Öffnen fortgesetzt werden, wird die Datei in das " +"Konfigurationsdateiformat der aktuellen Godot-Version umgewandelt.\n" "Warnung: Das Projekt kann nach der Konvertierung nicht mehr mit einer " -"älteren Version geöffnet werden." +"älteren Godot-Version geöffnet werden." #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file was generated by an older engine " "version, and needs to be converted for this version:\n" @@ -9280,14 +9039,14 @@ msgid "" "Warning: You won't be able to open the project with previous versions of the " "engine anymore." msgstr "" -"Die Projekteinstellungsdatei ist mit einer älteren Version erstellt worden " -"und muss in die folgende Version konvertiert werden:\n" +"Die folgende Projekteinstellungsdatei ist mit einer älteren Godot-Version " +"erstellt worden und muss für die aktuelle Version konvertiert werden:\n" "\n" "%s\n" "\n" -"Möchten Sie die Konvertierung durchführen?\n" -"Warnung: Das Projekt kann nach der Konvertierung nicht mehr mit einer " -"älteren Version geöffnet werden." +"Soll die Umwandlung vorgenommen werden?\n" +"Warnung: Das Projekt kann nach der Umwandlung nicht mehr mit einer älteren " +"Version geöffnet werden." #: editor/project_manager.cpp msgid "" @@ -9298,13 +9057,13 @@ msgstr "" "sind nicht kompatibel mit der aktuell genutzten Version." #: editor/project_manager.cpp -#, fuzzy 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 "" -"Projekt kann nicht ausgeführt werden: Keine Hauptszene festgelegt.\n" +"Das Projekt kann nicht ausgeführt werden: Es wurde keine Hauptszene " +"festgelegt.\n" "In den Projekteinstellungen unter der Kategorie „Anwendung“ kann die " "Hauptszene festgelegt werden." @@ -9318,39 +9077,34 @@ msgstr "" "Das Projekt muss eingestellt werden einen ersten Import einzuleiten." #: editor/project_manager.cpp -#, fuzzy msgid "Are you sure to run %d projects at once?" -msgstr "Sollen wirklich mehrere Projekte ausgeführt werden?" +msgstr "Sollen wirklich %d Projekte gleichzeitig ausgeführt werden?" #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove %d projects from the list?\n" "The project folders' contents won't be modified." msgstr "" -"Das Projekt aus der Liste entfernen? (Inhalte des Projektordners werden " -"nicht geändert)" +"%d Projekte aus der Liste entfernen?\n" +"Inhalte der Projektordner werden nicht geändert." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove this project from the list?\n" "The project folder's contents won't be modified." msgstr "" -"Das Projekt aus der Liste entfernen? (Inhalte des Projektordners werden " -"nicht geändert)" +"Dieses Projekt aus der Liste entfernen?\n" +"Inhalte des Projektordners werden nicht geändert." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove all missing projects from the list? (Folders contents will not be " "modified)" msgstr "" -"Das Projekt aus der Liste entfernen? (Inhalte des Projektordners werden " +"Alle fehlenden Projekte aus der Liste entfernen? (Dateisysteminhalte werden " "nicht geändert)" #: editor/project_manager.cpp -#, fuzzy msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." @@ -9360,11 +9114,12 @@ msgstr "" "Projektverwaltung aktualisiert." #: editor/project_manager.cpp -#, fuzzy msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." -msgstr "Sollen wirklich %s Ordner nach Godot-Projekten durchsucht werden?" +msgstr "" +"Sollen wirklich %s Ordner nach Godot-Projekten durchsucht werden?\n" +"Dies kann eine Weile dauern." #: editor/project_manager.cpp msgid "Project Manager" @@ -9387,9 +9142,8 @@ msgid "New Project" msgstr "Neues Projekt" #: editor/project_manager.cpp -#, fuzzy msgid "Remove Missing" -msgstr "Punkt entfernen" +msgstr "Fehlende entfernen" #: editor/project_manager.cpp msgid "Templates" @@ -9408,13 +9162,13 @@ msgid "Can't run project" msgstr "Projekt kann nicht ausgeführt werden" #: editor/project_manager.cpp -#, fuzzy msgid "" "You currently don't have any projects.\n" "Would you like to explore official example projects in the Asset Library?" msgstr "" "Zur Zeit sind keine Projekte vorhanden.\n" -"Sollen Beispielprojekte aus der Nutzerinhaltesammlung angezeigt werden?" +"Sollen offizielle Beispielprojekte aus der Nutzerinhaltesammlung angezeigt " +"werden?" #: editor/project_settings_editor.cpp msgid "Key " @@ -9441,9 +9195,8 @@ msgstr "" "oder ‚\"‘ enthalten" #: editor/project_settings_editor.cpp -#, fuzzy msgid "An action with the name '%s' already exists." -msgstr "Aktion ‚%s‘ existiert bereits!" +msgstr "Eine Aktion mit dem Namen ‚%s‘ existiert bereits." #: editor/project_settings_editor.cpp msgid "Rename Input Action Event" @@ -9662,9 +9415,9 @@ msgid "Override For..." msgstr "Überschreiben für..." #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -#, fuzzy msgid "The editor must be restarted for changes to take effect." -msgstr "Damit Änderungen Wirkung zeigen muss der Editor neu gestartet werden" +msgstr "" +"Damit die Änderungen Wirkung zeigen muss der Editor neu gestartet werden." #: editor/project_settings_editor.cpp msgid "Input Map" @@ -9723,12 +9476,10 @@ msgid "Locales Filter" msgstr "Sprachfilter" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show All Locales" msgstr "Alle Sprachen anzeigen" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show Selected Locales Only" msgstr "Nur ausgewählte Sprachen anzeigen" @@ -9818,7 +9569,6 @@ msgid "Suffix" msgstr "Suffix" #: editor/rename_dialog.cpp -#, fuzzy msgid "Advanced Options" msgstr "Erweiterte Einstellungen" @@ -10083,9 +9833,8 @@ msgid "User Interface" msgstr "Benutzerschnittstelle" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Other Node" -msgstr "Node löschen" +msgstr "Anderes Node" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" @@ -10128,7 +9877,6 @@ msgid "Clear Inheritance" msgstr "Leere Vererbung" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Open Documentation" msgstr "Dokumentation öffnen" @@ -10137,6 +9885,10 @@ msgid "Add Child Node" msgstr "Node hier anhängen" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "Alle ein-/ausklappen" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Typ ändern" @@ -10165,8 +9917,8 @@ msgid "Delete (No Confirm)" msgstr "Löschen (keine Bestätigung)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "Hinzufügen/Erstellen eines neuen Nodes" +msgid "Add/Create a New Node." +msgstr "Hinzufügen/Erstellen eines neuen Nodes." #: editor/scene_tree_dock.cpp msgid "" @@ -10201,19 +9953,16 @@ msgid "Toggle Visible" msgstr "Sichtbarkeit umschalten" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Unlock Node" -msgstr "Node auswählen" +msgstr "Node entsperren" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Button Group" -msgstr "Taste 7" +msgstr "Knopf-Gruppe" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "(Connecting From)" -msgstr "Verbindungsfehler" +msgstr "(Verbindung von)" #: editor/scene_tree_editor.cpp msgid "Node configuration warning:" @@ -10244,9 +9993,8 @@ msgstr "" "Hier klicken zur Gruppenverwaltung." #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Open Script:" -msgstr "Skript öffnen" +msgstr "Offenes Skript:" #: editor/scene_tree_editor.cpp msgid "" @@ -10298,39 +10046,32 @@ msgid "Select a Node" msgstr "Node auswählen" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is empty." -msgstr "Pfad ist leer" +msgstr "Pfad ist leer." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Filename is empty." -msgstr "Dateiname ist leer" +msgstr "Dateiname ist leer." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is not local." -msgstr "Pfad ist nicht lokal" +msgstr "Pfad ist nicht lokal." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid base path." -msgstr "Ungültiger Pfad" +msgstr "Ungültiger Basispfad." #: editor/script_create_dialog.cpp -#, fuzzy msgid "A directory with the same name exists." -msgstr "Ein Verzeichnis mit gleichem Namen existiert bereits" +msgstr "Ein Verzeichnis mit gleichem Namen existiert bereits." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid extension." -msgstr "Ungültige Erweiterung" +msgstr "Ungültige Dateiendung." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Wrong extension chosen." -msgstr "Falsche Erweiterung gewählt" +msgstr "Falsche Dateiendung ausgewählt." #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" @@ -10349,7 +10090,6 @@ msgid "N/A" msgstr "Nicht verfügbar" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Open Script / Choose Location" msgstr "Skript öffnen / Ort wählen" @@ -10358,43 +10098,36 @@ msgid "Open Script" msgstr "Skript öffnen" #: editor/script_create_dialog.cpp -#, fuzzy msgid "File exists, it will be reused." -msgstr "Datei existiert bereits, wird erneut verwendet" +msgstr "Datei existiert bereits, wird erneut verwendet." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid class name." -msgstr "Ungültiger Klassenname" +msgstr "Ungültiger Klassenname." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid inherited parent name or path." -msgstr "Ungültiger geerbter Name oder Pfad" +msgstr "Ungültiger geerbter Name oder Pfad." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script is valid." -msgstr "Skript gültig" +msgstr "Skript ist gültig." #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9 and _" msgstr "Erlaubt: a-z, A-Z, 0-9 und _" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Built-in script (into scene file)." -msgstr "Eingebettetes Skript (in Szenedatei)" +msgstr "Eingebettetes Skript (in Szenedatei)." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will create a new script file." -msgstr "Neue Skriptdatei erstellen" +msgstr "Dies wird eine neue Skriptdatei erstellen." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will load an existing script file." -msgstr "Lade bestehende Skriptdatei" +msgstr "Dies wird eine bestehende Skriptdatei laden." #: editor/script_create_dialog.cpp msgid "Language" @@ -10436,7 +10169,7 @@ msgstr "Stacktrace" msgid "Pick one or more items from the list to display the graph." msgstr "Ein oder mehrere Einträge der Liste auswählen um Graph anzuzeigen." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Fehler" @@ -10526,7 +10259,7 @@ msgstr "Nach Szenenbaum einstellen" #: editor/script_editor_debugger.cpp msgid "Export measures as CSV" -msgstr "" +msgstr "Maße als CSV exportieren" #: editor/settings_config_dialog.cpp msgid "Erase Shortcut" @@ -10658,12 +10391,11 @@ msgstr "GDNative-Bibliothek" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Enabled GDNative Singleton" -msgstr "" +msgstr "GDNative Singleton wurde aktiviert" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Disabled GDNative Singleton" -msgstr "Update-Anzeigerad deaktivieren" +msgstr "GDNative Singleton wurde deaktiviert" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Library" @@ -10752,9 +10484,8 @@ msgid "GridMap Fill Selection" msgstr "GridMap-Auswahl füllen" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Paste Selection" -msgstr "GridMap-Auswahl löschen" +msgstr "GridMap-Auswahl einfügen" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Paint" @@ -10840,54 +10571,6 @@ msgstr "Auswahlradius:" msgid "Class name can't be a reserved keyword" msgstr "Der Klassenname kann nicht ein reserviertes Schlüsselwort sein" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Lösungen erzeugen..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "C#-Projekt erzeugen..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Fehler beim Erzeugen einer Lösung." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Fehler beim Speichern der Lösung." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Fertig" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "C#-Projekt-Erzeugen fehlgeschlagen." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "Über die C#-Unterstützung" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Erzeuge C#-Lösung" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Fertigstellungen" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Projekt bauen" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Log anschauen" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Ende des inneren Exception-Stack-Traces" @@ -11183,10 +10866,9 @@ msgid "Available Nodes:" msgstr "Verfügbare Nodes:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Select or create a function to edit its graph." msgstr "" -"Zum bearbeiten des Graphen muss eine Funktion ausgewählt oder erstellt weden" +"Zum Bearbeiten des Graphs muss eine Funktion ausgewählt oder erstellt werden." #: modules/visual_script/visual_script_editor.cpp msgid "Delete Selected" @@ -11324,15 +11006,19 @@ msgstr "" #: platform/android/export/export.cpp msgid "Custom build requires a valid Android SDK path in Editor Settings." msgstr "" +"Eigene Builds erfordern gültigen Android-SDK-Pfad in den Editoreinstellungen." #: 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." #: platform/android/export/export.cpp msgid "" "Android project is not installed for compiling. Install from Editor menu." msgstr "" +"Es ist kein Android-Projekt zum Kompilieren installiert worden. Es kann im " +"Editormenü installiert werden." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -11347,6 +11033,9 @@ msgid "" "Trying to build from a custom built template, but no version info for it " "exists. Please reinstall from the 'Project' menu." msgstr "" +"Es wurde versucht aus einer eigener Build-Vorlage zu bauen aber es " +"existieren keine Versionsinformation für sie. Neuinstallation im ‚Projekt‘-" +"Menü benötigt." #: platform/android/export/export.cpp msgid "" @@ -11355,20 +11044,28 @@ msgid "" " Godot Version: %s\n" "Please reinstall Android build template from 'Project' menu." msgstr "" +"Android-Build-Versionsinkompatibilität:\n" +" Installierte Vorlage: %s\n" +" Godot-Version: %s\n" +"Bitte Android-Build-Vorlage im ‚Projekt‘-Menü neu installieren." #: platform/android/export/export.cpp msgid "Building Android Project (gradle)" -msgstr "" +msgstr "Baue Android-Projekt (gradle)" #: platform/android/export/export.cpp msgid "" "Building of Android project failed, check output for the error.\n" "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" +"Bauen des Android-Projekts fehlgeschlagen, Fehlerdetails befinden ich in der " +"Textausgabe.\n" +"Alternativ befindet sich die Android-Build-Dokumentation auf docs." +"godotengine.org." #: platform/android/export/export.cpp msgid "No build apk generated at: " -msgstr "" +msgstr "Es wurde kein Build-APK generiert in: " #: platform/iphone/export/export.cpp msgid "Identifier is missing." @@ -11488,8 +11185,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "Ungültige Abmessungen für Startbildschirm (sollte 620x300 sein)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Eine SpriteFrames-Ressource muss in der ‚Frames‘-Eigenschaft erstellt oder " @@ -11558,8 +11256,9 @@ msgstr "" "Eigenschaft „Particles Animation“ aktiviert." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Eine Textur mit der Form des Lichtkegels muss in der ‚Texture‘-Eigenschaft " @@ -11573,7 +11272,8 @@ msgstr "" "Occluder funktioniert." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "Das Occluder-Polygon für diesen Occluder ist leer. Bitte zeichne ein Polygon!" @@ -11668,50 +11368,58 @@ msgstr "" "Dieser Knochen hat keine korrekte Ruhe-Pose. Diese kann am Skeleton2D-Node " "festgelegt werden." +#: 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 "" +"Ein TileMap mit aktivierter „Use Parent“-Option benötigt ein " +"CollisionObject2D-Elternnode dem es Form verleiht. Das TileMap sollte als " +"als Unterobjekt von Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, usw. " +"verwendet werden um ihnen eine Form zu geben." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D funktioniert am besten, wenn es ein Unterobjekt erster " "Ordnung der bearbeiteten Szene ist." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera braucht ein ARVROrigin-Node als Überobjekt" #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRController must have an ARVROrigin node as its parent." -msgstr "ARVRController braucht ein ARVROrigin-Node als Überobjekt" +msgstr "ARVRController braucht ein ARVROrigin-Node als Überobjekt." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The controller ID must not be 0 or this controller won't be bound to an " "actual controller." msgstr "" -"Die Controller-ID sollte nicht null sein, sonst wird der Controller nicht an " -"einen echten Controller gebunden" +"Die Controller-ID darf nicht null sein, sonst wird der Controller nicht an " +"einen echten Controller gebunden." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRAnchor must have an ARVROrigin node as its parent." -msgstr "ARVRAnchor braucht ein ARVROrigin-Node als Überobjekt" +msgstr "ARVRAnchor braucht ein ARVROrigin-Node als Überobjekt." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The anchor ID must not be 0 or this anchor won't be bound to an actual " "anchor." msgstr "" "Die Anker-ID darf nicht null sein, sonst wird der Anker nicht an einen " -"echten Anker gebunden" +"echten Anker gebunden." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVROrigin requires an ARVRCamera child node." -msgstr "ARVROrigin benötigt ein ARVRCamera-Unterobjekt" +msgstr "ARVROrigin benötigt ein ARVRCamera-Unterobjekt." #: scene/3d/baked_lightmap.cpp msgid "%d%%" @@ -11773,9 +11481,10 @@ msgstr "" "RigidBody, KinematicBody usw. eingehängt werden um diesen eine Form zu geben." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Damit CollisionShape funktionieren kann, muss eine Form vorhanden sein. " "Bitte erzeuge eine shape Ressource dafür!" @@ -11793,13 +11502,12 @@ msgid "Nothing is visible because no mesh has been assigned." msgstr "Nichts ist sichtbar da kein Mesh zugewiesen wurden." #: scene/3d/cpu_particles.cpp -#, fuzzy msgid "" "CPUParticles animation requires the usage of a SpatialMaterial whose " "Billboard Mode is set to \"Particle Billboard\"." msgstr "" "CPUParticles-Animationen benötigen ein SpatialMaterial mit der Eigenschaft " -"„Billboard Particles“ aktiviert." +"„Billboard Mode“ gesetzt zu „Particle Billboard“." #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" @@ -11813,6 +11521,10 @@ msgstr "" "GIProbes werden vom GLES2-Videotreiber nicht unterstützt.\n" "BakedLightmaps können als Alternative verwendet werden." +#: 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 "" @@ -11844,13 +11556,12 @@ msgstr "" "Nichts ist sichtbar da keine Meshe den Zeichendurchläufen zugewiesen wurden." #: scene/3d/particles.cpp -#, fuzzy msgid "" "Particles animation requires the usage of a SpatialMaterial whose Billboard " "Mode is set to \"Particle Billboard\"." msgstr "" "Particles-Animationen benötigen ein SpatialMaterial mit der Eigenschaft " -"„Billboard Particles“ aktiviert." +"„Billboard Mode“ gesetzt zu „Particle Billboard“." #: scene/3d/path.cpp msgid "PathFollow only works when set as a child of a Path node." @@ -11859,9 +11570,10 @@ msgstr "" "gesetzt wird." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED erfordert die Aktivierung von „Up Vector“ in " "der Curve-Ressource des übergeordneten Pfades." @@ -11878,13 +11590,15 @@ msgstr "" "geändert werden." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "Die Pfad-Eigenschaft muss auf ein gültiges Spatial-Node verweisen." #: scene/3d/soft_body.cpp -#, fuzzy msgid "This body will be ignored until you set a mesh." -msgstr "Diese Körper wird ignoriert werden bis ein Mesh gesetzt wurde" +msgstr "Diese Körper wird ignoriert werden bis ein Mesh zugewiesen wurde." #: scene/3d/soft_body.cpp msgid "" @@ -11898,8 +11612,9 @@ msgstr "" "geändert werden." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Eine SpriteFrames-Ressource muss in der ‚Frames‘-Eigenschaft erzeugt oder " @@ -11915,8 +11630,10 @@ msgstr "" "verwendet werden." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "Ein WorldEnvironment benötigt eine Environment-Ressource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11955,7 +11672,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Nichts ist mit dem Eingang ‚%s‘ von Node ‚%s‘ verbunden." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "Für diesen Graphen wurde kein Wurzel-Animation-Node festgelegt." #: scene/animation/animation_tree.cpp @@ -11971,7 +11689,8 @@ msgstr "" "AnimationPlayer-Node." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "Die Wurzel des Animationsspieler ist kein gültiges Node." #: scene/animation/animation_tree_player.cpp @@ -11985,8 +11704,12 @@ msgid "Pick a color from the screen." msgstr "Wählt eine Farbe vom Bildschirm aus." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Rohdatenmodus" +msgid "HSV" +msgstr "HSV" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "Roh" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11999,16 +11722,24 @@ msgstr "Aktuelle Farbe als Vorlage hinzufügen." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" -"Einfache Container sind unnötig solange ihnen kein Skript angehängt ist das " -"die Platzierung der Inhalte vornimmt.\n" +"Einfache Container sind unnötig solange kein Skript die Platzierung der " +"Inhalte vornimmt.\n" "Falls kein Skript angehängt werden soll wird empfohlen ein einfaches " "‚Control‘-Node zu verwenden." +#: 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 "" +"Der Hinweis-Tooltip wird nicht angezeigt da der Mausfilter dieses Controls " +"als „Ignore“ festgelegt wurde. Zum Beheben muss der Mausfilter als „Stop“ " +"oder „Pass“ festgelegt werden." + #: scene/gui/dialogs.cpp msgid "Alert!" msgstr "Warnung!" @@ -12018,10 +11749,11 @@ msgid "Please Confirm..." msgstr "Bitte bestätigen..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Popups werden standardmäßig versteckt, es sei denn Sie rufen popup() oder " "irgendeine der popup*() Funktionen auf. Sie für die Bearbeitung sichtbar zu " @@ -12029,13 +11761,15 @@ msgstr "" "versteckt." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Wenn exp_edit true ist muss min_value größer als null sein." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer sollte mit einem einzigen Control-Unterobjekt verwendet " @@ -12090,6 +11824,11 @@ msgid "Input" msgstr "Eingang" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Ungültige Quelle für Shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Ungültige Quelle für Shader." @@ -12107,7 +11846,224 @@ msgstr "Varyings können nur in Vertex-Funktion zugewiesen werden." #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "Konstanten können nicht verändert werden." + +#~ msgid "Generating solution..." +#~ msgstr "Lösungen erzeugen..." + +#~ msgid "Generating C# project..." +#~ msgstr "C#-Projekt erzeugen..." + +#~ msgid "Failed to create solution." +#~ msgstr "Fehler beim Erzeugen einer Lösung." + +#~ 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." + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "Über die C#-Unterstützung" + +#~ msgid "Create C# solution" +#~ msgstr "Erzeuge C#-Lösung" + +#~ msgid "Builds" +#~ msgstr "Fertigstellungen" + +#~ msgid "Build Project" +#~ msgstr "Projekt bauen" + +#~ msgid "View log" +#~ msgstr "Log anschauen" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "Ein WorldEnvironment benötigt eine Environment-Ressource." + +#~ msgid "Enabled Classes" +#~ msgstr "Aktivierte Klassen" + +#~ msgid "Update Always" +#~ msgstr "Immer aktualisieren" + +#~ msgid "'camera' input parameter for all shader modes." +#~ msgstr "‚camera‘-Eingabeparameter für alle Shadermodi." + +#~ msgid "'inv_camera' input parameter for all shader modes." +#~ msgstr "‚inv_camera‘ Eingabeparameter für alle Shadermodi." + +#~ msgid "'inv_projection' input parameter for all shader modes." +#~ msgstr "‚inv_projection‘ Eingabeparameter für alle Shadermodi." + +#~ msgid "'normal' input parameter for all shader modes." +#~ msgstr "‚normal‘ Eingabeparameter für alle Shadermodi." + +#~ msgid "'projection' input parameter for all shader modes." +#~ msgstr "‚projection‘ Eingabeparameter für alle Shadermodi." + +#~ msgid "'time' input parameter for all shader modes." +#~ msgstr "‚time‘-Eingabeparameter für alle Shadermodi." + +#~ msgid "'viewport_size' input parameter for all shader modes." +#~ msgstr "‚viewport_size‘-Eingabeparameter für alle Shadermodi." + +#~ msgid "'world' input parameter for all shader modes." +#~ msgstr "‚world‘-Eingabeparameter für alle Shadermodi." + +#~ msgid "'alpha' input parameter for all shader modes." +#~ msgstr "‚alpha‘-Eingabeparameter für alle Shadermodi." + +#~ msgid "'color' input parameter for all shader modes." +#~ msgstr "‚color‘-Eingabeparameter für alle Shadermodi." + +#~ msgid "'texture_pixel_size' input parameter for all shader modes." +#~ msgstr "‚texture_pixel_size‘-Eingabeparameter für alle Shadermodi." + +#~ msgid "'alpha' input parameter for vertex and fragment shader modes." +#~ msgstr "‚alpha‘-Eingabeparameter für Vertex- und Fragment-Shadermodi." + +#~ msgid "'binormal' input parameter for vertex and fragment shader modes." +#~ msgstr "‚binormal‘-Eingabeparameter für Vertex- und Fragment-Shadermodi." + +#~ msgid "'color' input parameter for vertex and fragment shader modes." +#~ msgstr "‚color‘-Eingabeparameter für Vertex- und Fragment-Shadermodi." + +#~ msgid "'fragcoord' input parameter for fragment and light shader modes." +#~ msgstr "‚fragcoord‘-Eingabeparameter für Vertex- und Fragment-Shadermodi." + +#~ msgid "'point_coord' input parameter for fragment shader mode." +#~ msgstr "‚point_coord‘-Eingabeparameter für Vertex- und Fragment-Shadermodi." + +#~ msgid "'screen_uv' input parameter for fragment shader mode." +#~ msgstr "‚screen_uv‘-Eingabeparameter für Fragment-Shadermodus." + +#~ msgid "'tangent' input parameter for vertex and fragment shader modes." +#~ msgstr "‚tangent‘-Eingabeparameter für Vertex- und Fragment-Shadermodus." + +#~ msgid "'uv2' input parameter for vertex and fragment shader modes." +#~ msgstr "‚uv2‘-Eingabeparameter für Vertex- und Fragment-Shadermodus." + +#~ msgid "'vertex' input parameter for vertex and fragment shader modes." +#~ msgstr "‚vertex‘-Eingabeparameter für Vertex- und Fragment-Shadermodus." + +#~ msgid "'albedo' input parameter for light shader mode." +#~ msgstr "‚albedo‘-Eingabeparameter für Light-Shadermodus." + +#~ msgid "'attenuation' input parameter for light shader mode." +#~ msgstr "‚attenuation‘-Eingabeparameter für Light-Shadermodus." + +#~ msgid "'light' input parameter for light shader mode." +#~ msgstr "‚light‘-Eingabeparameter für Light-Shadermodus." + +#~ msgid "'light_color' input parameter for light shader mode." +#~ msgstr "‚light_color‘-Eingabeparameter für Light-Shadermodus." + +#~ msgid "'roughness' input parameter for light shader mode." +#~ msgstr "‚roughness‘-Eingabeparameter für Light-Shadermodus." + +#~ msgid "'specular' input parameter for light shader mode." +#~ msgstr "‚specular‘-Eingabeparameter für Light-Shadermodus." + +#~ msgid "'transmission' input parameter for light shader mode." +#~ msgstr "‚transmission‘-Eingabeparameter für Light-Shadermodus." + +#~ msgid "'modelview' input parameter for vertex shader mode." +#~ msgstr "‚modelview‘-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'point_size' input parameter for vertex shader mode." +#~ msgstr "‚point_size‘-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'tangent' input parameter for vertex and fragment shader mode." +#~ msgstr "‚tangent‘-Eingabeparameter für Vertex- und Fragment-Shadermodus." + +#~ msgid "'light_pass' input parameter for vertex and fragment shader modes." +#~ msgstr "‚light_pass‘-Eingabeparameter für Vertex- und Fragment-Shadermodus." + +#~ msgid "'point_coord' input parameter for fragment and light shader modes." +#~ msgstr "" +#~ "‚point_coord‘-Eingabeparameter für Vertex- und Fragment-Shadermodus." + +#~ msgid "'screen_pixel_size' input parameter for fragment shader mode." +#~ msgstr "Eingabeparameter 'screen_pixel_size' für den Fragment-Shader-Modus." + +#~ msgid "'screen_uv' input parameter for fragment and light shader modes." +#~ msgstr "Eingabeparameter 'screen_uv' für Fragment- und Licht-Shader-Modi." + +#~ msgid "'light_alpha' input parameter for light shader mode." +#~ msgstr "Eingabeparameter 'light_alpha' für den Licht-Shader-Modus." + +#~ msgid "'light_height' input parameter for light shader mode." +#~ msgstr "Eingabeparameter'light_height' für den Licht-Shader-Modus." + +#~ msgid "'light_uv' input parameter for light shader mode." +#~ msgstr "'light_uv'-Eingabeparameter für Licht-Shadermodus." + +#~ msgid "'light_vec' input parameter for light shader mode." +#~ msgstr "'light_vec'-Eingabeparameter für Licht-Shadermodus." + +#~ msgid "'normal' input parameter for light shader mode." +#~ msgstr "'normal'-Eingabeparamter für Licht-Shadermodus." + +#~ msgid "'shadow_color' input parameter for light shader mode." +#~ msgstr "'shadow_color'-Eingabeparameter für Licht-Shadermodus." + +#~ msgid "'extra' input parameter for vertex shader mode." +#~ msgstr "'extra'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'projection' input parameter for vertex shader mode." +#~ msgstr "'projection'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'vertex' input parameter for vertex shader mode." +#~ msgstr "'vertex'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'world' input parameter for vertex shader mode." +#~ msgstr "'world'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'active' input parameter for vertex shader mode." +#~ msgstr "'active'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'alpha' input parameter for vertex shader mode." +#~ msgstr "'alpha'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'color' input parameter for vertex shader mode." +#~ msgstr "'color'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'custom_alpha' input parameter for vertex shader mode." +#~ msgstr "'custom_alpha'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'delta' input parameter for vertex shader mode." +#~ msgstr "'delta'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'emission_transform' input parameter for vertex shader mode." +#~ msgstr "'emission_transform'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'index' input parameter for vertex shader mode." +#~ msgstr "'index'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'lifetime' input parameter for vertex shader mode." +#~ msgstr "'lifetime'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'restart' input parameter for vertex shader mode." +#~ msgstr "'restart'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'time' input parameter for vertex shader mode." +#~ msgstr "'time'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'transform' input parameter for vertex shader mode." +#~ msgstr "'transform'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "'velocity' input parameter for vertex shader mode." +#~ msgstr "'velocity'-Eingabeparameter für Vertex-Shadermodus." + +#~ msgid "Raw Mode" +#~ msgstr "Rohdatenmodus" #~ msgid "Path to Node:" #~ msgstr "Pfad zum Node:" @@ -12667,9 +12623,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Spatial-Sichtbarkeit umschalten" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "CanvasItem-Sichtbarkeit umschalten" - #~ msgid "Condition" #~ msgstr "Bedingung" @@ -13607,9 +13560,6 @@ msgstr "" #~ msgid "Images:" #~ msgstr "Bilder:" -#~ msgid "Select None" -#~ msgstr "Nichts auswählen" - #~ msgid "Group" #~ msgstr "Gruppe" diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po index 464238349c..d1d0c1ade8 100644 --- a/editor/translations/de_CH.po +++ b/editor/translations/de_CH.po @@ -453,6 +453,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Node(s) löschen" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -631,6 +641,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -680,7 +694,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -789,6 +803,11 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Script hinzufügen" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -952,7 +971,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1325,7 +1344,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1497,6 +1516,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1526,7 +1549,7 @@ msgid "Node Dock" msgstr "Bild bewegen/einfügen" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1582,7 +1605,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1597,7 +1620,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Node(s) löschen" #: editor/editor_feature_profile.cpp @@ -1621,14 +1644,10 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "TimeScale-Node" #: editor/editor_feature_profile.cpp -msgid "Enabled Classes" -msgstr "" - -#: editor/editor_feature_profile.cpp #, fuzzy msgid "Class Options" msgstr "Script hinzufügen" @@ -2673,10 +2692,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2785,15 +2824,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "" +#, fuzzy +msgid "Update When Changed" +msgstr "Typ ändern" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2988,7 +3028,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3090,20 +3130,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3616,6 +3656,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp #, fuzzy msgid "Filter nodes" msgstr "Node erstellen" @@ -5276,6 +5317,14 @@ msgid "Load Emission Mask" msgstr "Emissions-Maske laden" #: 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 +#, fuzzy +msgid "Restart" +msgstr "Datei speichern" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp #, fuzzy msgid "Clear Emission Mask" @@ -6214,10 +6263,20 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Node erstellen" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Node erstellen" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "" @@ -6449,18 +6508,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Bild einfügen" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -8071,51 +8134,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8123,203 +8142,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9991,6 +9834,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Typ ändern" @@ -10021,8 +9868,9 @@ msgid "Delete (No Confirm)" msgstr "Bitte bestätigen..." #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Node erstellen" #: editor/scene_tree_dock.cpp msgid "" @@ -10273,7 +10121,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10681,56 +10529,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "Projektname:" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Datei(en) öffnen" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11335,8 +11133,9 @@ 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 " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Damit AnimatedSprite Frames anzeigen kann, muss eine SpriteFrame Resource " @@ -11390,7 +11189,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11402,7 +11201,8 @@ msgstr "" "Okkluder funktioniert." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "Das Okkluder Polygon für diesen Okkluder ist leer. Bitte zeichne ein Polygon!" @@ -11480,17 +11280,24 @@ 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 #, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D funktioniert am besten, wenn es ein Unterobjekt erster " "Ordnung der bearbeiteten Hauptszene ist." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11569,7 +11376,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11598,6 +11405,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11635,8 +11446,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11648,7 +11459,9 @@ msgstr "" #: scene/3d/remote_transform.cpp #, fuzzy -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "Die Pfad-Variable muss auf einen gültigen Particles2D Node verweisen." #: scene/3d/soft_body.cpp @@ -11663,10 +11476,13 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" +"Damit AnimatedSprite Frames anzeigen kann, muss eine SpriteFrame Resource " +"unter der 'Frames' Property erstellt oder gesetzt sein." #: scene/3d/vehicle_body.cpp msgid "" @@ -11675,7 +11491,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11711,7 +11529,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11723,7 +11541,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11735,9 +11553,12 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -#, fuzzy -msgid "Raw Mode" -msgstr "Node erstellen" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11749,10 +11570,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11766,18 +11592,18 @@ msgstr "Bitte bestätigen..." #: 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11821,6 +11647,10 @@ msgid "Input" 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 "" @@ -11840,6 +11670,18 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "Projektname:" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "Datei(en) öffnen" + +#, fuzzy +#~ msgid "Raw Mode" +#~ msgstr "Node erstellen" + #~ msgid "Path to Node:" #~ msgstr "Pfad zum Node:" diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot index 9ea76e8d29..5f4f2ae64b 100644 --- a/editor/translations/editor.pot +++ b/editor/translations/editor.pot @@ -421,6 +421,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -595,6 +604,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -644,7 +657,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -747,6 +760,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -905,7 +922,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1269,7 +1286,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1440,6 +1457,10 @@ msgstr "" 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 "" @@ -1465,7 +1486,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1518,7 +1539,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1531,7 +1552,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1554,11 +1575,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2564,10 +2581,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2674,15 +2711,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2872,7 +2909,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2970,20 +3007,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3468,6 +3505,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5047,6 +5085,13 @@ 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 "" @@ -5947,10 +5992,18 @@ msgid "Find Next" 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 "" @@ -6178,18 +6231,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7709,51 +7765,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7761,203 +7773,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9584,6 +9420,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9612,7 +9452,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9849,7 +9689,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10249,54 +10089,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10873,7 +10665,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10922,7 +10714,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10932,7 +10724,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -10999,14 +10791,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11085,7 +10884,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11114,6 +10913,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11148,8 +10951,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11160,7 +10963,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11176,7 +10981,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11187,7 +10992,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11222,7 +11029,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11234,7 +11041,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11246,7 +11053,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11259,10 +11070,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11276,18 +11092,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11330,6 +11146,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/el.po b/editor/translations/el.po index 5a50cf69ae..ed1e0493b4 100644 --- a/editor/translations/el.po +++ b/editor/translations/el.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" +"PO-Revision-Date: 2019-07-02 10:48+0000\n" "Last-Translator: George Tsiamasiotis <gtsiam@windowslive.com>\n" "Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/" "el/>\n" @@ -17,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: Weblate 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -79,9 +79,8 @@ msgid "Time:" msgstr "ΧÏόνος:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Τιμή" +msgstr "Τιμή:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -89,7 +88,7 @@ msgstr "Εισαγωγή ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï ÎµÎ´ÏŽ" #: editor/animation_bezier_editor.cpp msgid "Duplicate Selected Key(s)" -msgstr "Διπλασιασμός επιλογής" +msgstr "ΑναπαÏαγωγή ΕπιλεγμÎνων Κλειδιών" #: editor/animation_bezier_editor.cpp msgid "Delete Selected Key(s)" @@ -105,7 +104,7 @@ msgstr "Μετακίνηση σημείου Bezier" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Duplicate Keys" -msgstr "Anim Διπλασιασμός κλειδιών" +msgstr "Anim ΑναπαÏαγωγή Κλειδιών" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Delete Keys" @@ -121,7 +120,7 @@ msgstr "Anim Αλλαγή μετάβασης" #: editor/animation_track_editor.cpp msgid "Anim Change Transform" -msgstr "Anim Αλλαγή Î¼ÎµÏ„Î±ÏƒÏ‡Î·Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï (transform)" +msgstr "Anim Αλλαγή μετασχηματισμοÏ" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Value" @@ -133,7 +132,7 @@ msgstr "Anim Αλλαγή κλήσης" #: editor/animation_track_editor.cpp msgid "Change Animation Length" -msgstr "Αλλαγή μήκους κίνησης" +msgstr "Αλλαγή Μήκους Κίνησης" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp @@ -195,7 +194,7 @@ msgstr "Αποσπάσματα κίνησης:" #: editor/animation_track_editor.cpp msgid "Change Track Path" -msgstr "Αλλαγή διαδÏομής κομματιοÏ" +msgstr "Αλλαγή ΔιαδÏομής ΚομματιοÏ" #: editor/animation_track_editor.cpp msgid "Toggle this track on/off." @@ -223,7 +222,7 @@ msgstr "ΧÏόνος (s): " #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" -msgstr "(Απ)ενεÏοποίηση κομματιοÏ" +msgstr "(Απ)ενεÏγοποίηση ΚομματιοÏ" #: editor/animation_track_editor.cpp msgid "Continuous" @@ -269,7 +268,7 @@ msgstr "Εισαγωγή κλειδιοÏ" #: editor/animation_track_editor.cpp msgid "Duplicate Key(s)" -msgstr "Διπλασιασμός κλειδιών" +msgstr "ΑναπαÏαγωγή Κλειδιών" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" @@ -277,11 +276,11 @@ msgstr "ΔιαγÏαφή κλειδιών" #: editor/animation_track_editor.cpp msgid "Change Animation Update Mode" -msgstr "Αλλαγή λειτουÏγίας ενημÎÏωσης κίνησης" +msgstr "Αλλαγή ΛειτουÏγίας ΕνημÎÏωσης Κίνησης" #: editor/animation_track_editor.cpp msgid "Change Animation Interpolation Mode" -msgstr "Αλλαγή λειτουÏγίας παÏεμβολής κίνησης" +msgstr "Αλλαγή ΛειτουÏγίας ΠαÏεμβολής Κίνησης" #: editor/animation_track_editor.cpp msgid "Change Animation Loop Mode" @@ -336,7 +335,7 @@ msgstr "Αλλαγή βήματος κίνησης" #: editor/animation_track_editor.cpp msgid "Rearrange Tracks" -msgstr "Αναδιάταξη κομματιών" +msgstr "Αναδιάταξη Κομματιών" #: editor/animation_track_editor.cpp msgid "Transform tracks only apply to Spatial-based nodes." @@ -436,10 +435,29 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Αυτή η κίνηση ανήκει σε εισαγμÎνη σκηνή, οπότε οι αλλαγÎÏ‚ σε εισαγμÎνα " +"κομμάτια δεν θα αποθυκευτοÏν.\n" +"\n" +"Για να ενεÏγοποιήσετε τα Ï€ÏοσαÏμοσμÎνα κομμάτια, πηγαίνετε στης Ïυθμίσεις " +"εισαγωγής της σκηνής και θÎστε\n" +"το «Animation > Storage» σε «Files», ενεÏγοποιήστε το «Animation > Keep " +"Custom Tracks», και κάντε επαν-εισαγωγή.\n" +"Εναλλακτικά, χÏησιμοποιήστε μία διαμόÏφωση εισαγωγής που εισάγει κινήσεις " +"σε ξεχωÏιστά αÏχεία." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Î Ïοσοχή: ΕπεξεÏγασία εισαγμÎνης κίνησης" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Επιλογή όλων" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Επιλογή κόμβου" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -492,11 +510,11 @@ msgstr "ΜεγÎθυνση από τον δείκτη" #: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp msgid "Duplicate Selection" -msgstr "Διπλασιασμός επιλογής" +msgstr "ΑναπαÏαγωγή Επιλογής" #: editor/animation_track_editor.cpp msgid "Duplicate Transposed" -msgstr "Διπλασιασμός ανεστÏαμÎνων" +msgstr "ΑναπαÏαγωγή ΑνεστÏαμÎνων" #: editor/animation_track_editor.cpp msgid "Delete Selection" @@ -504,11 +522,11 @@ msgstr "ΔιαγÏαφή επιλογής" #: editor/animation_track_editor.cpp msgid "Go to Next Step" -msgstr "Επόμενο βήμα" +msgstr "Επόμενο Βήμα" #: editor/animation_track_editor.cpp msgid "Go to Previous Step" -msgstr "Î ÏοηγοÏμενο βήμα" +msgstr "Î ÏοηγοÏμενο Βήμα" #: editor/animation_track_editor.cpp msgid "Optimize Animation" @@ -615,6 +633,10 @@ msgstr "Πήγαινε σε γÏαμμή" msgid "Line Number:" msgstr "ΑÏ. γÏαμμής:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Δεν υπάÏχουν αντιστοιχίες" @@ -646,7 +668,7 @@ msgstr "Μόνο στην επιλογή" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Τυπική" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -664,47 +686,41 @@ msgstr "ΣμÏκÏινση" msgid "Reset Zoom" msgstr "ΕπαναφοÏά μεγÎθυνσης" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Î Ïοειδοποιήσεις" #: editor/code_editor.cpp msgid "Line and column numbers." -msgstr "ΑÏιθμοί γÏαμμής και στήλης." +msgstr "ΑÏιθμοί γÏαμμών και στηλών." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Î ÏÎπει να οÏισθεί συνάÏτηση για τον στοχευμÎνο κόμβο!" +msgstr "Î ÏÎπει να οÏιστεί συνάÏτηση στον στοχευμÎνο κόμβο." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Η στοχευμÎνη συνάÏτηση δεν βÏÎθηκε! ΟÏίστε μία ÎγκυÏη μÎθοδο ή συνδÎστε μία " +"Η στοχευμÎνη συνάÏτηση δεν βÏÎθηκε. ΟÏίστε μία ÎγκυÏη μÎθοδο ή συνδÎστε μία " "δεσμή ενεÏγειών στον στοχευμÎνο κόμβο." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "ΣÏνδεση στον κόμβο:" +msgstr "ΣÏνδεση σε Κόμβο:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Δεν ήταν δυνατή η σÏνδεση στον κεντÏικό υπολογιστή:" +msgstr "ΣÏνδεση σε Δεσμή ΕνεÏγειών:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Σήματα:" +msgstr "Από Σήμα:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "Ο κόμβος δεν πεÏιÎχει γεωμετÏία." +msgstr "Η σκηνή δεν πεÏιÎχει δεσμή ενεÏγειών." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -732,9 +748,8 @@ msgid "Extra Call Arguments:" msgstr "ΕπιπλÎον παÏάμετÏοι κλήσης:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "ΕπιλογÎÏ‚ κουμπώματος" +msgstr "Για Î ÏοχωÏημÎνους" #: editor/connections_dialog.cpp msgid "Deferred" @@ -744,6 +759,8 @@ msgstr "ΑναβλημÎνη" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"ΚαθυστεÏεί το σήμα, αποθηκεÏοντας το σε ουÏά, και ενεÏγοποιώντας το σε " +"στιγμή ηÏεμίας." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -751,12 +768,11 @@ msgstr "Μία κλήση" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "ΑποσυνδÎει το σήμα μετά την Ï€Ïώτη του ενεÏγοποίηση." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "ΣÏνδεση σήματος: " +msgstr "ΑδÏνατη η σÏνδεση σήματος" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -777,6 +793,11 @@ msgid "Connect" msgstr "ΣÏνδεση" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Σήματα:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "ΣÏνδεση του '%s' στο '%s'" @@ -798,19 +819,17 @@ msgid "Disconnect" msgstr "ΑποσÏνδεση" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "ΣÏνδεση σήματος: " +msgstr "ΣÏνδεση Σήματος σε ΜÎθοδο" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "ΕπεξεÏγασία σÏνδεσης: " +msgstr "ΕπεξεÏγασία ΣÏνδεσης:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" msgstr "" -"Είστε σίγουÏοι πως θÎλετε να αφαιÏÎσετε όλες της συνδÎσεις απο το σήμα «%s»;" +"Είστε βÎβαιοι πως θÎλετε να καταÏγήσετε όλες τις συνδÎσεις από το σήμα «%s»;" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" @@ -883,22 +902,20 @@ msgid "Dependencies For:" msgstr "ΕξαÏτήσεις για:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" -"Γίνεται επεξεÏγασία στη σκηνή '%s'\n" -"Οι αλλαγÎÏ‚ δεν θα δÏάσουν, εκτός κι αν γίνει επαναφόÏτωση." +"Γίνεται επεξεÏγασία της σκηνής «%s».\n" +"Οι αλλαγÎÏ‚ θα δÏάσουν κατά την ανανÎωση." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" -"Ο πόÏος '%s' χÏησιμοποιείται.\n" -"Οι αλλαγÎÏ‚ θα δÏάσουν όταν γίνει επαναφόÏτωση." +"Ο πόÏος «%s» χÏησιμοποιείται.\n" +"Οι αλλαγÎÏ‚ θα δÏάσουν κατά την ανανÎωση." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -945,7 +962,8 @@ msgid "Owners Of:" msgstr "Ιδιοκτήτες του:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Îα αφαιÏεθοÏν τα επιλεγμÎνα αÏχεία από το ÎÏγο; (ΑδÏνατη η αναίÏεση)" #: editor/dependency_editor.cpp @@ -990,9 +1008,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Μόνιμη διαγÏαφή %d αντικειμÎνων; (ΑδÏνατη η αναίÏεση)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "ΕξαÏτήσεις" +msgstr "Εμφάνιση ΕξαÏτήσεων" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1204,7 +1221,7 @@ 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 "Διπλασιασμός" +msgstr "ΑναπαÏαγωγή" #: editor/editor_audio_buses.cpp msgid "Reset Volume" @@ -1256,7 +1273,7 @@ msgstr "Άνοιγμα διάταξης διαÏλων ήχου" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Δεν υπάÏχει αÏχείο «%s»." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1313,25 +1330,22 @@ msgid "Valid characters:" msgstr "ΈγκυÏοι χαÏακτήÏες:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"ΆκυÏο όνομα. Δεν Ï€ÏÎπει να συγχÎεται με υπαÏκτό όνομα κλάσης της godot." +msgstr "Δεν μποÏεί να συγχÎεται με υπαÏκτό όνομα κλάσης της μηχανής." #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "" -"ΆκυÏο όνομα. Δεν Ï€ÏÎπει να συγχÎεται με υπαÏκτό ενσωματωμÎνο όνομα Ï„Ïπου." +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 "ΆκυÏο όνομα. Δεν Ï€ÏÎπει να συγχÎεται με υπαÏκτό καθολικό όνομα." +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!" @@ -1362,7 +1376,6 @@ msgid "Rearrange Autoloads" msgstr "Αναδιάταξη των AutoLoad" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "ΆκυÏη διαδÏομή." @@ -1417,9 +1430,8 @@ msgid "[unsaved]" msgstr "[μη αποθηκευμÎνο]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "ΠαÏακαλοÏμε επιλÎξτε Ï€Ïώτα Îναν βασικό κατάλογο" +msgstr "ΕπιλÎξτε Ï€Ïώτα Îναν βασικό κατάλογο." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1503,122 +1515,111 @@ msgstr "Δεν βÏÎθηκε Ï€ÏοσαÏμοσμÎνο πακÎτο παÏαγ 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 -#, fuzzy msgid "3D Editor" -msgstr "ΕπεξεÏγαστής" +msgstr "3D ΕπεξεÏγαστής" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Άνοιγμα επεξεÏγαστή δεσμής ενεÏγειών" +msgstr "ΕπεξεÏγαστής Δεσμών ΕνεÏγειών" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Άνοιγμα βιβλιοθήκης" +msgstr "Βιβλιοθήκη Î ÏŒÏων" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "ΔÎντÏο σκηνής (Κόμβοι):" +msgstr "ΕπεξεÏγασία ΔÎντÏου Σκηνής" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Εισαγωγή" +msgstr "ΠλατφόÏμα Εισαγωγής" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "Μετακίνηση Κόμβου" +msgstr "ΠλατφόÏμα Κόμβου" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" -msgstr "ΣÏστημα αÏχείων" +msgid "FileSystem and Import Docks" +msgstr "ΠλατφόÏμα Συστήματος ΑÏχείων" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Αντικατάσταση όλων (χωÏίς ανÎÏαιση)" +msgstr "ΔιαγÏαφή Ï€Ïοφίλ «%s»; (χωÏίς ανÎÏαιση)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "Το Ï€Ïοφίλ Ï€ÏÎπει να είναι ÎγκυÏο όνομα αÏχείου και να μην Ï€ÏειÎχει «.»" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "ΥπάÏχει ήδη Îνα αÏχείο ή φάκελος με αυτό το όνομα." +msgstr "ΥπάÏχει ήδη Ï€Ïοφίλ με αυτό το όνομα." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(ΑπενεÏγοποίηση ΕπεξεÏγαστή και Ιδιοτήτων)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Μόνο ιδιότητες" +msgstr "(ΑπενεÏγοποίηση Ιδιοτήτων)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Η πεÏικοπή είναι απενεÏγοποιημÎνη" +msgstr "(ΑπενεÏγοποίηση ΕπεξεÏγαστή)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "ΠεÏιγÏαφή κλάσης:" +msgstr "ΕπιλογÎÏ‚ Κλάσης:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Άνοιγμα του επόμενου επεξεÏγαστή" +msgstr "ΕνεÏγοποίηση ΕπεξεÏγαστή Βάσει ΠεÏιβάλλοντος" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Ιδιότητες:" +msgstr "ΕνεÏγοποιημÎνες Ιδιότητες:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "Δυνατότητες" +msgstr "ΕνεÏγοποιημÎνες Δυνατότητες:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Αναζήτηση κλάσεων" +msgstr "ΕνεÏγοποιημÎνες Κλάσεις:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "ΆκυÏη μοÏφή αÏχείου «%s», ακÏÏωση εισαγωγής." #: editor/editor_feature_profile.cpp +#, fuzzy msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"ΥπαÏκτό Ï€Ïοφίλ «%s». ΑφαιÏÎστε το Ï€Ïιν την εισαγωγή, ακÏÏωση εισαγωγής." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Σφάλμα κατά την φόÏτωση Ï€ÏοτÏπου '%s'" +msgstr "Σφάλμα αποθήκευσης Ï€Ïοφίλ στο «%s»." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "ΚατάÏγηση" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" -msgstr "ΤÏÎχουσα Îκδοση:" +msgid "Current Profile:" +msgstr "ΤÏÎχων Î Ïοφίλ" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "ΤÏÎχων:" +msgstr "Κάνε ΤÏÎχων" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1637,43 +1638,32 @@ msgstr "Εξαγωγή" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" -msgstr "ΔιαθÎσιμοι κόμβοι:" - -#: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Αναζήτηση κλάσεων" +msgid "Available Profiles:" +msgstr "ΔιαθÎσιμα Î Ïοφίλ" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "ΠεÏιγÏαφή κλάσης" +msgstr "ΕπιλογÎÏ‚ Κλάσης" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "ÎÎο όνομα:" +msgstr "ÎÎο όνομα Ï€Ïοφίλ:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "ΔιαγÏαφή πεÏσιοχής" +msgstr "ΔιαγÏαφή Î Ïοφίλ" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "ΕισαγμÎνο ÎÏγο" +msgstr "Εισαγωγή Î Ïοφίλ" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Εξαγωγή ÎÏγου" +msgstr "Εξαγωγή Î Ïοφίλ" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "ΔιαχείÏιση Ï€ÏοτÏπων εξαγωγής" +msgstr "ΔιαχείÏιση Î Ïοφίλ Δυνατοτήτων ΕπεξεÏγαστή" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1796,9 +1786,8 @@ msgid "(Un)favorite current folder." msgstr "Εναλλαγή αγαπημÎνου Ï„ÏÎχοντος φακÎλου." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Εναλλαγή κÏυμμÎνων αÏχείων" +msgstr "Εναλλαγή οÏατότητας κÏυμÎνων αÏχείων." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1835,6 +1824,8 @@ msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"ΥπάÏχουν πολλαπλοί εισαγωγείς διαφοÏετικών Ï„Ïπων για το αÏχείο «%s», ακÏÏωση " +"εισαγωγής" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2020,9 +2011,8 @@ msgid "Output:" msgstr "Έξοδος:" #: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Copy Selection" -msgstr "ΑφαίÏεση επιλογής" +msgstr "ΑντιγÏαφή Επιλογής" #: editor/editor_log.cpp editor/editor_profiler.cpp #: editor/editor_properties.cpp @@ -2180,13 +2170,12 @@ msgstr "" "καταλάβετε καλÏτεÏα την διαδικασία." #: editor/editor_node.cpp -#, fuzzy 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 "" "Αυτός ο πόÏος ανήκει σε μία σκηνή που Îχει κλωνοποιηθεί ή κληÏονομηθεί.\n" -"Οι αλλαγÎÏ‚ δεν θα διατηÏηθοÏν κατά την αποθήκευση της Ï„ÏÎχουσας σκηνής." +"Δεν θα διατηÏηθοÏν αλλαγÎÏ‚ κατά την αποθήκευση της Ï„ÏÎχουσας σκηνής." #: editor/editor_node.cpp msgid "" @@ -2197,7 +2186,6 @@ msgstr "" "Ïυθμίσεις στο πλαίσιο εισαγωγής και μετά επαν-εισάγετε." #: editor/editor_node.cpp -#, fuzzy 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" @@ -2205,12 +2193,12 @@ msgid "" "understand this workflow." msgstr "" "Αυτή η σκηνή Îχει εισαχθεί, οπότε αλλαγÎÏ‚ σε αυτήν δεν θα διατηÏηθοÏν.\n" -"Η κλωνοποίηση ή η κληÏονόμηση της θα επιτÏÎψει την επεξεÏγασία της.\n" +"Η δημιουÏγία στιγμιοτÏπου ή κληÏονόμηση της θα επιτÏÎψει την επεξεÏγασία " +"της.\n" "ΠαÏακαλοÏμε διαβάστε την τεκμηÏίωση σχετική με την εισαγωγή σκηνών, για να " "καταλάβετε καλÏτεÏα την διαδικασία." #: editor/editor_node.cpp -#, fuzzy 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 " @@ -2244,9 +2232,8 @@ msgid "Open Base Scene" msgstr "Άνοιγμα σκηνής βάσης" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "ΓÏήγοÏο άνοιγμα σκηνής..." +msgstr "ΓÏήγοÏο Άνοιγμα..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2495,12 +2482,11 @@ msgstr "Κλείσιμο άλλον καÏτελών" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Κλείσιμο ΚαÏτελών Δεξιά" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Κλείσιμο όλων" +msgstr "Κλείσιμο Όλων των ΚαÏτελών" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2634,7 +2620,7 @@ msgstr "Άνοιγμα φακÎλου δεδομÎνων ÎÏγου" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Εγκατάσταση Î ÏοτÏπου Χτισίματος Android" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2746,10 +2732,34 @@ msgid "Editor Layout" msgstr "Διάταξη επεξεÏγαστή" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Βγάζει νόημα!" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Άνοιγμα φακÎλου δεδομÎνων/Ïυθμίσεων επεξεÏγαστή" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Άνοιγμα του επόμενου επεξεÏγαστή" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Εναλλαγή πλήÏους οθόνης" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Εναλλαγή οÏατότητας CanvasItem" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Άνοιγμα φακÎλου δεδομÎνων/Ïυθμίσεων επεξεÏγαστή" @@ -2762,9 +2772,8 @@ msgid "Open Editor Settings Folder" msgstr "Άνοιγμα φακÎλου Ïυθμίσεων επεξεÏγαστή" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "ΔιαχείÏιση Ï€ÏοτÏπων εξαγωγής" +msgstr "ΔιαχείÏιση Δυνατοτήτων ΕπεξεÏγαστή" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2857,15 +2866,18 @@ msgid "Spins when the editor window redraws." msgstr "ΠεÏιστÏÎφεται όταν το παÏάθυÏο του επεξεÏγαστή επαναχÏωματίζεται." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "ΕνημÎÏωση πάντα" +#, fuzzy +msgid "Update Continuously" +msgstr "Συνεχόμενη" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "ΕνημÎÏωση αλλαγών" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "ΑπενεÏγοποίηση δείκτη ενημÎÏωσης" #: editor/editor_node.cpp @@ -2895,17 +2907,21 @@ msgstr "ΧωÏις αποθήκευση" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." msgstr "" +"Λείπει το Ï€Ïότυπο χτισίματος Android, παÏακαλοÏμε εγκαταστήστε τα σχετικά " +"Ï€Ïότυπα." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "ΔιαχείÏιση Ï€ÏοτÏπων εξαγωγής" +msgstr "ΔιαχείÏιση Î ÏοτÏπων" #: editor/editor_node.cpp msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"Αυτό θα εγκαταστήσει το ÎÏγο Android για Ï€ÏοσαÏμοσμÎνα χτισίματα.\n" +"Σημειώστε πως, για τη χÏήση του, Ï€ÏÎπει να ενεÏγοποιηθεί ανά διαμόÏφωση " +"εξαγωγής." #: editor/editor_node.cpp msgid "" @@ -2913,6 +2929,9 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"Το Ï€Ïότυπο χτισίματος Android είναι εγκατεστημÎνο και δεν θα " +"αντικατασταθεί.\n" +"ΑφαιÏÎστε τον φάκελο «build» Ï€Ïιν ξαναδοκιμάσετε την ενÎÏγεια αυτήν." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3056,7 +3075,7 @@ msgstr "ΧÏόνος" msgid "Calls" msgstr "Κλήσεις" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Îαι" @@ -3110,7 +3129,7 @@ msgstr "" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Pick a Viewport" -msgstr "ΕπιλÎξτε μία οπτική γωνία" +msgstr "ΕπιλÎξτε Îνα Viewport" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New Script" @@ -3162,6 +3181,11 @@ 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 "ÎÎο κλειδί:" @@ -3173,11 +3197,6 @@ msgstr "ÎÎα τιμή:" msgid "Add Key/Value Pair" msgstr "Î Ïοσθήκη ζεÏγους κλειδιοÏ/τιμής" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "ΑφαίÏεση στοιχείου" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3384,9 +3403,8 @@ msgid "SSL Handshake Error" msgstr "Σφάλμα χαιÏÎµÏ„Î¹ÏƒÎ¼Î¿Ï SSL" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "Αποσυμπίεση asset" +msgstr "Αποσυμπίεση Πηγών Χτισίματος Android" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3405,9 +3423,8 @@ msgid "Remove Template" msgstr "ΑφαίÏεση Ï€ÏοτÏπου" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" -msgstr "ΕπιλÎξτε Îνα αÏχείο Ï€ÏοτÏπων" +msgstr "Επιλογή ΑÏχείου Î ÏοτÏπων" #: editor/export_template_manager.cpp msgid "Export Template Manager" @@ -3469,9 +3486,8 @@ msgid "No name provided." msgstr "Δεν δόθηκε όνομα." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "Το δοσμÎνο όνομα πεÏιÎχει άκυÏους χαÏακτήÏες" +msgstr "Το δοσμÎνο όνομα πεÏιÎχει άκυÏους χαÏακτήÏες." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3498,28 +3514,24 @@ msgid "Duplicating folder:" msgstr "Διπλασιασμός καταλόγου:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "ÎÎα κληÏονομημÎνη σκηνή..." +msgstr "ÎÎα ΚληÏονομημÎνη Σκηνή" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Άνοιγμα σκηνής" +msgstr "Άνοιγμα Σκηνών" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Στιγμιότυπο" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" -msgstr "Î Ïοσθήκη στα αγαπημÎνα" +msgstr "Î Ïοσθήκη στα ΑγαπημÎνα" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "ΚατάÏγηση από τα αγαπημÎνα" +msgstr "ΚατάÏγηση από τα ΑγαπημÎνα" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." @@ -3567,23 +3579,20 @@ msgid "Rename" msgstr "Μετονομασία" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Î ÏοηγοÏμενος φάκελος" +msgstr "Î ÏοηγοÏμενος Φάκελος/ΑÏχείο" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Επόμενος φάκελος" +msgstr "Επόμενος Φάκελος/ΑÏχείο" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "Εκ νÎου σάÏωση το συστήματος αÏχείων" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" -msgstr "Εναλλαγή λειτουÏγίας διαχωÏισμοÏ" +msgstr "Εναλλαγή ΛειτουÏγίας ΔιαχωÏισμοÏ" #: editor/filesystem_dock.cpp msgid "Search files" @@ -3618,14 +3627,12 @@ msgid "Find in Files" msgstr "ΕÏÏεση στα ΑÏχεία" #: editor/find_in_files.cpp -#, fuzzy msgid "Find:" -msgstr "ΕÏÏεση: " +msgstr "ΕÏÏεση:" #: editor/find_in_files.cpp -#, fuzzy msgid "Folder:" -msgstr "Φάκελος: " +msgstr "Φάκελος:" #: editor/find_in_files.cpp msgid "Filters:" @@ -3636,6 +3643,8 @@ 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 @@ -3675,7 +3684,6 @@ msgid "Group name already exists." msgstr "ΥπαÏκτό όνομα ομάδας." #: editor/groups_editor.cpp -#, fuzzy msgid "Invalid group name." msgstr "ΆκυÏο όνομα ομάδας." @@ -3688,6 +3696,7 @@ msgid "Nodes not in Group" msgstr "Κόμβοι εκτός ομάδας" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "ΦιλτÏάÏισμα κόμβων" @@ -4075,9 +4084,8 @@ msgid "Open Animation Node" msgstr "Άνοιγμα κόμβου κίνησης" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "Το Ï„Ïίγωνο υπάÏχει ήδη" +msgstr "Το Ï„Ïίγωνο υπάÏχει ήδη." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4225,9 +4233,8 @@ msgid "Edit Filtered Tracks:" msgstr "ΕπεξεÏγασία φιλτÏαÏισμÎνων κομματιών:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" -msgstr "ΕνεÏγοποίηση φιλτÏαÏίσματος" +msgstr "ΕνεÏγοποίηση ΦίλτÏου" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" @@ -4361,9 +4368,8 @@ msgid "Enable Onion Skinning" msgstr "ΕνεÏγοποίηση ξεφλουδίσματος κÏεμμυδιοÏ" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "ΞεφλοÏδισμα κÏεμμυδιοÏ" +msgstr "ΕπιλογÎÏ‚ Ξεφλουδίσματος ΚÏεμμυδιοÏ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4529,7 +4535,7 @@ msgstr "Μετάβαση: " #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "AnimationTree" -msgstr "ΔÎντÏο κίνησης" +msgstr "AnimationTree" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "New name:" @@ -4920,16 +4926,20 @@ msgid "" "Children of containers have their anchors and margins values overridden by " "their parent." msgstr "" +"Στα παιδιά Container, οι άγκυÏες και τα πεÏιθώÏια αντικαθίστανται από τον " +"γονÎα τους." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Presets for the anchors and margins values of a Control node." -msgstr "" +msgstr "ΔιαμοÏφώσεις για τις άγκυÏες και τα πεÏιθώÏια ενός κόμβου Control." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Όταν είναι ενεÏγό, η μετακίνηση των Control αλλάζει τις άγκυÏες, αντί για τα " +"πεÏιθώÏια τους." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -4945,41 +4955,35 @@ 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 -#, fuzzy msgid "Unlock Selected" -msgstr "ΔιαγÏαφή επιλεγμÎνου" +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 "Create Custom Bone(s) from Node(s)" -msgstr "ΔημιουÏγία Ï€ÏοσαÏμοσμÎνων οστών απο κόμβους" +msgstr "ΔημιουÏγία Î ÏοσαÏμοσμÎνων Οστών από Κόμβους" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "ΕκκαθάÏιση στάσης" +msgstr "ΕκκαθάÏιση Οστών" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -4994,13 +4998,14 @@ msgid "" "Warning: Children of a container get their position and size determined only " "by their parent." msgstr "" +"Î Ïοσοχή: Στα παιδιά Container, η θÎση και το μÎγεθος οÏίζονται μόνο απο τον " +"γονÎα τους." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom Reset" -msgstr "ΕπαναφοÏά μεγÎθυνσης" +msgstr "ΕπαναφοÏά ΜεγÎθυνσης" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Select Mode" @@ -5032,9 +5037,8 @@ msgid "Rotate Mode" msgstr "ΛειτουÏγία πεÏιστÏοφής" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Scale Mode" -msgstr "ΛειτουÏγία κλιμάκωσης (R)" +msgstr "ΛειτουÏγία Κλιμάκωσης" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5067,9 +5071,8 @@ msgid "Snapping Options" msgstr "ΕπιλογÎÏ‚ κουμπώματος" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" -msgstr "κουμπώματος στο πλÎγμα" +msgstr "ΚοÏμπωμα στο ΠλÎγμα" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" @@ -5089,39 +5092,32 @@ msgid "Use Pixel Snap" msgstr "ΧÏήση κουμπώματος εικονοστοιχείου" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" -msgstr "Έξυπνο κοÏμπωμα" +msgstr "Έξυπνο ΚοÏμπωμα" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" -msgstr "ΚοÏμπωμα στον γονÎα" +msgstr "ΚοÏμπωμα στον ΓονÎα" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" -msgstr "ΚοÏμπωμα στην άγκυÏα του κόμβου" +msgstr "ΚοÏμπωμα σε ΆγκυÏα Κόμβου" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" -msgstr "ΚοÏμπωμα στις πλευÏÎÏ‚ του κόμβου" +msgstr "ΚοÏμπωμα σε ΆκÏα Κόμβου" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" -msgstr "ΚοÏμπωμα στο κÎντÏο του κόμβου" +msgstr "ΚοÏμπωμα σε ΚÎντÏο Κόμβου" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" -msgstr "ΚοÏμπωμα σε άλλους κόμβους" +msgstr "ΚοÏμπωμα σε Άλλους Κόμβους" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" -msgstr "ΚοÏμπωμα στους οδηγοÏÏ‚" +msgstr "ΚοÏμπωμα σε ΟδηγοÏÏ‚" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5144,9 +5140,8 @@ msgid "Restores the object's children's ability to be selected." msgstr "ΕπαναφÎÏει την δυνατότητα των παιδιών του αντικειμÎνου να επιλεγοÏν." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Skeleton Options" -msgstr "Σκελετός..." +msgstr "ΕπιλογÎÏ‚ ΣκελετοÏ" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Bones" @@ -5188,11 +5183,11 @@ msgstr "Î Ïοβολή πηγής" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Viewport" -msgstr "Î Ïοβολή οπτικής γωνίας" +msgstr "Εμφάνιση οπτικής γωνίας" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Group And Lock Icons" -msgstr "" +msgstr "Εμφάνιση Εικονιδίων Ομάδας και Κλειδώματος" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" @@ -5204,24 +5199,23 @@ msgstr "Πλαισίωμα επιλογής" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "" +msgstr "Î Ïοεπισκόπηση Κλιμάκωσης Καμβά" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." -msgstr "" +msgstr "Μάσκα μετατόπισης για εισαγωγή κλειδιών." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation mask for inserting keys." -msgstr "" +msgstr "Μάσκα πεÏιστÏοφής για εισαγωγή κλειδιών." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Scale mask for inserting keys." -msgstr "" +msgstr "Μάσκα κλιμάκωσης για εισαγωγή κλειδιών." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Insert keys (based on mask)." -msgstr "Εισαγωγή ÎºÎ»ÎµÎ¹Î´Î¹Î¿Ï (ΥπαÏκτά κομμάτια)" +msgstr "Εισαγωγή κλειδιών (βάση μάσκας)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -5230,11 +5224,15 @@ msgid "" "Keys are only added to existing tracks, no new tracks will be created.\n" "Keys must be inserted manually for the first time." msgstr "" +"Αυτόματη εισαγωγή κλειδιών κατά την μετατόπιση, πεÏιστÏοφή ή κλιμάκωση " +"αντικειμÎνων (βάση μάσκας).\n" +"Τα κλειδιά Ï€Ïοστίθενται μόνο σε υπαÏκτά κομμάτια, οπότε δεν θα δημιουÏγηθοÏν " +"καινοÏÏγια.\n" +"Τα κλειδιά Ï€ÏÎπει να Ï€ÏοστεθοÏν χειÏοκίνητα την Ï€Ïώτη φοÏά." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Auto Insert Key" -msgstr "Anim εισαγωγή κλειδιοÏ" +msgstr "Αυτόματη Εισαγωγή ΚλειδιοÏ" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key (Existing Tracks)" @@ -5257,9 +5255,8 @@ msgid "Divide grid step by 2" msgstr "ΔιαίÏεση βήματος πλÎγματος με 2" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Pan View" -msgstr "Πίσω όψη" +msgstr "Μετατόπιση Οπτικής Γωνίας" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" @@ -5284,9 +5281,8 @@ msgid "Error instancing scene from %s" msgstr "Σφάλμα κατά την αÏχικοποίηση σκηνής από %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" -msgstr "Αλλαγή Ï€ÏοεπιλεγμÎνου Ï„Ïπου" +msgstr "Αλλαγή Î ÏοεπιλεγμÎνου ΤÏπου" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -5297,9 +5293,8 @@ msgstr "" "ΣÏÏσιμο & απόθεση + Alt: Αλλαγή του Ï„Ïπου του κόμβου" #: editor/plugins/collision_polygon_editor_plugin.cpp -#, fuzzy msgid "Create Polygon3D" -msgstr "Δημιουγία πολυγώνου" +msgstr "ΔημιουÏγία 3D Πολυγώνου" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly" @@ -5329,6 +5324,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "Επανεκκίνηση τώÏα" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "ΕκκαθάÏιση μάσκας εκπομπής" @@ -5374,12 +5377,10 @@ msgid "Create Emission Points From Node" msgstr "ΔημιουÏγία σημείων εκπομπής από κόμβο" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" msgstr "Επίπεδο 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" msgstr "Επίπεδο 1" @@ -5405,32 +5406,27 @@ msgstr "ΤÏοποπίηση εφαπτομÎνης καμπÏλης" #: editor/plugins/curve_editor_plugin.cpp msgid "Load Curve Preset" -msgstr "ΦόÏτωση Ï€ÏοκαθοÏισμÎνης καμπÏλης" +msgstr "ΦόÏτωση διαμόÏφωσης καμπÏλης" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" -msgstr "Î Ïοσθήκη σημείου" +msgstr "Î Ïοσθήκη Σημείου" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" -msgstr "ΑφαίÏεση σημείου" +msgstr "ΑφαίÏεση Σημείου" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" -msgstr "ΑÏιστεÏή γÏαμμική" +msgstr "ΑÏιστεÏή ΓÏαμμική" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" -msgstr "Δεξιά γÏαμμική" +msgstr "Δεξιά ΓÏαμμική" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" -msgstr "ΦόÏτωση διαμόÏφωσης" +msgstr "ΦόÏτωση ΔιαμόÏφωσης" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove Curve Point" @@ -5450,7 +5446,7 @@ msgstr "Î Ïοετοιμασία διεÏεÏνησης GI" #: editor/plugins/gradient_editor_plugin.cpp msgid "Gradient Edited" -msgstr "" +msgstr "ΕπεξεÏγασία Διαβάθμισης" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" @@ -5485,18 +5481,16 @@ msgid "This doesn't work on scene root!" msgstr "Αυτό δεν δουλεÏει στη Ïίζα της σκηνής!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "ΔημιουÏγία σχήματος πλÎγματος Ï„Ïιγώνων" +msgstr "ΔημιουÏγία Î£Ï„Î±Ï„Î¹ÎºÎ¿Ï Î£Ï‡Î®Î¼Î±Ï„Î¿Ï‚ ΠλÎγματος ΤÏιγώνων" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "Αποτυχία δημιουÏγίας σχημάτων!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "ΔημιουÏγία κυÏÏ„Î¿Ï ÏƒÏ‡Î®Î¼Î±Ï„Î¿Ï‚" +msgstr "ΔημιουÏγία ΚυÏτών Σχημάτων" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -5552,9 +5546,8 @@ msgid "Create Trimesh Collision Sibling" msgstr "ΔημιουÏγία Î±Î´ÎµÎ»Ï†Î¿Ï ÏƒÏγκÏουσης πλÎγατος Ï„Ïιγώνων" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Collision Sibling(s)" -msgstr "ΔημιουÏγία Î±Î´ÎµÎ»Ï†Î¿Ï ÏƒÏγκÏουσης κυÏÏ„Î¿Ï ÏƒÏŽÎ¼Î±Ï„Î¿Ï‚" +msgstr "ΔημιουÏγία ΚυÏÏ„Î¿Ï Î‘Î´ÎµÎ»Ï†Î¿Ï Î£ÏγκÏουσης" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." @@ -5714,9 +5707,8 @@ msgid "Convert to CPUParticles" msgstr "ΜετατÏοπή σε σωματίδια CPU" #: editor/plugins/particles_2d_editor_plugin.cpp -#, fuzzy msgid "Generating Visibility Rect" -msgstr "ΔημιουÏγία οÏθογωνίου οÏατότητας" +msgstr "ΔημιουÏγία ΟÏθογωνίου ΟÏατότητας" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generate Visibility Rect" @@ -5807,9 +5799,8 @@ msgid "Add Point to Curve" msgstr "Î Ïοσθήκη σημείου στην καμπÏλη" #: editor/plugins/path_2d_editor_plugin.cpp -#, fuzzy msgid "Split Curve" -msgstr "κλείσιμο καμπÏλης" +msgstr "ΔιαίÏεση ΚαμπÏλης" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Move Point in Curve" @@ -5839,9 +5830,8 @@ msgid "Click: Add Point" msgstr "Κλικ: Î Ïοσθήκη σημείου" #: editor/plugins/path_2d_editor_plugin.cpp -#, fuzzy msgid "Left Click: Split Segment (in curve)" -msgstr "ΔιαχωÏισμός τμήματος (στην καμπÏλη)" +msgstr "ΑÏιστεÏÏŒ Κλικ: ΔιαχωÏισμός τμήματος (σε καμπÏλη)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp @@ -5876,12 +5866,12 @@ msgstr "ΕπιλογÎÏ‚" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Mirror Handle Angles" -msgstr "" +msgstr "ΚαθÏεπτισμός Γωνιών Λαβών" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Mirror Handle Lengths" -msgstr "" +msgstr "ΚαθÏεπτισμός Μηκών Λαβών" #: editor/plugins/path_editor_plugin.cpp msgid "Curve Point #" @@ -5920,25 +5910,25 @@ msgid "Split Segment (in curve)" msgstr "ΔιαχωÏισμός τμήματος (στην καμπÏλη)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" -msgstr "Μετακίνηση σημείου" +msgstr "Μετακίνηση ΆÏθÏωσης" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" "The skeleton property of the Polygon2D does not point to a Skeleton2D node" -msgstr "" +msgstr "Η ιδιότητα skeleton του Polygon2D δεν δείχνει σε κόμβο Skeleton2D" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Sync Bones" -msgstr "Εμφάνιση οστών" +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 "" +"Καμιά υφή στο πολÏγωνο.\n" +"ΟÏίστε υφή για να επεξεÏγαστείτε τα UV." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create UV Map" @@ -5949,53 +5939,48 @@ msgid "" "Polygon 2D has internal vertices, so it can no longer be edited in the " "viewport." msgstr "" +"Το Polygon2D Îχει εσωτεÏικÎÏ‚ κοÏυφÎÏ‚, οπότε δεν μποÏεί πια να επεξεÏγαστεί " +"στην οθόνη." #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Create Polygon & UV" -msgstr "Δημιουγία πολυγώνου" +msgstr "ΔημιουÏγία Πολυγώνου & UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Create Internal Vertex" -msgstr "ΔημιουÏγία νÎου οÏιζόντιου οδηγοÏ" +msgstr "ΔημιουÏγία ΕσωτεÏικής ΚοÏυφής" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Remove Internal Vertex" -msgstr "ΑφαίÏεση σημείου ελÎγχου εισόδου" +msgstr "ΑφαίÏεση ΕσωτεÏικής ΚοÏυφής" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Invalid Polygon (need 3 different vertices)" -msgstr "" +msgstr "ΆκυÏο ΠολÏγωνο (απαιτεί 3 διαφοÏετικÎÏ‚ κοÏυφÎÏ‚)" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Add Custom Polygon" -msgstr "ΕπεγεÏγασία πολυγώνου" +msgstr "Î Ïοσθήκη Î ÏοσαÏμοσμÎνου Πολυγώνου" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Remove Custom Polygon" -msgstr "ΑφαίÏεση πολυγώνου και σημείου" +msgstr "ΑφαίÏεση Î ÏοσαÏμοσμÎνου Πολυγώνου" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Transform UV Map" msgstr "Μετασχηματισμός χάÏτη UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Transform Polygon" -msgstr "Είδος μετασχηματισμοÏ" +msgstr "ÎœÎµÏ„Î±ÏƒÏ‡Î·Î¼Î±Ï„Î¹ÏƒÎ¼Î¿Ï Î Î¿Î»Ï…Î³ÏŽÎ½Î¿Ï…" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Paint Bone Weights" -msgstr "" +msgstr "ΖωγÏάφισμα ΒαÏών Οστών" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Open Polygon 2D UV editor." -msgstr "ΕπεξεÏγαστής δισδιάστατου πολυγώνου" +msgstr "Άνοιγμα ΕπεξεÏγαστή UV Polygon2D." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon 2D UV Editor" @@ -6003,27 +5988,23 @@ msgstr "ΕπεξεÏγαστής δισδιάστατου πολυγώνου" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "UV" -msgstr "" +msgstr "UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Points" -msgstr "Σημείο" +msgstr "Σημεία" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Polygons" -msgstr "ΠολÏγωνο -> UV" +msgstr "ΠολÏγωνα" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Bones" -msgstr "ΔημιουÏγία οστών" +msgstr "Οστά" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Move Points" -msgstr "Μετακίνηση σημείου" +msgstr "Μετακίνηση Σημείων" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Ctrl: Rotate" @@ -6052,24 +6033,28 @@ 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 "" +msgstr "ΖωγÏαφίζει βάÏη με οÏισμÎνη Îνταση." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Unpaint weights with specified intensity." -msgstr "" +msgstr "Από-ζωγÏαφίζει βάÏη με οÏισμÎνη Îνταση." #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Radius:" -msgstr "" +msgstr "Ακτίνα:" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Polygon->UV" @@ -6084,9 +6069,8 @@ msgid "Clear UV" msgstr "ΕκκαθάÏιση UV" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Settings" -msgstr "Ρυθμίσεις GridMap" +msgstr "Ρυθμίσεις ΠλÎγματος" #: editor/plugins/polygon_2d_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6102,34 +6086,28 @@ msgid "Grid" msgstr "ΠλÎγμα" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Configure Grid:" -msgstr "Î ÏοσαÏμογή Ï€Ïοσκόλλησης" +msgstr "Î ÏοσαÏμογή ΠλÎγματος:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Offset X:" -msgstr "Μετατόπιση πλÎγατος:" +msgstr "Μετατόπιση ΠλÎγματος X:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Offset Y:" -msgstr "Μετατόπιση πλÎγατος:" +msgstr "Μετατόπιση ΠλÎγματος Y:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Step X:" -msgstr "Βήμα πλÎγματος:" +msgstr "Βήμα ΠλÎγματος X:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Grid Step Y:" -msgstr "Βήμα πλÎγματος:" +msgstr "Βήμα ΠλÎγματος Y:" #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Sync Bones to Polygon" -msgstr "Κλιμάκωση πολυγώνου" +msgstr "ΣυγχÏονισμός Οστών σε ΠολÏγωνο" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ERROR: Couldn't load resource!" @@ -6182,12 +6160,11 @@ msgstr "Î ÏόφÏαμμα Ï€ÏοφόÏτωσης" #: editor/plugins/root_motion_editor_plugin.cpp msgid "AnimationTree has no path set to an AnimationPlayer" -msgstr "" +msgstr "Το AnimationTree δεν Îχει διαδÏομή σε AnimationPlayer" #: editor/plugins/root_motion_editor_plugin.cpp -#, fuzzy msgid "Path to AnimationPlayer is invalid" -msgstr "Το δÎντÏο κίνησης δεν είναι ÎγκυÏο." +msgstr "ΆκυÏη διαδÏομή σε AnimationPlayer" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Files" @@ -6198,59 +6175,48 @@ msgid "Close and save changes?" msgstr "Κλείσιμο και αποθήκευση αλλαγών;" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error writing TextFile:" -msgstr "Σφάλμα κατά την μετακίνηση αÏχείου:\n" +msgstr "Σφάλμα εγγÏαφής TextFile:" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error: could not load file." -msgstr "Δεν ήταν δυνατή η φόÏτωση εικόνας" +msgstr "Σφάλμα φόÏτωσης αÏχείου." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error could not load file." -msgstr "Δεν ήταν δυνατή η φόÏτωση εικόνας" +msgstr "Σφάλμα φόÏτωσης αÏχείου." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error saving file!" -msgstr "Σφάλμα κατά την αποθήκευση TileSet!" +msgstr "Σφάλμα αποθήκευσης αÏχείου!" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error while saving theme." -msgstr "Σφάλμα κατά την αποθήκευση θÎματος" +msgstr "Σφάλμα αποθήκευσης θÎματος." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error Saving" -msgstr "Σφάλμα κατά την αποθήκευση" +msgstr "Σφάλμα αποθήκευσης" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error importing theme." -msgstr "Σφάλμα κατά την εισαγωγή θÎματος" +msgstr "Σφάλμα εισαγωγής θÎματος." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Error Importing" -msgstr "Σφάλμα κατά την εισαγωγή" +msgstr "Σφάλμα εισαγωγής" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "New TextFile..." -msgstr "ÎÎος φάκελος..." +msgstr "ÎÎο TextFile..." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open File" -msgstr "Άνοιγμα αÏχείου" +msgstr "Άνοιγμα ΑÏχείου" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Save File As..." -msgstr "Αποθήκευση ως..." +msgstr "Αποθήκευση ΑÏχείου Ως..." #: editor/plugins/script_editor_plugin.cpp msgid "Import Theme" @@ -6269,9 +6235,8 @@ msgid "Save Theme As..." msgstr "Αποθήκευση θÎματος ως..." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "%s Class Reference" -msgstr " ΑναφοÏά κλασεων" +msgstr "ΑναφοÏά Κλάσης %s" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -6279,8 +6244,18 @@ msgid "Find Next" msgstr "ΕÏÏεση επόμενου" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "ΦιλτÏάÏισμα ιδιοτήτων" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." -msgstr "" +msgstr "Εναλλαγή αλφαβητικής ταξινόμησης λίστας μεθόδων." + +#: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "ΛειτουÏγία φιλτÏαÏίσματος:" #: editor/plugins/script_editor_plugin.cpp msgid "Sort" @@ -6311,9 +6286,8 @@ msgid "File" msgstr "ΑÏχείο" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open..." -msgstr "Άνοιγμα" +msgstr "Άνοιγμα..." #: editor/plugins/script_editor_plugin.cpp msgid "Save All" @@ -6328,13 +6302,12 @@ msgid "Copy Script Path" msgstr "ΑντιγÏαφή διαδÏομής δεσμής ενεÏγειών" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "History Previous" -msgstr "ΙστοÏικά Ï€ÏοηγοÏμενο" +msgstr "Î ÏοηγοÏμενο ΙστοÏικοÏ" #: editor/plugins/script_editor_plugin.cpp msgid "History Next" -msgstr "ΙστοÏικά επόμενο" +msgstr "Επόμενο ΙστοÏικοÏ" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -6342,9 +6315,8 @@ msgid "Theme" msgstr "ΘÎμα" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Import Theme..." -msgstr "Εισαγωγή θÎματος" +msgstr "Εισαγωγή θÎματος..." #: editor/plugins/script_editor_plugin.cpp msgid "Reload Theme" @@ -6392,22 +6364,20 @@ msgid "Keep Debugger Open" msgstr "ΔιατήÏησε τον αποσφαλματωτή ανοιχτό" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Debug with External Editor" -msgstr "Αποσφαλμάτωση με εξωτεÏικό επεξεÏγαστή" +msgstr "Αποσφαλμάτωση με ΕξωτεÏικό ΕπεξεÏγαστή" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Άνοιγμα ηλεκτÏονικής τεκμηÏίωσης της Godot" +msgstr "Άνοιγμα ηλεκτÏονικής τεκμηÏίωσης της Godot." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" -msgstr "" +msgstr "Αίτηση ΤεκμηÏίωσης" #: editor/plugins/script_editor_plugin.cpp msgid "Help improve the Godot documentation by giving feedback." -msgstr "" +msgstr "Βοηθήστε στην βελτίωση της τεκμηÏίωσης σχολιάζοντας." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6448,44 +6418,39 @@ msgid "Debugger" msgstr "Αποσφαλματωτής" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Search Results" -msgstr "Αναζήτηση βοήθειας" +msgstr "ΑποτελÎσματα Αναζήτησης" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "ΣÏνδεση στον κόμβο:" +msgstr "ΣÏνδεση σε μÎθοδο:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Πηγή:" +msgstr "Πηγή" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Σήματα" +msgstr "Σήμα" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Target" -msgstr "ΔιαδÏομή Ï€ÏοοÏισμοÏ:" +msgstr "Στόχος" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "ΑποσÏνδεση του '%s' απο το '%s'" +msgstr "" +"Λείπει η συνδεδεμÎνη μÎθοδος «%s» του σήματος «%s» από τον κόμβο «%s» στον " +"κόμβο «%s»." #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Line" -msgstr "ΓÏαμμή:" +msgstr "ΓÏαμμή" #: editor/plugins/script_text_editor.cpp msgid "(ignore)" -msgstr "" +msgstr "(ΠαÏάβλεψη)" #: editor/plugins/script_text_editor.cpp msgid "Go to Function" @@ -6496,9 +6461,8 @@ msgid "Only resources from filesystem can be dropped." msgstr "Μόνο οι πόÏοι από το σÏστημα αÏχείων μποÏοÏν να διαγÏαφοÏν." #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Lookup Symbol" -msgstr "ΣυμπλήÏωση συμβόλου" +msgstr "Αναζήτηση Συμβόλου" #: editor/plugins/script_text_editor.cpp msgid "Pick Color" @@ -6522,23 +6486,27 @@ msgstr "Κεφαλαιοποίηση" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Syntax Highlighter" +msgstr "Επισημαντής ΣÏνταξης" + +#: editor/plugins/script_text_editor.cpp +msgid "Go To" msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "ΑγαπημÎνα" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +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 "ΔιαγÏαφή γÏαμμής" @@ -6556,24 +6524,20 @@ msgid "Toggle Comment" msgstr "Εναλλαγή σχολιασμοÏ" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "Εναλλαγή ελεÏθεÏης κάμεÏας" +msgstr "Εναλλαγή ΑγαπημÎνου" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "Πήγαινε στο επόμενο σημείο διακοπής" +msgstr "Πήγαινε στο Επόμενο ΑγαπημÎνο" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Previous Bookmark" -msgstr "ΕπιστÏοφή στο Ï€ÏοηγοÏμενο σημείο διακοπής" +msgstr "Πήγαινε στο Î ÏοηγοÏμενο ΑγαπημÎνο" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "ΑφαίÏεση όλων των στοιχείων" +msgstr "ΑφαίÏεση Όλων των ΑγαπημÎνων" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -6600,14 +6564,12 @@ msgid "Trim Trailing Whitespace" msgstr "ΠεÏικοπή ÎºÎ±Ï„Î±Î»Î·ÎºÏ„Î¹ÎºÎ¿Ï ÎºÎµÎ½Î¿Ï Î´Î¹Î±ÏƒÏ„Î®Î¼Î±Ï„Î¿Ï‚" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Convert Indent to Spaces" -msgstr "ΜετατÏοπή εσοχής σε κενά" +msgstr "ΜετατÏοπή Εσοχών σε Κενά" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Convert Indent to Tabs" -msgstr "ΜετατÏοπή εσοχής σε στηλοθÎτες" +msgstr "ΜετατÏοπή Εσοχών σε ΣτηλοθÎτες" #: editor/plugins/script_text_editor.cpp msgid "Auto Indent" @@ -6635,9 +6597,8 @@ msgid "Find Previous" msgstr "ΈυÏεση Ï€ÏοηγοÏμενου" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Find in Files..." -msgstr "ΦιλτÏάÏισμα αÏχείων..." +msgstr "ΕÏÏεση σε ΑÏχεία..." #: editor/plugins/script_text_editor.cpp msgid "Go to Function..." @@ -6652,63 +6613,57 @@ msgid "Contextual Help" msgstr "Βοήθεια ανάλογα με τα συμφÏαζόμενα" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"Τα ακόλουθα αÏχεία είναι νεότεÏα στον δίσκο.\n" -"Τι δÏάση να ληφθεί;:" +"Αυτό το Ï€ÏόγÏαμμα σκίασης Îχει αλλάξει στον δίσκο.\n" +"Τι δÏάση να ληφθεί;" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" -msgstr "Î ÏόγÏαμμα σκίασης" +msgstr "Î ÏόγÏαμμα Σκίασης" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "This skeleton has no bones, create some children Bone2D nodes." msgstr "" +"Αυτός ο σκελετός δεν Îχει οστά, δώστε του κάποιους κόμβους-παιδιά Bone2D." #: editor/plugins/skeleton_2d_editor_plugin.cpp -#, fuzzy msgid "Create Rest Pose from Bones" -msgstr "ΔημιουÏγία σημείων εκπομπής από πλÎγμα" +msgstr "ΔημιουÏγία Στάσης ΑδÏάνειας από Οστά" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Set Rest Pose to Bones" -msgstr "" +msgstr "ΟÏισμός Στάσης ΑδÏάνειας σε Οστά" #: editor/plugins/skeleton_2d_editor_plugin.cpp -#, fuzzy msgid "Skeleton2D" -msgstr "Σκελετός..." +msgstr "Skeleton2D" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Make Rest Pose (From Bones)" -msgstr "" +msgstr "Κάνε Στάση ΑδÏάνειας (Από Οστά)" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Set Bones to Rest Pose" -msgstr "" +msgstr "ΘÎσε Οστά σε Στάση ΑδÏάνειας" #: editor/plugins/skeleton_editor_plugin.cpp -#, fuzzy msgid "Create physical bones" -msgstr "ΔημιουÏγία πλÎγματος πλοήγησης" +msgstr "ΔημιουÏγία φυσικών οστών" #: editor/plugins/skeleton_editor_plugin.cpp -#, fuzzy msgid "Skeleton" -msgstr "Σκελετός..." +msgstr "Σκελετός" #: editor/plugins/skeleton_editor_plugin.cpp -#, fuzzy msgid "Create physical skeleton" -msgstr "ΔημιουÏγία λÏσης C#" +msgstr "ΔημιουÏγία Ï†Ï…ÏƒÎ¹ÎºÎ¿Ï ÏƒÎºÎµÎ»ÎµÏ„Î¿Ï" #: editor/plugins/skeleton_ik_editor_plugin.cpp -#, fuzzy msgid "Play IK" -msgstr "ΑναπαÏαγωγή" +msgstr "ΑναπαÏαγωγή IK" #: editor/plugins/spatial_editor_plugin.cpp msgid "Orthogonal" @@ -6765,7 +6720,7 @@ msgstr "Τόνος" #: editor/plugins/spatial_editor_plugin.cpp msgid "Yaw" -msgstr "" +msgstr "ΠαÏÎκκλιση" #: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" @@ -6836,9 +6791,8 @@ msgid "Rear" msgstr "Πίσω" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Align with View" -msgstr "Στοίχηση με την Ï€Ïοβολή" +msgstr "Στοίχιση με Î Ïοβολή" #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "No parent to instance a child at." @@ -6850,9 +6804,8 @@ msgid "This operation requires a single selected node." msgstr "Αυτή η λειτουÏγία απαιτεί Îναν μόνο επιλεγμÎνο κόμβο." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock View Rotation" -msgstr "Εμφάνιση πληÏοφοÏιών" +msgstr "Κλείδωμα ΠεÏιστÏοφής Î Ïοβολής" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Normal" @@ -6899,9 +6852,8 @@ msgid "Doppler Enable" msgstr "Φαινόμενο ÎτόπλεÏ" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Cinematic Preview" -msgstr "ΔημιουÏγία Ï€Ïοεπισκοπήσεων πλεγμάτων" +msgstr "ΚινηματογÏαφική Î Ïοεπισκόπηση" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Left" @@ -6936,20 +6888,21 @@ 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 "" +"Σημείωση: Η τιμή FPS είναι τα καÏΠανά δευτεÏόλεπτο του επεξεÏγαστή.\n" +"Δεν μποÏεί να χÏησιμοποιηθεί ως αξιόπιστη Îνδειξη της απόδοσης του " +"παιχνιδιοÏ." #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "View Rotation Locked" -msgstr "Εμφάνιση πληÏοφοÏιών" +msgstr "Κλείδωμα ΠεÏιστÏοφής" #: editor/plugins/spatial_editor_plugin.cpp msgid "XForm Dialog" msgstr "Διάλογος XForm" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Nodes To Floor" -msgstr "κουμπώματος στο πλÎγμα" +msgstr "ΚοÏμπωμα Κόμβων στο Δάπεδο" #: editor/plugins/spatial_editor_plugin.cpp msgid "Select Mode (Q)" @@ -7014,9 +6967,8 @@ msgid "Right View" msgstr "Δεξιά όψη" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" -msgstr "Εναλλαγή Î Ïοοπτικής / ΑξονομετÏικής Ï€Ïοβολής" +msgstr "Εναλλαγή Î Ïοοπτικής/ΑξονομετÏικής Î Ïοβολής" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" @@ -7060,9 +7012,8 @@ msgid "Transform" msgstr "Μετασχηματισμός" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" -msgstr "κουμπώματος στο πλÎγμα" +msgstr "ΚοÏμπωμα ΑντικειμÎνου στο Δάπεδο" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Dialog..." @@ -7093,9 +7044,8 @@ msgid "4 Viewports" msgstr "4 ΟπτικÎÏ‚ γωνίες" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Gizmos" -msgstr "Εμφάνιση μαÏαφετιών" +msgstr "ΜαÏαφÎτια" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Origin" @@ -7172,106 +7122,91 @@ msgstr "Μετά" #: editor/plugins/spatial_editor_plugin.cpp msgid "Nameless gizmo" -msgstr "" +msgstr "Ανώνυμο μαÏαφÎτι" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create Mesh2D" -msgstr "ΔημιουÏγία πλÎγματος πεÏιγÏάμματος" +msgstr "ΔημιουÏγία Mesh2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create Polygon2D" -msgstr "Δημιουγία πολυγώνου" +msgstr "ΔημιουÏγία Polygon2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create CollisionPolygon2D" -msgstr "ΔημιουÏγία πολυγώνου πλοήγησης" +msgstr "ΔημιουÏγία CollisionPolygon2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create LightOccluder2D" -msgstr "ΔημιουÏγία πολυγώνου εμποδίου" +msgstr "ΔημιουÏγία LightOccluder2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Sprite is empty!" -msgstr "Η διαδÏομή αποθήκευσης είναι άδεια!" +msgstr "Το Sprite είναι άδειο!" #: editor/plugins/sprite_editor_plugin.cpp msgid "Can't convert a sprite using animation frames to mesh." -msgstr "" +msgstr "Αποτυχία μετατÏοπής sprite με την χÏήση καÏΠκίνησης σε πλÎγμα." #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't replace by mesh." -msgstr "" +msgstr "ΆκυÏη γεωμετÏία, αδÏνατη η αντικατάσταση με πλÎγμα." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to Mesh2D" -msgstr "ΜετατÏοπή σε %s" +msgstr "ΜετατÏοπή σε Mesh2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." -msgstr "" +msgstr "ΆκυÏη γεωμετÏία, αδÏνατη η δημιουÏγία πολυγώνου." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to Polygon2D" -msgstr "Μετακίνηση πολυγώνου" +msgstr "Μετακίνηση σε Polygon2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create collision polygon." -msgstr "" +msgstr "ΆκυÏη γεωμετÏία, αδÏνατη η δημιουÏγία πολυγώνου σÏγκÏουσης." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create CollisionPolygon2D Sibling" -msgstr "ΔημιουÏγία πολυγώνου πλοήγησης" +msgstr "ΔημιουÏγία Î‘Î´ÎµÎ»Ï†Î¿Ï CollisionPolygon2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create light occluder." -msgstr "" +msgstr "ΆκυÏη γεωμετÏία, αδÏνατη η δημιουÏγία εμποδίου φωτός." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create LightOccluder2D Sibling" -msgstr "ΔημιουÏγία πολυγώνου εμποδίου" +msgstr "ΔημιουÏγία Î‘Î´ÎµÎ»Ï†Î¿Ï LightOccluder2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Sprite" -msgstr "KαÏÎ Sprite" +msgstr "Sprite" #: editor/plugins/sprite_editor_plugin.cpp msgid "Simplification: " -msgstr "" +msgstr "Απλοποίηση: " #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Grow (Pixels): " -msgstr "ΚοÏμπωμα (Εικονοστοιχεία):" +msgstr "ΑÏξηση (Εικονοστοιχεία): " #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Update Preview" -msgstr "Î Ïοεπισκόπηση" +msgstr "ΑνανÎωση Î Ïοεπισκόπησης" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Settings:" -msgstr "Ρυθμίσεις" +msgstr "Ρυθμίσεις:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "Πλαισίωμα επιλογής" +msgstr "Δεν ΕπιλÎχθηκαν ΚαÏÎ" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "Î Ïοσθήκη καÏÎ" +msgstr "Î Ïοσθήκη %d ΚαÏÎ" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" @@ -7302,14 +7237,12 @@ msgid "(empty)" msgstr "(άδειο)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Animations:" -msgstr "Κινήσεις" +msgstr "Κινήσεις:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "New Animation" -msgstr "Κίνηση" +msgstr "ÎÎα Κίνηση" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Speed (FPS):" @@ -7320,18 +7253,16 @@ msgid "Loop" msgstr "Επανάληψη" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Animation Frames:" -msgstr "ΚαÏΠκίνησης" +msgstr "ΚαÏΠΚίνησης:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Î ÏοσθÎστε κόμβο/-ους από δÎντÏο" +msgstr "Î Ïοσθήκη Υφής από ΑÏχείο" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "Î Ïοσθήκη ΚαÏΠαπό ΦÏλλο Sprite" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7350,28 +7281,24 @@ msgid "Move (After)" msgstr "Μετκίνιση (Μετά)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "Στοίβαξη καÏÎ" +msgstr "Επιλογή ΚαÏÎ" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Horizontal:" -msgstr "" +msgstr "ΟÏιζόντια:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "ΚοÏυφÎÏ‚" +msgstr "Κάθετα:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "Επιλογή όλων" +msgstr "Επιλογή/ΕκκαθάÏιση Όλων των ΚαÏÎ" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "ΔημιουÏγία από σκηνή" +msgstr "ΔημιουÏγία ΚαÏΠαπό ΦÏλλο Sprite" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" @@ -7382,9 +7309,8 @@ msgid "Set Region Rect" msgstr "ΟÏισμός οÏθογωνίου πεÏιοχής" #: editor/plugins/texture_region_editor_plugin.cpp -#, fuzzy msgid "Set Margin" -msgstr "ΟÏισμός λαβής" +msgstr "ΟÏισμός ΠεÏιθωÏίου" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Snap Mode:" @@ -7392,9 +7318,8 @@ msgstr "ΛειτουÏγία κουμπώματος:" #: editor/plugins/texture_region_editor_plugin.cpp #: scene/resources/visual_shader.cpp -#, fuzzy msgid "None" -msgstr "<Τίποτα>" +msgstr "Τίποτα" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Pixel Snap" @@ -7418,12 +7343,11 @@ msgstr "Βήμα:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Sep.:" -msgstr "" +msgstr "ΔιαχωÏιστικό:" #: editor/plugins/texture_region_editor_plugin.cpp -#, fuzzy msgid "TextureRegion" -msgstr "ΠεÏιοχή υφής" +msgstr "TextureRegion" #: editor/plugins/theme_editor_plugin.cpp msgid "Can't save theme to file:" @@ -7446,9 +7370,8 @@ msgid "Remove All" msgstr "ΑφαίÏεση όλων" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "ΕπεξεÏγασία θÎματος..." +msgstr "ΕπεξεÏγασία ΘÎματος" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7475,23 +7398,20 @@ msgid "Create From Current Editor Theme" msgstr "ΔημιουÏγία από το Ï„ÏÎχων θÎμα του επεξεÏγαστή" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Toggle Button" -msgstr "Κουμπί ποντικιοÏ" +msgstr "Εναλλαγή ΚουμπιοÏ" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Μεσαίο κουμπί" +msgstr "ΑπενεÏγοποιημÎνο Κουμπί" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" msgstr "Στοιχείο" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "ΑπενεÏγοποιημÎνο" +msgstr "ΑπενεÏγοποιημÎνο Στοιχείο" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -7511,21 +7431,19 @@ msgstr "ΕπιλεγμÎνο στοιχείο επιλογής" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "ΟνομασμÎνο ΔιαχωÏιστικό" #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Υπό-ΜενοÏ" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "Στοιχείο" +msgstr "Στοιχείο 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "Στοιχείο" +msgstr "Στοιχείο 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -7536,9 +7454,8 @@ msgid "Many" msgstr "ΠολλÎÏ‚" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled LineEdit" -msgstr "ΑπενεÏγοποιημÎνο" +msgstr "ΑπενεÏγοποιημÎνο LineEdit" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -7553,13 +7470,12 @@ msgid "Tab 3" msgstr "ΚαÏÏ„Îλα 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "ΕπεξεÏγάσιμα παιδιά" +msgstr "ΕπεξεÏγάσιμο Στοιχείο" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "ΥπόδεντÏο" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7594,15 +7510,13 @@ msgid "Erase Selection" msgstr "ΔιαγÏαφή επιλογής" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Fix Invalid Tiles" -msgstr "Μη ÎγκυÏο όνομα." +msgstr "ΔιόÏθωση ΆκυÏων Πλακιδίων" #: editor/plugins/tile_map_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Cut Selection" -msgstr "ΚεντÏάÏισμα επιλογής" +msgstr "Αποκοπή Επιλογής" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint TileMap" @@ -7625,9 +7539,8 @@ msgid "Erase TileMap" msgstr "ΔιαγÏαφή TileMap" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Find Tile" -msgstr "ΕÏÏεση πλακιδίου" +msgstr "ΕÏÏεση Πλακιδίου" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Transpose" @@ -7642,14 +7555,12 @@ msgid "Mirror Y" msgstr "ΣυμμετÏία στον άξονα Î¥" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "Αυτόματο πλακίδια" +msgstr "ΑπενεÏγοποίηση Αυτόματων Πλακιδίων" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "ΕπεξεÏγασία φίλτÏων" +msgstr "ΕπεξεÏγασία Î ÏοτεÏαιότητας" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7660,43 +7571,40 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift+Δεξί Κλικ: ΖωγÏάφισμα ΓÏαμμής\n" +"Shift+Ctrl+Δεξί Κλικ: ΖωγÏάφισμα ΟÏθογωνίου" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" msgstr "Επιλογή πλακιδίου" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" -msgstr "ΛειτουÏγία πεÏιστÏοφής" +msgstr "ΠεÏιστÏοφή ΑÏιστεÏά" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" -msgstr "Μετακίνηση δεξιά" +msgstr "ΠεÏιστÏοφή Δεξιά" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Flip Horizontally" -msgstr "" +msgstr "ΑναστÏοφή ΟÏιζόντια" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Flip Vertically" -msgstr "" +msgstr "ΑναστÏοφή Κάθετα" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" -msgstr "Μετασχηματισμός" +msgstr "ΕκκαθάÏιση ΜετασχηματισμοÏ" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Add Texture(s) to TileSet." -msgstr "Î ÏοσθÎστε κόμβο/-ους από δÎντÏο" +msgstr "Î Ïοσθήκη Υφών σε TileSet." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove selected Texture from TileSet." -msgstr "ΑφαίÏεση Ï„ÏÎχουσας εγγÏαφής" +msgstr "ΑφαίÏεση επιλεγμÎνης υφής από το TileSet." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from Scene" @@ -7707,936 +7615,671 @@ msgid "Merge from Scene" msgstr "Συγχώνευση από σκηνή" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Next Coordinate" -msgstr "Επόμενο πάτωμα" +msgstr "Επόμενη ΣυντεταγμÎνη" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select the next shape, subtile, or Tile." -msgstr "" +msgstr "Επιλογή επόμενου σχήματος, υπό-πλακιδίου, ή πλακιδίου." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Previous Coordinate" -msgstr "Î ÏοηγοÏμενο πάτωμα" +msgstr "Î ÏοηγοÏμενη ΣυντεταγμÎνη" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select the previous shape, subtile, or Tile." -msgstr "" +msgstr "Επιλογή Ï€ÏοηγοÏμενου σχήματος, υπό-πλακιδίου, ή πλακιδίου." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "ΛειτουÏγία εκτÎλεσης:" +msgstr "ΛειτουÏγία ΠεÏιοχής" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "ΜÎθοδος παÏεμβολής" +msgstr "ΛειτουÏγία ΣÏγκÏουσης" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "ΕπεγεÏγασία πολυγώνου" +msgstr "ΛειτουÏγία Εμποδίου" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "ΔημιουÏγία πλÎγματος πλοήγησης" +msgstr "ΔημιουÏγία Πλοήγησης" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "ΛειτουÏγία πεÏιστÏοφής" +msgstr "ΛειτουÏγία Μάσκας Bit" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "ΛειτουÏγία εξαγωγής:" +msgstr "ΛειτουÏγία Î ÏοτεÏαιότητας" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "ΛειτουÏγία Μετακίνησης κάμεÏας" +msgstr "ΛειτουÏγία Εικονιδίων" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "ΛειτουÏγία Μετακίνησης κάμεÏας" +msgstr "ΛειτουÏγία Δείκτη Z" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." -msgstr "" +msgstr "ΑντιγÏαφή μάσκας bit." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Paste bitmask." -msgstr "Επικόλληση κίνησης" +msgstr "Επικόλληση μάσκας bit." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Erase bitmask." -msgstr "ΔιαγÏαφή σημείων." +msgstr "ΔιαγÏαφή μάσκας bit." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create a new rectangle." -msgstr "ΔημιουÏγία νÎων κόμβων." +msgstr "ΔημιουÏγία νÎου οÏθογωνίου." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create a new polygon." -msgstr "ΔημιουÏγία νÎου πολυγώνου από την αÏχή." +msgstr "ΔημιουÏγία νÎου πολυγώνου." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Keep polygon inside region Rect." -msgstr "" +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 "" +msgstr "ΑπενεÏγοποίηση Ονομάτων Πλακιδίων (ΚÏατήστε πατημÎνο το Alt)" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove selected texture? This will remove all tiles which use it." -msgstr "ΑφαίÏεση Ï„ÏÎχουσας εγγÏαφής" +msgstr "" +"ΑφαίÏεση επιλεγμÎνης υφής; Αυτό θα αφαιÏÎσει όλα τα πλακίδια που την " +"χÏησιμοποιοÏν." #: editor/plugins/tile_set_editor_plugin.cpp msgid "You haven't selected a texture to remove." -msgstr "" +msgstr "Δεν Îχετε επιλÎξει υφή για αφαίÏεση." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from scene? This will overwrite all current tiles." -msgstr "" +msgstr "ΔημιουÏγία από σκηνή; Αυτό θα αντικαταστήσει όλα τα Ï„ÏÎχοντα πλακίδια." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Merge from scene?" msgstr "Συγχώνευση από σκηνή;" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Texture" -msgstr "ΑφαίÏεση Ï€ÏοτÏπου" +msgstr "ΑφαίÏεση Υφής" #: editor/plugins/tile_set_editor_plugin.cpp msgid "%s file(s) were not added because was already on the list." -msgstr "" +msgstr "Το/α αÏχείο/α %s δεν Ï€ÏοστÎθηκε/αν γιατί ήταν ήδη στην λίστα." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" "Drag handles to edit Rect.\n" "Click on another Tile to edit it." msgstr "" +"ΣÏÏετε τις λαβÎÏ‚ για επεξεÏγασία του ΟÏθογωνίου.\n" +"Πατήστε σε άλλο πλακίδιο για να το επεξεÏγαστείτε." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Delete selected Rect." -msgstr "ΔιαγÏαφή επιλεγμÎνων αÏχείων;" +msgstr "ΔιαγÏαφή επιλεγμÎνου ΟÏθογωνίου." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "Select current edited sub-tile.\n" "Click on another Tile to edit it." -msgstr "ΕπÎλεξε το Ï„ÏÎχων επεξεÏγαζόμενο υπο-πλακίδιο." +msgstr "" +"ΕπÎλεξε το Ï„ÏÎχων επεξεÏγαζόμενο υποπλακίδιο.\n" +"Πατήστε σε άλλο πλακίδιο για να το επεξεÏγαστείτε." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Delete polygon." -msgstr "ΔιαγÏαφή σημείων" +msgstr "ΔιαγÏαφή πολυγώνου." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy 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 "" -"ΑÏιστεÏÏŒ κλικ: ενεÏγοποίησε το bit.\n" -"Δεξί κλικ: απενεÏγοποίησε το bit." +"ΑÏιστεÏÏŒ κλικ: ΕνεÏγοποίηση bit.\n" +"Δεξί κλικ: ΑπενεÏγοποίηση bit.\n" +"Shift + ΑÏιστεÏÏŒ κλικ: ΕνεÏγοποίηση του bit μπαλαντÎÏ.\n" +"Πατήστε σε άλλο πλακίδιο για να το επεξεÏγαστείτε." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy 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 "" -"ΕπιλÎξτε υπότιτλο για εικονίδιο, o οποίος θα χÏησιμοποιείται και σε μη " -"ÎγκυÏες συνδÎσεις αυτόματων πλακιδίων." +"ΕπιλÎξτε υπότιτλο για εικονίδιο, που θα χÏησιμοποιείται και σε μη ÎγκυÏους " +"δεσμοÏÏ‚ αυτόματων πλακιδίων.\n" +"Πατήστε σε άλλο πλακίδιο για να το επεξεÏγαστείτε." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "Select sub-tile to change its priority.\n" "Click on another Tile to edit it." -msgstr "ΕπιλÎξτε υπο-πλακίδιο για να αλλάξετε την Ï€ÏοτεÏαιότητα του." +msgstr "ΕπιλÎξτε υποπλακίδιο για να αλλάξετε την Ï€ÏοτεÏαιότητα του." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "Select sub-tile to change its z index.\n" "Click on another Tile to edit it." -msgstr "ΕπιλÎξτε υπο-πλακίδιο για να αλλάξετε την Ï€ÏοτεÏαιότητα του." +msgstr "" +"ΕπιλÎξτε υποπλακίδιο για να αλλάξετε την Ï€ÏοτεÏαιότητα z του.\n" +"Πατήστε σε άλλο πλακίδιο για να το επεξεÏγαστείτε." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Set Tile Region" -msgstr "ΟÏισμός οÏθογωνίου πεÏιοχής" +msgstr "ΟÏισμός ΠεÏιοχής Πλακιδίου" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create Tile" -msgstr "ΔημιουÏγία φακÎλου" +msgstr "ΔημιουÏγία Πλακιδίου" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Set Tile Icon" -msgstr "" +msgstr "ΟÏισμός Εικονιδίου Πλακιδίου" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Tile Bitmask" -msgstr "ΕπεξεÏγασία φίλτÏων" +msgstr "ΕπεξεÏγασία Μάσκας Bit Πλακιδίου" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Collision Polygon" -msgstr "ΕπεξεÏγασία υπαÏÎºÏ„Î¿Ï Ï€Î¿Î»Ï…Î³ÏŽÎ½Î¿Ï…:" +msgstr "ΕπεξεÏγασία Πολυγώνου ΣÏγκÏουσης" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Occlusion Polygon" -msgstr "ΕπεγεÏγασία πολυγώνου" +msgstr "ΕπεξεÏγασία Πολυγώνου Εμποδίου" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Navigation Polygon" -msgstr "ΔημιουÏγία πολυγώνου πλοήγησης" +msgstr "ΕπεξεÏγασία Πολυγώνου Πλοήγησης" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Paste Tile Bitmask" -msgstr "Επικόλληση κίνησης" +msgstr "Επικόλληση Μάσκας Bit Πλακιδίου" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Clear Tile Bitmask" -msgstr "" +msgstr "ΕκκαθάÏιση Μάσκας Bit Πλακιδίου" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Make Polygon Concave" -msgstr "Μετακίνηση πολυγώνου" +msgstr "ΜετατÏοπή Πολυγώνου σε Κοίλο" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Make Polygon Convex" -msgstr "Μετακίνηση πολυγώνου" +msgstr "ΜετατÏοπή Πολυγώνου σε ΚυÏτό" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Tile" -msgstr "ΑφαίÏεση Ï€ÏοτÏπου" +msgstr "ΑφαίÏεση Πλακιδίου" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Collision Polygon" -msgstr "ΑφαίÏεση πολυγώνου και σημείου" +msgstr "ΑφαίÏεση Πολυγώνου ΣÏγκÏουσης" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Occlusion Polygon" -msgstr "ΔημιουÏγία πολυγώνου εμποδίου" +msgstr "ΑφαίÏεση Πολυγώνου Εμποδίου" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Remove Navigation Polygon" -msgstr "ΔημιουÏγία πολυγώνου πλοήγησης" +msgstr "ΑφαίÏεση Πολυγώνου Πλοήγησης" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Edit Tile Priority" -msgstr "ΕπεξεÏγασία φίλτÏων" +msgstr "Αλλαγή Î ÏοτεÏαιότητας Πλακιδίου" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Tile Z Index" -msgstr "" +msgstr "Αλλαγή Δείκτη Z Πλακιδίου" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create Collision Polygon" -msgstr "ΔημιουÏγία πολυγώνου πλοήγησης" +msgstr "ΔημιουÏγία Πολυγώνου ΣÏγκÏουσης" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Create Occlusion Polygon" -msgstr "ΔημιουÏγία πολυγώνου εμποδίου" +msgstr "ΔημιουÏγία Πολυγώνου Εμποδίου" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "This property can't be changed." -msgstr "Αυτή η λειτουÏγία δεν μποÏεί να γίνει χωÏίς σκηνή." +msgstr "Αυτή η ιδιότητα δεν μποÏεί να αλλάξει." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "TileSet" -msgstr "ΣÏνολο πλακιδίων" +msgstr "TileSet" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input +" -msgstr "Î Ïοσθήκη εισόδου" +msgstr "Î Ïοσθήκη εισόδου +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add output +" -msgstr "Î Ïοσθήκη εισόδου" +msgstr "Î Ïοσθήκη εξόδου +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "Κλιμάκωση:" +msgstr "Βαθμωτό ΜÎγεθος" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "ΕπιθεωÏητής" +msgstr "Διάνυσμα" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Λογική Τιμή" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "Î Ïοσθήκη εισόδου" +msgstr "Î Ïοσθήκη θÏÏας εισόδου" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Î Ïοσθήκη θÏÏας εξόδου" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "Αλλαγή Ï€ÏοεπιλεγμÎνου Ï„Ïπου" +msgstr "Αλλαγή Ï„Ïπου θÏÏας εισόδου" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "Αλλαγή Ï€ÏοεπιλεγμÎνου Ï„Ïπου" +msgstr "Αλλαγή Ï„Ïπου θÏÏας εξόδου" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "Αλλαγή ονόματος εισόδου" +msgstr "Αλλαγή ονόματος θÏÏας εισόδου" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "Αλλαγή ονόματος εισόδου" +msgstr "Αλλαγή ονόματος θÏÏας εξόδου" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "ΑφαίÏεση σημείου" +msgstr "ΑφαίÏεση θÏÏας εισόδου" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "ΑφαίÏεση σημείου" +msgstr "ΑφαίÏεση θÏÏας εξόδου" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "Αλλαγή ÎκφÏασης" +msgstr "ΟÏισμός ÎκφÏασης" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "Î ÏόγÏαμμα σκίασης" +msgstr "Κλιμάκωση κόμβου VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" -msgstr "" +msgstr "Αλλαγή Ονόματος Ενιαίας Μεταβλητής" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set Input Default Port" -msgstr "ΟÏισμός ως Ï€Ïοεπιλογής για '%s'" +msgstr "ΟÏισμός Î ÏοεπιλεγμÎνης ΘÏÏας Εισόδου" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add Node to Visual Shader" -msgstr "Î ÏόγÏαμμα σκίασης" +msgstr "Î Ïοσθήκη Κόμβου στο Οπτικό Î ÏόγÏαμμα Σκίασης" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Duplicate Nodes" -msgstr "Διπλασιασμός κόμβων" +msgstr "ΑναπαÏαγωγή Κόμβων" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Delete Nodes" msgstr "ΔιαγÏαφή Κόμβων" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Visual Shader Input Type Changed" -msgstr "" +msgstr "Αλλαγή ΤÏπου Εισόδου ÎŸÏ€Ï„Î¹ÎºÎ¿Ï Î ÏογÏάμματος Σκίασης" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vertex" -msgstr "ΚοÏυφÎÏ‚" +msgstr "ΚοÏυφή" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Fragment" -msgstr "ΠαÏάμετÏοι:" +msgstr "Τμήμα" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Light" -msgstr "Δεξιά" +msgstr "Φως" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "ΔημιουÏγία κόμβου" +msgstr "ΔημιουÏγία Κόμβου Σκίασης" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "Πήγαινε σε συνάÏτηση" +msgstr "ΣυνάÏτηση χÏώματος." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "Τελεστής χÏώματος." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "ΔημιουÏγήστε μία συνάÏτηση" +msgstr "ΣυνάÏτηση κλίμακας του γκÏι." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "ΜετατÏÎπει διανÏσμα HSV στο αντίστοιχο RGB." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "ΜετατÏÎπει διανÏσμα RGB στο αντίστοιχο HSV." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "Μετονομασία συνάÏτησης" +msgstr "ΣυνάÏτησης ΣÎπια." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "Τελεστής καψίματος." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "Τελεστής σκοτεινιάσματος." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Difference operator." -msgstr "Μόνο διαφοÏÎÏ‚" +msgstr "Τελεστής διαφοÏάς." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." -msgstr "" +msgstr "Τελεστής άμβλυνσης." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "HardLight operator" -msgstr "" +msgstr "Τελεστής HardLight" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." -msgstr "" +msgstr "Τελεστής φωτισμοÏ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." -msgstr "" +msgstr "Τελεστής επικάλυψης." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Screen operator." -msgstr "" +msgstr "Τελεστής οθόνης." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "SoftLight operator." -msgstr "" +msgstr "Τελεστής SoftLight." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color constant." -msgstr "ΣταθεÏή" +msgstr "ΣταθεÏή χÏώματος." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color uniform." -msgstr "Μετασχηματισμός" +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 an associated vector if the provided boolean value is true or false." msgstr "" +"ΕπιστÏÎφει Îνα συσχετισμÎνο διάνυσμα εάν η λογική τιμή είναι αληθής ή ψευδής." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Boolean constant." -msgstr "Αλλαγή διανυσματικής σταθεÏάς" +msgstr "Λογική σταθεÏά." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean uniform." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." -msgstr "" +msgstr "Λογική ενιαία μεταβλητή." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy -msgid "Input parameter." -msgstr "ΚοÏμπωμα στον γονÎα" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" +msgid "'%s' input parameter for all shader modes." +msgstr "ΠαÏάμετÏος εισόδου «uv» για όλες τις λειτουÏγίες σκίασης." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" +msgid "Input parameter." +msgstr "ΠαÏάμετÏος εισόδου." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "ΠαÏάμετÏος εισόδου «uv» για σκίαση κοÏυφής και τμήματος." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "ΠαÏάμετÏος εισόδου «view» για σκίαση τμήματος και φωτός." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for fragment shader mode." +msgstr "ΠαÏάμετÏος εισόδου «side» για σκίαση τμήματος." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for light shader mode." +msgstr "ΠαÏάμετÏος εισόδου «diffuse» για σκίαση φωτός." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for vertex shader mode." +msgstr "ΠαÏάμετÏος εισόδου «custom» για σκίαση κοÏυφής." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "ΠαÏάμετÏος εισόδου «uv» για σκίαση κοÏυφής και τμήματος." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar function." -msgstr "Αλλαγή μονόμετÏης συνάÏτησης" +msgstr "Βαθμωτή συνάÏτηση." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar operator." -msgstr "Αλλαγή μονόμετÏου τελεστή" +msgstr "Βαθμωτός τελεστής." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "ΣταθεÏά e (e=2.718282). ΑναπαÏιστά την βάση του Ï†Ï…ÏƒÎ¹ÎºÎ¿Ï Î»Î¿Î³Î¬Ïιθμου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "ΣταθεÏά Epsilon (ε=0.00001). ΜικÏότεÏος δυνατός βαθμωτός αÏιθμός." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "ΣταθεÏά Phi (φ=1.618034). ΧÏυσή τομή." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "ΣταθεÏά Pi/4 (Ï€/4=0.785398) ή 45 μοίÏες." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "ΣταθεÏά Pi/2 (Ï€/2=1.570796) ή 90 μοίÏες." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "ΣταθεÏά Pi (Ï€=3.141593) ή 180 μοίÏες." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "ΣταθεÏά Tau (Ï„=6.283185) ή 360 μοίÏες." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "ΣταθεÏά Sqrt2 (1.414214). ΤετÏαγωνική Ïίζα του 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "ΕπιστÏÎφει την απόλυτη τιμή της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "ΕπιστÏÎφει το τόξο συνημιτόνου της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." msgstr "" +"(Μόνο GLES3) ΕπιστÏÎφει το αντίστÏοφο υπεÏβολικό συνημίτονο της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "ΕπιστÏÎφει το τόξο ημιτόνου της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." msgstr "" +"(Μόνο GLES3) ΕπιστÏÎφει το αντίστÏοφο υπεÏβολικό ημίτονο της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "ΕπιστÏÎφει το τόξο εφαπτομÎνης της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "ΕπιστÏÎφει το τόξο εφαπτομÎνης των παÏαμÎÏ„Ïων." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." msgstr "" +"(Μόνο GLES3) ΕπιστÏÎφει την αντίστÏοφη υπεÏβολική εφαπτομÎνη της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "Î’Ïίσκει τον κοντινότεÏο ακÎÏαιο, μεγαλÏτεÏο ή ίσο της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "ΠεÏιοÏίζει μια τιμή ανάμεσα σε δÏο άλλες τιμÎÏ‚." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "ΕπιστÏÎφει το συνημίτονο της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Μόνο GLES3) ΕπιστÏÎφει το υπεÏβολικό συνημίτονο της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "ΜετατÏÎπει ακτίνια σε μοίÏες." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "Εκθετικό βάσης e." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "Εκθετικό βάσης 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "Î’Ïίσκει τον κοντινότεÏο ακÎÏαιο μικÏότεÏο ή ίσο της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "Υπολογίζει το δεκαδικό τμήμα του οÏίσματος." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "ΕπιστÏÎφει το αντίστÏοφο της τετÏαγωνικής Ïίζας της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "Φυσικός λογάÏιθμος." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "ΛογάÏιθμος βάσης 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "ΕπιστÏÎφει το μÎγιστο δÏο τιμών." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "ΕπιστÏÎφει το ελάχιστο δÏο τιμών." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "ΓÏαμμική παÏεμβολή ανάμεσα σε δÏο βαθμωτά μεγÎθη." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "ΕπιστÏÎφει την αντίθετη τιμή της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - βαθμωτό μÎγεθος" #: 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 "" +msgstr "ΜετατÏÎπει μοίÏες σε ακτίνια." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / βαθμωτό μÎγεθος" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(Μόνο GLES3) Î’Ïίσκει τον κοντινότεÏο ακÎÏαιο στην παÏάμετÏο." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(Μόνο GLES3) Î’Ïίσκει τον κοντινότεÏο άÏτιο ακÎÏαιο στην παÏάμετÏο." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "ΠεÏιοÏίζει την τιμή ανάμεσα στο 0.0 και το 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "Εξάγει το Ï€Ïόσημο της τιμής." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "ΕπιστÏÎφει το ημίτονο της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(Μόνο GLES3) ΕπιστÏÎφει το υπεÏβολικό ημίτονο της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "ΕπιστÏÎφει την τετÏαγωνική Ïίζα της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8646,6 +8289,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"ΣυνάÏτηση SmoothStep( βαθμωτό(ÏŒÏιο0), βαθμωτό(ÏŒÏιο1), βαθμωτό(x) ).\n" +"\n" +"ΕπιστÏÎφει 0.0 αν x < ÏŒÏιο0 και 1.0 αν x > ÏŒÏιο1. Αλλιώς επιστÏÎφει μια " +"παÏεμβεβλημÎνη τιμή ανάμεσα στο 0.0 και το 1.0 χÏησιμοποιώντας πολυώνυμα " +"Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8653,71 +8301,69 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"ΣυνάÏτηση Step( βαθμωτό(ÏŒÏιο), βαθμωτό(x) ).\n" +"\n" +"ΕπιστÏÎφει 0.0 αν x < ÏŒÏιο, αλλιώς 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "ΕπιστÏÎφει την εφαπτομÎνη της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Μόνο GLES3) ΕπιστÏÎφει την υπεÏβολική εφαπτομÎνη της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." -msgstr "" +msgstr "(Μόνο GLES3) Î’Ïίσκει την πεÏικομμÎνη τιμή της παÏαμÎÏ„Ïου." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "Î Ïοσθήκη βαθμωτών μεγεθών." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "ΔιαίÏεση βαθμωτών μεγεθών." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "Πολ/μός βαθμωτών μεγεθών." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "ΕπιστÏÎφει το υπόλοιπο δÏο βαθμωτών μεγεθών." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "ΑφαίÏεση βαθμωτών μεγεθών." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar constant." -msgstr "Αλλαγή μονόμετÏης σταθεÏάς" +msgstr "Βαθμωτή σταθεÏά." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar uniform." -msgstr "Αλλαγή μονόμετÏης ομοιόμοÏφης μεταβλητής" +msgstr "Βαθμωτή ενιαία μεταβλητή." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "ΕκτÎλεση κυβικής αντιστοιχίας υφής." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the texture lookup." -msgstr "" +msgstr "ΕκτÎλεση αντιστοιχίας υφής." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Cubic texture uniform." -msgstr "Αλλαγή ομοιόμοÏφης μεταβλητής υφής" +msgstr "Ενιαία μεταβλητή κυβικής υφής." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "2D texture uniform." -msgstr "Αλλαγή ομοιόμοÏφης μεταβλητής υφής" +msgstr "Ενιαία μεταβλητή 2D υφής." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform function." -msgstr "Διάλογος μετασχηματισμοÏ..." +msgstr "ΣυνάÏτηση μετασχηματισμοÏ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8956,9 +8602,8 @@ msgid "" msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "VisualShader" -msgstr "Î ÏόγÏαμμα σκίασης" +msgstr "Οπτικό Î ÏόγÏαμμα Σκίασης" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9713,9 +9358,8 @@ msgid "Action:" msgstr "ΕνÎÏγεια:" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Action" -msgstr "ΕνÎÏγεια:" +msgstr "ΕνÎÏγεια" #: editor/project_settings_editor.cpp msgid "Deadzone" @@ -10051,7 +9695,7 @@ msgstr "Μετακίνηση κόμβων στον γονÎα" #: editor/scene_tree_dock.cpp msgid "Duplicate Node(s)" -msgstr "Διπλασιασμός κόμβων" +msgstr "ΑναπαÏαγωγή Κόμβων" #: editor/scene_tree_dock.cpp msgid "Can't reparent nodes in inherited scenes, order of nodes can't change." @@ -10188,6 +9832,11 @@ msgid "Add Child Node" msgstr "Î Ïοσθήκη κόμβου ως παιδί" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "ΣÏμπτηξη Όλων" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Αλλαγή Ï„Ïπου" @@ -10218,7 +9867,8 @@ msgid "Delete (No Confirm)" msgstr "ΔιαγÏαφή (ΧωÏίς επιβεβαίωση)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Î Ïοσθήκη/ΔημιουÏγία κόμβου" #: editor/scene_tree_dock.cpp @@ -10495,7 +10145,7 @@ msgstr "" "ΕπιλÎξτε Îνα ή πεÏισσότεÏα αντικείμενα από την λίστα για να εμφανιστεί το " "γÏάφημα." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Σφάλματα" @@ -10608,7 +10258,7 @@ msgstr "ΣυντομεÏσεις" #: editor/settings_config_dialog.cpp msgid "Binding" -msgstr "ΣÏνδεση" +msgstr "Δεσμός" #: editor/spatial_editor_gizmos.cpp msgid "Change Light Radius" @@ -10896,9 +10546,8 @@ msgid "Clear Selection" msgstr "ΕκκαθάÏιση επιλογής" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "Fill Selection" -msgstr "Επιλογή όλων" +msgstr "ΓÎμισμα Επιλογής" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Settings" @@ -10912,54 +10561,6 @@ msgstr "Επιλογή απόστασης:" msgid "Class name can't be a reserved keyword" msgstr "Το όνομα της κλάσης δεν μποÏεί να είναι λÎξη-κλειδί" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "ΔημιουÏγία λÏσης..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "ΔημιουÏγία ÎÏγου C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "ΑπÎτυχε η δημιουÏγία λÏσης." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "ΑπÎτυχε η αποθήκευση της λÏσης." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "ΤÎλος" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "ΑπÎτυχε η δημιουÏγία ÎÏγου C#." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Μονοφωνικό" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "Σχετικά με την υποστήÏιξη C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "ΔημιουÏγία λÏσης C#" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Δόμηση" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Δόμηση ÎÏγου" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Î Ïοβολή αÏχείου καταγÏαφής" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "ΤÎλος ιχνηλάτησης στοίβας εσωτεÏικής εξαίÏεσης" @@ -11128,7 +10729,7 @@ msgstr "ΑφαίÏεση κόμβων VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Duplicate VisualScript Nodes" -msgstr "Διπλασιασμός κόμβων VisualScript" +msgstr "ΑναπαÏαγωγή Κόμβων VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." @@ -11562,8 +11163,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "ΆκυÏες διαστάσεις εικόνας οθόνης εκκίνησης (Ï€ÏÎπει να είναι 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Ένας πόÏος SpriteFrames Ï€ÏÎπει να Îχει δημιουÏγηθεί ή οÏισθεί στην ιδιότητα " @@ -11631,8 +11233,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "Μία υφή με το σχήμα του φωτός Ï€ÏÎπει να δοθεί στην ιδιότητα 'texture'." @@ -11644,7 +11247,8 @@ msgstr "" "αυτό το εμπόδιο." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "Το πολÏγωνο εμποδίου για αυτό το εμπόδιο είναι άδειο. ΖωγÏαφίστε Îνα " "πολÏγονο!" @@ -11726,16 +11330,30 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 "" +"To CollisionShape2D υπάÏχει μόνο για να δώσει Îνα σχήμα σÏγκÏουσης σε Îναν " +"κόμβο που Ï€ÏοÎÏχεται από το CollisionObject2D. ΧÏησιμοποιήστε το μόνο εάν " +"κληÏονομεί τα Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, κλπ, για " +"να τους δώσετε Îνα σχήμα." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "Το VisibilityEnable2D δουλεÏει καλÏτεÏα όταν χÏησιμοποιείται μα την Ïίζα της " "επεξεÏγασμÎνης σκηνÎÏ‚ κατευθείαν ως γονÎας." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "Η ARVRCamera Ï€ÏÎπει να Îχει Îναν κόμβο ARVROrigin ως γονÎα" #: scene/3d/arvr_nodes.cpp @@ -11834,9 +11452,10 @@ msgstr "" "δώσετε Îνα σχήμα." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Ένα σχήμα Ï€ÏÎπει να δοθεί στο CollisionShape για να λειτουÏγήσει. " "ΔημιουÏγήστε Îνα πόÏο σχήματος για αυτό!" @@ -11869,6 +11488,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11909,8 +11532,8 @@ msgstr "Το PathFollow2D δουλεÏει μόνο όταν κληÏονομεΠ#: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11924,7 +11547,10 @@ msgstr "" "Αλλάξτε μÎγεθος στα σχήματα σÏγκÏουσης των παιδιών." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "Η ιδιότητα Path Ï€ÏÎπει να δείχνει σε Îναν ÎγκυÏο κόμβο Spatial για να " "δουλÎψει αυτός ο κόμβος." @@ -11945,8 +11571,9 @@ msgstr "" "Αλλάξτε μÎγεθος στα σχήματα σÏγκÏουσης των παιδιών." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Ένας πόÏος SpriteFrames Ï€ÏÎπει να δημιουÏγηθεί ή οÏισθεί στην ιδιότητα " @@ -11961,8 +11588,10 @@ msgstr "" "χÏησιμοποιήστε το ως παιδί του VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "Το WorldEnvironment χÏειάζεται Îναν πόÏο Environment." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -12003,7 +11632,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "ΑποσÏνδεση του '%s' απο το '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -12019,7 +11648,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "Το δÎντÏο κίνησης δεν είναι ÎγκυÏο." #: scene/animation/animation_tree_player.cpp @@ -12031,24 +11660,38 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Ωμή λειτουÏγία" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +#, fuzzy +msgid "Raw" +msgstr "ΠαÏÎκκλιση" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." msgstr "" #: scene/gui/color_picker.cpp -#, fuzzy msgid "Add current color as a preset." -msgstr "Î Ïοσθήκη του Ï„ÏÎχοντος χÏώματος ως Ï€ÏοκαθοÏισμÎνο" +msgstr "Î Ïοσθήκη Ï„ÏÎχοντος χÏώματος στα Ï€ÏοκαθοÏισμÎνα." #: scene/gui/container.cpp +#, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." +msgstr "" +"Το Container από μόνο του δεν Îχει κάποιο σκοπό αν κάποια δÎσμη ενεÏγειών " +"δεν οÏίσει την τοποθÎτηση των παιδιών του.\n" +"Εάν δεν σκοπεÏετε να Ï€ÏοσθÎσετε κάποια δÎσμη ενεÏγειών, χÏησιμοποιήστε Îνα " +"απλό «Control»." + +#: 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 @@ -12060,28 +11703,30 @@ msgid "Please Confirm..." msgstr "ΠαÏακαλώ επιβεβαιώστε..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Οι κόμβοι Ï„Ïπου Popup θα είναι κÏυμμÎνοι από Ï€Ïοεπιλογή, εκτός κι αν " "καλÎσετε την popup() ή καμία από τις συναÏτήσεις popup*(). Το να τους κάνετε " "οÏατοÏÏ‚ κατά την επεξεÏγασία, όμως, δεν είναι Ï€Ïόβλημα." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "" #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "Το ScrollContainer είναι φτιαγμÎνο για να δουλεÏει με Îνα μόνο υπο-στοιχείο " "control.\n" -"ΧÏησιμοποιήστε Îνα container ως παιδί (VBox, HBox, κτλ), ή Îνα Control και " +"ΧÏησιμοποιήστε Îνα Container ως παιδί (VBox, HBox, κτλ), ή Îνα Control και " "οÏίστε το Ï€ÏοσαÏμοσμÎνο ελάχιστο μÎγεθος χειÏοκίνητα." #: scene/gui/tree.cpp @@ -12103,7 +11748,7 @@ msgid "" "obtain a size. Otherwise, make it a RenderTarget and assign its internal " "texture to some node for display." msgstr "" -"Το Viewport δεν Îχει οÏισθεί ως \"render target'. Αν σκοπεÏετε να δείχνει τα " +"Το Viewport δεν Îχει οÏισθεί ως «render target». Αν σκοπεÏετε να δείχνει τα " "πεÏιεχόμενα του, κάντε το να κληÏονομεί Îνα Control, ώστε να αποκτήσει " "μÎγεθος. Αλλιώς, κάντε το Îνα RenderTarget και οÏίστε το internal texture σε " "Îναν κόμβο για απεικόνιση." @@ -12125,9 +11770,13 @@ msgid "Invalid font size." msgstr "Μη ÎγκυÏο μÎγεθος γÏαμματοσειÏάς." #: scene/resources/visual_shader.cpp -#, fuzzy msgid "Input" -msgstr "Î Ïοσθήκη εισόδου" +msgstr "Είσοδος" + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Μη ÎγκυÏη πηγή!" #: scene/resources/visual_shader_nodes.cpp #, fuzzy @@ -12150,6 +11799,225 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Generating solution..." +#~ msgstr "Επίλυση..." + +#~ msgid "Generating C# project..." +#~ msgstr "ΔημιουÏγία ÎÏγου C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "ΑπÎτυχε η δημιουÏγία λÏσης." + +#~ msgid "Failed to save solution." +#~ msgstr "ΑπÎτυχε η αποθήκευση της λÏσης." + +#~ msgid "Done" +#~ msgstr "ΤÎλος" + +#~ msgid "Failed to create C# project." +#~ msgstr "ΑπÎτυχε η δημιουÏγία ÎÏγου C#." + +#~ msgid "Mono" +#~ msgstr "Μονοφωνικό" + +#~ msgid "About C# support" +#~ msgstr "Σχετικά με την υποστήÏιξη C#" + +#~ msgid "Create C# solution" +#~ msgstr "ΔημιουÏγία λÏσης C#" + +#~ msgid "Builds" +#~ msgstr "Δόμηση" + +#~ msgid "Build Project" +#~ msgstr "Δόμηση ÎÏγου" + +#~ msgid "View log" +#~ msgstr "Î Ïοβολή αÏχείου καταγÏαφής" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "Το WorldEnvironment χÏειάζεται Îναν πόÏο Environment." + +#~ msgid "Enabled Classes" +#~ msgstr "ΕνεÏγοποιημÎνες Κλάσεις" + +#~ msgid "Update Always" +#~ msgstr "ΕνημÎÏωση πάντα" + +#~ msgid "'camera' input parameter for all shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «camera» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'inv_camera' input parameter for all shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «inv_camera» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'inv_projection' input parameter for all shader modes." +#~ msgstr "" +#~ "ΠαÏάμετÏος εισόδου «inv_projection» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'normal' input parameter for all shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «normal» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'projection' input parameter for all shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «projection» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'time' input parameter for all shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «time» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'viewport_size' input parameter for all shader modes." +#~ msgstr "" +#~ "ΠαÏάμετÏος εισόδου «viewport_size» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'world' input parameter for all shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «world» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'alpha' input parameter for all shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «alpha» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'color' input parameter for all shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «color» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'texture_pixel_size' input parameter for all shader modes." +#~ msgstr "" +#~ "ΠαÏάμετÏος εισόδου «texture_pixel_size» για όλες τις λειτουÏγίες σκίασης." + +#~ msgid "'alpha' input parameter for vertex and fragment shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «alpha» για σκίαση κοÏυφής και τμήματος." + +#~ msgid "'binormal' input parameter for vertex and fragment shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «binormal» για σκίαση κοÏυφής και τμήματος." + +#~ msgid "'color' input parameter for vertex and fragment shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «color» για σκίαση κοÏυφής και τμήματος." + +#~ msgid "'fragcoord' input parameter for fragment and light shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «fragcoord» για σκίαση τμήματος και φωτός." + +#~ msgid "'point_coord' input parameter for fragment shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «point_coord» για σκίαση τμήματος." + +#~ msgid "'screen_uv' input parameter for fragment shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «screen_uv» για σκίαση τμήματος." + +#~ msgid "'tangent' input parameter for vertex and fragment shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «tangent» για σκίαση κοÏυφής και τμήματος." + +#~ msgid "'uv2' input parameter for vertex and fragment shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «uv2» για σκίαση κοÏυφής και τμήματος." + +#~ msgid "'vertex' input parameter for vertex and fragment shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «vertex» για σκίαση κοÏυφής και τμήματος." + +#~ msgid "'albedo' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «albedo» για σκίαση φωτός." + +#~ msgid "'attenuation' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «attenuation» για σκίαση φωτός." + +#~ msgid "'light' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «light» για σκίαση φωτός." + +#~ msgid "'light_color' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «light_color» για σκίαση φωτός." + +#~ msgid "'roughness' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «roughness» για σκίαση φωτός." + +#~ msgid "'specular' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «specular» για σκίαση φωτός." + +#~ msgid "'transmission' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «transmission» για σκίαση φωτός." + +#~ msgid "'modelview' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «modelview» για σκίαση κοÏυφής." + +#~ msgid "'point_size' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «point_size» για σκίαση κοÏυφής." + +#~ msgid "'tangent' input parameter for vertex and fragment shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «tangent» για σκίαση κοÏυφής και τμήματος." + +#~ msgid "'light_pass' input parameter for vertex and fragment shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «light_pass» για σκίαση κοÏυφής και τμήματος." + +#~ msgid "'point_coord' input parameter for fragment and light shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «point_coord» για σκίαση τμήματος και φωτός." + +#~ msgid "'screen_pixel_size' input parameter for fragment shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «screen_pixel_size» για σκίαση τμήματος." + +#~ msgid "'screen_uv' input parameter for fragment and light shader modes." +#~ msgstr "ΠαÏάμετÏος εισόδου «screen_uv» για σκίαση τμήματος και φωτός." + +#~ msgid "'light_alpha' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «light_alpha» για σκίαση φωτός." + +#~ msgid "'light_height' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «light_height» για σκίαση φωτός." + +#~ msgid "'light_uv' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «light_uv» για σκίαση φωτός." + +#~ msgid "'light_vec' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «light_vec» για σκίαση φωτός." + +#~ msgid "'normal' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «normal» για σκίαση φωτός." + +#~ msgid "'shadow_color' input parameter for light shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «shadow_color» για σκίαση φωτός." + +#~ msgid "'extra' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «extra» για σκίαση κοÏυφής." + +#~ msgid "'projection' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «projection» για σκίαση κοÏυφής." + +#~ msgid "'vertex' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «vertex» για σκίαση κοÏυφής." + +#~ msgid "'world' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «world» για σκίαση κοÏυφής." + +#~ msgid "'active' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «active» για σκίαση κοÏυφής." + +#~ msgid "'alpha' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «alpha» για σκίαση κοÏυφής." + +#~ msgid "'color' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «color» για σκίαση κοÏυφής." + +#~ msgid "'custom_alpha' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «custom_alpha» για σκίαση κοÏυφής." + +#~ msgid "'delta' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «delta» για σκίαση κοÏυφής." + +#~ msgid "'emission_transform' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «emission_transform» για σκίαση κοÏυφής." + +#~ msgid "'index' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «index» για σκίαση κοÏυφής." + +#~ msgid "'lifetime' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «lifetime» για σκίαση κοÏυφής." + +#~ msgid "'restart' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «restart» για σκίαση κοÏυφής." + +#~ msgid "'time' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «time» για σκίαση κοÏυφής." + +#~ msgid "'transform' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «transform» για σκίαση κοÏυφής." + +#~ msgid "'velocity' input parameter for vertex shader mode." +#~ msgstr "ΠαÏάμετÏος εισόδου «velocity» για σκίαση κοÏυφής." + +#~ msgid "Raw Mode" +#~ msgstr "Ωμή λειτουÏγία" + #~ msgid "Path to Node:" #~ msgstr "ΔιαδÏομή για τον κόμβο:" @@ -12707,9 +12575,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Εναλλαγή οÏατότητας Spatial" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Εναλλαγή οÏατότητας CanvasItem" - #~ msgid "Condition" #~ msgstr "Συνθήκη" diff --git a/editor/translations/eo.po b/editor/translations/eo.po index 12de01ffd7..2289770903 100644 --- a/editor/translations/eo.po +++ b/editor/translations/eo.po @@ -3,18 +3,19 @@ # Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) # This file is distributed under the same license as the Godot source code. # Scott Starkey <yekrats@gmail.com>, 2019. +# AlexHoratio <yukithetupper@gmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" -"Last-Translator: Scott Starkey <yekrats@gmail.com>\n" +"PO-Revision-Date: 2019-07-02 10:48+0000\n" +"Last-Translator: AlexHoratio <yukithetupper@gmail.com>\n" "Language-Team: Esperanto <https://hosted.weblate.org/projects/godot-engine/" "godot/eo/>\n" "Language: eo\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8-bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -29,7 +30,7 @@ msgstr "Ne sufiĉas bitokoj por malĉifri bitokojn, aÅ nevalida formo." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "Nevalida enigo %i (ne pasita) en esprimo" +msgstr "Nevalida enigo %i (ne pasitis) en esprimo" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -53,7 +54,7 @@ msgstr "Malvalidaj argumentoj por konstrui '%s'" #: core/math/expression.cpp msgid "On call to '%s':" -msgstr "" +msgstr "En voko al '%s':" #: editor/animation_bezier_editor.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -70,11 +71,11 @@ msgstr "Spegulo" #: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp msgid "Time:" -msgstr "" +msgstr "Tempo:" #: editor/animation_bezier_editor.cpp msgid "Value:" -msgstr "" +msgstr "Valoro:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -82,215 +83,215 @@ msgstr "Enmetu Ålosilon ĉi tien" #: editor/animation_bezier_editor.cpp msgid "Duplicate Selected Key(s)" -msgstr "" +msgstr "Duplikati Elektita(j)n Åœlosilo(j)n" #: editor/animation_bezier_editor.cpp msgid "Delete Selected Key(s)" -msgstr "" +msgstr "Forigi Elektita(j)n Åœlosilo(j)n" #: editor/animation_bezier_editor.cpp msgid "Add Bezier Point" -msgstr "" +msgstr "Aldoni Bezier-punkton" #: editor/animation_bezier_editor.cpp msgid "Move Bezier Points" -msgstr "" +msgstr "Movi Bezier-punktojn" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Duplicate Keys" -msgstr "" +msgstr "Animado Duplikati Åœlosilojn" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Delete Keys" -msgstr "" +msgstr "Animado Forigi Åœlosilojn" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Time" -msgstr "" +msgstr "Animado Aliigi Kernakadron Fojon" #: editor/animation_track_editor.cpp msgid "Anim Change Transition" -msgstr "" +msgstr "Animado Aliigi Transiron" #: editor/animation_track_editor.cpp msgid "Anim Change Transform" -msgstr "" +msgstr "Animado Aliigi Transformon" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Value" -msgstr "" +msgstr "Animado Aliigi Kernakadron Valoron" #: editor/animation_track_editor.cpp msgid "Anim Change Call" -msgstr "" +msgstr "Animado Aliigi Alvokon" #: editor/animation_track_editor.cpp msgid "Change Animation Length" -msgstr "" +msgstr "Aliigi Animadon Longecon" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Change Animation Loop" -msgstr "" +msgstr "Aliigi Animadon Iteracion" #: editor/animation_track_editor.cpp msgid "Property Track" -msgstr "" +msgstr "Atributo Vojeto" #: editor/animation_track_editor.cpp msgid "3D Transform Track" -msgstr "" +msgstr "3D Transformo Vojeto" #: editor/animation_track_editor.cpp msgid "Call Method Track" -msgstr "" +msgstr "Alvoki Metodon Vojeto" #: editor/animation_track_editor.cpp msgid "Bezier Curve Track" -msgstr "" +msgstr "Bezier-kurbo Vojeto" #: editor/animation_track_editor.cpp msgid "Audio Playback Track" -msgstr "" +msgstr "AÅdio Reproduktado Vojeto" #: editor/animation_track_editor.cpp msgid "Animation Playback Track" -msgstr "" +msgstr "Animado Reproduktado Vojeto" #: editor/animation_track_editor.cpp msgid "Animation length (frames)" -msgstr "" +msgstr "Animado loneco (filmeroj)" #: editor/animation_track_editor.cpp msgid "Animation length (seconds)" -msgstr "" +msgstr "Animado loneco (sekundoj)" #: editor/animation_track_editor.cpp msgid "Add Track" -msgstr "" +msgstr "Adici Vojeton" #: editor/animation_track_editor.cpp msgid "Animation Looping" -msgstr "" +msgstr "Animado Iteracianti" #: editor/animation_track_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Functions:" -msgstr "" +msgstr "Funkcioj:" #: editor/animation_track_editor.cpp msgid "Audio Clips:" -msgstr "" +msgstr "AÅdio Filmitaĵero:" #: editor/animation_track_editor.cpp msgid "Anim Clips:" -msgstr "" +msgstr "Animado Filmitaĵero:" #: editor/animation_track_editor.cpp msgid "Change Track Path" -msgstr "" +msgstr "Aliigi Vojeton Vojon" #: editor/animation_track_editor.cpp msgid "Toggle this track on/off." -msgstr "" +msgstr "Baskuligi tio ĉi vojeto Åaltita/malÅaltita." #: editor/animation_track_editor.cpp msgid "Update Mode (How this property is set)" -msgstr "" +msgstr "Aktualigi Modon (Kiel tio ĉi atributo estas determinigis)" #: editor/animation_track_editor.cpp msgid "Interpolation Mode" -msgstr "" +msgstr "Interpolado Modo" #: editor/animation_track_editor.cpp msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" -msgstr "" +msgstr "Iteracio Volvi Modo (Interpoli finon kun komenco de iteracio)" #: editor/animation_track_editor.cpp msgid "Remove this track." -msgstr "" +msgstr "Forigi tio ĉi vojeton." #: editor/animation_track_editor.cpp msgid "Time (s): " -msgstr "" +msgstr "Fojo (s): " #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" -msgstr "" +msgstr "Baskuligi Vojeton Åœaltitis" #: editor/animation_track_editor.cpp msgid "Continuous" -msgstr "" +msgstr "Seninterrompa" #: editor/animation_track_editor.cpp msgid "Discrete" -msgstr "" +msgstr "Diskreta" #: editor/animation_track_editor.cpp msgid "Trigger" -msgstr "" +msgstr "Startigilo" #: editor/animation_track_editor.cpp msgid "Capture" -msgstr "" +msgstr "Kapti" #: editor/animation_track_editor.cpp msgid "Nearest" -msgstr "" +msgstr "Plej apuda" #: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp #: editor/property_editor.cpp msgid "Linear" -msgstr "" +msgstr "Lineara" #: editor/animation_track_editor.cpp msgid "Cubic" -msgstr "" +msgstr "Kubika" #: editor/animation_track_editor.cpp msgid "Clamp Loop Interp" -msgstr "" +msgstr "Krampi Iteracion Interpolon" #: editor/animation_track_editor.cpp msgid "Wrap Loop Interp" -msgstr "" +msgstr "ĈirkaÅvolvi Iteracion Interpolon" #: editor/animation_track_editor.cpp #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key" -msgstr "" +msgstr "Enmeti Åœlosilon" #: editor/animation_track_editor.cpp msgid "Duplicate Key(s)" -msgstr "" +msgstr "Duobligi Åœlosilo(j)n" #: editor/animation_track_editor.cpp msgid "Delete Key(s)" -msgstr "" +msgstr "Forigi Åœlosilo(j)n" #: editor/animation_track_editor.cpp msgid "Change Animation Update Mode" -msgstr "" +msgstr "Aliigi Animadon Aktualigon Modon" #: editor/animation_track_editor.cpp msgid "Change Animation Interpolation Mode" -msgstr "" +msgstr "Aliigi Animadon Interpolon Modon" #: editor/animation_track_editor.cpp msgid "Change Animation Loop Mode" -msgstr "" +msgstr "Aliigi Animadon Iteracion Modon" #: editor/animation_track_editor.cpp msgid "Remove Anim Track" -msgstr "" +msgstr "Formovi Animadon Vojeton" #: editor/animation_track_editor.cpp msgid "Create NEW track for %s and insert key?" -msgstr "" +msgstr "Fari NOVAN vojeton por %s kaj enmeti Ålosilon?" #: editor/animation_track_editor.cpp msgid "Create %d NEW tracks and insert keys?" -msgstr "" +msgstr "Fari %d NOVAJN vojetojn kaj enmeti Ålosilojn?" #: editor/animation_track_editor.cpp editor/create_dialog.cpp #: editor/editor_audio_buses.cpp editor/editor_feature_profile.cpp @@ -301,39 +302,39 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_create_dialog.cpp msgid "Create" -msgstr "" +msgstr "Krei" #: editor/animation_track_editor.cpp msgid "Anim Insert" -msgstr "" +msgstr "Animado Enmetu" #: editor/animation_track_editor.cpp msgid "AnimationPlayer can't animate itself, only other players." -msgstr "" +msgstr "AnimationPlayer ne povas animi si mem, nur aliajn ludantojn." #: editor/animation_track_editor.cpp msgid "Anim Create & Insert" -msgstr "" +msgstr "Animado Krei & Enmeti" #: editor/animation_track_editor.cpp msgid "Anim Insert Track & Key" -msgstr "" +msgstr "Animado Enmeti Vojeton & Åœlosilon" #: editor/animation_track_editor.cpp msgid "Anim Insert Key" -msgstr "" +msgstr "Animado Enmeti Åœlosilon" #: editor/animation_track_editor.cpp msgid "Change Animation Step" -msgstr "" +msgstr "Aliigi Animadon PaÅon" #: editor/animation_track_editor.cpp msgid "Rearrange Tracks" -msgstr "" +msgstr "RearanÄi Vojetojn" #: editor/animation_track_editor.cpp msgid "Transform tracks only apply to Spatial-based nodes." -msgstr "" +msgstr "Transforma vojetoj nur almetas al Spatial nodojn." #: editor/animation_track_editor.cpp msgid "" @@ -342,71 +343,76 @@ msgid "" "-AudioStreamPlayer2D\n" "-AudioStreamPlayer3D" msgstr "" +"AÅdio vojetoj nur volas indiki al nodojn de tipojn:\n" +"-AudioStreamPlayer\n" +"-AudioStreamPlayer2D\n" +"-AudioStreamPlayer3D" #: editor/animation_track_editor.cpp msgid "Animation tracks can only point to AnimationPlayer nodes." -msgstr "" +msgstr "Animado vojetoj nur volas indiki al AnimationPlayer nodojn." #: editor/animation_track_editor.cpp msgid "An animation player can't animate itself, only other players." -msgstr "" +msgstr "Animado legilo ne volas animi si mem, nur aliajn ludantojn." #: editor/animation_track_editor.cpp msgid "Not possible to add a new track without a root" -msgstr "" +msgstr "Äœi ne estas ebla adici novan vojeton sen radiko" #: editor/animation_track_editor.cpp msgid "Add Bezier Track" -msgstr "" +msgstr "Adici Bezier-vojeton" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a key." -msgstr "" +msgstr "Vojeto vojo estas malvalida, do ne volas adici Ålosilon." #: editor/animation_track_editor.cpp msgid "Track is not of type Spatial, can't insert key" -msgstr "" +msgstr "Vojeto ne estas de tipo Spatial, ne volas enmeti Ålosilon" #: editor/animation_track_editor.cpp msgid "Add Transform Track Key" -msgstr "" +msgstr "Adici Transformon Vojeton Åœlosilon" #: editor/animation_track_editor.cpp msgid "Add Track Key" -msgstr "" +msgstr "Adici Vojeton Åœlosilon" #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a method key." -msgstr "" +msgstr "Vojeto vojo estas malvalida, do ne volas adici metodon Ålosilon." #: editor/animation_track_editor.cpp msgid "Add Method Track Key" -msgstr "" +msgstr "Adici Metodon Vojeton Åœlosilon" #: editor/animation_track_editor.cpp msgid "Method not found in object: " -msgstr "" +msgstr "Metodon ne trovis en objekto: " #: editor/animation_track_editor.cpp msgid "Anim Move Keys" -msgstr "" +msgstr "Animado Movi Åœlosilojn" #: editor/animation_track_editor.cpp msgid "Clipboard is empty" -msgstr "" +msgstr "Tondujo estas malplena" #: editor/animation_track_editor.cpp msgid "Paste Tracks" -msgstr "" +msgstr "ElpoÅigi Vojetojn" #: editor/animation_track_editor.cpp msgid "Anim Scale Keys" -msgstr "" +msgstr "Animado Skali Åœlosilojn" #: editor/animation_track_editor.cpp msgid "" "This option does not work for Bezier editing, as it's only a single track." msgstr "" +"Tio ĉi opcio ne funkcias por Bezier redakti, ĉar Äi estas nur unuopa vojeto." #: editor/animation_track_editor.cpp msgid "" @@ -420,34 +426,53 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Tio ĉi animado apartenas al enporta sceno, do aliigoj al enportajn vojetojn " +"ne konservos.\n" +"\n" +"Por Åalti la eblecon aldoni proprajn vojetojn, navigu al la enporto-agordoj " +"de la sceno kaj agordu \n" +"\"Animado > Memorilo\" al \"Dosieroj\", Åaltu \"Animado -> Konservi Proprajn " +"Vojetojn\", poste re-enportu.\n" +"Alterne, uzu enporto-antaÅelekton ke enportas animadojn al malkunajn " +"dosierojn." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" +msgstr "Averto: Redaktanti importis animadon" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" msgstr "" #: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Nur Elektaro" + +#: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." -msgstr "" +msgstr "Nur vidigi vojetojn el elektis nodojn en arbo." #: editor/animation_track_editor.cpp msgid "Group tracks by node or display them as plain list." -msgstr "" +msgstr "Grupigi vojetoj de nodo aÅ montri ilin kiel klara listo." #: editor/animation_track_editor.cpp msgid "Snap:" -msgstr "" +msgstr "Klako:" #: editor/animation_track_editor.cpp msgid "Animation step value." -msgstr "" +msgstr "Animado paÅo valoro." #: editor/animation_track_editor.cpp msgid "Seconds" -msgstr "" +msgstr "Sekundoj" #: editor/animation_track_editor.cpp msgid "FPS" -msgstr "" +msgstr "FPS" #: editor/animation_track_editor.cpp editor/editor_properties.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -456,107 +481,107 @@ msgstr "" #: editor/project_manager.cpp editor/project_settings_editor.cpp #: editor/property_editor.cpp modules/visual_script/visual_script_editor.cpp msgid "Edit" -msgstr "" +msgstr "Editori" #: editor/animation_track_editor.cpp msgid "Animation properties." -msgstr "" +msgstr "Animado atributoj." #: editor/animation_track_editor.cpp msgid "Copy Tracks" -msgstr "" +msgstr "Duplikati Vojetojn" #: editor/animation_track_editor.cpp msgid "Scale Selection" -msgstr "" +msgstr "Skali Elektaron" #: editor/animation_track_editor.cpp msgid "Scale From Cursor" -msgstr "" +msgstr "Skali El Kursoron" #: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp msgid "Duplicate Selection" -msgstr "" +msgstr "Duobligi Elektaron" #: editor/animation_track_editor.cpp msgid "Duplicate Transposed" -msgstr "" +msgstr "Duobligi Transmetis" #: editor/animation_track_editor.cpp msgid "Delete Selection" -msgstr "" +msgstr "Forigi Elektaron" #: editor/animation_track_editor.cpp msgid "Go to Next Step" -msgstr "" +msgstr "Iri al Neksta PaÅo" #: editor/animation_track_editor.cpp msgid "Go to Previous Step" -msgstr "" +msgstr "Iri al AntaÅa PaÅo" #: editor/animation_track_editor.cpp msgid "Optimize Animation" -msgstr "" +msgstr "Optimigi Animadon" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation" -msgstr "" +msgstr "Senrubigi Animadon" #: editor/animation_track_editor.cpp msgid "Pick the node that will be animated:" -msgstr "" +msgstr "Elekti la nodon ke estos animatan:" #: editor/animation_track_editor.cpp msgid "Use Bezier Curves" -msgstr "" +msgstr "Uzu Bezier-kurbojn" #: editor/animation_track_editor.cpp msgid "Anim. Optimizer" -msgstr "" +msgstr "Anim. Optimiganto" #: editor/animation_track_editor.cpp msgid "Max. Linear Error:" -msgstr "" +msgstr "Maks. Lineara Eraro:" #: editor/animation_track_editor.cpp msgid "Max. Angular Error:" -msgstr "" +msgstr "Maks. Angula Eraro:" #: editor/animation_track_editor.cpp msgid "Max Optimizable Angle:" -msgstr "" +msgstr "Maks. Optimigebla Angulo:" #: editor/animation_track_editor.cpp msgid "Optimize" -msgstr "" +msgstr "Optimigi" #: editor/animation_track_editor.cpp msgid "Remove invalid keys" -msgstr "" +msgstr "Forigi Nevalidajn Åœlosilojn" #: editor/animation_track_editor.cpp msgid "Remove unresolved and empty tracks" -msgstr "" +msgstr "Forigi maladrestrajn kaj malplenajn vojetojn" #: editor/animation_track_editor.cpp msgid "Clean-up all animations" -msgstr "" +msgstr "Senrubigi ciuĵn animadojn" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation(s) (NO UNDO!)" -msgstr "" +msgstr "Senrubigi Animado(j)n (NE MALFARA!)" #: editor/animation_track_editor.cpp msgid "Clean-Up" -msgstr "" +msgstr "Senrubigi" #: editor/animation_track_editor.cpp msgid "Scale Ratio:" -msgstr "" +msgstr "Skali RejÅo:" #: editor/animation_track_editor.cpp msgid "Select tracks to copy:" -msgstr "" +msgstr "Elekti vojetojn por duplikati:" #: editor/animation_track_editor.cpp editor/editor_log.cpp #: editor/editor_properties.cpp @@ -565,96 +590,100 @@ msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" -msgstr "" +msgstr "Duplikati" #: editor/animation_track_editor_plugins.cpp msgid "Add Audio Track Clip" -msgstr "" +msgstr "Adici AÅdio-Vojeton Eltondaĵon" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip Start Offset" -msgstr "" +msgstr "Aliigi AÅdio-Vojeton Eltondaĵon Komencon DeiÄon" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip End Offset" -msgstr "" +msgstr "Aliigi AÅdio-Vojeton Eltondaĵon Finon DeiÄon" #: editor/array_property_edit.cpp msgid "Resize Array" -msgstr "" +msgstr "Regrandigi Vicon" #: editor/array_property_edit.cpp msgid "Change Array Value Type" -msgstr "" +msgstr "Aliigi Vicanon-Tipon" #: editor/array_property_edit.cpp msgid "Change Array Value" -msgstr "" +msgstr "Aliigi Vicanon" #: editor/code_editor.cpp msgid "Go to Line" -msgstr "" +msgstr "Iri al Lineon" #: editor/code_editor.cpp msgid "Line Number:" +msgstr "Lineo-Numeron:" + +#: editor/code_editor.cpp +msgid "Found %d match(es)." msgstr "" #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" -msgstr "" +msgstr "Ne Rezultoj" #: editor/code_editor.cpp msgid "Replaced %d occurrence(s)." -msgstr "" +msgstr "AnstataÅigis %d apero(j)n." #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Match Case" -msgstr "" +msgstr "Kongrui Usklon" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Whole Words" -msgstr "" +msgstr "Plenaj Vortoj" #: editor/code_editor.cpp editor/rename_dialog.cpp msgid "Replace" -msgstr "" +msgstr "AnstataÅigi" #: editor/code_editor.cpp msgid "Replace All" -msgstr "" +msgstr "AnstataÅigi Ĉiujn" #: editor/code_editor.cpp msgid "Selection Only" -msgstr "" +msgstr "Nur Elektaro" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Norma" #: 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 "" +msgstr "Zomi" #: 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 "" +msgstr "Malzomi" #: editor/code_editor.cpp msgid "Reset Zoom" -msgstr "" +msgstr "Rekomencigi Zomon" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" -msgstr "" +msgstr "Avertoj" #: editor/code_editor.cpp msgid "Line and column numbers." -msgstr "" +msgstr "Lineoj kaj kolumnoj numeroj." #: editor/connections_dialog.cpp msgid "Method in target node must be specified." @@ -708,9 +737,8 @@ msgid "Extra Call Arguments:" msgstr "" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Ekvilibra" +msgstr "Altnivela" #: editor/connections_dialog.cpp msgid "Deferred" @@ -752,6 +780,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -910,7 +942,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1274,7 +1306,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1314,9 +1346,8 @@ msgid "Rearrange Autoloads" msgstr "" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." -msgstr "Nevalida tipara grando." +msgstr "Nevalida dosierindiko." #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp msgid "File does not exist." @@ -1446,6 +1477,10 @@ msgstr "" 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 "" @@ -1471,7 +1506,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1524,7 +1559,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1537,7 +1572,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1560,11 +1595,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2570,10 +2601,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2680,15 +2731,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "Seninterrompa" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2878,7 +2930,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2976,20 +3028,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3474,6 +3526,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5053,6 +5106,13 @@ 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 "" @@ -5953,10 +6013,18 @@ msgid "Find Next" 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 "" @@ -6184,18 +6252,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7715,51 +7786,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7767,203 +7794,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9590,6 +9441,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9618,7 +9473,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9744,18 +9599,16 @@ msgid "Path is not local." msgstr "" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid base path." -msgstr "Nevalida tipara grando." +msgstr "Nevalida dosierindiko." #: editor/script_create_dialog.cpp msgid "A directory with the same name exists." msgstr "" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid extension." -msgstr "Nevalida tipara grando." +msgstr "Nevalida kromprogramo." #: editor/script_create_dialog.cpp msgid "Wrong extension chosen." @@ -9857,7 +9710,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10257,54 +10110,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10881,7 +10686,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10930,7 +10735,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10940,7 +10745,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11007,14 +10812,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11093,7 +10905,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11122,6 +10934,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11156,8 +10972,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11168,7 +10984,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11184,7 +11002,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11195,7 +11013,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11230,7 +11050,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11242,7 +11062,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11254,7 +11074,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11267,10 +11091,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11284,18 +11113,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11338,6 +11167,11 @@ msgid "Input" msgstr "Enigo" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Nevalida fonto por ombrigilo." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Nevalida fonto por ombrigilo." diff --git a/editor/translations/es.po b/editor/translations/es.po index b42801bf98..10f46b198c 100644 --- a/editor/translations/es.po +++ b/editor/translations/es.po @@ -44,8 +44,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" -"Last-Translator: roger <616steam@gmail.com>\n" +"PO-Revision-Date: 2019-07-09 10:47+0000\n" +"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" "Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/" "godot/es/>\n" "Language: es\n" @@ -53,7 +53,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -65,16 +65,15 @@ msgstr "El argumento para convert() no es correcto, utiliza constantes TYPE_*." #: modules/visual_script/visual_script_builtin_funcs.cpp msgid "Not enough bytes for decoding bytes, or invalid format." msgstr "" -"O no hay suficientes bytes para decodificar bytes o el formato no es " -"correcto." +"No hay suficientes bytes para decodificar bytes, o el formato no es válido." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "Entrada inválida %i (no se transmitió) en la expresión" +msgstr "Entrada inválida %i (no pasó) en la expresión" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" -msgstr "self no puede ser usado ya que la instancia es nula (no pasó)" +msgstr "No se puede usar self porque la instancia es nula (no pasó)" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." @@ -114,9 +113,8 @@ msgid "Time:" msgstr "Tiempo:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Valor" +msgstr "Valor:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -140,40 +138,40 @@ msgstr "Mover Puntos Bezier" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Duplicate Keys" -msgstr "Duplicar claves de animación" +msgstr "Duplicar Claves de Animación" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp msgid "Anim Delete Keys" -msgstr "Borrar claves de animación" +msgstr "Eliminar Claves de Animación" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Time" -msgstr "Cambiar el tiempo del fotograma clave de animación" +msgstr "Cambiar Tiempo del Fotograma Clave de Animación" #: editor/animation_track_editor.cpp msgid "Anim Change Transition" -msgstr "Cambiar la transición de animación" +msgstr "Cambiar Transición de Animación" #: editor/animation_track_editor.cpp msgid "Anim Change Transform" -msgstr "Cambiar la transformación de la animación" +msgstr "Cambiar Transformación de la Animación" #: editor/animation_track_editor.cpp msgid "Anim Change Keyframe Value" -msgstr "Cambiar valor de la clave de animación" +msgstr "Cambiar Valor de la Clave de Animación" #: editor/animation_track_editor.cpp msgid "Anim Change Call" -msgstr "Cambiar llamada de animación" +msgstr "Cambiar Llamada de Animación" #: editor/animation_track_editor.cpp msgid "Change Animation Length" -msgstr "Cambiar duración de la animación" +msgstr "Cambiar Duración de la Animación" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Change Animation Loop" -msgstr "Cambiar repetición de animación" +msgstr "Cambiar Loop de la Animación" #: editor/animation_track_editor.cpp msgid "Property Track" @@ -226,11 +224,11 @@ msgstr "Clips de Audio:" #: editor/animation_track_editor.cpp msgid "Anim Clips:" -msgstr "Clips de Anim:" +msgstr "Clips de Animación:" #: editor/animation_track_editor.cpp msgid "Change Track Path" -msgstr "Cambiar ruta de la pista" +msgstr "Cambiar Ruta de la Pista" #: editor/animation_track_editor.cpp msgid "Toggle this track on/off." @@ -238,7 +236,7 @@ msgstr "Act./Desact. esta pista." #: editor/animation_track_editor.cpp msgid "Update Mode (How this property is set)" -msgstr "Modo de Actualización (Como esta configurada esta propriedad)" +msgstr "Modo de actualización (Cómo se establece)" #: editor/animation_track_editor.cpp msgid "Interpolation Mode" @@ -246,11 +244,11 @@ msgstr "Modo de Interpolación" #: editor/animation_track_editor.cpp msgid "Loop Wrap Mode (Interpolate end with beginning on loop)" -msgstr "Modo Loop Envolvente (Interpolar el final con el comienzo al loopear)" +msgstr "Modo Loop Envolvente (Interpolar el final con el comienzo del loop)" #: editor/animation_track_editor.cpp msgid "Remove this track." -msgstr "Quitar esta pista." +msgstr "Eliminar esta pista." #: editor/animation_track_editor.cpp msgid "Time (s): " @@ -258,7 +256,7 @@ msgstr "Tiempo (s): " #: editor/animation_track_editor.cpp msgid "Toggle Track Enabled" -msgstr "Pista de Conmutación Activada" +msgstr "Act./Desact. Pista" #: editor/animation_track_editor.cpp msgid "Continuous" @@ -300,7 +298,7 @@ msgstr "Interp de Loop Envolvente" #: editor/animation_track_editor.cpp #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key" -msgstr "Insertar clave" +msgstr "Insertar Clave" #: editor/animation_track_editor.cpp msgid "Duplicate Key(s)" @@ -324,7 +322,7 @@ msgstr "Cambiar Modo Loop de Animación" #: editor/animation_track_editor.cpp msgid "Remove Anim Track" -msgstr "Quitar pista de animación" +msgstr "Eliminar Pista de Animación" #: editor/animation_track_editor.cpp msgid "Create NEW track for %s and insert key?" @@ -347,7 +345,7 @@ msgstr "Crear" #: editor/animation_track_editor.cpp msgid "Anim Insert" -msgstr "Insertar animación" +msgstr "Insertar Animación" #: editor/animation_track_editor.cpp msgid "AnimationPlayer can't animate itself, only other players." @@ -359,11 +357,11 @@ msgstr "Crear e Insertar Animación" #: editor/animation_track_editor.cpp msgid "Anim Insert Track & Key" -msgstr "Insertar pista y clave de animación" +msgstr "Insertar Pista y Clave de Animación" #: editor/animation_track_editor.cpp msgid "Anim Insert Key" -msgstr "Insertar clave de animación" +msgstr "Insertar Clave de Animación" #: editor/animation_track_editor.cpp msgid "Change Animation Step" @@ -375,7 +373,8 @@ msgstr "Reordenar Pistas" #: editor/animation_track_editor.cpp msgid "Transform tracks only apply to Spatial-based nodes." -msgstr "Las pistas Transform solo aplican a nodos de tipo Spatial." +msgstr "" +"Las pistas de transformación sólo se aplican a los nodos basados en Spatial." #: editor/animation_track_editor.cpp msgid "" @@ -452,7 +451,7 @@ msgstr "Pegar Pistas" #: editor/animation_track_editor.cpp msgid "Anim Scale Keys" -msgstr "Escalar claves de animación" +msgstr "Escalar Claves de Animación" #: editor/animation_track_editor.cpp msgid "" @@ -473,10 +472,28 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Esta animación pertenece a una escena importada, por lo que los cambios en " +"las pistas importadas no se guardarán.\n" +"\n" +"Para habilitar la capacidad de añadir pistas personalizadas, ve a la " +"configuración de importación de la escena y establece\n" +"\"Animation > Storage\" a \"Files\", activa \"Animation > Keep Custom Tracks" +"\", y luego reimporta.\n" +"También puedes usar un preset de importación que importa animaciones para " +"separar archivos." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Advertencia: Edición de animación importada" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Seleccionar Todo" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "Deseleccionar todo" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -521,43 +538,43 @@ msgstr "Copiar Pistas" #: editor/animation_track_editor.cpp msgid "Scale Selection" -msgstr "Escalar selección" +msgstr "Escalar Selección" #: editor/animation_track_editor.cpp msgid "Scale From Cursor" -msgstr "Escalar desde cursor" +msgstr "Escalar Desde Cursor" #: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp msgid "Duplicate Selection" -msgstr "Duplicar selección" +msgstr "Duplicar Selección" #: editor/animation_track_editor.cpp msgid "Duplicate Transposed" -msgstr "Duplicar transpuesto" +msgstr "Duplicar Transpuesto" #: editor/animation_track_editor.cpp msgid "Delete Selection" -msgstr "Eliminar selección" +msgstr "Eliminar Selección" #: editor/animation_track_editor.cpp msgid "Go to Next Step" -msgstr "Ir al paso siguiente" +msgstr "Ir al Paso Siguiente" #: editor/animation_track_editor.cpp msgid "Go to Previous Step" -msgstr "Ir al paso anterior" +msgstr "Ir al Paso Anterior" #: editor/animation_track_editor.cpp msgid "Optimize Animation" -msgstr "Optimizar animación" +msgstr "Optimizar Animación" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation" -msgstr "Limpiar animación" +msgstr "Limpiar Animación" #: editor/animation_track_editor.cpp msgid "Pick the node that will be animated:" -msgstr "Elegà el nodo que será animado:" +msgstr "Selecciona el nodo que será animado:" #: editor/animation_track_editor.cpp msgid "Use Bezier Curves" @@ -565,19 +582,19 @@ msgstr "Usar Curvas Bezier" #: editor/animation_track_editor.cpp msgid "Anim. Optimizer" -msgstr "Optimizador de animación" +msgstr "Optimizador de Animación" #: editor/animation_track_editor.cpp msgid "Max. Linear Error:" -msgstr "Error lineal máximo:" +msgstr "Error Lineal Máximo:" #: editor/animation_track_editor.cpp msgid "Max. Angular Error:" -msgstr "Error angular máximo:" +msgstr "Error Angular Máximo:" #: editor/animation_track_editor.cpp msgid "Max Optimizable Angle:" -msgstr "Ãngulo optimizable máximo:" +msgstr "Ãngulo Optimizable Máximo:" #: editor/animation_track_editor.cpp msgid "Optimize" @@ -585,11 +602,11 @@ msgstr "Optimizar" #: editor/animation_track_editor.cpp msgid "Remove invalid keys" -msgstr "Quitar claves incorrectas" +msgstr "Eliminar claves incorrectas" #: editor/animation_track_editor.cpp msgid "Remove unresolved and empty tracks" -msgstr "Quitar pistas vacÃas y sin resolver" +msgstr "Eliminar pistas vacÃas y sin resolver" #: editor/animation_track_editor.cpp msgid "Clean-up all animations" @@ -597,7 +614,7 @@ msgstr "Limpiar todas las animaciones" #: editor/animation_track_editor.cpp msgid "Clean-Up Animation(s) (NO UNDO!)" -msgstr "Limpiar las animación(es) (¡IRREVERSIBLE!)" +msgstr "Limpiar Animación(es) (¡NO SE PUEDE DESHACER!)" #: editor/animation_track_editor.cpp msgid "Clean-Up" @@ -605,7 +622,7 @@ msgstr "Limpiar" #: editor/animation_track_editor.cpp msgid "Scale Ratio:" -msgstr "Relación de escala:" +msgstr "Ratio de Escala:" #: editor/animation_track_editor.cpp msgid "Select tracks to copy:" @@ -626,35 +643,39 @@ msgstr "Añadir Clip de Pista de Audio" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip Start Offset" -msgstr "Cambiar Desplazamiento de Inicio de Clip de Pista de Audio" +msgstr "Cambiar Offset de Inicio de Clip de Pista de Audio" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip End Offset" -msgstr "Cambiar Desplazamiento Final del Clip de Pista de Audio" +msgstr "Cambiar Offset Final del Clip de Pista de Audio" #: editor/array_property_edit.cpp msgid "Resize Array" -msgstr "Redimensionar array" +msgstr "Redimensionar Array" #: editor/array_property_edit.cpp msgid "Change Array Value Type" -msgstr "Cambiar tipo de valor del array" +msgstr "Cambiar Tipo de Valor del Array" #: editor/array_property_edit.cpp msgid "Change Array Value" -msgstr "Cambiar valor del array" +msgstr "Cambiar Valor del Array" #: editor/code_editor.cpp msgid "Go to Line" -msgstr "Ir a lÃnea" +msgstr "Ir a LÃnea" #: editor/code_editor.cpp msgid "Line Number:" -msgstr "Número de lÃnea:" +msgstr "Número de LÃnea:" + +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" -msgstr "Sin coincidencias" +msgstr "Sin Coincidencias" #: editor/code_editor.cpp msgid "Replaced %d occurrence(s)." @@ -666,7 +687,7 @@ msgstr "Coincidir mayús/minúsculas" #: editor/code_editor.cpp editor/find_in_files.cpp msgid "Whole Words" -msgstr "Palabras completas" +msgstr "Palabras Completas" #: editor/code_editor.cpp editor/rename_dialog.cpp msgid "Replace" @@ -674,7 +695,7 @@ msgstr "Reemplazar" #: editor/code_editor.cpp msgid "Replace All" -msgstr "Reemplazar todo" +msgstr "Reemplazar Todo" #: editor/code_editor.cpp msgid "Selection Only" @@ -689,19 +710,19 @@ msgstr "Estándar" #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp msgid "Zoom In" -msgstr "Acercar" +msgstr "Acercar 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 "Alejar" +msgstr "Alejar Zoom" #: editor/code_editor.cpp msgid "Reset Zoom" -msgstr "Restablecer zoom" +msgstr "Restablecer Zoom" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Advertencias" @@ -710,38 +731,32 @@ msgid "Line and column numbers." msgstr "Números de lÃnea y columna." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "¡Debes establecer un método en el nodo seleccionado!" +msgstr "Se debe establecer un método en el nodo destino." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"¡Método objetivo no encontrado! Especifica un método válido o añade un " -"script al nodo objetivo." +"Método objetivo no encontrado. Especifica un método válido o añade un script " +"al nodo de destino." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "Conectar a nodo:" +msgstr "Conectar al Nodo:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "No se puede conectar al host:" +msgstr "Conectar al Script:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Señales:" +msgstr "Desde la Señal:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "El nodo no posee geometrÃa." +msgstr "La escena no contiene ningún script." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -758,7 +773,7 @@ msgstr "Añadir" #: editor/plugins/visual_shader_editor_plugin.cpp editor/project_manager.cpp #: editor/project_settings_editor.cpp msgid "Remove" -msgstr "Quitar" +msgstr "Eliminar" #: editor/connections_dialog.cpp msgid "Add Extra Call Argument:" @@ -769,9 +784,8 @@ msgid "Extra Call Arguments:" msgstr "Argumentos extras de llamada:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Opciones avanzadas" +msgstr "Avanzado" #: editor/connections_dialog.cpp msgid "Deferred" @@ -781,6 +795,8 @@ msgstr "Diferido" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Difiere la señal, la almacena en una cola y sólo la ejecuta en tiempo de " +"inactividad." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -788,12 +804,11 @@ msgstr "OneShot" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Desconecta la señal después de su primera emisión." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Conectar Señal: " +msgstr "No se puede conectar la señal" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -814,6 +829,11 @@ msgid "Connect" msgstr "Conectar" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Señales:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Conectar «%s» a «%s»" @@ -835,19 +855,17 @@ msgid "Disconnect" msgstr "Desconectar" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Conectar Señal: " +msgstr "Conectar una Señal a un Método" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Editar Conexión: " +msgstr "Editar Conexión:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" msgstr "" -"¿Estás seguro/a que quieres quitar todas las conexiones de la señal \"%s\"?" +"¿Estás seguro/a que quieres eliminar todas las conexiones de la señal \"%s\"?" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" @@ -855,7 +873,8 @@ msgstr "Señales" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from this signal?" -msgstr "¿Estás seguro/a que quieres quitar todas las conexiones de esta señal?" +msgstr "" +"¿Estás seguro/a que quieres eliminar todas las conexiones de esta señal?" #: editor/connections_dialog.cpp msgid "Disconnect All" @@ -879,7 +898,7 @@ msgstr "Cambiar" #: editor/create_dialog.cpp msgid "Create New %s" -msgstr "Crear nuevo %s" +msgstr "Crear Nuevo %s" #: editor/create_dialog.cpp editor/editor_file_dialog.cpp #: editor/filesystem_dock.cpp @@ -912,29 +931,27 @@ msgstr "Descripción:" #: editor/dependency_editor.cpp msgid "Search Replacement For:" -msgstr "Buscar reemplazo para:" +msgstr "Buscar Reemplazo Para:" #: editor/dependency_editor.cpp msgid "Dependencies For:" -msgstr "Dependencias para:" +msgstr "Dependencias Para:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" -"Estás editando la escena «%s».\n" -"Por lo que los cambios no tendrán efecto hasta que recargues." +"La escena '%s' está siendo editada.\n" +"Los cambios no tendrán efecto hasta que recargues." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" -"Se está usando el recurso «%s».\n" -"Por lo que los cambios no tendrán efecto hasta que recargues." +"El recurso '%s' está en uso.\n" +"Los cambios no tendrán efecto hasta que recargues." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -956,15 +973,15 @@ msgstr "Dependencias:" #: editor/dependency_editor.cpp msgid "Fix Broken" -msgstr "Arreglar rota(s)" +msgstr "Corregir Errores" #: editor/dependency_editor.cpp msgid "Dependency Editor" -msgstr "Editor de dependencias" +msgstr "Editor de Dependencias" #: editor/dependency_editor.cpp msgid "Search Replacement Resource:" -msgstr "Buscar recurso de reemplazo:" +msgstr "Buscar Recurso de Reemplazo:" #: editor/dependency_editor.cpp editor/editor_file_dialog.cpp #: editor/editor_help_search.cpp editor/editor_node.cpp @@ -978,11 +995,12 @@ msgstr "Abrir" #: editor/dependency_editor.cpp msgid "Owners Of:" -msgstr "Propietarios de:" +msgstr "Propietarios De:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" -msgstr "¿Quitar los archivos seleccionados del proyecto? (irreversible)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" +msgstr "¿Eliminar los archivos seleccionados del proyecto? (irreversible)" #: editor/dependency_editor.cpp msgid "" @@ -992,7 +1010,7 @@ msgid "" msgstr "" "Otros recursos necesitan los archivos que estás intentando quitar para " "funcionar.\n" -"¿Quitarlos de todos modos? (irreversible)" +"¿Eliminarlos de todos modos? (irreversible)" #: editor/dependency_editor.cpp editor/export_template_manager.cpp msgid "Cannot remove:" @@ -1008,32 +1026,31 @@ msgstr "Falló la carga debido a dependencias faltantes:" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Open Anyway" -msgstr "Abrir de todos modos" +msgstr "Abrir Igualmente" #: editor/dependency_editor.cpp msgid "Which action should be taken?" -msgstr "¿Qué es lo que quieres hacer?" +msgstr "¿Qué acciones se deberÃan tomar?" #: editor/dependency_editor.cpp msgid "Fix Dependencies" -msgstr "Arreglar dependencias" +msgstr "Corregir Dependencias" #: editor/dependency_editor.cpp msgid "Errors loading!" -msgstr "¡Hubo errores al cargar!" +msgstr "¡Errores al cargar!" #: editor/dependency_editor.cpp msgid "Permanently delete %d item(s)? (No undo!)" -msgstr "¿Eliminar permanentemente %d elemento(s)? (¡Irreversible!)" +msgstr "¿Eliminar permanentemente %d Ãtem(s)? (¡No se puede deshacer!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "Dependencias" +msgstr "Mostrar Dependencias" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" -msgstr "Explorador de recursos huérfanos" +msgstr "Explorador de Recursos Huérfanos" #: editor/dependency_editor.cpp editor/editor_audio_buses.cpp #: editor/editor_file_dialog.cpp editor/editor_node.cpp @@ -1049,15 +1066,15 @@ msgstr "Propietario" #: editor/dependency_editor.cpp msgid "Resources Without Explicit Ownership:" -msgstr "Recursos sin propietario explÃcito:" +msgstr "Recursos Sin Propietario ExplÃcito:" #: editor/dictionary_property_edit.cpp msgid "Change Dictionary Key" -msgstr "Cambiar clave del diccionario" +msgstr "Cambiar Clave del Diccionario" #: editor/dictionary_property_edit.cpp msgid "Change Dictionary Value" -msgstr "Cambiar valor del diccionario" +msgstr "Cambiar Valor del Diccionario" #: editor/editor_about.cpp msgid "Thanks from the Godot community!" @@ -1069,15 +1086,15 @@ msgstr "Contribuidores de Godot" #: editor/editor_about.cpp msgid "Project Founders" -msgstr "Fundadores del proyecto" +msgstr "Fundadores del Proyecto" #: editor/editor_about.cpp msgid "Lead Developer" -msgstr "Desarrollador principal" +msgstr "Desarrollador Principal" #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Administrador del proyecto " +msgstr "Administrador del Proyecto " #: editor/editor_about.cpp msgid "Developers" @@ -1089,27 +1106,27 @@ msgstr "Autores" #: editor/editor_about.cpp msgid "Platinum Sponsors" -msgstr "Patrocinadores de platino" +msgstr "Patrocinadores Platino" #: editor/editor_about.cpp msgid "Gold Sponsors" -msgstr "Patrocinadores de oro" +msgstr "Patrocinadores Oro" #: editor/editor_about.cpp msgid "Mini Sponsors" -msgstr "Mini patrocinadores" +msgstr "Mini Patrocinadores" #: editor/editor_about.cpp msgid "Gold Donors" -msgstr "Donantes de oro" +msgstr "Donantes Oro" #: editor/editor_about.cpp msgid "Silver Donors" -msgstr "Donantes de plata" +msgstr "Donantes Plata" #: editor/editor_about.cpp msgid "Bronze Donors" -msgstr "Donantes de bronce" +msgstr "Donantes Bronce" #: editor/editor_about.cpp msgid "Donors" @@ -1121,7 +1138,7 @@ msgstr "Licencia" #: editor/editor_about.cpp msgid "Thirdparty License" -msgstr "Licencia de terceros" +msgstr "Licencia de Terceros" #: editor/editor_about.cpp msgid "" @@ -1137,7 +1154,7 @@ msgstr "" #: editor/editor_about.cpp msgid "All Components" -msgstr "Todos los componentes" +msgstr "Todos los Componentes" #: editor/editor_about.cpp msgid "Components" @@ -1153,7 +1170,7 @@ msgstr "Error al abrir el archivo empaquetado, no tiene formato zip." #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" -msgstr "Descomprimiendo assets" +msgstr "Descomprimiendo Assets" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Package installed successfully!" @@ -1162,7 +1179,7 @@ msgstr "¡Paquete instalado con éxito!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Success!" -msgstr "¡Finalizado!" +msgstr "¡Éxito!" #: editor/editor_asset_installer.cpp editor/editor_node.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -1179,43 +1196,43 @@ msgstr "Altavoces" #: editor/editor_audio_buses.cpp msgid "Add Effect" -msgstr "Añadir efecto" +msgstr "Añadir Efecto" #: editor/editor_audio_buses.cpp msgid "Rename Audio Bus" -msgstr "Renombrar bus de audio" +msgstr "Renombrar Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Change Audio Bus Volume" -msgstr "Cambiar volumen de bus de audio" +msgstr "Cambiar Volumen de Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Solo" -msgstr "Act/desact. solo de bus de audio" +msgstr "Act./Desact. Solo de Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Mute" -msgstr "Act/desact. silencio de bus de audio" +msgstr "Act./Desact. Silencio de Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Bypass Effects" -msgstr "Act/desact. puenteado de efectos de bus de audio" +msgstr "Act./Desact. Bypass de Efectos de Audio Bus" #: editor/editor_audio_buses.cpp msgid "Select Audio Bus Send" -msgstr "Seleccionar envÃo de bus de audio" +msgstr "Seleccionar EnvÃo de Audio Bus" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus Effect" -msgstr "Añadir efecto de bus de audio" +msgstr "Añadir Efecto de Audio Bus" #: editor/editor_audio_buses.cpp msgid "Move Bus Effect" -msgstr "Mover efecto de bus" +msgstr "Mover Efecto de Bus" #: editor/editor_audio_buses.cpp msgid "Delete Bus Effect" -msgstr "Eliminar efecto de bus" +msgstr "Eliminar Efecto de Bus" #: editor/editor_audio_buses.cpp msgid "Audio Bus, Drag and Drop to rearrange." @@ -1235,7 +1252,7 @@ msgstr "Bypass" #: editor/editor_audio_buses.cpp msgid "Bus options" -msgstr "Opciones del bus" +msgstr "Opciones de Bus" #: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp #: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp @@ -1244,11 +1261,11 @@ msgstr "Duplicar" #: editor/editor_audio_buses.cpp msgid "Reset Volume" -msgstr "Restablecer volumen" +msgstr "Restablecer Volumen" #: editor/editor_audio_buses.cpp msgid "Delete Effect" -msgstr "Eliminar efecto" +msgstr "Eliminar Efecto" #: editor/editor_audio_buses.cpp msgid "Audio" @@ -1256,7 +1273,7 @@ msgstr "Audio" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" -msgstr "Añadir bus de audio" +msgstr "Añadir Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Master bus can't be deleted!" @@ -1264,51 +1281,51 @@ msgstr "¡No se puede borrar el bus maestro!" #: editor/editor_audio_buses.cpp msgid "Delete Audio Bus" -msgstr "Borrar bus de audio" +msgstr "Eliminar Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Duplicate Audio Bus" -msgstr "Duplicar bus de audio" +msgstr "Duplicar Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Reset Bus Volume" -msgstr "Restablecer volumen de bus" +msgstr "Restablecer Volumen de Bus" #: editor/editor_audio_buses.cpp msgid "Move Audio Bus" -msgstr "Mover bus de audio" +msgstr "Mover Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Save Audio Bus Layout As..." -msgstr "Guardar configuración de Bus de Audio como..." +msgstr "Guardar Layout de Bus de Audio Como..." #: editor/editor_audio_buses.cpp msgid "Location for New Layout..." -msgstr "Ubicación para nueva configuración..." +msgstr "Ubicación para el Nuevo Layout..." #: editor/editor_audio_buses.cpp msgid "Open Audio Bus Layout" -msgstr "Abrir configuración de bus de audio" +msgstr "Abrir Layout de Bus de Audio" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "No hay ningún archivo `%s'." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" -msgstr "Disposición" +msgstr "Layout" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." -msgstr "Archivo inválido, no es una configuración de bus de audio." +msgstr "Archivo inválido. No es un layout de bus de audio." #: editor/editor_audio_buses.cpp msgid "Add Bus" -msgstr "Añadir bus" +msgstr "Añadir Bus" #: editor/editor_audio_buses.cpp msgid "Add a new Audio Bus to this layout." -msgstr "Añade un nuevo Bus de Audio a esta configuración." +msgstr "Añade un nuevo Bus de Audio a este layout." #: editor/editor_audio_buses.cpp editor/editor_properties.cpp #: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp @@ -1318,27 +1335,27 @@ msgstr "Cargar" #: editor/editor_audio_buses.cpp msgid "Load an existing Bus Layout." -msgstr "Cargar una configuración de bus existente." +msgstr "Cargar un Bus Layout existente." #: editor/editor_audio_buses.cpp msgid "Save As" -msgstr "Guardar como" +msgstr "Guardar Como" #: editor/editor_audio_buses.cpp msgid "Save this Bus Layout to a file." -msgstr "Guardar la configuración de este bus a un archivo." +msgstr "Guardar este Bus Layout a un archivo." #: editor/editor_audio_buses.cpp editor/import_dock.cpp msgid "Load Default" -msgstr "Cargar ajuste predeterminado" +msgstr "Cargar Valores por Defecto" #: editor/editor_audio_buses.cpp msgid "Load the default Bus Layout." -msgstr "Cargar configuración de bus por defecto." +msgstr "Cargar el Bus Layout predeterminado." #: editor/editor_audio_buses.cpp msgid "Create a new Bus Layout." -msgstr "Crear nueva configuración de bus." +msgstr "Crear un nuevo Bus Layout." #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -1346,36 +1363,27 @@ msgstr "Nombre inválido." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" -msgstr "Letras válidas:" +msgstr "Caracteres válidos:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"Nombre inválido. No debe coincidir con el nombre de una clase que ya exista " -"en el motor gráfico." +msgstr "No debe coincidir con el nombre de una clase ya existente del motor." #: editor/editor_autoload_settings.cpp -#, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "" -"Nombre inválido. No debe coincidir con un nombre de tipo que ya esté " -"integrado en el motor gráfico." +msgid "Must not collide with an existing built-in type name." +msgstr "No debe coincidir con un nombre de tipo built-in existente." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." -msgstr "" -"Nombre inválido. No debe coincidir con un nombre de constante global ya " -"existente en el motor gráfico." +msgstr "No debe coincidir con una constante global existente." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "La palabra clave no se puede utilizar como nombre de autoload." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" -msgstr "¡El fichero «%s» ya existe!" +msgstr "¡Autoload «%s» ya existe!" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" @@ -1383,7 +1391,7 @@ msgstr "Renombrar Autoload" #: editor/editor_autoload_settings.cpp msgid "Toggle AutoLoad Globals" -msgstr "Act/desact. globales de Autoload" +msgstr "Act./Desact. Globales de Autoload" #: editor/editor_autoload_settings.cpp msgid "Move Autoload" @@ -1391,7 +1399,7 @@ msgstr "Mover Autoload" #: editor/editor_autoload_settings.cpp msgid "Remove Autoload" -msgstr "Quitar Autoload" +msgstr "Eliminar Autoload" #: editor/editor_autoload_settings.cpp msgid "Enable" @@ -1402,7 +1410,6 @@ msgid "Rearrange Autoloads" msgstr "Reordenar Autoloads" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "Ruta inválida." @@ -1425,7 +1432,7 @@ msgstr "Ruta:" #: editor/editor_autoload_settings.cpp msgid "Node Name:" -msgstr "Nombre del nodo:" +msgstr "Nombre del Nodo:" #: editor/editor_autoload_settings.cpp editor/editor_help_search.cpp #: editor/editor_profiler.cpp editor/settings_config_dialog.cpp @@ -1438,7 +1445,7 @@ msgstr "Singleton" #: editor/editor_data.cpp msgid "Updating Scene" -msgstr "Actualizando escena" +msgstr "Actualizando Escena" #: editor/editor_data.cpp msgid "Storing local changes..." @@ -1457,9 +1464,8 @@ msgid "[unsaved]" msgstr "[sin guardar]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Por favor, selecciona primero un directorio base" +msgstr "Por favor, selecciona primero un directorio base." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1469,7 +1475,7 @@ msgstr "Selecciona un directorio" #: editor/filesystem_dock.cpp editor/project_manager.cpp #: scene/gui/file_dialog.cpp msgid "Create Folder" -msgstr "Crear carpeta" +msgstr "Crear Carpeta" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp @@ -1489,7 +1495,7 @@ msgstr "Elegir" #: editor/editor_export.cpp msgid "Storing File:" -msgstr "Archivo de almacenamiento:" +msgstr "Archivo de Almacenamiento:" #: editor/editor_export.cpp msgid "No export template found at the expected path:" @@ -1544,122 +1550,111 @@ msgstr "Plantilla release personalizada no encontrada." msgid "Template file not found:" msgstr "Archivo de plantilla no encontrado:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Editor" +msgstr "3D Editor" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Abrir editor de script" +msgstr "Editor de Script" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Abrir biblioteca de assets" +msgstr "Biblioteca de Assets" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Ãrbol de escenas (nodos):" +msgstr "Editor del Ãrbol de Escenas" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Importar" +msgstr "Importación" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "Nodo Movido" +msgstr "Nodos" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Filesystem Dock" -msgstr "Sistema de Archivos" +msgid "FileSystem and Import Docks" +msgstr "Sistema de Archivo e Importación" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Reemplazar todo (no se puede deshacer)" +msgstr "¿Borrar perfil '%s'? (no se puede deshacer)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" msgstr "" +"El perfil debe tener un nombre de archivo válido y no debe contener '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Ya existe un archivo o carpeta con este nombre." +msgstr "Ya existe un perfil con este nombre." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Editor Desactivado, Propiedades Desactivadas)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Solo Propiedades" +msgstr "(Propiedades Desactivadas)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Clip deshabilitado" +msgstr "(Editor Desactivado)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Descripción de la Clase:" +msgstr "Opciones de Clase:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Abrir editor siguiente" +msgstr "Activar el Editor Contextual" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Propiedades:" +msgstr "Propiedades Activadas:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "CaracterÃsticas" +msgstr "CaracterÃsticas Activadas:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Buscar clases" +msgstr "Clases Activadas:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." msgstr "" +"El formato '%s' del archivo no es válido, la importación ha sido cancelada." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"El perfil '%s' ya existe. ElimÃnalo primero antes de importar, importación " +"abortada." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Error al cargar la plantilla '%s'" +msgstr "Error al guardar el perfil en la ruta: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Desactivar" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Current Profile" -msgstr "Versión actual:" +msgid "Current Profile:" +msgstr "Perfil Actual:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Actual:" +msgstr "Hacer Actual" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1677,48 +1672,36 @@ msgid "Export" msgstr "Exportar" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Available Profiles" -msgstr "Nodos disponibles:" +msgid "Available Profiles:" +msgstr "Perfiles Disponibles:" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Buscar clases" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Descripción de la Clase" +msgstr "Opciones de Clases" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Nuevo nombre:" +msgstr "Nuevo nombre de perfil:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Borrar área" +msgstr "Borrar Perfil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Proyecto importado" +msgstr "Importar Perfil(es)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Exportar proyecto" +msgstr "Exportar Perfil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "Cargar plantillas de exportación" +msgstr "Administrar Perfiles de CaracterÃsticas del Editor" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" -msgstr "Seleccionar carpeta actual" +msgstr "Seleccionar Carpeta Actual" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File Exists, Overwrite?" @@ -1726,11 +1709,11 @@ msgstr "El archivo ya existe ¿Quieres sobreescribirlo?" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select This Folder" -msgstr "Seleccionar esta carpeta" +msgstr "Seleccionar Esta Carpeta" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "Copy Path" -msgstr "Copiar ruta" +msgstr "Copiar Ruta" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "Open in File Manager" @@ -1743,7 +1726,7 @@ msgstr "Mostrar en Explorador de Archivos" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "New Folder..." -msgstr "Nueva carpeta..." +msgstr "Nueva Carpeta..." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Refresh" @@ -1751,23 +1734,23 @@ msgstr "Recargar" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Recognized" -msgstr "Reconocidos" +msgstr "Todos Reconocidos" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Files (*)" -msgstr "Todos los archivos (*)" +msgstr "Todos los Archivos (*)" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open a File" -msgstr "Abrir un archivo" +msgstr "Abrir un Archivo" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open File(s)" -msgstr "Abrir archivo(s)" +msgstr "Abrir Archivo(s)" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open a Directory" -msgstr "Abrir un directorio" +msgstr "Abrir un Directorio" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open a File or Directory" @@ -1782,7 +1765,7 @@ msgstr "Guardar" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Save a File" -msgstr "Guardar un archivo" +msgstr "Guardar un Archivo" #: editor/editor_file_dialog.cpp msgid "Go Back" @@ -1798,11 +1781,11 @@ msgstr "Subir" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Toggle Hidden Files" -msgstr "Ver/ocultar archivos ocultos" +msgstr "Act./Desact. Archivos Ocultos" #: editor/editor_file_dialog.cpp msgid "Toggle Favorite" -msgstr "Añadir/quitar favorito" +msgstr "Act./Desact. Favorito" #: editor/editor_file_dialog.cpp msgid "Toggle Mode" @@ -1810,7 +1793,7 @@ msgstr "Cambiar Modo" #: editor/editor_file_dialog.cpp msgid "Focus Path" -msgstr "Seleccionar ruta" +msgstr "Foco en Ruta" #: editor/editor_file_dialog.cpp msgid "Move Favorite Up" @@ -1834,16 +1817,15 @@ msgstr "Ir a la carpeta padre." #: editor/editor_file_dialog.cpp msgid "(Un)favorite current folder." -msgstr "Quitar carpeta actual de favoritos." +msgstr "Eliminar carpeta actual de favoritos." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Ver/ocultar archivos ocultos" +msgstr "Ver/Ocultar archivos ocultos." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." -msgstr "Ver Ãtems como una cuadrÃcula de miniaturas." +msgstr "Ver Ãtems como un grid de miniaturas." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a list." @@ -1851,13 +1833,13 @@ msgstr "Ver Ãtems como una lista." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Directories & Files:" -msgstr "Directorios y archivos:" +msgstr "Directorios y Archivos:" #: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp #: editor/plugins/style_box_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp msgid "Preview:" -msgstr "Vista previa:" +msgstr "Vista Previa:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File:" @@ -1869,17 +1851,19 @@ msgstr "Debe tener una extensión válida." #: editor/editor_file_system.cpp msgid "ScanSources" -msgstr "Analizando fuentes" +msgstr "Escanear Fuentes" #: editor/editor_file_system.cpp msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"Hay varios importadores para diferentes tipos que apuntan al archivo %s, " +"importación abortada" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" -msgstr "(Re)Importando assets" +msgstr "(Re)Importando Assets" #: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp msgid "Top" @@ -1899,7 +1883,7 @@ msgstr "Heredada por:" #: editor/editor_help.cpp msgid "Brief Description:" -msgstr "Descripción breve:" +msgstr "Descripción Breve:" #: editor/editor_help.cpp msgid "Properties" @@ -1967,33 +1951,33 @@ msgid "" "$url]contribute one[/url][/color] or [color=$color][url=$url2]request one[/" "url][/color]." msgstr "" -"Actualmente no hay tutoriales para esta clase, puedes [color=$color][url=" -"$url]aportar uno[/url][/color] o [color=$color][url=$url2]pedir uno[color=" -"$color][url=$url2]." +"Actualmente no existen tutoriales para esta clase, puedes [color=$color][url=" +"$url]contribuir uno[/url][/color] o [color=$color][url=$url2]solicitar uno[/" +"url][/color]." #: editor/editor_help.cpp msgid "Property Descriptions" -msgstr "Descripción de la propiedad" +msgstr "Descripción de Propiedades" #: editor/editor_help.cpp msgid "Property Descriptions:" -msgstr "Descripción de la propiedad:" +msgstr "Descripción de Propiedades:" #: editor/editor_help.cpp msgid "" "There is currently no description for this property. Please help us by " "[color=$color][url=$url]contributing one[/url][/color]!" msgstr "" -"Actualmente no hay una descripción para esta propiedad. Por favor, ¡ayúdanos " -"[color=$color][url=$url]aportando una[/url][/color]!" +"Actualmente no existe descripción para esta propiedad. Por favor ¡ayúdanos " +"[color=$color][url=$url]contribuyendo una[/url][/color]!" #: editor/editor_help.cpp msgid "Method Descriptions" -msgstr "Descripción de Método" +msgstr "Descripción de Métodos" #: editor/editor_help.cpp msgid "Method Descriptions:" -msgstr "Descripciones del método:" +msgstr "Descripción de Métodos:" #: editor/editor_help.cpp msgid "" @@ -2001,28 +1985,31 @@ msgid "" "$color][url=$url]contributing one[/url][/color]!" msgstr "" "Actualmente no hay una descripción para este método. Por favor, ¡ayúdanos " -"[color=$color][url=$url]aportando una[/url][/color]!" +"[color=$color][url=$url]aportando una[/url][/color]!\n" +"\n" +"Actualmente no existe descripción para este método. Por favor ¡ayúdanos " +"[color=$color][url=$url]contribuyendo una[/url][/color]!" #: editor/editor_help_search.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp msgid "Search Help" -msgstr "Ayuda de búsqueda" +msgstr "Buscar en la Ayuda" #: editor/editor_help_search.cpp msgid "Display All" -msgstr "Mostrar todos" +msgstr "Mostrar Todos" #: editor/editor_help_search.cpp msgid "Classes Only" -msgstr "Solo clases" +msgstr "Solo Clases" #: editor/editor_help_search.cpp msgid "Methods Only" -msgstr "Solo métodos" +msgstr "Solo Métodos" #: editor/editor_help_search.cpp msgid "Signals Only" -msgstr "Solo señales" +msgstr "Solo Señales" #: editor/editor_help_search.cpp msgid "Constants Only" @@ -2072,11 +2059,11 @@ msgstr "Copiar Selección" #: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Clear" -msgstr "Borrar todo" +msgstr "Limpiar" #: editor/editor_log.cpp msgid "Clear Output" -msgstr "Borrar salida" +msgstr "Limpiar Salida" #: editor/editor_node.cpp msgid "Project export failed with error code %d." @@ -2105,7 +2092,7 @@ msgstr "" #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Save Resource As..." -msgstr "Guardar recurso como..." +msgstr "Guardar Recurso Como..." #: editor/editor_node.cpp msgid "Can't open file for writing:" @@ -2113,7 +2100,7 @@ msgstr "No se puede abrir el archivo para escribir:" #: editor/editor_node.cpp msgid "Requested file format unknown:" -msgstr "Formato de archivo desconocido:" +msgstr "Formato de archivo requerido desconocido:" #: editor/editor_node.cpp msgid "Error while saving." @@ -2134,7 +2121,7 @@ msgstr "Fin de archivo '%s' inesperado." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." -msgstr "La escena '%s' tiene dependencias rotas." +msgstr "No se encuentra '%s' o sus dependencias." #: editor/editor_node.cpp msgid "Error while loading '%s'." @@ -2142,7 +2129,7 @@ msgstr "Error al cargar '%s'." #: editor/editor_node.cpp msgid "Saving Scene" -msgstr "Guardar escena" +msgstr "Guardar Escena" #: editor/editor_node.cpp msgid "Analyzing" @@ -2150,7 +2137,7 @@ msgstr "Analizando" #: editor/editor_node.cpp msgid "Creating Thumbnail" -msgstr "Creando miniatura" +msgstr "Creando Miniatura" #: editor/editor_node.cpp msgid "This operation can't be done without a tree root." @@ -2170,8 +2157,8 @@ msgid "" "Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " "be satisfied." msgstr "" -"No se pudo guardar la escena. Las dependencias (instancias o herencia) no se " -"pudieron resolver." +"No se pudo guardar la escena. Las posibles dependencias (instancias o " +"herencias) no se pudieron resolver." #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "Can't overwrite scene that is still open!" @@ -2187,7 +2174,7 @@ msgstr "¡Error al guardar la MeshLibrary!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" -msgstr "¡No se puede cargar TileSet para poder unir los datos!" +msgstr "¡No se puede cargar TileSet para la combinación!" #: editor/editor_node.cpp msgid "Error saving TileSet!" @@ -2195,19 +2182,19 @@ msgstr "¡Error al guardar el TileSet!" #: editor/editor_node.cpp msgid "Error trying to save layout!" -msgstr "¡Hubo un problema al intentar guardar los ajustes!" +msgstr "¡Error al guardar el layout!" #: editor/editor_node.cpp msgid "Default editor layout overridden." -msgstr "Se han sobrescrito los ajustes predeterminados del editor." +msgstr "Se ha sobreescrito el layout del editor por defecto." #: editor/editor_node.cpp msgid "Layout name not found!" -msgstr "¡Nombre del ajuste no encontrado!" +msgstr "¡Nombre de layout no encontrado!" #: editor/editor_node.cpp msgid "Restored default layout to base settings." -msgstr "Se han restaurado los ajustes predeterminados." +msgstr "Se restauró el layout por defecto a su configuración básica." #: editor/editor_node.cpp msgid "" @@ -2220,7 +2207,6 @@ msgstr "" "entender mejor el flujo de trabajo." #: editor/editor_node.cpp -#, fuzzy 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." @@ -2238,28 +2224,26 @@ msgstr "" "ajustes en el panel de importación e impórtalo de nuevo." #: editor/editor_node.cpp -#, fuzzy msgid "" "This scene was imported, so changes to it won't be kept.\n" "Instancing it or inheriting will allow making changes to it.\n" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" -"Esta escena ha sido importada, por lo tanto, los cambios no se mantendrán.\n" -"Instanciarla o heredarla permitirá hacerle cambios.\n" -"Por favor, lee la documentación referente a la importación de escenas para " -"entender mejor el flujo de trabajo." +"Esta escena fue importada, por lo que los cambios no se mantendrán.\n" +"Instanciarla o heredarla permitirá realizar cambios en esta.\n" +"Por favor, lee la documentación relevante para importar escenas para " +"entender mejor este flujo de trabajo." #: editor/editor_node.cpp -#, fuzzy msgid "" "This is a remote object, so changes to it won't be kept.\n" "Please read the documentation relevant to debugging to better understand " "this workflow." msgstr "" -"Este es un objeto remoto, por lo tanto, los cambios no se mantendrán.\n" -"Por favor, lee la documentación referente a la depuración para entender " -"mejor el flujo de trabajo." +"Este es un objeto remoto, por lo que los cambios en él no se mantendrán.\n" +"Por favor, lee la documentación relativa a la depuración para entender mejor " +"el flujo de trabajo." #: editor/editor_node.cpp msgid "There is no defined scene to run." @@ -2276,28 +2260,27 @@ msgstr "¡No se pudo comenzar el subproceso!" #: editor/editor_node.cpp editor/filesystem_dock.cpp msgid "Open Scene" -msgstr "Abrir escena" +msgstr "Abrir Escena" #: editor/editor_node.cpp msgid "Open Base Scene" -msgstr "Abrir escena base" +msgstr "Abrir Escena Base" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Apertura rápida de escena..." +msgstr "Apertura Rápida..." #: editor/editor_node.cpp msgid "Quick Open Scene..." -msgstr "Apertura rápida de escena..." +msgstr "Apertura Rápida de Escena..." #: editor/editor_node.cpp msgid "Quick Open Script..." -msgstr "Apertura rápida de script..." +msgstr "Apertura Rápida de Script..." #: editor/editor_node.cpp msgid "Save & Close" -msgstr "Guardar y cerrar" +msgstr "Guardar y Cerrar" #: editor/editor_node.cpp msgid "Save changes to '%s' before closing?" @@ -2313,7 +2296,7 @@ msgstr "Se necesita un nodo raÃz para guardar la escena." #: editor/editor_node.cpp msgid "Save Scene As..." -msgstr "Guardar escena como..." +msgstr "Guardar Escena Como..." #: editor/editor_node.cpp msgid "No" @@ -2362,13 +2345,11 @@ msgstr "Revertir" #: editor/editor_node.cpp msgid "This action cannot be undone. Revert anyway?" -msgstr "" -"Esta acción no se podrá volver a realizar. ¿Quieres revertirla de todos " -"modos?" +msgstr "Esta acción no se puede deshacer. ¿Revertir de todos modos?" #: editor/editor_node.cpp msgid "Quick Run Scene..." -msgstr "Ejecución rápida de escena..." +msgstr "Ejecución Rápida de Escena..." #: editor/editor_node.cpp msgid "Quit" @@ -2376,11 +2357,11 @@ msgstr "Salir" #: editor/editor_node.cpp msgid "Exit the editor?" -msgstr "¿Quieres salir del editor?" +msgstr "¿Salir del editor?" #: editor/editor_node.cpp msgid "Open Project Manager?" -msgstr "¿Abrir el administrador de proyectos?" +msgstr "¿Abrir el Administrador de Proyectos?" #: editor/editor_node.cpp msgid "Save & Quit" @@ -2388,13 +2369,13 @@ msgstr "Guardar y salir" #: editor/editor_node.cpp msgid "Save changes to the following scene(s) before quitting?" -msgstr "¿Guardar cambios a la(s) siguiente(s) escena(s) antes de salir?" +msgstr "¿Guardar los cambios en las siguientes escenas antes de salir?" #: editor/editor_node.cpp msgid "Save changes the following scene(s) before opening Project Manager?" msgstr "" -"¿Guardar cambios a la(s) siguiente(s) escena(s) antes de abrir el " -"administrador de proyectos?" +"¿Guardar los cambios en las siguientes escenas antes de abrir el " +"Administrador de Proyectos?" #: editor/editor_node.cpp msgid "" @@ -2406,12 +2387,13 @@ msgstr "" #: editor/editor_node.cpp msgid "Pick a Main Scene" -msgstr "Selecciona una escena principal" +msgstr "Selecciona una Escena Principal" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" -"No se pudo activar el plugin addon en: '%s' falló lectura de configuración." +"No se pudo activar el plugin addon: Ha fallado el análisis de la " +"configuración de '%s'." #: editor/editor_node.cpp msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." @@ -2476,9 +2458,9 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"No se ha definido ninguna escena principal, ¿Quieres elegir alguna?\n" -"Es posible cambiarla más tarde en «Ajustes del Proyecto» bajo la categorÃa " -"«Aplicación»." +"No se ha definido ninguna escena principal, ¿seleccionar una?\n" +"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categorÃa " +"'application'." #: editor/editor_node.cpp msgid "" @@ -2486,9 +2468,9 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"La escena '%s' seleccionada no existe, ¿seleccionar una válida?\n" +"La escena seleccionada '%s' no existe, ¿seleccionar una válida?\n" "Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categorÃa " -"'aplicación'." +"'application'." #: editor/editor_node.cpp msgid "" @@ -2499,15 +2481,15 @@ msgstr "" "La escena '%s' seleccionada no es un archivo de escena, ¿seleccionar uno " "válido?\n" "Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categorÃa " -"'aplicación'." +"'application'." #: editor/editor_node.cpp msgid "Save Layout" -msgstr "Guardar ajustes" +msgstr "Guardar Layout" #: editor/editor_node.cpp msgid "Delete Layout" -msgstr "Borrar ajustes" +msgstr "Eliminar Layout" #: editor/editor_node.cpp editor/import_dock.cpp #: editor/script_create_dialog.cpp @@ -2521,28 +2503,27 @@ msgstr "Mostrar en Sistema de Archivos" #: editor/editor_node.cpp msgid "Play This Scene" -msgstr "Reproducir esta escena" +msgstr "Reproducir Esta Escena" #: editor/editor_node.cpp msgid "Close Tab" -msgstr "Cerrar pestaña" +msgstr "Cerrar Pestaña" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" -msgstr "Cerrar las demás pestañas" +msgstr "Cerrar Otras Pestañas" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Cerrar Pestañas a la Derecha" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Cerrar todo" +msgstr "Cerrar Todas las Pestañas" #: editor/editor_node.cpp msgid "Switch Scene Tab" -msgstr "Cambiar pestaña de escena" +msgstr "Cambiar Pestaña de Escena" #: editor/editor_node.cpp msgid "%d more files or folders" @@ -2558,7 +2539,7 @@ msgstr "%d más archivos" #: editor/editor_node.cpp msgid "Dock Position" -msgstr "Posición del dock" +msgstr "Posición del Dock" #: editor/editor_node.cpp msgid "Distraction Free Mode" @@ -2566,7 +2547,7 @@ msgstr "Modo sin distracciones" #: editor/editor_node.cpp msgid "Toggle distraction-free mode." -msgstr "Act/desact. modo sin distracciones." +msgstr "Act./Desact. modo sin distracciones." #: editor/editor_node.cpp msgid "Add a new scene." @@ -2590,7 +2571,7 @@ msgstr "Pestaña anterior" #: editor/editor_node.cpp msgid "Filter Files..." -msgstr "Filtrado de archivos..." +msgstr "Filtrar Archivos..." #: editor/editor_node.cpp msgid "Operations with scene files." @@ -2598,19 +2579,19 @@ msgstr "Operaciones con archivos de escena." #: editor/editor_node.cpp msgid "New Scene" -msgstr "Nueva escena" +msgstr "Nueva Escena" #: editor/editor_node.cpp msgid "New Inherited Scene..." -msgstr "Nueva escena heredada..." +msgstr "Nueva Escena Heredada..." #: editor/editor_node.cpp msgid "Open Scene..." -msgstr "Abrir escena..." +msgstr "Abrir Escena..." #: editor/editor_node.cpp msgid "Save Scene" -msgstr "Guardar escena" +msgstr "Guardar Escena" #: editor/editor_node.cpp msgid "Save All Scenes" @@ -2618,11 +2599,11 @@ msgstr "Guardar Todas las Escenas" #: editor/editor_node.cpp msgid "Close Scene" -msgstr "Cerrar escena" +msgstr "Cerrar Escena" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Open Recent" -msgstr "Abrir reciente" +msgstr "Abrir Reciente" #: editor/editor_node.cpp msgid "Convert To..." @@ -2648,7 +2629,7 @@ msgstr "Rehacer" #: editor/editor_node.cpp msgid "Revert Scene" -msgstr "Revertir escena" +msgstr "Revertir Escena" #: editor/editor_node.cpp msgid "Miscellaneous project or scene-wide tools." @@ -2668,15 +2649,15 @@ msgstr "Herramientas" #: editor/editor_node.cpp msgid "Open Project Data Folder" -msgstr "Abrir carpeta de datos del proyecto" +msgstr "Abrir Carpeta de Datos del Proyecto" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Instalar plantilla de compilación de Android" #: editor/editor_node.cpp msgid "Quit to Project List" -msgstr "Salir al listado de proyectos" +msgstr "Salir al Listado de Proyectos" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp @@ -2685,19 +2666,19 @@ msgstr "Depurar" #: editor/editor_node.cpp msgid "Deploy with Remote Debug" -msgstr "Exportar con depuración remota" +msgstr "Exportar con Depuración Remota" #: editor/editor_node.cpp msgid "" "When exporting or deploying, the resulting executable will attempt to " "connect to the IP of this computer in order to be debugged." msgstr "" -"Al exportar o publicar, el ejecutable tratará de conectarse a la IP de este " -"equipo para iniciar la depuración." +"Al exportar o distribuir, el ejecutable generado intentará conectarse a la " +"IP de este equipo para ser depurado." #: editor/editor_node.cpp msgid "Small Deploy with Network FS" -msgstr "Exportación mini con recursos en red" +msgstr "Exportación Mini con Recursos en Red" #: editor/editor_node.cpp msgid "" @@ -2716,19 +2697,19 @@ msgstr "" #: editor/editor_node.cpp msgid "Visible Collision Shapes" -msgstr "Ver formas de colisión" +msgstr "Ver Formas de Colisión" #: editor/editor_node.cpp msgid "" "Collision shapes and raycast nodes (for 2D and 3D) will be visible on the " "running game if this option is turned on." msgstr "" -"Los \"Collision Shapes\" y los nodos \"raycast\" (para 2D y 3D) serán " -"visibles durante la ejecución del juego cuando esta opción esté activada." +"Los Collision shapes y nodos raycast (para 2D y 3D) serán visibles durante " +"la ejecución del juego cuando esta opción queda activada." #: editor/editor_node.cpp msgid "Visible Navigation" -msgstr "Navegación visible" +msgstr "Navegación Visible" #: editor/editor_node.cpp msgid "" @@ -2756,7 +2737,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Sync Script Changes" -msgstr "Actualizar cambios en scripts" +msgstr "Sincronizar Cambios en Scripts" #: editor/editor_node.cpp msgid "" @@ -2776,36 +2757,57 @@ msgstr "Editor" #: editor/editor_node.cpp editor/settings_config_dialog.cpp msgid "Editor Settings" -msgstr "Ajustes del Editor" +msgstr "Configuración del Editor" #: editor/editor_node.cpp msgid "Editor Layout" -msgstr "Ajustes de diseño del editor" +msgstr "Layout del Editor" + +#: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "Realizar Captura de Pantalla" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "" +"Las capturas de pantalla se almacenan en la carpeta Editor de Datos / " +"Configuración." + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "Abrir Capturas de Pantalla Automáticamente" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "Abrir en un editor de imágenes externo." #: editor/editor_node.cpp msgid "Toggle Fullscreen" -msgstr "Act/desact. Pantalla Completa" +msgstr "Cambiar a Pantalla Completa" + +#: editor/editor_node.cpp +msgid "Toggle System Console" +msgstr "Act./Desact. Consola del Sistema" #: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" -msgstr "Abrir carpeta de datos/configuración del Editor" +msgstr "Abrir Editor de Datos/Carpeta de Configuración" #: editor/editor_node.cpp msgid "Open Editor Data Folder" -msgstr "Abrir Carpeta de Datos del Editor" +msgstr "Abrir Carpeta de Editor de Datos" #: editor/editor_node.cpp msgid "Open Editor Settings Folder" -msgstr "Abrir carpeta de configuración del Editor" +msgstr "Abrir Carpeta de Configuración del Editor" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "Cargar plantillas de exportación" +msgstr "Administrar CaracterÃsticas del Editor" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" -msgstr "Cargar plantillas de exportación" +msgstr "Administrar Plantillas de Exportación" #: editor/editor_node.cpp msgid "Help" @@ -2822,7 +2824,7 @@ msgstr "Buscar" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Online Docs" -msgstr "Documentación en lÃnea" +msgstr "Documentación Online" #: editor/editor_node.cpp msgid "Q&A" @@ -2854,7 +2856,7 @@ msgstr "Pausar la escena" #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "Pausar la escena" +msgstr "Pausar Escena" #: editor/editor_node.cpp msgid "Stop the scene." @@ -2870,7 +2872,7 @@ msgstr "Reproducir la escena editada." #: editor/editor_node.cpp msgid "Play Scene" -msgstr "Reproducir escena" +msgstr "Reproducir Escena" #: editor/editor_node.cpp msgid "Play custom scene" @@ -2878,7 +2880,7 @@ msgstr "Reproducir escena personalizada" #: editor/editor_node.cpp msgid "Play Custom Scene" -msgstr "Reproducir escena personalizada" +msgstr "Reproducir Escena Personalizada" #: editor/editor_node.cpp msgid "Changing the video driver requires restarting the editor." @@ -2894,16 +2896,16 @@ msgid "Spins when the editor window redraws." msgstr "Gira cuando la ventana del editor se redibuja." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Actualizar siempre" +msgid "Update Continuously" +msgstr "Actualizar Continuamente" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "Actualizar cambios" +msgid "Update When Changed" +msgstr "Actualizar Al Cambiar" #: editor/editor_node.cpp -msgid "Disable Update Spinner" -msgstr "Desactivar indicador de actividad" +msgid "Hide Update Spinner" +msgstr "Ocultar Spinner de Actualización" #: editor/editor_node.cpp msgid "FileSystem" @@ -2919,7 +2921,7 @@ msgstr "Nodos" #: editor/editor_node.cpp msgid "Expand Bottom Panel" -msgstr "Expandir panel inferior" +msgstr "Expandir Panel Inferior" #: editor/editor_node.cpp scene/resources/visual_shader.cpp msgid "Output" @@ -2927,22 +2929,25 @@ msgstr "Salida" #: editor/editor_node.cpp msgid "Don't Save" -msgstr "No guardar" +msgstr "No Guardar" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." msgstr "" +"Falta la plantilla de compilación de Android, por favor, instala las " +"plantillas correspondientes." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Cargar plantillas de exportación" +msgstr "Administrar Plantillas" #: editor/editor_node.cpp msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"Esto instalará el proyecto Android para compilaciones personalizadas.\n" +"Para utilizarlo, es necesario habilitarlo mediante un preset de exportación." #: editor/editor_node.cpp msgid "" @@ -2950,6 +2955,10 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"La plantilla de compilación de Android ya está instalada y no se " +"sobrescribirá.\n" +"Elimina el directorio \"build\" manualmente antes de intentar esta operación " +"nuevamente." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -2957,15 +2966,15 @@ msgstr "Importar plantillas desde un archivo ZIP" #: editor/editor_node.cpp editor/project_export.cpp msgid "Export Project" -msgstr "Exportar proyecto" +msgstr "Exportar Proyecto" #: editor/editor_node.cpp msgid "Export Library" -msgstr "Exportar biblioteca" +msgstr "Exportar LibrerÃa" #: editor/editor_node.cpp msgid "Merge With Existing" -msgstr "Unir con existentes" +msgstr "Combinar Con Existentes" #: editor/editor_node.cpp msgid "Password:" @@ -2973,11 +2982,11 @@ msgstr "Contraseña:" #: editor/editor_node.cpp msgid "Open & Run a Script" -msgstr "Abrir y ejecutar un script" +msgstr "Abrir y Ejecutar un Script" #: editor/editor_node.cpp msgid "New Inherited" -msgstr "Nueva escena heredada" +msgstr "Nueva Escena Heredada" #: editor/editor_node.cpp msgid "Load Errors" @@ -2989,27 +2998,27 @@ msgstr "Seleccionar" #: editor/editor_node.cpp msgid "Open 2D Editor" -msgstr "Abrir editor 2D" +msgstr "Abrir Editor 2D" #: editor/editor_node.cpp msgid "Open 3D Editor" -msgstr "Abrir editor 3D" +msgstr "Abrir Editor 3D" #: editor/editor_node.cpp msgid "Open Script Editor" -msgstr "Abrir editor de script" +msgstr "Abrir Editor de Script" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" -msgstr "Abrir biblioteca de assets" +msgstr "Abrir Biblioteca de Assets" #: editor/editor_node.cpp msgid "Open the next Editor" -msgstr "Abrir editor siguiente" +msgstr "Abrir Editor siguiente" #: editor/editor_node.cpp msgid "Open the previous Editor" -msgstr "Abrir editor anterior" +msgstr "Abrir Editor anterior" #: editor/editor_plugin.cpp msgid "Creating Mesh Previews" @@ -3025,7 +3034,7 @@ msgstr "Editar Plugin" #: editor/editor_plugin_settings.cpp msgid "Installed Plugins:" -msgstr "Plugins instalados:" +msgstr "Plugins Instalados:" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp msgid "Update" @@ -3059,19 +3068,19 @@ msgstr "Medida:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" -msgstr "Duración de cuadro (seg)" +msgstr "Duración de Frame (seg)" #: editor/editor_profiler.cpp msgid "Average Time (sec)" -msgstr "Tiempo promedio (seg)" +msgstr "Tiempo Promedio (seg)" #: editor/editor_profiler.cpp msgid "Frame %" -msgstr "% de cuadro" +msgstr "Frame %" #: editor/editor_profiler.cpp msgid "Physics Frame %" -msgstr "% de cuadro fÃsico" +msgstr "Frames de FÃsica %" #: editor/editor_profiler.cpp msgid "Inclusive" @@ -3083,7 +3092,7 @@ msgstr "Propio" #: editor/editor_profiler.cpp msgid "Frame #:" -msgstr "Nº de cuadro:" +msgstr "Frame #:" #: editor/editor_profiler.cpp msgid "Time" @@ -3093,7 +3102,7 @@ msgstr "Tiempo" msgid "Calls" msgstr "Llamadas" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Activado" @@ -3115,14 +3124,14 @@ msgstr "Asignar..." #: editor/editor_properties.cpp msgid "Invalid RID" -msgstr "RID no válido" +msgstr "RID inválido" #: editor/editor_properties.cpp msgid "" "The selected resource (%s) does not match any type expected for this " "property (%s)." msgstr "" -"El recurso seleccionado (%s) no concuerda con el tipo esperado para esta " +"El recurso seleccionado (%s) no coincide con ningún tipo esperado para esta " "propiedad (%s)." #: editor/editor_properties.cpp @@ -3148,11 +3157,11 @@ msgstr "" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Pick a Viewport" -msgstr "Selecciona un viewport" +msgstr "Selecciona un Viewport" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New Script" -msgstr "Nuevo script" +msgstr "Nuevo Script" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New %s" @@ -3160,7 +3169,7 @@ msgstr "Nuevo %s" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Make Unique" -msgstr "Hacer único" +msgstr "Hacer Único" #: editor/editor_properties.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp @@ -3200,6 +3209,11 @@ msgid "Page: " msgstr "Página: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Eliminar Item" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Nueva Clave:" @@ -3211,11 +3225,6 @@ msgstr "Nuevo Valor:" msgid "Add Key/Value Pair" msgstr "Agregar Par Clave/Valor" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Remover item" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3259,15 +3268,15 @@ msgstr "Examinar" #: editor/editor_sub_scene.cpp msgid "Scene Path:" -msgstr "Ruta de la escena:" +msgstr "Ruta de la Escena:" #: editor/editor_sub_scene.cpp msgid "Import From Node:" -msgstr "Importar desde nodo:" +msgstr "Importar Desde Nodo:" #: editor/export_template_manager.cpp msgid "Re-Download" -msgstr "Volver a descargar" +msgstr "Volver a Descargar" #: editor/export_template_manager.cpp msgid "Uninstall" @@ -3292,7 +3301,7 @@ msgstr "(Actual)" #: editor/export_template_manager.cpp msgid "Retrieving mirrors, please wait..." -msgstr "Obteniendo mirrors, por favor espere..." +msgstr "Obteniendo mirrors, por favor espera..." #: editor/export_template_manager.cpp msgid "Remove template version '%s'?" @@ -3316,7 +3325,7 @@ msgstr "Error al crear ruta para las plantillas:" #: editor/export_template_manager.cpp msgid "Extracting Export Templates" -msgstr "Extrayendo plantillas de exportación" +msgstr "Extrayendo Plantillas de Exportación" #: editor/export_template_manager.cpp msgid "Importing:" @@ -3348,12 +3357,12 @@ msgstr "No responde." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Request Failed." -msgstr "Petición fallida." +msgstr "Petición Fallida." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Redirect Loop." -msgstr "Bucle de redireccionamiento." +msgstr "Redireccionar Loop." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -3362,7 +3371,7 @@ msgstr "Fallido:" #: editor/export_template_manager.cpp msgid "Download Complete." -msgstr "Descarga completada." +msgstr "Descarga Completada." #: editor/export_template_manager.cpp msgid "" @@ -3378,7 +3387,7 @@ msgstr "Error al solicitar url: " #: editor/export_template_manager.cpp msgid "Connecting to Mirror..." -msgstr "Intentando conexión alternativa..." +msgstr "Conectando con Mirror...." #: editor/export_template_manager.cpp msgid "Disconnected" @@ -3416,45 +3425,43 @@ msgstr "Descargando" #: editor/export_template_manager.cpp msgid "Connection Error" -msgstr "Error de conexión" +msgstr "Error de Conexión" #: editor/export_template_manager.cpp msgid "SSL Handshake Error" -msgstr "Error de negociación SSL" +msgstr "Error de Negociación SSL" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "Descomprimiendo assets" +msgstr "Descomprimir los Recursos de la Compilación de Android" #: editor/export_template_manager.cpp msgid "Current Version:" -msgstr "Versión actual:" +msgstr "Versión Actual:" #: editor/export_template_manager.cpp msgid "Installed Versions:" -msgstr "Versiones instaladas:" +msgstr "Versiones Instaladas:" #: editor/export_template_manager.cpp msgid "Install From File" -msgstr "Instalar desde archivo" +msgstr "Instalar Desde Archivo" #: editor/export_template_manager.cpp msgid "Remove Template" -msgstr "Eliminar plantilla" +msgstr "Eliminar Plantilla" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" -msgstr "Seleccionar archivo plantilla" +msgstr "Selecciona un Archivo de Plantilla" #: editor/export_template_manager.cpp msgid "Export Template Manager" -msgstr "Gestor de plantillas de exportación" +msgstr "Gestor de Plantillas de Exportación" #: editor/export_template_manager.cpp msgid "Download Templates" -msgstr "Descargar plantillas" +msgstr "Descargar Plantillas" #: editor/export_template_manager.cpp msgid "Select mirror from list: (Shift+Click: Open in Browser)" @@ -3508,9 +3515,8 @@ msgid "No name provided." msgstr "Nombre no proporcionado." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "El nombre proporcionado contiene caracteres inválidos" +msgstr "El nombre contiene caracteres inválidos." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3537,36 +3543,32 @@ msgid "Duplicating folder:" msgstr "Duplicando carpeta:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Nueva escena heredada..." +msgstr "Nueva Escena Heredada" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Abrir escena" +msgstr "Abrir Escenas" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Instanciar" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" -msgstr "Agregar a favoritos" +msgstr "Agregar a Favoritos" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "Quitar de favoritos" +msgstr "Eliminar de Favoritos" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." -msgstr "Editar dependencias..." +msgstr "Editar Dependencias..." #: editor/filesystem_dock.cpp msgid "View Owners..." -msgstr "Ver propietarios..." +msgstr "Ver Propietarios..." #: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Rename..." @@ -3606,23 +3608,20 @@ msgid "Rename" msgstr "Renombrar" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Carpeta Anterior" +msgstr "Carpeta/Archivo Anterior" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Carpeta Siguiente" +msgstr "Carpeta/Archivo Siguiente" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" -msgstr "Re-escanear sistema de archivos" +msgstr "Re-escanear Sistema de Archivos" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" -msgstr "Act/Desact. Modo Dividido" +msgstr "Act./Desact. Modo Dividido" #: editor/filesystem_dock.cpp msgid "Search files" @@ -3650,7 +3649,7 @@ msgstr "Sobreescribir" #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "Create Script" -msgstr "Crear script" +msgstr "Crear Script" #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp msgid "Find in Files" @@ -3673,6 +3672,8 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Incluye los archivos con las siguientes extensiones. Añádelos o elimÃnalos " +"en Ajustes del proyecto." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3724,6 +3725,7 @@ msgid "Nodes not in Group" msgstr "Nodos fuera del Grupo" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtrar nodos" @@ -3733,11 +3735,11 @@ msgstr "Nodos dentro del Grupo" #: editor/groups_editor.cpp msgid "Add to Group" -msgstr "Añadir al grupo" +msgstr "Añadir al Grupo" #: editor/groups_editor.cpp msgid "Remove from Group" -msgstr "Quitar del grupo" +msgstr "Eliminar del Grupo" #: editor/groups_editor.cpp msgid "Manage Groups" @@ -3745,52 +3747,52 @@ msgstr "Administrar Grupos" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" -msgstr "Importar como escena individual" +msgstr "Importar como Escena Individual" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Animations" -msgstr "Importar con animaciones separadas" +msgstr "Importar con Animaciones Separadas" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials" -msgstr "Importar con materiales separados" +msgstr "Importar con Materiales Separados" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects" -msgstr "Importar con objetos separados" +msgstr "Importar con Objetos Separados" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials" -msgstr "Importar con objetos y materiales separados" +msgstr "Importar con Objetos y Materiales Separados" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Animations" -msgstr "Importar con objetos y animaciones separados" +msgstr "Importar con Objetos y Animaciones Separados" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials+Animations" -msgstr "Importar con materiales y animaciones separados" +msgstr "Importar con Materiales y Animaciones Separados" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials+Animations" -msgstr "Importar con objetos, materiales y animaciones separados" +msgstr "Importar con Objetos, Materiales y Animaciones Separados" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes" -msgstr "Importar como múltiples escenas" +msgstr "Importar como Múltiples Escenas" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" -msgstr "Importar como escenas y materiales múltiples" +msgstr "Importar como Escenas y Materiales Múltiples" #: editor/import/resource_importer_scene.cpp #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Import Scene" -msgstr "Importar escena" +msgstr "Importar Escena" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene..." -msgstr "Importando escena..." +msgstr "Importando Escena..." #: editor/import/resource_importer_scene.cpp msgid "Generating Lightmaps" @@ -3802,7 +3804,7 @@ msgstr "Generando para Mesh: " #: editor/import/resource_importer_scene.cpp msgid "Running Custom Script..." -msgstr "Ejecutando script personalizado..." +msgstr "Ejecutando Script Personalizado..." #: editor/import/resource_importer_scene.cpp msgid "Couldn't load post-import script:" @@ -3823,11 +3825,11 @@ msgstr "Guardando..." #: editor/import_dock.cpp msgid "Set as Default for '%s'" -msgstr "Configurar por defecto para '%s'" +msgstr "Establecer como predeterminado para '%s'" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "Borrar por defecto para '%s'" +msgstr "Restablecer Predeterminado para '%s'" #: editor/import_dock.cpp msgid " Files" @@ -3839,7 +3841,7 @@ msgstr "Importar como:" #: editor/import_dock.cpp editor/property_editor.cpp msgid "Preset..." -msgstr "Ajuste..." +msgstr "Preset..." #: editor/import_dock.cpp msgid "Reimport" @@ -3879,11 +3881,11 @@ msgstr "Guardar como..." #: editor/inspector_dock.cpp msgid "Copy Params" -msgstr "Copiar parámetros" +msgstr "Copiar Parámetros" #: editor/inspector_dock.cpp msgid "Paste Params" -msgstr "Pegar parámetros" +msgstr "Pegar Parámetros" #: editor/inspector_dock.cpp msgid "Edit Resource Clipboard" @@ -3891,11 +3893,11 @@ msgstr "Editar Portapapeles de Recursos" #: editor/inspector_dock.cpp msgid "Copy Resource" -msgstr "Copiar recurso" +msgstr "Copiar Recurso" #: editor/inspector_dock.cpp msgid "Make Built-In" -msgstr "Convertirlo en integrado" +msgstr "Crear Integrado" #: editor/inspector_dock.cpp msgid "Make Sub-Resources Unique" @@ -3980,7 +3982,7 @@ msgstr "¿Activar ahora?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create Polygon" -msgstr "Crear polÃgono" +msgstr "Crear PolÃgono" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp @@ -4009,7 +4011,7 @@ msgstr "Editar PolÃgono" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Insert Point" -msgstr "Insertar punto" +msgstr "Insertar Punto" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Edit Polygon (Remove Point)" @@ -4025,7 +4027,7 @@ msgstr "Remover PolÃgono y Punto" #: editor/plugins/animation_state_machine_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Animation" -msgstr "Añadir animación" +msgstr "Añadir Animación" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4097,7 +4099,7 @@ msgstr "Seleccionar y mover puntos, crear puntos con clic derecho." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp msgid "Enable snap and show grid." -msgstr "Activar snap y mostrar cuadricula." +msgstr "Activar snap y mostrar grid." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4112,9 +4114,8 @@ msgid "Open Animation Node" msgstr "Abrir Nodo de Animación" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "El triángulo ya existe" +msgstr "El triángulo ya existe." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4146,7 +4147,7 @@ msgstr "No hay ningún triángulo, asà que no se puede hacer blending." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Toggle Auto Triangles" -msgstr "Act/desact. Auto Triángulos" +msgstr "Act./Desact. Auto Triángulos" #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Create triangles by connecting points." @@ -4172,7 +4173,7 @@ msgstr "Parámetro Modificado" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Edit Filters" -msgstr "Editar filtros" +msgstr "Editar Filtros" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Output node can't be added to the blend tree." @@ -4215,7 +4216,7 @@ msgstr "Eliminar Nodo" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" -msgstr "Eliminar nodo(s)" +msgstr "Eliminar Nodo(s)" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Toggle Filter On/Off" @@ -4259,24 +4260,23 @@ msgstr "Agregar Nodo..." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/root_motion_editor_plugin.cpp msgid "Edit Filtered Tracks:" -msgstr "Editar pistas filtradas:" +msgstr "Editar Pistas Filtradas:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" -msgstr "Habilitar filtrado" +msgstr "Habilitar Filtrado" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" -msgstr "Act/desact. Reproducción Automática" +msgstr "Act./Desact. Reproducción Automática" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Animation Name:" -msgstr "Nombre de animación nueva:" +msgstr "Nombre de Animación Nueva:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Anim" -msgstr "Nueva animación" +msgstr "Nueva Animación" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Animation Name:" @@ -4284,12 +4284,12 @@ msgstr "Cambiar nombre de animación:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Delete Animation?" -msgstr "¿Eliminar animación?" +msgstr "¿Eliminar Animación?" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Remove Animation" -msgstr "Quitar animación" +msgstr "Eliminar Animación" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Invalid animation name!" @@ -4302,23 +4302,23 @@ msgstr "¡El nombre de animación ya existe!" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Rename Animation" -msgstr "Renombrar animación" +msgstr "Renombrar Animación" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Next Changed" -msgstr "Mezclar el siguiente cambio" +msgstr "Mezclar el Siguiente Cambio" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Blend Time" -msgstr "Cambiar tiempo de mezcla" +msgstr "Cambiar Tiempo de Mezcla" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load Animation" -msgstr "Cargar animación" +msgstr "Cargar Animación" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Duplicate Animation" -msgstr "Duplicar animación" +msgstr "Duplicar Animación" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation to copy!" @@ -4330,11 +4330,11 @@ msgstr "¡No hay recursos de animación en el portapapeles!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pasted Animation" -msgstr "Animación pegada" +msgstr "Animación Pegada" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Paste Animation" -msgstr "Pegar animación" +msgstr "Pegar Animación" #: editor/plugins/animation_player_editor_plugin.cpp msgid "No animation to edit!" @@ -4348,7 +4348,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from end. (Shift+A)" msgstr "" -"Reproducir hacia atrás la animación seleccionada desde el final. (Mayús + A)" +"Reproducir hacia atrás la animación seleccionada desde el final. (Shift + A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" @@ -4356,7 +4356,7 @@ msgstr "Detener la reproducción de la animación. (S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "Reproducir animación seleccionada desde el principio. (Mayús + D)" +msgstr "Reproducir animación seleccionada desde el principio. (Shift + D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" @@ -4372,7 +4372,7 @@ msgstr "Escalar globalmente la reproducción de la animación para el nodo." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Tools" -msgstr "Herramientas de animación" +msgstr "Herramientas de Animación" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/canvas_item_editor_plugin.cpp @@ -4393,16 +4393,15 @@ msgstr "Mostrar la lista de animaciones en el reproductor." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" -msgstr "Autoreproducir al cargar" +msgstr "Autoreproducir al Cargar" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" -msgstr "Activar papel cebolla" +msgstr "Activar Papel Cebolla" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "Papel Cebolla" +msgstr "Opciones de Papel Cebolla" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4434,11 +4433,11 @@ msgstr "3 pasos" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Differences Only" -msgstr "Solo las diferencias" +msgstr "Solo las Diferencias" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Force White Modulate" -msgstr "Forzar modulación hacia el blanco" +msgstr "Forzar Modulación en Blanco" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Include Gizmos (3D)" @@ -4446,15 +4445,15 @@ msgstr "Incluir Gizmos (3D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pin AnimationPlayer" -msgstr "Pinear el AnimationPlayer" +msgstr "Fijar AnimationPlayer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" -msgstr "Crear animación nueva" +msgstr "Crear Animación Nueva" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "Nombre de animación:" +msgstr "Nombre de Animación:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp @@ -4466,11 +4465,11 @@ msgstr "¡Error!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Times:" -msgstr "Tiempos de mezcla:" +msgstr "Tiempos de Mezcla:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Next (Auto Queue):" -msgstr "Siguiente (cola automática):" +msgstr "Siguiente (Cola Automática):" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Cross-Animation Blend Times" @@ -4487,7 +4486,7 @@ msgstr "Añadir Transición" #: editor/plugins/animation_state_machine_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Add Node" -msgstr "Añadir nodo" +msgstr "Añadir Nodo" #: editor/plugins/animation_state_machine_editor.cpp msgid "End" @@ -4537,7 +4536,7 @@ msgid "" msgstr "" "Seleccionar y mover nodos.\n" "Clic der. para agregar nuevos nodos.\n" -"Shift + clic izq. para crear conexiones." +"Shift + Clic Izq. para crear conexiones." #: editor/plugins/animation_state_machine_editor.cpp msgid "Create new nodes." @@ -4658,7 +4657,7 @@ msgstr "El árbol de animación no es correcto." #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Animation Node" -msgstr "Nodo de animación" +msgstr "Nodo de Animación" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "OneShot Node" @@ -4694,11 +4693,11 @@ msgstr "Nodo Transition" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Import Animations..." -msgstr "Importar animaciones..." +msgstr "Importar Animaciones..." #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Edit Node Filters" -msgstr "Editar filtros de nodo" +msgstr "Editar Filtros de Nodo" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Filters..." @@ -4710,7 +4709,7 @@ msgstr "Contenido:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "View Files" -msgstr "Ver archivos" +msgstr "Ver Archivos" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve hostname:" @@ -4878,7 +4877,7 @@ msgstr "Bake Lightmaps" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp msgid "Preview" -msgstr "Vista previa" +msgstr "Vista Previa" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" @@ -4886,19 +4885,19 @@ msgstr "Configurar Snap" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Grid Offset:" -msgstr "Desplazamiento de CuadrÃcula:" +msgstr "Grid Offset:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Grid Step:" -msgstr "Step de cuadrÃcula:" +msgstr "Grid Step:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Offset:" -msgstr "Desplazamiento de Rotación:" +msgstr "Offset de Rotación:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation Step:" -msgstr "Step de rotaciones:" +msgstr "Step de Rotación:" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move vertical guide" @@ -4910,7 +4909,7 @@ msgstr "Crear nueva guÃa vertical" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Remove vertical guide" -msgstr "Quitar guÃa vertical" +msgstr "Eliminar guÃa vertical" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move horizontal guide" @@ -4922,7 +4921,7 @@ msgstr "Crear nueva guÃa horizontal" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Remove horizontal guide" -msgstr "Quitar guÃa horizontal" +msgstr "Eliminar guÃa horizontal" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Create new horizontal and vertical guides" @@ -4969,6 +4968,8 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Cuando está activo, el movimiento de los nodos de Control cambian sus " +"anclajes en lugar de sus márgenes." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -4976,53 +4977,47 @@ msgstr "Sólo anclado" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change Anchors and Margins" -msgstr "Cambiar anclas y márgenes" +msgstr "Cambiar Anclas y Márgenes" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change Anchors" -msgstr "Cambiar anclas" +msgstr "Cambiar Anclas" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "Seleccionar" +msgstr "Bloqueo Seleccionado" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "Quitar seleccionados" +msgstr "Desbloquear Seleccionado" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Copiar Selección" +msgstr "Agrupar Seleccionados" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Copiar Selección" +msgstr "Desagrupar Seleccionados" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" -msgstr "Pegar pose" +msgstr "Pegar Pose" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" -msgstr "Crear Hueso(s) Personalizados a partir de Nodo(s)" +msgstr "Crear Hueso(s) Personalizado(s) a partir de Nodo(s)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "Restablecer pose" +msgstr "Limpiar Huesos" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" -msgstr "Crear cadena IK" +msgstr "Crear Cadena IK" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear IK Chain" @@ -5044,7 +5039,7 @@ msgstr "Resetear el Zoom" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Select Mode" -msgstr "Modo de selección" +msgstr "Modo de Selección" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Drag: Rotate" @@ -5057,8 +5052,8 @@ msgstr "Alt+Arrastrar: Mover" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." msgstr "" -"Presiona 'v' para Cambiar el Pivote, 'Shift+v' para Arrastrar el Pivote (al " -"mover)." +"Presiona 'v' para Cambiar el Pivote, 'Shift + v' para Arrastrar el Pivote " +"(al mover)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+RMB: Depth list selection" @@ -5066,15 +5061,15 @@ msgstr "Alt + Clic Derecho: Selección en listado de solapamientos" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move Mode" -msgstr "Modo movimiento" +msgstr "Modo Movimiento" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotate Mode" -msgstr "Modo rotación" +msgstr "Modo Rotación" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Scale Mode" -msgstr "Modo de Escalado" +msgstr "Modo Escalado" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5096,7 +5091,7 @@ msgstr "Modo desplazamiento lateral" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Toggle snapping." -msgstr "Act/Desact. alineado." +msgstr "Act./Desact. alineado." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Snap" @@ -5107,9 +5102,8 @@ msgid "Snapping Options" msgstr "Opciones de Alineado" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" -msgstr "Alinear a la cuadrÃcula" +msgstr "Ajustar en Grid" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" @@ -5122,66 +5116,59 @@ msgstr "Configurar Snap..." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap Relative" -msgstr "Usar Snap Relativo" +msgstr "Snap Relativo" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Pixel Snap" msgstr "Usar Pixel Snap" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" -msgstr "Fijado inteligente" +msgstr "Ajuste Inteligente" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" -msgstr "Alinear al Padre" +msgstr "Ajustar al Padre" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" -msgstr "Alinear al ancla de nodo" +msgstr "Ajustar al Ancla de Nodo" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" -msgstr "Alinear a los lados del nodo" +msgstr "Ajustar a los Lados del Nodo" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" -msgstr "Alinear al centro del nodo" +msgstr "Ajustar al Centro del Nodo" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" -msgstr "Alinear a otros nodos" +msgstr "Ajustar a Otros Nodos" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" -msgstr "Alinear a guÃas" +msgstr "Ajustar a las GuÃas" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock the selected object in place (can't be moved)." -msgstr "Inmovilizar el objeto." +msgstr "Bloquear el objeto seleccionado en su sitio (no se puede mover)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Unlock the selected object (can be moved)." -msgstr "Liberar objeto inmovilizado." +msgstr "Desbloquear el objeto seleccionado (puede ser movido)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Makes sure the object's children are not selectable." -msgstr "Asegurarse que los hijos de un objeto no sean seleccionables." +msgstr "Asegura que los hijos del objeto no sean seleccionables." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Restores the object's children's ability to be selected." -msgstr "Restaurar la habilidad de seleccionar los hijos de un objeto." +msgstr "Restaura la capacidad de selección de los hijos del objeto." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Skeleton Options" @@ -5189,7 +5176,7 @@ msgstr "Opciones de Esqueleto" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Bones" -msgstr "Mostrar huesos" +msgstr "Mostrar Huesos" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make Custom Bone(s) from Node(s)" @@ -5207,44 +5194,43 @@ msgstr "Ver" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Show Grid" -msgstr "Mostrar cuadrÃcula" +msgstr "Ver Grid" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Helpers" -msgstr "Mostrar ayudas" +msgstr "Ver Ayudas" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Rulers" -msgstr "Mostrar reglas" +msgstr "Ver Reglas" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Guides" -msgstr "Mostrar guÃas" +msgstr "Ver GuÃas" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Origin" -msgstr "Ver origen" +msgstr "Ver Origen" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Viewport" -msgstr "Ver viewport" +msgstr "Ver Viewport" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Group And Lock Icons" -msgstr "Mostrar Grupo y Bloquear Iconos" +msgstr "Ver Grupo y Bloquear Iconos" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" -msgstr "Centrar selección" +msgstr "Centrar Selección" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Frame Selection" -msgstr "Encuadrar selección" +msgstr "Encuadrar Selección" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Preview Canvas Scale" -msgstr "Vista previa del atlas" +msgstr "Previsualización de la Escala del Lienzo" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -5285,24 +5271,23 @@ msgstr "Insertar clave (pistas existentes)" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Copy Pose" -msgstr "Copiar pose" +msgstr "Copiar Pose" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Pose" -msgstr "Restablecer pose" +msgstr "Limpiar Pose" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Multiply grid step by 2" -msgstr "Multiplicar step de cuadrÃcula por 2" +msgstr "Multiplicar grid step por 2" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Divide grid step by 2" -msgstr "Dividir step de cuadrÃcula por 2" +msgstr "Dividir grid step por 2" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Pan View" -msgstr "Vista posterior" +msgstr "Vista Panorámica" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" @@ -5319,7 +5304,7 @@ msgstr "No se pueden instanciar varios nodos sin un nodo raÃz." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Create Node" -msgstr "Crear nodo" +msgstr "Crear Nodo" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp @@ -5327,17 +5312,16 @@ msgid "Error instancing scene from %s" msgstr "Error al instanciar escena desde %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" -msgstr "Cambiar tipo por defecto" +msgstr "Cambiar Tipo por Defecto" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" "Drag & drop + Shift : Add node as sibling\n" "Drag & drop + Alt : Change node type" msgstr "" -"Arrastrar y soltar + Shift : Añadir nodo como hermano\n" -"Arrastrar y soltar + Alt : Cambiar tipo de nodo" +"Arrastrar y Soltar + Shift : Añadir nodo como hermano\n" +"Arrastrar y Soltar + Alt : Cambiar tipo de nodo" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Create Polygon3D" @@ -5345,15 +5329,15 @@ msgstr "Crear Polygon3D" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly" -msgstr "Editar polÃgono" +msgstr "Editar PolÃgono" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly (Remove Point)" -msgstr "Editar polÃgono (quitar punto)" +msgstr "Editar PolÃgono (Eliminar Punto)" #: editor/plugins/collision_shape_2d_editor_plugin.cpp msgid "Set Handle" -msgstr "Establecer handle" +msgstr "Establecer Handle" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5368,7 +5352,14 @@ msgstr "No hay pÃxeles con transparencia > 128 en la imagen..." #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Load Emission Mask" -msgstr "Cargar máscara de emisión" +msgstr "Cargar Máscara de Emisión" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Restart" +msgstr "Reiniciar" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5384,7 +5375,7 @@ msgstr "PartÃculas" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generated Point Count:" -msgstr "Conteo de puntos generados:" +msgstr "Conteo de Puntos Generados:" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5408,83 +5399,76 @@ msgstr "CPUParticles" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Mesh" -msgstr "Crear Puntos de Emisión desde Mesh" +msgstr "Crear Puntos de Emisión Desde Mesh" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Node" -msgstr "Crear puntos de emisión desde el nodo" +msgstr "Crear Puntos de Emisión Desde el Nodo" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "Flat0" +msgstr "Flat 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "Flat1" +msgstr "Flat 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" -msgstr "Transición entrada" +msgstr "Ease In" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease Out" -msgstr "Transición salida" +msgstr "Ease Out" #: editor/plugins/curve_editor_plugin.cpp msgid "Smoothstep" -msgstr "Paso suavizado" +msgstr "Smoothstep" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Point" -msgstr "Modificar punto de la curva" +msgstr "Modificar Punto de Curva" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Tangent" -msgstr "Modificar tangente de la curva" +msgstr "Modificar Tangente de Curva" #: editor/plugins/curve_editor_plugin.cpp msgid "Load Curve Preset" -msgstr "Cargar ajuste predeterminado de curva" +msgstr "Cargar Preset de Curva" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" -msgstr "Añadir punto" +msgstr "Añadir Punto" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" -msgstr "Quitar punto" +msgstr "Eliminar Punto" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" -msgstr "Izquierda lineal" +msgstr "Izquierda Lineal" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" -msgstr "Derecha lineal" +msgstr "Derecha Lineal" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" -msgstr "Cargar ajuste predeterminado" +msgstr "Cargar Ajuste Predeterminado" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove Curve Point" -msgstr "Quitar punto de la curva" +msgstr "Eliminar Punto de Curva" #: editor/plugins/curve_editor_plugin.cpp msgid "Toggle Curve Linear Tangent" -msgstr "Act/desact. curva de tangente lineal" +msgstr "Act./Desact. Curva de Tangente Lineal" #: editor/plugins/curve_editor_plugin.cpp msgid "Hold Shift to edit tangents individually" -msgstr "Mantén Mayús para editar las tangentes individualmente" +msgstr "Mantén Shift para editar las tangentes individualmente" #: editor/plugins/gi_probe_editor_plugin.cpp msgid "Bake GI Probe" @@ -5504,11 +5488,11 @@ msgstr "Elementos" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item List Editor" -msgstr "Editor de lista de elementos" +msgstr "Editor de Lista de Items" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Occluder Polygon" -msgstr "Crear polÃgono oclusor" +msgstr "Crear PolÃgono Oclusor" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh is empty!" @@ -5516,33 +5500,31 @@ msgstr "¡El Mesh está vacÃo!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" -msgstr "Crear cuerpo estático \"Trimesh\"" +msgstr "Crear Static Trimesh Body" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Convex Body" -msgstr "Crear cuerpo estático convexo" +msgstr "Crear Static Convex Body" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "This doesn't work on scene root!" msgstr "¡No puedes hacer esto en una escena raÃz!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Crear forma triangular" +msgstr "Crear Forma Estática de Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "¡Falló en la creación de los shapes!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "Crear forma convexa" +msgstr "Crear Shape(s) Convexo(s)" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" -msgstr "Crear Mesh de Navegación" +msgstr "Crear Navigation Mesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Contained Mesh is not of type ArrayMesh." @@ -5575,11 +5557,11 @@ msgstr "¡El tipo primitivo de mesh no es PRIMITIVE_TRIANGLES!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Could not create outline!" -msgstr "¡No se pudo crear el contorno!" +msgstr "¡No se pudo crear el outline!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline" -msgstr "Crear contorno" +msgstr "Crear Outline" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh" @@ -5587,16 +5569,15 @@ msgstr "Mesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" -msgstr "Crear cuerpo estático triangular" +msgstr "Crear Trimesh Static Body" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Collision Sibling" -msgstr "Crear colisión hermanada triangular" +msgstr "Crear Trimesh Collision Hermano" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Collision Sibling(s)" -msgstr "Crear colisión hermanada convexa" +msgstr "Crear Convex Collision Hermano(s)" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." @@ -5620,7 +5601,7 @@ msgstr "Crear Outline Mesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Outline Size:" -msgstr "Tamaño del contorno:" +msgstr "Tamaño del Outline:" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Remove item %d?" @@ -5629,7 +5610,7 @@ msgstr "¿Quieres borrar el elemento %d?" #: editor/plugins/mesh_library_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp msgid "Add Item" -msgstr "Añadir elemento" +msgstr "Añadir Item" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Remove Selected Item" @@ -5714,15 +5695,15 @@ msgstr "Mesh de Origen:" #: editor/plugins/multimesh_editor_plugin.cpp msgid "X-Axis" -msgstr "Eje X" +msgstr "Eje-X" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Y-Axis" -msgstr "Eje Y" +msgstr "Eje-Y" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Z-Axis" -msgstr "Eje Z" +msgstr "Eje-Z" #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh Up Axis:" @@ -5760,7 +5741,7 @@ msgstr "Generando Rect. de Visibilidad" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generate Visibility Rect" -msgstr "Generar rectángulo de visibilidad" +msgstr "Generar Rect. de Visibilidad" #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Can only set point into a ParticlesMaterial process material" @@ -5770,7 +5751,7 @@ msgstr "" #: editor/plugins/particles_2d_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Generation Time (sec):" -msgstr "Tiempo de generación (seg):" +msgstr "Tiempo de Generación (seg):" #: editor/plugins/particles_editor_plugin.cpp msgid "Faces contain no area!" @@ -5782,7 +5763,7 @@ msgstr "¡Sin caras!" #: editor/plugins/particles_editor_plugin.cpp msgid "Node does not contain geometry." -msgstr "El nodo no posee geometrÃa." +msgstr "El nodo no tiene geometrÃa." #: editor/plugins/particles_editor_plugin.cpp msgid "Node does not contain geometry (faces)." @@ -5790,15 +5771,15 @@ msgstr "El nodo no posee geometrÃa (caras)." #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emitter" -msgstr "Crear emisor" +msgstr "Crear Emisor" #: editor/plugins/particles_editor_plugin.cpp msgid "Emission Points:" -msgstr "Puntos de emisión:" +msgstr "Puntos de Emisión:" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points" -msgstr "Puntos de la superficie" +msgstr "Puntos de Superficie" #: editor/plugins/particles_editor_plugin.cpp msgid "Surface Points+Normal (Directed)" @@ -5810,7 +5791,7 @@ msgstr "Volumen" #: editor/plugins/particles_editor_plugin.cpp msgid "Emission Source: " -msgstr "Fuente de emisión: " +msgstr "Fuente de Emisión: " #: editor/plugins/particles_editor_plugin.cpp msgid "A processor material of type 'ParticlesMaterial' is required." @@ -5830,7 +5811,7 @@ msgstr "Generar AABB" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Point from Curve" -msgstr "Borrar punto de la curva" +msgstr "Borrar Punto de la Curva" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Remove Out-Control from Curve" @@ -5843,7 +5824,7 @@ msgstr "Eliminar \"In-Control\" de la curva" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Add Point to Curve" -msgstr "Añadir punto a curva" +msgstr "Añadir Punto a Curva" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Split Curve" @@ -5864,12 +5845,12 @@ msgstr "Mover Out-Control en curva" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Select Points" -msgstr "Seleccionar puntos" +msgstr "Seleccionar Puntos" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Shift+Drag: Select Control Points" -msgstr "Mayús + arrastrar: Seleccionar puntos de control" +msgstr "Shift + Arrastrar: Seleccionar puntos de control" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp @@ -5883,11 +5864,11 @@ msgstr "Clic Izquierdo: Partir Segmento (en curva)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Right Click: Delete Point" -msgstr "Clic derecho: Eliminar punto" +msgstr "Clic derecho: Eliminar Punto" #: editor/plugins/path_2d_editor_plugin.cpp msgid "Select Control Points (Shift+Drag)" -msgstr "Seleccionar puntos de control (Mayús + arrastrar)" +msgstr "Seleccionar puntos de control (Shift + Arrastrar)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp @@ -5897,12 +5878,12 @@ msgstr "Añadir punto (en espacio vacÃo)" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Delete Point" -msgstr "Eliminar punto" +msgstr "Eliminar Punto" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Close Curve" -msgstr "Cerrar curva" +msgstr "Cerrar Curva" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp @@ -5922,44 +5903,43 @@ msgstr "Manejadores de Tamaño de Espejo" #: editor/plugins/path_editor_plugin.cpp msgid "Curve Point #" -msgstr "Punto de curva #" +msgstr "Punto de Curva #" #: editor/plugins/path_editor_plugin.cpp msgid "Set Curve Point Position" -msgstr "Establecer posición de punto de curva" +msgstr "Establecer Posición de Punto de Curva" #: editor/plugins/path_editor_plugin.cpp msgid "Set Curve In Position" -msgstr "Establecer posición de entrada de curva" +msgstr "Establecer Posición de Entrada de Curva" #: editor/plugins/path_editor_plugin.cpp msgid "Set Curve Out Position" -msgstr "Establecer posición de salida de curva" +msgstr "Establecer Posición de Salida de Curva" #: editor/plugins/path_editor_plugin.cpp msgid "Split Path" -msgstr "Dividir ruta" +msgstr "Dividir Ruta" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Path Point" -msgstr "Quitar punto de ruta" +msgstr "Eliminar Punto de Ruta" #: editor/plugins/path_editor_plugin.cpp msgid "Remove Out-Control Point" -msgstr "Eliminar punto Out-Control" +msgstr "Eliminar Punto Out-Control" #: editor/plugins/path_editor_plugin.cpp msgid "Remove In-Control Point" -msgstr "Eliminar punto In-Control" +msgstr "Eliminar Punto In-Control" #: editor/plugins/path_editor_plugin.cpp msgid "Split Segment (in curve)" -msgstr "Dividir segmento (en curva)" +msgstr "Dividir Segmento (en curva)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" -msgstr "Mover unión" +msgstr "Mover Unión" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" @@ -5980,7 +5960,7 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create UV Map" -msgstr "Crear mapa UV" +msgstr "Crear Mapa UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" @@ -5996,11 +5976,11 @@ msgstr "Crear PolÃgono y UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create Internal Vertex" -msgstr "Crear vértice interno" +msgstr "Crear Vértice Interno" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Remove Internal Vertex" -msgstr "Eliminar vértice interno" +msgstr "Eliminar Vértice Interno" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Invalid Polygon (need 3 different vertices)" @@ -6008,11 +5988,11 @@ msgstr "PolÃgono no válido (necesita 3 vértices diferentes)" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Add Custom Polygon" -msgstr "Añadir polÃgono personalizado" +msgstr "Añadir PolÃgono Personalizado" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Remove Custom Polygon" -msgstr "Eliminar polÃgono personalizado" +msgstr "Eliminar PolÃgono Personalizado" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Transform UV Map" @@ -6060,23 +6040,23 @@ msgstr "Ctrl: Rotar" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift: Move All" -msgstr "Mayús: Mover todos" +msgstr "Shift: Mover todos" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Shift+Ctrl: Scale" -msgstr "Mayús + Ctrl: Escalar" +msgstr "Shift + Ctrl: Escalar" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Move Polygon" -msgstr "Mover polÃgono" +msgstr "Mover PolÃgono" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Rotate Polygon" -msgstr "Rotar polÃgono" +msgstr "Rotar PolÃgono" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Scale Polygon" -msgstr "Escalar polÃgono" +msgstr "Escalar PolÃgono" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create a custom polygon. Enables custom polygon rendering." @@ -6118,7 +6098,7 @@ msgstr "Limpiar UV" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid Settings" -msgstr "Ajustes de cuadrÃcula" +msgstr "Configuración del Grid" #: editor/plugins/polygon_2d_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -6131,27 +6111,27 @@ msgstr "Activar Snap" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid" -msgstr "CuadrÃcula" +msgstr "Grid" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Configure Grid:" -msgstr "Configurar cuadrÃcula:" +msgstr "Configurar Grid:" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid Offset X:" -msgstr "Desplazamiento de CuadrÃcula en X:" +msgstr "Grid Offset X:" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid Offset Y:" -msgstr "Desplazamiento de CuadrÃcula en Y:" +msgstr "Grid Offset Y:" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid Step X:" -msgstr "Step de cuadrÃcula en X:" +msgstr "Grid Step X:" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Grid Step Y:" -msgstr "Step de cuadrÃcula en Y:" +msgstr "Grid Step Y:" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Sync Bones to Polygon" @@ -6163,16 +6143,16 @@ msgstr "¡ERROR: No se pudo cargar el recurso!" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Add Resource" -msgstr "Añadir recurso" +msgstr "Añadir Recurso" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Rename Resource" -msgstr "Renombrar recurso" +msgstr "Renombrar Recurso" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Delete Resource" -msgstr "Eliminar recurso" +msgstr "Eliminar Recurso" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Resource clipboard is empty!" @@ -6180,7 +6160,7 @@ msgstr "¡El portapapeles de recursos está vacÃo!" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Paste Resource" -msgstr "Pegar recurso" +msgstr "Pegar Recurso" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/scene_tree_editor.cpp @@ -6196,15 +6176,15 @@ msgstr "Tipo:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp msgid "Open in Editor" -msgstr "Abrir en el editor" +msgstr "Abrir en el Editor" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Load Resource" -msgstr "Cargar recurso" +msgstr "Cargar Recurso" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "ResourcePreloader" -msgstr "Precargador de recursos" +msgstr "Precargador de Recursos" #: editor/plugins/root_motion_editor_plugin.cpp msgid "AnimationTree has no path set to an AnimationPlayer" @@ -6216,7 +6196,7 @@ msgstr "La ruta al AnimationPlayer es inválida" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Files" -msgstr "Limpiar lista archivos recientes" +msgstr "Limpiar Archivos Recientes" #: editor/plugins/script_editor_plugin.cpp msgid "Close and save changes?" @@ -6260,15 +6240,15 @@ msgstr "Nuevo TextFile..." #: editor/plugins/script_editor_plugin.cpp msgid "Open File" -msgstr "Abrir archivo" +msgstr "Abrir Archivo" #: editor/plugins/script_editor_plugin.cpp msgid "Save File As..." -msgstr "Guardar archivo como..." +msgstr "Guardar Archivo Como..." #: editor/plugins/script_editor_plugin.cpp msgid "Import Theme" -msgstr "Importar tema" +msgstr "Importar Tema" #: editor/plugins/script_editor_plugin.cpp msgid "Error while saving theme" @@ -6280,7 +6260,7 @@ msgstr "Error al guardar" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme As..." -msgstr "Guardar tema como..." +msgstr "Guardar Tema Como..." #: editor/plugins/script_editor_plugin.cpp msgid "%s Class Reference" @@ -6289,13 +6269,21 @@ msgstr "%s Referencia de Clase" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp msgid "Find Next" -msgstr "Buscar siguiente" +msgstr "Buscar Siguiente" + +#: editor/plugins/script_editor_plugin.cpp +msgid "Filter scripts" +msgstr "Filtrar scripts" #: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "Alternar la ordenación alfabética de la lista de métodos." #: editor/plugins/script_editor_plugin.cpp +msgid "Filter methods" +msgstr "Filtrar métodos" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Ordenar" @@ -6329,7 +6317,7 @@ msgstr "Abrir..." #: editor/plugins/script_editor_plugin.cpp msgid "Save All" -msgstr "Guardar todo" +msgstr "Guardar Todo" #: editor/plugins/script_editor_plugin.cpp msgid "Soft Reload Script" @@ -6337,7 +6325,7 @@ msgstr "Recargar parcialmente el script" #: editor/plugins/script_editor_plugin.cpp msgid "Copy Script Path" -msgstr "Copiar ruta del script" +msgstr "Copiar Ruta del Script" #: editor/plugins/script_editor_plugin.cpp msgid "History Previous" @@ -6345,7 +6333,7 @@ msgstr "Previo en Historial" #: editor/plugins/script_editor_plugin.cpp msgid "History Next" -msgstr "Siguiente en el historial" +msgstr "Siguiente en el Historial" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp @@ -6358,19 +6346,19 @@ msgstr "Importar Tema..." #: editor/plugins/script_editor_plugin.cpp msgid "Reload Theme" -msgstr "Recargar tema" +msgstr "Recargar Tema" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme" -msgstr "Guardar tema" +msgstr "Guardar Tema" #: editor/plugins/script_editor_plugin.cpp msgid "Close Docs" -msgstr "Cerrar documentación" +msgstr "Cerrar Documentación" #: editor/plugins/script_editor_plugin.cpp msgid "Close All" -msgstr "Cerrar todo" +msgstr "Cerrar Todo" #: editor/plugins/script_editor_plugin.cpp editor/project_manager.cpp msgid "Run" @@ -6378,7 +6366,7 @@ msgstr "Ejecutar" #: editor/plugins/script_editor_plugin.cpp msgid "Toggle Scripts Panel" -msgstr "Act/desact. panel de scripts" +msgstr "Act./Desact. Panel de Scripts" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Step Over" @@ -6399,25 +6387,23 @@ msgstr "Continuar" #: editor/plugins/script_editor_plugin.cpp msgid "Keep Debugger Open" -msgstr "Mantener el depurador abierto" +msgstr "Mantener el Depurador Abierto" #: editor/plugins/script_editor_plugin.cpp msgid "Debug with External Editor" msgstr "Depurar con Editor Externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Abrir documentación online de Godot" +msgstr "Abrir la documentación en lÃnea de Godot." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" msgstr "Solicitar Documentos" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "Ayuda a mejorar la documentación de Godot dando feedback" +msgstr "Ayuda a mejorar la documentación de Godot aportando retroalimentación." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6446,12 +6432,12 @@ msgstr "" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Reload" -msgstr "Volver a cargar" +msgstr "Recargar" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/shader_editor_plugin.cpp msgid "Resave" -msgstr "Volver a guardar" +msgstr "Volver a Guardar" #: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp msgid "Debugger" @@ -6462,29 +6448,27 @@ msgid "Search Results" msgstr "Resultados de la Búsqueda" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "Conectar a nodo:" +msgstr "Conexiones al método:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Fuente:" +msgstr "Fuente" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Señales" +msgstr "Señal" #: editor/plugins/script_text_editor.cpp msgid "Target" msgstr "Objetivo" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "Nada conectado a la entrada '%s' del nodo '%s'." +msgstr "" +"Falta el método de conexión '%s' para la señal '%s' del nodo '%s' al nodo " +"'%s'." #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6508,11 +6492,11 @@ msgstr "Buscar SÃmbolo" #: editor/plugins/script_text_editor.cpp msgid "Pick Color" -msgstr "Seleccionar color" +msgstr "Seleccionar Color" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Convert Case" -msgstr "Convertir Mayús/Minúsculas" +msgstr "Convertir Mayúsculas y Minúsculas" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Uppercase" @@ -6524,86 +6508,86 @@ msgstr "Minúscula" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Capitalize" -msgstr "Poner en mayúsculas" +msgstr "Capitalizar" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Syntax Highlighter" -msgstr "Resaltador de sintaxis" +msgstr "Resaltador de Sintaxis" + +#: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "Marcadores" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Crear puntos." #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Cortar" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Seleccionar todo" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" -msgstr "Eliminar lÃnea" +msgstr "Eliminar LÃnea" #: editor/plugins/script_text_editor.cpp msgid "Indent Left" -msgstr "Indentar a la izquierda" +msgstr "Indentar a la Izquierda" #: editor/plugins/script_text_editor.cpp msgid "Indent Right" -msgstr "Indentar a la derecha" +msgstr "Indentar a la Derecha" #: editor/plugins/script_text_editor.cpp msgid "Toggle Comment" -msgstr "Act/desact. comentario" +msgstr "Act./Desact. Comentario" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "Act/desact. Vista Libre" +msgstr "Act./Desact. Marcador" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "Ir al Siguente Breakpoint" +msgstr "Ir al Siguiente Marcador" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Previous Bookmark" -msgstr "Ir al Breakpoint Anterior" +msgstr "Ir al Marcador Anterior" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "Quitar todos los elementos" +msgstr "Eliminar Todos los Marcadores" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" -msgstr "Plegar/Desplegar lÃnea" +msgstr "Plegar/Desplegar LÃnea" #: editor/plugins/script_text_editor.cpp msgid "Fold All Lines" -msgstr "Plegar todas las lÃneas" +msgstr "Plegar Todas las LÃneas" #: editor/plugins/script_text_editor.cpp msgid "Unfold All Lines" -msgstr "Desplegar todas las lÃneas" +msgstr "Desplegar Todas las LÃneas" #: editor/plugins/script_text_editor.cpp msgid "Clone Down" -msgstr "Clonar hacia abajo" +msgstr "Clonar Hacia Abajo" #: editor/plugins/script_text_editor.cpp msgid "Complete Symbol" -msgstr "Completar sÃmbolo" +msgstr "Completar SÃmbolo" #: editor/plugins/script_text_editor.cpp msgid "Trim Trailing Whitespace" -msgstr "Borrar espacios sobrantes al final" +msgstr "Eliminar Espacios Sobrantes al Final" #: editor/plugins/script_text_editor.cpp msgid "Convert Indent to Spaces" @@ -6620,11 +6604,11 @@ msgstr "Autoindentar" #: editor/plugins/script_text_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Toggle Breakpoint" -msgstr "Act/desact. Breakpoint" +msgstr "Act./Desact. Breakpoint" #: editor/plugins/script_text_editor.cpp msgid "Remove All Breakpoints" -msgstr "Borrar todos los Breakpoints" +msgstr "Eliminar Todos los Breakpoints" #: editor/plugins/script_text_editor.cpp msgid "Go to Next Breakpoint" @@ -6636,7 +6620,7 @@ msgstr "Ir al Breakpoint Anterior" #: editor/plugins/script_text_editor.cpp msgid "Find Previous" -msgstr "Buscar anterior" +msgstr "Buscar Anterior" #: editor/plugins/script_text_editor.cpp msgid "Find in Files..." @@ -6652,16 +6636,15 @@ msgstr "Ir a LÃnea..." #: editor/plugins/script_text_editor.cpp msgid "Contextual Help" -msgstr "Ayuda contextual" +msgstr "Ayuda Contextual" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"Los siguientes archivos son nuevos en disco.\n" -"¿Qué es lo que quieres hacer?:" +"Este shader ha sido modificado en disco.\n" +"¿Qué acciones deben tomarse?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -6685,11 +6668,11 @@ msgstr "Skeleton2D" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Make Rest Pose (From Bones)" -msgstr "Crear Pose de Descanso (De los Huesos)" +msgstr "Crear Pose de Descanso (Desde Huesos)" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Set Bones to Rest Pose" -msgstr "Establecer Huesos a la Pose de Descanso" +msgstr "Asignar Pose de Descanso a Huesos" #: editor/plugins/skeleton_editor_plugin.cpp msgid "Create physical bones" @@ -6717,23 +6700,23 @@ msgstr "Perspectiva" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Aborted." -msgstr "Se ha cancelado la transformación." +msgstr "Transformación Abortada." #: editor/plugins/spatial_editor_plugin.cpp msgid "X-Axis Transform." -msgstr "Transformación en el eje X." +msgstr "Transformación en Eje-X." #: editor/plugins/spatial_editor_plugin.cpp msgid "Y-Axis Transform." -msgstr "Transformación en el eje Y." +msgstr "Transformación en Eje-Y." #: editor/plugins/spatial_editor_plugin.cpp msgid "Z-Axis Transform." -msgstr "Transformación en el eje Z." +msgstr "Transformación en Eje-Z." #: editor/plugins/spatial_editor_plugin.cpp msgid "View Plane Transform." -msgstr "Ver transformación de plano." +msgstr "Ver Transformación en Plano." #: editor/plugins/spatial_editor_plugin.cpp msgid "Scaling: " @@ -6741,11 +6724,11 @@ msgstr "Escalado: " #: editor/plugins/spatial_editor_plugin.cpp msgid "Translating: " -msgstr "Trasladando: " +msgstr "Trasladar: " #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotating %s degrees." -msgstr "Girando %s grados." +msgstr "Rotando %s grados." #: editor/plugins/spatial_editor_plugin.cpp msgid "Keying is disabled (no key inserted)." @@ -6765,23 +6748,23 @@ msgstr "Yaw" #: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" -msgstr "Objetos dibujados" +msgstr "Objetos Dibujados" #: editor/plugins/spatial_editor_plugin.cpp msgid "Material Changes" -msgstr "Cambios del material" +msgstr "Cambios del Material" #: editor/plugins/spatial_editor_plugin.cpp msgid "Shader Changes" -msgstr "Cambios del shader" +msgstr "Cambios del Shader" #: editor/plugins/spatial_editor_plugin.cpp msgid "Surface Changes" -msgstr "Cambios de superficie" +msgstr "Cambios de Superficie" #: editor/plugins/spatial_editor_plugin.cpp msgid "Draw Calls" -msgstr "Llamadas de dibujado" +msgstr "Llamadas de Dibujado" #: editor/plugins/spatial_editor_plugin.cpp msgid "Vertices" @@ -6789,11 +6772,11 @@ msgstr "Vértices" #: editor/plugins/spatial_editor_plugin.cpp msgid "Top View." -msgstr "Vista superior." +msgstr "Vista Superior." #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom View." -msgstr "Vista inferior." +msgstr "Vista Inferior." #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom" @@ -6801,7 +6784,7 @@ msgstr "Abajo" #: editor/plugins/spatial_editor_plugin.cpp msgid "Left View." -msgstr "Vista izquierda." +msgstr "Vista Izquierda." #: editor/plugins/spatial_editor_plugin.cpp msgid "Left" @@ -6845,35 +6828,35 @@ msgstr "Esta operación requiere un solo nodo seleccionado." #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock View Rotation" -msgstr "Bloquear rotación de vista" +msgstr "Bloquear Rotación de Vista" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Normal" -msgstr "Mostrar normales" +msgstr "Mostrar Normal" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Wireframe" -msgstr "Mostrar polÃgonos" +msgstr "Mostrar Wireframe" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Overdraw" -msgstr "Mostrar superposiciones" +msgstr "Mostrar Overdraw" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Unshaded" -msgstr "Mostrar sin sombra" +msgstr "Mostrar Sin Sombreado" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Environment" -msgstr "Ver entorno" +msgstr "Ver Entorno" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Gizmos" -msgstr "Ver gizmos" +msgstr "Ver Gizmos" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Information" -msgstr "Ver información" +msgstr "Ver Información" #: editor/plugins/spatial_editor_plugin.cpp msgid "View FPS" @@ -6881,11 +6864,11 @@ msgstr "Ver FPS" #: editor/plugins/spatial_editor_plugin.cpp msgid "Half Resolution" -msgstr "Media resolución" +msgstr "Media Resolución" #: editor/plugins/spatial_editor_plugin.cpp msgid "Audio Listener" -msgstr "Oyente de audio" +msgstr "Oyente de Audio" #: editor/plugins/spatial_editor_plugin.cpp msgid "Doppler Enable" @@ -6893,35 +6876,35 @@ msgstr "Activar Doppler" #: editor/plugins/spatial_editor_plugin.cpp msgid "Cinematic Preview" -msgstr "Vista previa cinemática" +msgstr "Vista Previa Cinemática" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Left" -msgstr "Vista libre izquierda" +msgstr "Vista Libre Izquierda" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Right" -msgstr "Vista libre derecha" +msgstr "Vista Libre Derecha" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Forward" -msgstr "Vista libre frontal" +msgstr "Vista Libre Frontal" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Backwards" -msgstr "Vista libre posterior" +msgstr "Vista Libre Posterior" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Up" -msgstr "Vista libre arriba" +msgstr "Vista Libre Arriba" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Down" -msgstr "Vista libre abajo" +msgstr "Vista Libre Abajo" #: editor/plugins/spatial_editor_plugin.cpp msgid "Freelook Speed Modifier" -msgstr "Modificador de velocidad de vista libre" +msgstr "Modificador de Velocidad de Vista Libre" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -6945,7 +6928,7 @@ msgstr "Ajustar Nodos al Suelo" #: editor/plugins/spatial_editor_plugin.cpp msgid "Select Mode (Q)" -msgstr "Modo de selección (Q)" +msgstr "Modo de Selección (Q)" #: editor/plugins/spatial_editor_plugin.cpp msgid "" @@ -6959,23 +6942,23 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Move Mode (W)" -msgstr "Modo movimiento (W)" +msgstr "Modo Movimiento (W)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotate Mode (E)" -msgstr "Modo rotación (E)" +msgstr "Modo Rotación (E)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale Mode (R)" -msgstr "Modo escalado (R)" +msgstr "Modo Escalado (R)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Local Coords" -msgstr "Coordenadas locales" +msgstr "Coordenadas Locales" #: editor/plugins/spatial_editor_plugin.cpp msgid "Local Space Mode (%s)" -msgstr "Modo de espacio local (%s)" +msgstr "Modo de Espacio Local (%s)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Mode (%s)" @@ -6983,68 +6966,67 @@ msgstr "Modo de Snap (%s)" #: editor/plugins/spatial_editor_plugin.cpp msgid "Bottom View" -msgstr "Vista inferior" +msgstr "Vista Inferior" #: editor/plugins/spatial_editor_plugin.cpp msgid "Top View" -msgstr "Vista superior" +msgstr "Vista Superior" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rear View" -msgstr "Vista posterior" +msgstr "Vista Posterior" #: editor/plugins/spatial_editor_plugin.cpp msgid "Front View" -msgstr "Vista frontal" +msgstr "Vista Frontal" #: editor/plugins/spatial_editor_plugin.cpp msgid "Left View" -msgstr "Vista izquierda" +msgstr "Vista Izquierda" #: editor/plugins/spatial_editor_plugin.cpp msgid "Right View" -msgstr "Vista derecha" +msgstr "Vista Derecha" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" -msgstr "Intercambiar vista perspectiva/ortogonal" +msgstr "Cambiar Vista Perspectiva/Ortogonal" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" -msgstr "Insertar clave de animación" +msgstr "Insertar Clave de Animación" #: editor/plugins/spatial_editor_plugin.cpp msgid "Focus Origin" -msgstr "Enfocar origen" +msgstr "Foco en Origen" #: editor/plugins/spatial_editor_plugin.cpp msgid "Focus Selection" -msgstr "Enfocar selección" +msgstr "Foco en Selección" #: editor/plugins/spatial_editor_plugin.cpp msgid "Align Selection With View" -msgstr "Alinear selección con visor" +msgstr "Alinear Selección Con Vista" #: editor/plugins/spatial_editor_plugin.cpp msgid "Tool Select" -msgstr "Seleccionar" +msgstr "Seleccionar Herramienta" #: editor/plugins/spatial_editor_plugin.cpp msgid "Tool Move" -msgstr "Mover" +msgstr "Herramienta Mover" #: editor/plugins/spatial_editor_plugin.cpp msgid "Tool Rotate" -msgstr "Rotar" +msgstr "Herramienta Rotar" #: editor/plugins/spatial_editor_plugin.cpp msgid "Tool Scale" -msgstr "Escalar" +msgstr "Herramienta Escalar" #: editor/plugins/spatial_editor_plugin.cpp msgid "Toggle Freelook" -msgstr "Act/desact. Vista Libre" +msgstr "Act./Desact. Vista Libre" #: editor/plugins/spatial_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7052,9 +7034,8 @@ msgid "Transform" msgstr "Transformar" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" -msgstr "Ajustar objeto al suelo" +msgstr "Ajustar Objeto al Suelo" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Dialog..." @@ -7090,16 +7071,16 @@ msgstr "Gizmos" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Origin" -msgstr "Ver origen" +msgstr "Ver Origen" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Grid" -msgstr "Ver cuadrÃcula" +msgstr "Ver Grid" #: editor/plugins/spatial_editor_plugin.cpp #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Settings" -msgstr "Ajustes" +msgstr "Configuración" #: editor/plugins/spatial_editor_plugin.cpp msgid "Snap Settings" @@ -7119,43 +7100,43 @@ msgstr "Snap de Escala (%):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Viewport Settings" -msgstr "Ajustes del viewport" +msgstr "Ajustes de Viewport" #: editor/plugins/spatial_editor_plugin.cpp msgid "Perspective FOV (deg.):" -msgstr "Anchura de perspectiva (en grados):" +msgstr "FOV de Perspectiva (grados.):" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Z-Near:" -msgstr "Profundidad mÃnima de vista:" +msgstr "Profundidad MÃnima de Vista:" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Z-Far:" -msgstr "Profundidad máxima de vista:" +msgstr "Profundidad Máxima de Vista:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Change" -msgstr "Cambio de transformación" +msgstr "Cambio de Transformación" #: editor/plugins/spatial_editor_plugin.cpp msgid "Translate:" -msgstr "Mover:" +msgstr "Trasladar:" #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotate (deg.):" -msgstr "Girar (grados):" +msgstr "Rotar (grados.):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Scale (ratio):" -msgstr "Escalar (porcentaje):" +msgstr "Escalar (ratio):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Type" -msgstr "Tipo de transformación" +msgstr "Tipo de Transformación" #: editor/plugins/spatial_editor_plugin.cpp msgid "Pre" -msgstr "Previa" +msgstr "Anterior" #: editor/plugins/spatial_editor_plugin.cpp msgid "Post" @@ -7235,29 +7216,27 @@ msgstr "Crecer (Pixeles): " #: editor/plugins/sprite_editor_plugin.cpp msgid "Update Preview" -msgstr "Actualizar vista previa" +msgstr "Actualizar Vista Previa" #: editor/plugins/sprite_editor_plugin.cpp msgid "Settings:" -msgstr "Ajustes:" +msgstr "Configuración:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "Encuadrar selección" +msgstr "No hay Frames Seleccionados" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "Añadir fotograma" +msgstr "Añadir %d Frame(s)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" -msgstr "Añadir fotograma" +msgstr "Añadir Frame" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "ERROR: Couldn't load frame resource!" -msgstr "ERROR: ¡No se pudo cargar el recurso de fotogramas!" +msgstr "ERROR: ¡No se pudo cargar el recurso de frames!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Resource clipboard is empty or not a texture!" @@ -7265,15 +7244,15 @@ msgstr "¡El portapapeles de recursos esta vacÃo o no es una textura!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Paste Frame" -msgstr "Pegar fotograma" +msgstr "Pegar Frame" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Empty" -msgstr "Añadir elemento vacÃo" +msgstr "Añadir VacÃo" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Change Animation FPS" -msgstr "Cambiar FPS de animación" +msgstr "Cambiar FPS de Animación" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "(empty)" @@ -7293,28 +7272,27 @@ msgstr "Velocidad (FPS):" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Loop" -msgstr "Repetir" +msgstr "Loop" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Animation Frames:" -msgstr "Fotogramas de animación:" +msgstr "Frames de Animación:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Agregar Textura(s) al TileSet." +msgstr "Añadir Textura desde Archivo" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "Añadir Frames de un Sprite Sheet" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" -msgstr "Insertar vacÃo (antes)" +msgstr "Insertar VacÃo (Antes)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (After)" -msgstr "Insertar vacÃo (después)" +msgstr "Insertar VacÃo (Después)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Move (Before)" @@ -7325,29 +7303,24 @@ msgid "Move (After)" msgstr "Mover (Después)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "Frames del stack" +msgstr "Seleccionar Frames" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Voltear horizontalmente" +msgstr "Horizontal:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "Vértices" +msgstr "Vertical:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "Seleccionar todo" +msgstr "Seleccionar/Limpiar Todos los Frames" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "Crear desde escena" +msgstr "Crear Frames a partir de Sprite Sheet" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" @@ -7355,7 +7328,7 @@ msgstr "SpriteFrames" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Set Region Rect" -msgstr "Establecer rectángulo de región" +msgstr "Establecer Region Rect" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Set Margin" @@ -7376,15 +7349,15 @@ msgstr "Pixel Snap" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Grid Snap" -msgstr "Snap de cuadrÃcula" +msgstr "Grid Snap" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Auto Slice" -msgstr "Autotrocear" +msgstr "Corte Automático" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Offset:" -msgstr "Desplazamiento:" +msgstr "Offset:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Step:" @@ -7396,7 +7369,7 @@ msgstr "Sep.:" #: editor/plugins/texture_region_editor_plugin.cpp msgid "TextureRegion" -msgstr "Región de textura" +msgstr "Región de Textura" #: editor/plugins/theme_editor_plugin.cpp msgid "Can't save theme to file:" @@ -7404,24 +7377,23 @@ msgstr "No se pudo guardar el tema a un archivo:" #: editor/plugins/theme_editor_plugin.cpp msgid "Add All Items" -msgstr "Añadir todos los elementos" +msgstr "Añadir Todos los Elementos" #: editor/plugins/theme_editor_plugin.cpp msgid "Add All" -msgstr "Añadir todos" +msgstr "Añadir Todos" #: editor/plugins/theme_editor_plugin.cpp msgid "Remove All Items" -msgstr "Quitar todos los elementos" +msgstr "Eliminar Todos los Ãtems" #: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp msgid "Remove All" -msgstr "Quitar todos" +msgstr "Eliminar Todos" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "Editar tema..." +msgstr "Editar Tema" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7433,11 +7405,11 @@ msgstr "Añadir elementos de clase" #: editor/plugins/theme_editor_plugin.cpp msgid "Remove Class Items" -msgstr "Quitar elementos de clases" +msgstr "Eliminar Ãtems de Clases" #: editor/plugins/theme_editor_plugin.cpp msgid "Create Empty Template" -msgstr "Crear plantilla vacÃa" +msgstr "Crear Plantilla VacÃa" #: editor/plugins/theme_editor_plugin.cpp msgid "Create Empty Editor Template" @@ -7448,57 +7420,52 @@ msgid "Create From Current Editor Theme" msgstr "Crear desde el tema actual del editor" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Toggle Button" -msgstr "Botón del ratón" +msgstr "Botón de Conmutación" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Botón del medio" +msgstr "Botón Desactivado" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" -msgstr "Elemento" +msgstr "Ãtem" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "Desactivado" +msgstr "Desactivar Ãtem" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" -msgstr "Casilla de verificación" +msgstr "Activar Ãtem" #: editor/plugins/theme_editor_plugin.cpp msgid "Checked Item" -msgstr "Casilla de verificación activa" +msgstr "Ãtem Activado" #: editor/plugins/theme_editor_plugin.cpp msgid "Radio Item" -msgstr "Radio Item" +msgstr "Radio Ãtem" #: editor/plugins/theme_editor_plugin.cpp msgid "Checked Radio Item" -msgstr "Ratio item activo" +msgstr "Radio Ãtem Activo" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "Separador con nombre." #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Submenú" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "Elemento" +msgstr "Ãtem 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "Elemento" +msgstr "Ãtem 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -7509,9 +7476,8 @@ msgid "Many" msgstr "Muchas" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled LineEdit" -msgstr "Desactivado" +msgstr "Desactivar LineEdit" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -7526,13 +7492,12 @@ msgid "Tab 3" msgstr "Tab 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "Hijos editables" +msgstr "Ãtem Editable" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "Subárbol" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7564,7 +7529,7 @@ msgstr "Constante" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase Selection" -msgstr "Borrar selección" +msgstr "Borrar Selección" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Fix Invalid Tiles" @@ -7581,15 +7546,15 @@ msgstr "Dibujar TileMap" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Line Draw" -msgstr "Dibujar lÃnea" +msgstr "Dibujar LÃnea" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Rectangle Paint" -msgstr "Dibujar rectángulo" +msgstr "Dibujar Rectángulo" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Bucket Fill" -msgstr "Cubo de relleno" +msgstr "Bote de Relleno" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase TileMap" @@ -7605,21 +7570,19 @@ msgstr "Transponer" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Mirror X" -msgstr "Voltear horizontalmente" +msgstr "Voltear X" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Mirror Y" -msgstr "Voltear verticalmente" +msgstr "Voltear Y" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "Autotiles" +msgstr "Desactivar Autotile" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "Editar Prioridad del Tile" +msgstr "Activar Prioridad" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7630,35 +7593,32 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift + Clic derecho: Trazar lÃnea\n" +"Shift + Ctrl + Clic derecho: Pintar Rectángulo" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" -msgstr "Elegir tile" +msgstr "Elegir Tile" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" -msgstr "Rotar a la izquierda" +msgstr "Rotar a la Izquierda" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" -msgstr "Rotar a la derecha" +msgstr "Rotar a la Derecha" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Horizontally" -msgstr "Voltear horizontalmente" +msgstr "Voltear Horizontalmente" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Vertically" -msgstr "Voltear verticalmente" +msgstr "Voltear Verticalmente" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" -msgstr "Reestablecer transform" +msgstr "Reestablecer Transformación" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Add Texture(s) to TileSet." @@ -7666,7 +7626,7 @@ msgstr "Agregar Textura(s) al TileSet." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove selected Texture from TileSet." -msgstr "Quitar Textura seleccionada del TileSet." +msgstr "Eliminar Textura seleccionada del TileSet." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from Scene" @@ -7678,7 +7638,7 @@ msgstr "Unir desde escena" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Next Coordinate" -msgstr "Coordenada Siguiente" +msgstr "Siguiente Coordenada" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select the next shape, subtile, or Tile." @@ -7686,51 +7646,43 @@ msgstr "Seleccionar la próxima forma, subtile o Tile." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Previous Coordinate" -msgstr "Coordenada Anterior" +msgstr "Anterior Coordenada" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select the previous shape, subtile, or Tile." msgstr "Seleccionar la anterior forma, subtile, o Tile." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "Modo de ejecución:" +msgstr "Modo Región" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "Modo de Interpolación" +msgstr "Modo Colisión" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "Editar PolÃgono de Oclusión" +msgstr "Modo Oclusión" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "Crear Mesh de Navegación" +msgstr "Modo Navegación" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "Modo rotación" +msgstr "Modo Bitmask" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "Modo de exportación:" +msgstr "Modo Prioridad" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "Modo desplazamiento lateral" +msgstr "Modo Icono" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "Modo desplazamiento lateral" +msgstr "Modo Ãndice Z" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7758,7 +7710,7 @@ msgstr "Mantener el polÃgono dentro del region Rect." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Enable snap and show grid (configurable via the Inspector)." -msgstr "Activar snap y mostrar cuadricula (configurable vÃa el Inspector)." +msgstr "Activar snap y mostrar grid (configurable a través del Inspector)." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Display Tile Names (Hold Alt Key)" @@ -7776,11 +7728,11 @@ msgstr "No elegiste una textura para eliminar." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from scene? This will overwrite all current tiles." -msgstr "¿Crear desde la escena? Esto sobrescribirá todos los tiles actuales." +msgstr "¿Crear desde escena? Esto sobrescribirá todos los tiles actuales." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Merge from scene?" -msgstr "¿Mezclar desde escena?" +msgstr "¿Unir desde escena?" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove Texture" @@ -7815,16 +7767,16 @@ msgid "Delete polygon." msgstr "Eliminar polÃgono." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy 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 "" -"Clic izq: Activar bit.\n" -"Clic der: Desactivar bit.\n" -"Clic en otro Tile para editarlo." +"Clic Izquierdo: Activar bit.\n" +"Clic Derecho: Desactivar bit.\n" +"Shift + Clic Izquierdo: Establecer valor de bit comodÃn.\n" +"Haz clic en otro Tile para editarlo." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -7849,8 +7801,8 @@ msgid "" "Select sub-tile to change its z index.\n" "Click on another Tile to edit it." msgstr "" -"Seleccionar sub-tile para cambiar su z index.\n" -"Clic en otro Tile para editarlo." +"Selecciona sub-tile para cambiar su Ãndice z.\n" +"Haz clic en otro Tile para editarlo." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Set Tile Region" @@ -7890,11 +7842,11 @@ msgstr "Reestablecer Máscara de Bits de Tile" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Make Polygon Concave" -msgstr "Hacer PolÃgono Cóncavo" +msgstr "Crear PolÃgono Cóncavo" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Make Polygon Convex" -msgstr "Hacer Póligono Convexo" +msgstr "Crear Póligono Convexo" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove Tile" @@ -7910,7 +7862,7 @@ msgstr "Eliminar PolÃgono de Oclusión" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove Navigation Polygon" -msgstr "Crear PolÃgono de Navegación" +msgstr "Eliminar PolÃgono de Navegación" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Tile Priority" @@ -7918,7 +7870,7 @@ msgstr "Editar Prioridad del Tile" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Tile Z Index" -msgstr "Editar Z Index de Tile" +msgstr "Editar Ãndice Z de Tile" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create Collision Polygon" @@ -7937,77 +7889,64 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input +" -msgstr "Añadir Entrada" +msgstr "Añadir entrada +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add output +" -msgstr "Añadir Entrada" +msgstr "Añadir salida +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "Escala:" +msgstr "Escalar" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Inspector" +msgstr "Vector" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Booleano" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "Añadir Entrada" +msgstr "Agregar puerto de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Añadir puerto de salida" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "Cambiar tipo por defecto" +msgstr "Cambiar tipo de puerto de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "Cambiar tipo por defecto" +msgstr "Cambiar tipo de puerto de salida" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "Cambiar nombre de entrada" +msgstr "Cambiar nombre del puerto de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "Cambiar nombre de entrada" +msgstr "Cambiar nombre del puerto de salida" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "Quitar punto" +msgstr "Eliminar puerto de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "Quitar punto" +msgstr "Eliminar puerto de salida" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "Cambiar expresión" +msgstr "Establecer expresión" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "VisualShader" +msgstr "Redimensionar nodo VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" @@ -8046,540 +7985,314 @@ msgid "Light" msgstr "Luz" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "Crear nodo" +msgstr "Crear Nodo Shader" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "Ir a Función" +msgstr "Función Color." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "Operador Color." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "Crear función" +msgstr "Función Grayscale." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "Convertir vector HSV a equivalente RGB." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "Convertir vector RGB a equivalente HSV." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "Renombrar función" +msgstr "Función Sepia." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "Operador Burn." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "Operador Darken." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Difference operator." -msgstr "Solo las diferencias" +msgstr "Operador diferencial." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." -msgstr "" +msgstr "Operador Dodge." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "HardLight operator" -msgstr "" +msgstr "Operador HardLight" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." -msgstr "" +msgstr "Operador Lighten." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." -msgstr "" +msgstr "Operador Overlay." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Screen operator." -msgstr "" +msgstr "Operador Screen." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "SoftLight operator." -msgstr "" +msgstr "Operador SoftLight." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color constant." -msgstr "Constante" +msgstr "Constante de color." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color uniform." -msgstr "Reestablecer transform" +msgstr "Color uniforme." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided scalars are equal, greater or " "less." msgstr "" +"Devuelve un vector asociado si los escalares proporcionados son iguales, " +"mayores o menores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided boolean value is true or false." msgstr "" +"Devuelve un vector asociado si el valor booleano proporcionado es verdadero " +"o falso." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Boolean constant." -msgstr "Cambiar Constante Vec." +msgstr "Constante booleana." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean uniform." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" +msgstr "Boolean uniforme." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" +msgid "'%s' input parameter for all shader modes." +msgstr "Parámetro de entrada %s' para todos los modos de shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Input parameter." -msgstr "Alinear al Padre" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" +msgstr "Parámetro de entrada." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "Parámetro de entrada '%s' para vértices y fragmentos en modo shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "Parámetro de entrada '%s' para fragmentos y luces en modo shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" +msgid "'%s' input parameter for fragment shader mode." +msgstr "Parámetro de entrada '%s' para fragmentos en modo de shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" +msgid "'%s' input parameter for light shader mode." +msgstr "Parámetro de entrada '%s' para luces en modo shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" +msgid "'%s' input parameter for vertex shader mode." +msgstr "Parámetro de entrada '%s' para vértices en modo shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "Parámetro de entrada '%s' para vértices y fragmentos en modo shader." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar function." -msgstr "Cambiar función Scalar" +msgstr "Función Scalar." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar operator." -msgstr "Cambiar operador escalar" +msgstr "Operador de Scalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "Constante E (2.718282). Representa la base del logaritmo natural." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "Constante de Épsilon (0.00001). El número escalar más pequeño posible." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "Constante Phi (1.618034). Ratio de oro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "Constante Pi/4 (0.785398) o 45 grados." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "Constante Pi/2 (1.570796) o 90 grados." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "Constante Pi (3.141593) o 180 grados." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "Constante Tau (6.283185) o 360 grados." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "Constante Sqrt2 (1.414214). RaÃz cuadrada de 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "Devuelve el valor absoluto del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "Devuelve el arcocoseno del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Sólo GLES3) Devuelve el coseno hiperbólico inverso del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "Devuelve el arcoseno del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "(Sólo GLES3) Devuelve el seno hiperbólico inverso del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "Devuelve el arcotangente del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "Devuelve el arcotangente de los parámetros." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Sólo GLES3) Devuelve la tangente hiperbólica inversa del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "Encuentra el entero más cercano mayor o igual que el parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "Limita un valor a estar entre dos valores más." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "Devuelve el coseno del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Sólo GLES3) Devuelve el coseno hiperbólico del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "Convierte una cantidad en radianes a grados." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "Exponencial en base e." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "Exponencial en base 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "Encuentra el número entero más cercano menor o igual que el parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "Calcula la parte fraccional del argumento." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "Devuelve el inverso de la raÃz cuadrada del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "Logaritmo natural." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "Logaritmo de la base 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "Devuelve el mayor de dos valores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "Devuelve el menor de dos valores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "Interpolación lineal entre dos escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "Devuelve el valor opuesto del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - escalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." msgstr "" +"Devuelve el valor del primer parámetro elevado a la potencia del segundo." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "Convierte una cantidad de grados a radianes." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / escalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(Sólo GLES3) Encuentra el entero más cercano al parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(Sólo GLES3) Encuentra el entero más cercano al parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "Ajusta el valor entre 0.0 y 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "Extrae el signo del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "Devuelve el seno del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(Sólo GLES3) Devuelve el seno hiperbólico del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "Devuelve la raÃz cuadrada del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8589,6 +8302,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep function( scalar(edge0), scalar(edge1), scalar(x) ).\n" +"\n" +"Devuelve 0.0 si 'x' es menor que 'edge0' y 1.0 si x es mayor que 'edge1'. De " +"lo contrario, el valor de retorno se interpola entre 0.0 y 1.0 utilizando " +"polinomios de Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8596,71 +8314,69 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Step function( scalar(edge), scalar(x) ).\n" +"\n" +"Devuelve 0.0 si 'x' es menor que 'edge' y en caso contrario devuelve 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "Devuelve la tangente del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Sólo GLES3) Devuelve la tangente hiperbólica del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." -msgstr "" +msgstr "(Sólo GLES3) Encuentra el valor truncado del parámetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "Añade escalar a escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "Divide escalar por escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "Multiplica escalar por escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "Devuelve el resto de dos escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "Resta escalar de escalar." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar constant." -msgstr "Cambiar constante escalar" +msgstr "Constante de escalar." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar uniform." -msgstr "Cambiar Scalar uniforme" +msgstr "Escalar uniforme." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "Realiza una búsqueda de texturas cúbicas." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the texture lookup." -msgstr "" +msgstr "Realiza una búsqueda de texturas." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Cubic texture uniform." -msgstr "Cambiar textura uniforme" +msgstr "Textura cúbica uniforme." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "2D texture uniform." -msgstr "Cambiar textura uniforme" +msgstr "Textura 2D uniforme." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform function." -msgstr "Dialogo de Transformación..." +msgstr "Función Transform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8672,74 +8388,77 @@ msgid "" "whose number of rows is the number of components in 'c' and whose number of " "columns is the number of components in 'r'." msgstr "" +"(GLES3 solamente) Calcula el producto exterior de un par de vectores.\n" +"\n" +"OuterProduct trata el primer parámetro 'c' como un vector de columna (matriz " +"con una columna) y el segundo parámetro 'r' como un vector de fila (matriz " +"con una fila) y multiplica una matriz algebraica lineal 'c * r', dando como " +"resultado una matriz cuyo número de filas es el número de componentes en 'c' " +"y cuyo número de columnas es el número de componentes en 'r'." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes transform from four vectors." -msgstr "" +msgstr "Compone una transformación a partir de cuatro vectores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes transform to four vectors." -msgstr "" +msgstr "Se descompone y transforma en cuatro vectores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the determinant of a transform." -msgstr "" +msgstr "(Sólo GLES3) Calcula el determinante de una transformación." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the inverse of a transform." -msgstr "" +msgstr "(Sólo GLES3) Calcula el inverso de una transformación." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the transpose of a transform." -msgstr "" +msgstr "(Sólo GLES3) Calcula la transposición de una transformación." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies transform by transform." -msgstr "" +msgstr "Multiplica transformación por transformación." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by transform." -msgstr "" +msgstr "Multiplica vector por transformación." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform constant." -msgstr "Se ha cancelado la transformación." +msgstr "Constante Transform." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform uniform." -msgstr "Se ha cancelado la transformación." +msgstr "Transform uniforme." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector function." -msgstr "Asignación a función." +msgstr "Función Vector." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector operator." -msgstr "Cambiar operador Vec" +msgstr "Operador de Vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "Compone vector a partir de tres escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "Descompone vector a tres escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "Calcula el producto cruzado de dos vectores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "Devuelve la distancia entre dos puntos." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "Calcula el producto punto de dos vectores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8748,36 +8467,43 @@ msgid "" "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 "" +"Devuelve un vector que apunta en la misma dirección que un vector de " +"referencia. La función tiene tres parámetros vectoriales: N, el vector a " +"orientar, I, el vector incidente, y Nref, el vector de referencia. Si el " +"producto punto de I y Nref es menor que cero, el valor de retorno es N. De " +"lo contrario, se devuelve -N." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "Calcula la longitud de un vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "Interpolación lineal entre dos vectores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." -msgstr "" +msgstr "Calcula el producto normalizado del vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - vector" -msgstr "" +msgstr "1.0 - vector" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / vector" -msgstr "" +msgstr "1.0 / vector" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns a vector that points in the direction of reflection ( a : incident " "vector, b : normal vector )." msgstr "" +"Devuelve un vector que apunta en dirección a su reflexión ( a : vector " +"incidente, b : vector normal)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns a vector that points in the direction of refraction." -msgstr "" +msgstr "Devuelve un vector que apunta en dirección a su refracción." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8787,6 +8513,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep function( vector(edge0), vector(edge1), vector(x) ).\n" +"\n" +"Devuelve 0.0 si 'x' es menor que 'edge0' y 1.0 si 'x' es mayor que 'edge1'. " +"De lo contrario, el valor de retorno se interpola entre 0.0 y 1.0 utilizando " +"polinomios de Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8796,6 +8527,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep function( scalar(edge0), scalar(edge1), vector(x) ).\n" +"\n" +"Devuelve 0.0 si 'x' es menor que 'edge0' y 1.0 si 'x' es mayor que 'edge1'. " +"De lo contrario, el valor de retorno se interpola entre 0.0 y 1.0 utilizando " +"polinomios de Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8803,6 +8539,9 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Step function( vector(edge), vector(x) ).\n" +"\n" +"Devuelve 0.0 si 'x' es menor que 'edge' y 1.0 en caso contrario." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8810,36 +8549,37 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Step function( scalar(edge), vector(x) ).\n" +"\n" +"Devuelve 0.0 si 'x' es menor que 'edge' y 1.0 en caso contrario." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." -msgstr "" +msgstr "Añade vector a vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "" +msgstr "Divide vector por vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." -msgstr "" +msgstr "Multiplica vector por vector." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two vectors." -msgstr "" +msgstr "Devuelve el resto de los dos vectores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts vector from vector." -msgstr "" +msgstr "Sustrae vector de vector." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector constant." -msgstr "Cambiar Constante Vec." +msgstr "Constante Vector." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector uniform." -msgstr "Asignación a uniform." +msgstr "Vector uniforme." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8847,56 +8587,76 @@ msgid "" "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 "" +"Expresión personalizada del lenguaje de shaders de Godot, con una cantidad " +"determinada de puertos de entrada y salida. Esta es una inyección directa de " +"código en la función vertex/fragment/light, no la uses para escribir " +"declaraciones de funciones en su interior." #: 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 "" +"Los retornos decrecen en función del producto punto de la superficie normal " +"y de la dirección de visión de la cámara (pasando las entradas asociadas a " +"esta)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function." -msgstr "" +msgstr "(Sólo GLES3) (Sólo modo Fragmento/Luz) Función de derivación escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function." msgstr "" +"(Sólo GLES3) (Sólo modo Fragmento/Luz) Función de derivación vectorial." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using " "local differencing." msgstr "" +"(Sólo GLES3) (Sólo modo Fragmento/Luz) (Vector) Derivado en 'x' utilizando " +"diferenciación local." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using " "local differencing." msgstr "" +"(Sólo GLES3) (Sólo modo Fragmento/Luz) (Escalar) Derivado en 'x' utilizando " +"diferenciación local." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using " "local differencing." msgstr "" +"(Sólo GLES3) (Sólo modo Fragmento/Luz) (Vector) Derivado en 'y' utilizando " +"diferenciación local." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using " "local differencing." msgstr "" +"(Sólo GLES3) (Sólo modo Fragmento/Luz) (Escalar) Derivado en 'y' utilizando " +"diferenciación local." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(Sólo GLES3) (Sólo modo Fragmento/Luz) (Vector) Suma de la derivada absoluta " +"en 'x' e 'y'." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(Sólo GLES3) (Sólo modo Fragmento/Luz) (Escalar) Suma del derivado absoluto " +"en 'x' e 'y'." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "VisualShader" @@ -8908,7 +8668,7 @@ msgstr "Editar Propiedad Visual" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Visual Shader Mode Changed" -msgstr "Se ha cambiado el Modo de Visual Shader" +msgstr "Cambiar Modo de Visual Shader" #: editor/project_export.cpp msgid "Runnable" @@ -8987,7 +8747,7 @@ msgstr "Exportar los recursos seleccionado (incluyendo dependencias)" #: editor/project_export.cpp msgid "Export Mode:" -msgstr "Modo de exportación:" +msgstr "Modo de Exportación:" #: editor/project_export.cpp msgid "Resources to export:" @@ -9009,7 +8769,7 @@ msgstr "" #: editor/project_export.cpp msgid "Patches" -msgstr "Exportaciones previas" +msgstr "Parches" #: editor/project_export.cpp msgid "Make Patch" @@ -9025,7 +8785,7 @@ msgstr "Personalizado (separado por comas):" #: editor/project_export.cpp msgid "Feature List:" -msgstr "Lista de caracterÃsticas:" +msgstr "Lista de CaracterÃsticas:" #: editor/project_export.cpp msgid "Script" @@ -9033,7 +8793,7 @@ msgstr "Script" #: editor/project_export.cpp msgid "Script Export Mode:" -msgstr "Modo de exportación de scipts:" +msgstr "Modo de Exportación de Scipts:" #: editor/project_export.cpp msgid "Text" @@ -9098,15 +8858,15 @@ msgstr "El directorio ya contiene un proyecto de Godot." #: editor/project_manager.cpp msgid "New Game Project" -msgstr "Nuevo proyecto de juego" +msgstr "Nuevo Proyecto de Juego" #: editor/project_manager.cpp msgid "Imported Project" -msgstr "Proyecto importado" +msgstr "Proyecto Importado" #: editor/project_manager.cpp msgid "Invalid Project Name." -msgstr "Nombre de proyecto inválido." +msgstr "Nombre de Proyecto Inválido." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -9146,15 +8906,15 @@ msgstr "Los siguientes archivos no se pudieron extraer del paquete:" #: editor/project_manager.cpp msgid "Rename Project" -msgstr "Renombrar proyecto" +msgstr "Renombrar Proyecto" #: editor/project_manager.cpp msgid "Import Existing Project" -msgstr "Importar proyecto existente" +msgstr "Importar Proyecto Existente" #: editor/project_manager.cpp msgid "Import & Edit" -msgstr "Importar y editar" +msgstr "Importar y Editar" #: editor/project_manager.cpp msgid "Create New Project" @@ -9166,11 +8926,11 @@ msgstr "Crear y editar" #: editor/project_manager.cpp msgid "Install Project:" -msgstr "Instalar proyecto:" +msgstr "Instalar Proyecto:" #: editor/project_manager.cpp msgid "Install & Edit" -msgstr "Instalar y editar" +msgstr "Instalar y Editar" #: editor/project_manager.cpp msgid "Project Name:" @@ -9178,11 +8938,11 @@ msgstr "Nombre del Proyecto:" #: editor/project_manager.cpp msgid "Project Path:" -msgstr "Ruta del proyecto:" +msgstr "Ruta del Proyecto:" #: editor/project_manager.cpp msgid "Project Installation Path:" -msgstr "Ruta de instalación del proyecto:" +msgstr "Ruta de Instalación del Proyecto:" #: editor/project_manager.cpp msgid "Renderer:" @@ -9228,7 +8988,7 @@ msgstr "" #: editor/project_manager.cpp msgid "Unnamed Project" -msgstr "Proyecto sin nombre" +msgstr "Proyecto Sin Nombre" #: editor/project_manager.cpp msgid "Can't open project at '%s'." @@ -9239,7 +8999,6 @@ msgid "Are you sure to open more than one project?" msgstr "¿Seguro que quieres abrir más de un proyecto?" #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file does not specify the version of Godot " "through which it was created.\n" @@ -9251,8 +9010,8 @@ msgid "" "Warning: You won't be able to open the project with previous versions of the " "engine anymore." msgstr "" -"El siguiente archivo de configuración del proyecto no especifica la versión " -"de Godot con la que fue creado.\n" +"El archivo de configuración del proyecto no especifica la versión de Godot " +"con la que fue creado.\n" "\n" "%s\n" "\n" @@ -9262,7 +9021,6 @@ msgstr "" "motor." #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file was generated by an older engine " "version, and needs to be converted for this version:\n" @@ -9273,13 +9031,13 @@ msgid "" "Warning: You won't be able to open the project with previous versions of the " "engine anymore." msgstr "" -"El siguiente archivo de configuración del proyecto fue generado por una " -"versión anterior del motor y debe convertirse para esta versión:\n" +"El archivo de configuración del proyecto fue generado en una versión " +"anterior del motor, por lo que es necesario convertirlo para esta versión:\n" "\n" "%s\n" "\n" "¿Quieres convertirlo?\n" -"Advertencia: ya no podrá abrir el proyecto con versiones anteriores del " +"Advertencia: Ya no podrá abrir el proyecto con versiones anteriores del " "motor." #: editor/project_manager.cpp @@ -9291,15 +9049,14 @@ msgstr "" "cuya configuración no es compatible con esta versión." #: editor/project_manager.cpp -#, fuzzy 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 "" -"No hay una escena principal definida para ejecutar el proyecto.\n" -"Por favor elija la escena principal en \"Ajustes del Proyecto\" en la " -"categorÃa \"Application\"." +"No se puede ejecutar el proyecto: no hay una escena principal definida.\n" +"Por favor, edita el proyecto y configura la escena principal en los Ajustes " +"del proyecto, en la categorÃa \"Application\"." #: editor/project_manager.cpp msgid "" @@ -9310,63 +9067,58 @@ msgstr "" "Por favor, edita el proyecto para activar el importado inicial." #: editor/project_manager.cpp -#, fuzzy msgid "Are you sure to run %d projects at once?" -msgstr "¿Seguro que quieres ejecutar más de un proyecto?" +msgstr "¿Estás seguro de que vas a ejecutar %d proyectos a la vez?" #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove %d projects from the list?\n" "The project folders' contents won't be modified." msgstr "" -"¿Quieres quitar el proyecto de la lista? (El contenido de la carpeta no se " -"modificará)" +"¿Eliminar %d proyectos de la lista?\n" +"El contenido de las carpetas del proyecto no se modificará." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove this project from the list?\n" "The project folder's contents won't be modified." msgstr "" -"¿Quieres quitar el proyecto de la lista? (El contenido de la carpeta no se " -"modificará)" +"¿Eliminar este proyecto de la lista?\n" +"El contenido de la carpeta de proyecto no se modificará." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove all missing projects from the list? (Folders contents will not be " "modified)" msgstr "" -"¿Quieres quitar el proyecto de la lista? (El contenido de la carpeta no se " -"modificará)" +"¿Eliminar todos los proyectos faltantes de la lista? (El contenido de las " +"carpetas no se modificará)" #: editor/project_manager.cpp -#, fuzzy msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." msgstr "" "Idioma cambiado.\n" -"La interfaz se actualizará la próxima vez que se inicie el editor o el " -"gestor de proyectos." +"La interfaz se actualizará después de reiniciar el editor o el gestor de " +"proyectos." #: editor/project_manager.cpp -#, fuzzy msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." msgstr "" -"Estás a punto de analizar %s carpetas en busca de proyectos de Godot. " -"¿Quieres continuar?" +"¿Está seguro de escanear %s carpetas para los proyectos de Godot " +"existentes?\n" +"Esto puede tardar un poco." #: editor/project_manager.cpp msgid "Project Manager" -msgstr "Administrador de proyectos" +msgstr "Administrador de Proyectos" #: editor/project_manager.cpp msgid "Project List" -msgstr "Lista de proyectos" +msgstr "Listado de Proyectos" #: editor/project_manager.cpp msgid "Scan" @@ -9378,12 +9130,11 @@ msgstr "Selecciona una carpeta para escanear" #: editor/project_manager.cpp msgid "New Project" -msgstr "Nuevo proyecto" +msgstr "Nuevo Proyecto" #: editor/project_manager.cpp -#, fuzzy msgid "Remove Missing" -msgstr "Quitar punto" +msgstr "Eliminar Faltantes" #: editor/project_manager.cpp msgid "Templates" @@ -9395,21 +9146,19 @@ msgstr "Salir" #: editor/project_manager.cpp msgid "Restart Now" -msgstr "Reiniciar ahora" +msgstr "Reiniciar Ahora" #: editor/project_manager.cpp msgid "Can't run project" msgstr "No se puede ejecutar el proyecto" #: editor/project_manager.cpp -#, fuzzy msgid "" "You currently don't have any projects.\n" "Would you like to explore official example projects in the Asset Library?" msgstr "" "Actualmente no tienes ningún proyecto.\n" -"¿Quieres explorar los proyectos de ejemplo oficiales en la Biblioteca de " -"Assets?" +"¿Quieres explorar proyectos de ejemplo oficiales en la Biblioteca de Assets?" #: editor/project_settings_editor.cpp msgid "Key " @@ -9417,15 +9166,15 @@ msgstr "Tecla " #: editor/project_settings_editor.cpp msgid "Joy Button" -msgstr "Botón del mando" +msgstr "Botón del Mando" #: editor/project_settings_editor.cpp msgid "Joy Axis" -msgstr "Eje del mando" +msgstr "Eje del Mando" #: editor/project_settings_editor.cpp msgid "Mouse Button" -msgstr "Botón del ratón" +msgstr "Botón del Mouse" #: editor/project_settings_editor.cpp msgid "" @@ -9436,9 +9185,8 @@ msgstr "" "'\\' o '\"'" #: editor/project_settings_editor.cpp -#, fuzzy msgid "An action with the name '%s' already exists." -msgstr "¡La acción «%s» ya existe!" +msgstr "Ya existe una acción con el nombre '%s'." #: editor/project_settings_editor.cpp msgid "Rename Input Action Event" @@ -9450,11 +9198,11 @@ msgstr "Cambiar zona muerta de la acción" #: editor/project_settings_editor.cpp msgid "Add Input Action Event" -msgstr "Añadir evento de acción de entrada" +msgstr "Añadir Evento de Acción de Entrada" #: editor/project_settings_editor.cpp msgid "All Devices" -msgstr "Todos los dispositivos" +msgstr "Todos los Dispositivos" #: editor/project_settings_editor.cpp msgid "Device" @@ -9462,7 +9210,7 @@ msgstr "Dispositivo" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "Shift+" -msgstr "Mayús+" +msgstr "Shift+" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "Alt+" @@ -9478,35 +9226,35 @@ msgstr "Presiona una tecla..." #: editor/project_settings_editor.cpp msgid "Mouse Button Index:" -msgstr "Ãndice de botón del ratón:" +msgstr "Ãndice de Botones del Mouse:" #: editor/project_settings_editor.cpp msgid "Left Button" -msgstr "Botón izquierdo" +msgstr "Botón Izquierdo" #: editor/project_settings_editor.cpp msgid "Right Button" -msgstr "Botón derecho" +msgstr "Botón Derecho" #: editor/project_settings_editor.cpp msgid "Middle Button" -msgstr "Botón del medio" +msgstr "Botón Central" #: editor/project_settings_editor.cpp msgid "Wheel Up Button" -msgstr "Botón rueda arriba" +msgstr "Botón Subir la Rueda" #: editor/project_settings_editor.cpp msgid "Wheel Down Button" -msgstr "Botón rueda abajo" +msgstr "Botón Bajar la Rueda" #: editor/project_settings_editor.cpp msgid "Wheel Left Button" -msgstr "Botón rueda izquierda" +msgstr "Botón Rueda Izquierda" #: editor/project_settings_editor.cpp msgid "Wheel Right Button" -msgstr "Botón rueda derecha" +msgstr "Botón Rueda Derecha" #: editor/project_settings_editor.cpp msgid "X Button 1" @@ -9518,7 +9266,7 @@ msgstr "Botón X 2" #: editor/project_settings_editor.cpp msgid "Joypad Axis Index:" -msgstr "Ãndice de eje del mando:" +msgstr "Ãndice de Ejes del Mando:" #: editor/project_settings_editor.cpp msgid "Axis" @@ -9526,19 +9274,19 @@ msgstr "Eje" #: editor/project_settings_editor.cpp msgid "Joypad Button Index:" -msgstr "Ãndice de boton del mando:" +msgstr "Ãndice de Botones del Mando:" #: editor/project_settings_editor.cpp msgid "Erase Input Action" -msgstr "Borrar acción de entrada" +msgstr "Eliminar Acción de Entrada" #: editor/project_settings_editor.cpp msgid "Erase Input Action Event" -msgstr "Borrar evento de acción de entrada" +msgstr "Eliminar Evento de Acción de Entrada" #: editor/project_settings_editor.cpp msgid "Add Event" -msgstr "Añadir evento" +msgstr "Añadir Evento" #: editor/project_settings_editor.cpp msgid "Button" @@ -9546,27 +9294,27 @@ msgstr "Botón" #: editor/project_settings_editor.cpp msgid "Left Button." -msgstr "Botón izquierdo." +msgstr "Botón Izquierdo." #: editor/project_settings_editor.cpp msgid "Right Button." -msgstr "Botón derecho." +msgstr "Botón Derecho." #: editor/project_settings_editor.cpp msgid "Middle Button." -msgstr "Botón central." +msgstr "Botón Central." #: editor/project_settings_editor.cpp msgid "Wheel Up." -msgstr "Rueda hacia arriba." +msgstr "Rueda Hacia Arriba." #: editor/project_settings_editor.cpp msgid "Wheel Down." -msgstr "Rueda hacia abajo." +msgstr "Rueda Hacia Abajo." #: editor/project_settings_editor.cpp msgid "Add Global Property" -msgstr "Añadir propiedad global" +msgstr "Añadir Propiedad Global" #: editor/project_settings_editor.cpp msgid "Select a setting item first!" @@ -9582,7 +9330,7 @@ msgstr "El ajuste '%s' es interno y no puede ser eliminado." #: editor/project_settings_editor.cpp msgid "Delete Item" -msgstr "Eliminar elemento" +msgstr "Eliminar Ãtem" #: editor/project_settings_editor.cpp msgid "" @@ -9606,47 +9354,47 @@ msgstr "Los ajustes se han guardado correctamente." #: editor/project_settings_editor.cpp msgid "Override for Feature" -msgstr "Sobrescribir la caracterÃstica" +msgstr "Sobrescribir la CaracterÃstica" #: editor/project_settings_editor.cpp msgid "Add Translation" -msgstr "Añadir traducción" +msgstr "Añadir Traducción" #: editor/project_settings_editor.cpp msgid "Remove Translation" -msgstr "Quitar traducción" +msgstr "Eliminar Traducción" #: editor/project_settings_editor.cpp msgid "Add Remapped Path" -msgstr "Añadir ruta remapeada" +msgstr "Añadir Ruta Remapeada" #: editor/project_settings_editor.cpp msgid "Resource Remap Add Remap" -msgstr "Añadir remapeo de recursos" +msgstr "Añadir Remapeo de Recursos" #: editor/project_settings_editor.cpp msgid "Change Resource Remap Language" -msgstr "Cambiar idioma de remapeo de recursos" +msgstr "Cambiar Idioma de Remapeo de Recursos" #: editor/project_settings_editor.cpp msgid "Remove Resource Remap" -msgstr "Quitar remapeo de recursos" +msgstr "Eliminar Remapeo de Recursos" #: editor/project_settings_editor.cpp msgid "Remove Resource Remap Option" -msgstr "Quitar opción de remapeo de recursos" +msgstr "Eliminar Opción de Remapeo de Recursos" #: editor/project_settings_editor.cpp msgid "Changed Locale Filter" -msgstr "Cambiar filtro de localización" +msgstr "Cambiar Filtro de Localización" #: editor/project_settings_editor.cpp msgid "Changed Locale Filter Mode" -msgstr "Modo de filtro de localización cambiado" +msgstr "Cambiar Modo de Filtro Local" #: editor/project_settings_editor.cpp msgid "Project Settings (project.godot)" -msgstr "Ajustes del proyecto (project.godot)" +msgstr "Ajustes del Proyecto (project.godot)" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "General" @@ -9657,13 +9405,12 @@ msgid "Override For..." msgstr "Sustituir por..." #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -#, fuzzy msgid "The editor must be restarted for changes to take effect." -msgstr "Se debe reiniciar el editor para que los cambios surtan efecto" +msgstr "Debe reiniciarse el editor para que los cambios surtan efecto." #: editor/project_settings_editor.cpp msgid "Input Map" -msgstr "Mapa de entradas" +msgstr "Mapa de Entrada" #: editor/project_settings_editor.cpp msgid "Action:" @@ -9715,17 +9462,15 @@ msgstr "Idioma" #: editor/project_settings_editor.cpp msgid "Locales Filter" -msgstr "Filtro de localizaciones" +msgstr "Filtro de Idioma" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show All Locales" -msgstr "Mostrar todas las localizaciones" +msgstr "Mostrar Todos los Idiomas" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show Selected Locales Only" -msgstr "Mostrar solo las configuraciones regionales seleccionadas" +msgstr "Mostrar Sólo las Localizaciones Seleccionadas" #: editor/project_settings_editor.cpp msgid "Filter mode:" @@ -9745,11 +9490,11 @@ msgstr "Cero" #: editor/property_editor.cpp msgid "Easing In-Out" -msgstr "Transición entrada-salida" +msgstr "Easing In-Out" #: editor/property_editor.cpp msgid "Easing Out-In" -msgstr "Transición salida-entrada" +msgstr "Easing Out-In" #: editor/property_editor.cpp msgid "File..." @@ -9765,7 +9510,7 @@ msgstr "Asignar" #: editor/property_editor.cpp msgid "Select Node" -msgstr "Seleccionar nodo" +msgstr "Seleccionar Nodo" #: editor/property_editor.cpp msgid "Error loading file: Not a resource!" @@ -9773,7 +9518,7 @@ msgstr "Error al cargar el archivo: ¡No es un recurso!" #: editor/property_editor.cpp msgid "Pick a Node" -msgstr "Selecciona un nodo" +msgstr "Selecciona un Nodo" #: editor/property_editor.cpp msgid "Bit %d, val %d." @@ -9781,15 +9526,15 @@ msgstr "Bit %d, valor %d." #: editor/property_selector.cpp msgid "Select Property" -msgstr "Seleccionar propiedad" +msgstr "Seleccionar Propiedad" #: editor/property_selector.cpp msgid "Select Virtual Method" -msgstr "Seleccionar método virtual" +msgstr "Seleccionar Método Virtual" #: editor/property_selector.cpp msgid "Select Method" -msgstr "Seleccionar método" +msgstr "Seleccionar Método" #: editor/pvrtc_compress.cpp msgid "Could not execute PVRTC tool:" @@ -9802,7 +9547,7 @@ msgstr "" #: editor/rename_dialog.cpp editor/scene_tree_dock.cpp msgid "Batch Rename" -msgstr "Renombrar en masa" +msgstr "Renombrar por lote" #: editor/rename_dialog.cpp msgid "Prefix" @@ -9813,9 +9558,8 @@ msgid "Suffix" msgstr "Sufijo" #: editor/rename_dialog.cpp -#, fuzzy msgid "Advanced Options" -msgstr "Opciones avanzadas" +msgstr "Opciones Avanzadas" #: editor/rename_dialog.cpp msgid "Substitute" @@ -9851,7 +9595,7 @@ msgstr "" #: editor/rename_dialog.cpp msgid "Per Level counter" -msgstr "Contador por nivel" +msgstr "Contador por Nivel" #: editor/rename_dialog.cpp msgid "If set the counter restarts for each group of child nodes" @@ -9943,19 +9687,19 @@ msgstr "Modo de ejecución:" #: editor/run_settings_dialog.cpp msgid "Current Scene" -msgstr "Escena actual" +msgstr "Escena Actual" #: editor/run_settings_dialog.cpp msgid "Main Scene" -msgstr "Escena principal" +msgstr "Escena Principal" #: editor/run_settings_dialog.cpp msgid "Main Scene Arguments:" -msgstr "Argumentos de escena principal:" +msgstr "Argumentos de Escena Principal:" #: editor/run_settings_dialog.cpp msgid "Scene Run Settings" -msgstr "Ajustes de ejecución de escena" +msgstr "Configuración de Ejecución de Escena" #: editor/scene_tree_dock.cpp msgid "No parent to instance the scenes at." @@ -9975,15 +9719,15 @@ msgstr "" #: editor/scene_tree_dock.cpp msgid "Instance Scene(s)" -msgstr "Instanciar escenas" +msgstr "Instanciar Escena(s)" #: editor/scene_tree_dock.cpp msgid "Instance Child Scene" -msgstr "Instanciar escena hija" +msgstr "Instanciar Escena Hija" #: editor/scene_tree_dock.cpp msgid "Clear Script" -msgstr "Quitar script" +msgstr "Eliminar Script" #: editor/scene_tree_dock.cpp msgid "This operation can't be done on the tree root." @@ -9991,15 +9735,15 @@ msgstr "Esta operación no puede ser hecha en el árbol raÃz." #: editor/scene_tree_dock.cpp msgid "Move Node In Parent" -msgstr "Mover nodo dentro del padre" +msgstr "Mover Nodo Dentro del Padre" #: editor/scene_tree_dock.cpp msgid "Move Nodes In Parent" -msgstr "Mover nodos dentro del padre" +msgstr "Mover Nodos Dentro del Padre" #: editor/scene_tree_dock.cpp msgid "Duplicate Node(s)" -msgstr "Duplicar nodo(s)" +msgstr "Duplicar Nodo(s)" #: editor/scene_tree_dock.cpp msgid "Can't reparent nodes in inherited scenes, order of nodes can't change." @@ -10021,7 +9765,7 @@ msgstr "Convertir nodo como RaÃz" #: editor/scene_tree_dock.cpp msgid "Delete Node(s)?" -msgstr "¿Eliminar nodo(s)?" +msgstr "¿Eliminar Nodo(s)?" #: editor/scene_tree_dock.cpp msgid "Can not perform with the root node." @@ -10033,7 +9777,7 @@ msgstr "Esta operación no puede realizarse en escenas instanciadas." #: editor/scene_tree_dock.cpp msgid "Save New Scene As..." -msgstr "Guardar nueva escena como..." +msgstr "Guardar Nueva Escena Como..." #: editor/scene_tree_dock.cpp msgid "" @@ -10045,7 +9789,7 @@ msgstr "" #: editor/scene_tree_dock.cpp msgid "Editable Children" -msgstr "Hijos editables" +msgstr "Hijos Editables" #: editor/scene_tree_dock.cpp msgid "Load As Placeholder" @@ -10053,7 +9797,7 @@ msgstr "Cargar como Placeholder" #: editor/scene_tree_dock.cpp msgid "Make Local" -msgstr "Crear local" +msgstr "Crear Local" #: editor/scene_tree_dock.cpp msgid "New Scene Root" @@ -10076,9 +9820,8 @@ msgid "User Interface" msgstr "Interfaz de usuario" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Other Node" -msgstr "Eliminar Nodo" +msgstr "Otro Nodo" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" @@ -10094,15 +9837,15 @@ msgstr "Añadir Script" #: editor/scene_tree_dock.cpp msgid "Remove Node(s)" -msgstr "Eliminar nodo(s)" +msgstr "Eliminar Nodo(s)" #: editor/scene_tree_dock.cpp msgid "" "Couldn't save new scene. Likely dependencies (instances) couldn't be " "satisfied." msgstr "" -"No se pudo guardar la escena nueva. Es posible que no se hayan podido " -"resolver las dependencias (instancias)." +"No se pudo guardar la nueva escena. Las posibles dependencias (instancias) " +"no pudieron ser resueltas." #: editor/scene_tree_dock.cpp msgid "Error saving scene." @@ -10118,20 +9861,23 @@ msgstr "Sub-Recursos" #: editor/scene_tree_dock.cpp msgid "Clear Inheritance" -msgstr "Limpiar heredado" +msgstr "Limpiar Heredado" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Open Documentation" -msgstr "Abrir documentación" +msgstr "Abrir Documentación" #: editor/scene_tree_dock.cpp msgid "Add Child Node" -msgstr "Añadir nodo hijo" +msgstr "Añadir Nodo Hijo" + +#: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "Expandir/Colapsar Todo" #: editor/scene_tree_dock.cpp msgid "Change Type" -msgstr "Cambiar tipo" +msgstr "Cambiar Tipo" #: editor/scene_tree_dock.cpp msgid "Extend Script" @@ -10139,27 +9885,27 @@ msgstr "Extender Script" #: editor/scene_tree_dock.cpp msgid "Make Scene Root" -msgstr "Convertir en raÃz de escena" +msgstr "Convertir en RaÃz de Escena" #: editor/scene_tree_dock.cpp msgid "Merge From Scene" -msgstr "Unir desde escena" +msgstr "Unir Desde Escena" #: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp msgid "Save Branch as Scene" -msgstr "Guardar rama como escena" +msgstr "Guardar Rama como Escena" #: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp msgid "Copy Node Path" -msgstr "Copiar ruta del nodo" +msgstr "Copiar Ruta del Nodo" #: editor/scene_tree_dock.cpp msgid "Delete (No Confirm)" msgstr "Eliminar (Sin confirmar)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "Añadir/Crear un nuevo nodo" +msgid "Add/Create a New Node." +msgstr "Añadir/Crear un Nuevo Nodo." #: editor/scene_tree_dock.cpp msgid "" @@ -10191,22 +9937,19 @@ msgstr "¿Quieres limpiar la herencia? (No se puede deshacer)" #: editor/scene_tree_editor.cpp msgid "Toggle Visible" -msgstr "Act/Desact. Visible" +msgstr "Act./Desact. Visible" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Unlock Node" -msgstr "Seleccionar nodo" +msgstr "Desbloquear Nodo" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Button Group" -msgstr "Botón 7" +msgstr "Grupo de Botones" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "(Connecting From)" -msgstr "Error de conexión" +msgstr "(Conectando Desde)" #: editor/scene_tree_editor.cpp msgid "Node configuration warning:" @@ -10237,9 +9980,8 @@ msgstr "" "Haz clic para mostrar el panel de grupos." #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Open Script:" -msgstr "Abrir script" +msgstr "Abrir Script:" #: editor/scene_tree_editor.cpp msgid "" @@ -10259,7 +10001,7 @@ msgstr "" #: editor/scene_tree_editor.cpp msgid "Toggle Visibility" -msgstr "Cambiar visibilidad" +msgstr "Cambiar Visibilidad" #: editor/scene_tree_editor.cpp msgid "" @@ -10276,11 +10018,11 @@ msgstr "" #: editor/scene_tree_editor.cpp msgid "Rename Node" -msgstr "Renombrar nodo" +msgstr "Renombrar Nodo" #: editor/scene_tree_editor.cpp msgid "Scene Tree (Nodes):" -msgstr "Ãrbol de escenas (nodos):" +msgstr "Ãrbol de Escenas (Nodos):" #: editor/scene_tree_editor.cpp msgid "Node Configuration Warning!" @@ -10288,42 +10030,35 @@ msgstr "¡Alerta de configuración de nodos!" #: editor/scene_tree_editor.cpp msgid "Select a Node" -msgstr "Selecciona un nodo" +msgstr "Selecciona un Nodo" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is empty." -msgstr "La ruta está vacia" +msgstr "La ruta está vacÃa." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Filename is empty." -msgstr "Nombre de archivo vacÃo" +msgstr "El nombre del archivo está vacÃo." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is not local." -msgstr "La ruta no es local" +msgstr "La ruta no es local." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid base path." -msgstr "Ruta base incorrecta" +msgstr "Ruta base incorrecta." #: editor/script_create_dialog.cpp -#, fuzzy msgid "A directory with the same name exists." -msgstr "Ya existe un directorio con el mismo nombre" +msgstr "Ya existe un directorio con el mismo nombre." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid extension." -msgstr "La extensión no es correcta" +msgstr "Extensión inválida." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Wrong extension chosen." -msgstr "Se ha elegido una extensión incorrecta" +msgstr "Se ha elegido una extensión incorrecta." #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" @@ -10342,52 +10077,44 @@ msgid "N/A" msgstr "N/D" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Open Script / Choose Location" -msgstr "Abrir script/Elegir ubicación" +msgstr "Abrir Script / Seleccionar Ubicación" #: editor/script_create_dialog.cpp msgid "Open Script" -msgstr "Abrir script" +msgstr "Abrir Script" #: editor/script_create_dialog.cpp -#, fuzzy msgid "File exists, it will be reused." -msgstr "El archivo ya existe, será reutilizado" +msgstr "El archivo ya existe, será reutilizado." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid class name." -msgstr "El nombre de clase no es correcto" +msgstr "Nombre de clase inválido." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid inherited parent name or path." -msgstr "Nombre heredado o ruta inválida" +msgstr "Nombre o ruta del padre heredado inválido." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script is valid." -msgstr "Script válido" +msgstr "El script es válido." #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9 and _" msgstr "Permitido: a-z, A-Z, 0-9 y _" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Built-in script (into scene file)." -msgstr "Script integrado (en el archivo de escena)" +msgstr "Script Integrado (en el archivo de escena)." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will create a new script file." -msgstr "Crear nuevo archivo de script" +msgstr "Se creará un nuevo archivo de script." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will load an existing script file." -msgstr "Cargar archivo de script existente" +msgstr "Se cargará un archivo de script existente." #: editor/script_create_dialog.cpp msgid "Language" @@ -10407,7 +10134,7 @@ msgstr "Plantilla" #: editor/script_create_dialog.cpp msgid "Built-in Script" -msgstr "Script integrado" +msgstr "Script Integrado" #: editor/script_create_dialog.cpp msgid "Attach Node Script" @@ -10429,7 +10156,7 @@ msgstr "Stack Trace" msgid "Pick one or more items from the list to display the graph." msgstr "Elige uno o más elementos de la lista para mostrar el gráfico." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Errores" @@ -10439,7 +10166,7 @@ msgstr "Proceso Hijo Conectado" #: editor/script_editor_debugger.cpp msgid "Copy Error" -msgstr "Error de copia" +msgstr "Error de Copia" #: editor/script_editor_debugger.cpp msgid "Inspect Previous Instance" @@ -10451,7 +10178,7 @@ msgstr "Inspeccionar Instancia Siguiente" #: editor/script_editor_debugger.cpp msgid "Stack Frames" -msgstr "Frames del stack" +msgstr "Frames del Stack" #: editor/script_editor_debugger.cpp msgid "Profiler" @@ -10479,11 +10206,11 @@ msgstr "Total:" #: editor/script_editor_debugger.cpp msgid "Video Mem" -msgstr "Memoria de vÃdeo" +msgstr "Memoria de VÃdeo" #: editor/script_editor_debugger.cpp msgid "Resource Path" -msgstr "Ruta de recursos" +msgstr "Ruta de Recursos" #: editor/script_editor_debugger.cpp msgid "Type" @@ -10507,7 +10234,7 @@ msgstr "Controles seleccionados:" #: editor/script_editor_debugger.cpp msgid "Clicked Control Type:" -msgstr "Tipo de controles seleccionados:" +msgstr "Tipos de Control Seleccionados:" #: editor/script_editor_debugger.cpp msgid "Live Edit Root:" @@ -10515,11 +10242,11 @@ msgstr "RaÃz de edición en vivo:" #: editor/script_editor_debugger.cpp msgid "Set From Tree" -msgstr "Establecer desde árbol" +msgstr "Establecer Desde Ãrbol" #: editor/script_editor_debugger.cpp msgid "Export measures as CSV" -msgstr "" +msgstr "Exportar los datos como CSV" #: editor/settings_config_dialog.cpp msgid "Erase Shortcut" @@ -10539,23 +10266,23 @@ msgstr "Atajos" #: editor/settings_config_dialog.cpp msgid "Binding" -msgstr "Asignación" +msgstr "Binding" #: editor/spatial_editor_gizmos.cpp msgid "Change Light Radius" -msgstr "Cambiar radio de luces" +msgstr "Cambiar Radio de Luces" #: editor/spatial_editor_gizmos.cpp msgid "Change AudioStreamPlayer3D Emission Angle" -msgstr "Cambiar el ángulo de emisión de AudioStreamPlayer3D" +msgstr "Cambiar Ãngulo de Emisión de AudioStreamPlayer3D" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" -msgstr "Cambiar FOV de cámara" +msgstr "Cambiar FOV de Cámara" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera Size" -msgstr "Cambiar tamaño de cámara" +msgstr "Cambiar Tamaño de Cámara" #: editor/spatial_editor_gizmos.cpp msgid "Change Notifier AABB" @@ -10567,51 +10294,51 @@ msgstr "Cambiar partÃculas AABB" #: editor/spatial_editor_gizmos.cpp msgid "Change Probe Extents" -msgstr "Cambiar alcance de la sonda" +msgstr "Cambiar Alcance de la Sonda" #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp msgid "Change Sphere Shape Radius" -msgstr "Cambiar radio de shape esférico" +msgstr "Cambiar Radio de Sphere Shape" #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp msgid "Change Box Shape Extents" -msgstr "Cambiar radio de shape caja" +msgstr "Cambiar Radio de Box Shape" #: editor/spatial_editor_gizmos.cpp msgid "Change Capsule Shape Radius" -msgstr "Cambiar radio de shape cápsula" +msgstr "Cambiar Radio de Capsule Shape" #: editor/spatial_editor_gizmos.cpp msgid "Change Capsule Shape Height" -msgstr "Cambiar altura de shape cápsula" +msgstr "Cambiar Altura de Capsule Shape" #: editor/spatial_editor_gizmos.cpp msgid "Change Cylinder Shape Radius" -msgstr "Cambiar radio de Shape Cilindro" +msgstr "Cambiar Radio de Cylinder Shape" #: editor/spatial_editor_gizmos.cpp msgid "Change Cylinder Shape Height" -msgstr "Cambiar altura de Shape Cilindro" +msgstr "Cambiar Altura de Cylinder Shape" #: editor/spatial_editor_gizmos.cpp msgid "Change Ray Shape Length" -msgstr "Cambiar longitud de forma de rayo" +msgstr "Cambiar Longitud de Ray Shape" #: modules/csg/csg_gizmos.cpp msgid "Change Cylinder Radius" -msgstr "Cambiar Radio de Cilindro" +msgstr "Cambiar Radio de Cylinder" #: modules/csg/csg_gizmos.cpp msgid "Change Cylinder Height" -msgstr "Cambiar Altura de Cilindro" +msgstr "Cambiar Altura de Cylinder" #: modules/csg/csg_gizmos.cpp msgid "Change Torus Inner Radius" -msgstr "Cambiar radio interno de Toro" +msgstr "Cambiar Radio Interno de Torus" #: modules/csg/csg_gizmos.cpp msgid "Change Torus Outer Radius" -msgstr "Cambiar radio externo de Toro" +msgstr "Cambiar Radio Externo de Torus" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Select the dynamic library for this entry" @@ -10639,7 +10366,7 @@ msgstr "Plataforma" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Dynamic Library" -msgstr "LibrerÃa dinámica" +msgstr "LibrerÃa Dinámica" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Add an architecture entry" @@ -10651,12 +10378,11 @@ msgstr "GDNativeLibrary" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Enabled GDNative Singleton" -msgstr "" +msgstr "Activar Singleton GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Disabled GDNative Singleton" -msgstr "Desactivar indicador de actividad" +msgstr "GDNative Singleton desactivado" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Library" @@ -10716,11 +10442,11 @@ msgstr "El objeto no puede proporcionar una longitud." #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Plane" -msgstr "Siguiente plano" +msgstr "Siguiente Plano" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Previous Plane" -msgstr "Plano anterior" +msgstr "Anterior Plano" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Plane:" @@ -10728,11 +10454,11 @@ msgstr "Plano:" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Floor" -msgstr "Siguiente suelo" +msgstr "Siguiente Suelo" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Previous Floor" -msgstr "Suelo anterior" +msgstr "Anterior Suelo" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Floor:" @@ -10740,16 +10466,15 @@ msgstr "Suelo:" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Delete Selection" -msgstr "GridMap Quitar seleccionados" +msgstr "GridMap Eliminar Seleccionados" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Fill Selection" -msgstr "Llenar selección en GridMap" +msgstr "Rellenar Selección en GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Paste Selection" -msgstr "GridMap Quitar seleccionados" +msgstr "Pegar lo Seleccionado en GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Paint" @@ -10757,63 +10482,63 @@ msgstr "Pintar GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Grid Map" -msgstr "Mapa de cuadrÃcula" +msgstr "Grid Map" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Snap View" -msgstr "Anclar Vista" +msgstr "Ajustar Vista" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Disabled" -msgstr "Clip deshabilitado" +msgstr "Clip Deshabilitado" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Above" -msgstr "Clip arriba" +msgstr "Clip Arriba" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Below" -msgstr "Clip debajo" +msgstr "Clip Abajo" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Edit X Axis" -msgstr "Editar eje X" +msgstr "Editar Eje X" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Edit Y Axis" -msgstr "Editar eje Y" +msgstr "Editar Eje Y" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Edit Z Axis" -msgstr "Editar eje Z" +msgstr "Editar Eje Z" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Rotate X" -msgstr "Rotar cursor X" +msgstr "Rotar Cursor X" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Rotate Y" -msgstr "Rotar cursor Y" +msgstr "Rotar Cursor Y" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Rotate Z" -msgstr "Rotar cursor Z" +msgstr "Rotar Cursor Z" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Back Rotate X" -msgstr "Rotar cursor trasero X" +msgstr "Rotar Cursor Trasero X" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Back Rotate Y" -msgstr "Rotar cursor trasero Y" +msgstr "Rotar Cursor Trasero Y" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Back Rotate Z" -msgstr "Rotar cursor trasero Z" +msgstr "Rotar Cursor Trasero Z" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Clear Rotation" -msgstr "Quitar rotación del cursor" +msgstr "Eliminar Rotación del Cursor" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clear Selection" @@ -10821,68 +10546,20 @@ msgstr "Deseleccionar" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Fill Selection" -msgstr "Llenar la selección" +msgstr "Rellenar Selección" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Settings" -msgstr "Ajustes del GridMap" +msgstr "Configuración de GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Pick Distance:" -msgstr "Seleccionar distancia:" +msgstr "Seleccionar Distancia:" #: 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" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Generando solución..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "Generando proyecto C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Fallo al crear solución." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Fallo al guardar solución." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Hecho" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "Fallo al crear proyecto C#." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "Sobre el soporte de C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Crear solución C#" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Compilaciones" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Compilar proyecto" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Ver registro" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Fin del reporte de la pila de excepciones" @@ -10893,7 +10570,7 @@ msgstr "Bake NavMesh" #: modules/recast/navigation_mesh_editor_plugin.cpp msgid "Clear the navigation mesh." -msgstr "Restablecer mesh de navegación." +msgstr "Limpiar el navigation mesh." #: modules/recast/navigation_mesh_generator.cpp msgid "Setting up Configuration..." @@ -10901,7 +10578,7 @@ msgstr "Estableciendo la configuración..." #: modules/recast/navigation_mesh_generator.cpp msgid "Calculating grid size..." -msgstr "Calculando tamaño de cuadrÃcula..." +msgstr "Calculando tamaño de grid..." #: modules/recast/navigation_mesh_generator.cpp msgid "Creating heightfield..." @@ -10933,11 +10610,11 @@ msgstr "Creando polymesh..." #: modules/recast/navigation_mesh_generator.cpp msgid "Converting to native navigation mesh..." -msgstr "Convirtiendo a mesh de navegación nativo..." +msgstr "Convertir a navigation mesh nativo..." #: modules/recast/navigation_mesh_generator.cpp msgid "Navigation Mesh Generator Setup:" -msgstr "Configuración del Generador de Meshes de Navegación:" +msgstr "Configuración del Generador de Navigation Mesh:" #: modules/recast/navigation_mesh_generator.cpp msgid "Parsing Geometry..." @@ -10987,23 +10664,23 @@ msgstr "Desbordamiento de pila en el nivel: " #: modules/visual_script/visual_script_editor.cpp msgid "Change Signal Arguments" -msgstr "Cambiar argumentos de la señal" +msgstr "Cambiar Argumentos de la Señal" #: modules/visual_script/visual_script_editor.cpp msgid "Change Argument Type" -msgstr "Cambiar tipo del argumento" +msgstr "Cambiar Tipo del Argumento" #: modules/visual_script/visual_script_editor.cpp msgid "Change Argument name" -msgstr "Cambiar nombre del argumento" +msgstr "Cambiar Nombre del Argumento" #: modules/visual_script/visual_script_editor.cpp msgid "Set Variable Default Value" -msgstr "Establecer valor por defecto de la variable" +msgstr "Establecer Valor por Defecto de la Variable" #: modules/visual_script/visual_script_editor.cpp msgid "Set Variable Type" -msgstr "Establecer tipo de la variable" +msgstr "Establecer Tipo de la Variable" #: modules/visual_script/visual_script_editor.cpp msgid "Variables:" @@ -11019,39 +10696,39 @@ msgstr "Otra función/variable/señal ya utiliza este nombre:" #: modules/visual_script/visual_script_editor.cpp msgid "Rename Function" -msgstr "Renombrar función" +msgstr "Renombrar Función" #: modules/visual_script/visual_script_editor.cpp msgid "Rename Variable" -msgstr "Renombrar variable" +msgstr "Renombrar Variable" #: modules/visual_script/visual_script_editor.cpp msgid "Rename Signal" -msgstr "Renombrar señal" +msgstr "Renombrar Señal" #: modules/visual_script/visual_script_editor.cpp msgid "Add Function" -msgstr "Añadir función" +msgstr "Añadir Función" #: modules/visual_script/visual_script_editor.cpp msgid "Add Variable" -msgstr "Añadir variable" +msgstr "Añadir Variable" #: modules/visual_script/visual_script_editor.cpp msgid "Add Signal" -msgstr "Añadir señal" +msgstr "Añadir Señal" #: modules/visual_script/visual_script_editor.cpp msgid "Change Expression" -msgstr "Cambiar expresión" +msgstr "Cambiar Expresión" #: modules/visual_script/visual_script_editor.cpp msgid "Remove VisualScript Nodes" -msgstr "Quitar nodos de VisualScript" +msgstr "Eliminar Nodos de VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Duplicate VisualScript Nodes" -msgstr "Duplicar nodos de VisualScript" +msgstr "Duplicar Nodos de VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature." @@ -11062,12 +10739,12 @@ msgstr "" #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a Getter. Hold Shift to drop a generic signature." msgstr "" -"Mantén pulsado Ctrl para soltar un «Getter». Mantén pulsado Mayús para " +"Mantén pulsado Ctrl para soltar un «Getter». Mantén pulsado Shift para " "soltar una signatura genérica." #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a simple reference to the node." -msgstr "Mantén pulsado %s para quitar una referencia simple del nodo." +msgstr "Mantén pulsado %s para eliminar una referencia simple del nodo." #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a simple reference to the node." @@ -11075,7 +10752,7 @@ msgstr "Mantén pulsado Ctrl para soltar una referencia simple al nodo." #: modules/visual_script/visual_script_editor.cpp msgid "Hold %s to drop a Variable Setter." -msgstr "Mantén pulsado %s para quitar un Setter de variable." +msgstr "Mantén pulsado %s para eliminar un Setter de Variable." #: modules/visual_script/visual_script_editor.cpp msgid "Hold Ctrl to drop a Variable Setter." @@ -11083,43 +10760,43 @@ msgstr "Mantén pulsado Ctrl para soltar un Setter de variable." #: modules/visual_script/visual_script_editor.cpp msgid "Add Preload Node" -msgstr "Añadir nodo Preload" +msgstr "Añadir Nodo Preload" #: modules/visual_script/visual_script_editor.cpp msgid "Add Node(s) From Tree" -msgstr "Añadir nodo(s) desde árbol" +msgstr "Añadir Nodo(s) Desde Ãrbol" #: modules/visual_script/visual_script_editor.cpp msgid "Add Getter Property" -msgstr "Añadir propiedad Getter" +msgstr "Añadir Propiedad Getter" #: modules/visual_script/visual_script_editor.cpp msgid "Add Setter Property" -msgstr "Añadir propiedad Setter" +msgstr "Añadir Propiedad Setter" #: modules/visual_script/visual_script_editor.cpp msgid "Change Base Type" -msgstr "Cambiar tipo base" +msgstr "Cambiar Tipo Base" #: modules/visual_script/visual_script_editor.cpp msgid "Move Node(s)" -msgstr "Mover nodo(s)" +msgstr "Mover Nodo(s)" #: modules/visual_script/visual_script_editor.cpp msgid "Remove VisualScript Node" -msgstr "Quitar nodo de VisualScript" +msgstr "Eliminar Nodo de VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Connect Nodes" -msgstr "Conectar nodos" +msgstr "Conectar Nodos" #: modules/visual_script/visual_script_editor.cpp msgid "Connect Node Data" -msgstr "Conectar datos de nodos" +msgstr "Conectar Datos de Nodos" #: modules/visual_script/visual_script_editor.cpp msgid "Connect Node Sequence" -msgstr "Conectar secuencia de nodos" +msgstr "Conectar Secuencia de Nodos" #: modules/visual_script/visual_script_editor.cpp msgid "Script already has function '%s'" @@ -11127,7 +10804,7 @@ msgstr "El script ya contiene la función '%s'" #: modules/visual_script/visual_script_editor.cpp msgid "Change Input Value" -msgstr "Cambiar valor de entrada" +msgstr "Cambiar Valor de Entrada" #: modules/visual_script/visual_script_editor.cpp msgid "Resize Comment" @@ -11147,19 +10824,19 @@ msgstr "Pegar nodos de VisualScript" #: modules/visual_script/visual_script_editor.cpp msgid "Remove Function" -msgstr "Quitar función" +msgstr "Eliminar Función" #: modules/visual_script/visual_script_editor.cpp msgid "Remove Variable" -msgstr "Quitar variable" +msgstr "Eliminar Variable" #: modules/visual_script/visual_script_editor.cpp msgid "Editing Variable:" -msgstr "Editando variable:" +msgstr "Editar Variable:" #: modules/visual_script/visual_script_editor.cpp msgid "Remove Signal" -msgstr "Quitar señal" +msgstr "Eliminar Señal" #: modules/visual_script/visual_script_editor.cpp msgid "Editing Signal:" @@ -11167,7 +10844,7 @@ msgstr "Editando señal:" #: modules/visual_script/visual_script_editor.cpp msgid "Base Type:" -msgstr "Tipo base:" +msgstr "Tipo Base:" #: modules/visual_script/visual_script_editor.cpp msgid "Members:" @@ -11178,29 +10855,28 @@ msgid "Available Nodes:" msgstr "Nodos disponibles:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Select or create a function to edit its graph." -msgstr "Selecciona o crea una función para editar el gráfico" +msgstr "Selecciona o crea una función para editar el gráfico." #: modules/visual_script/visual_script_editor.cpp msgid "Delete Selected" -msgstr "Quitar seleccionados" +msgstr "Eliminar Seleccionados" #: modules/visual_script/visual_script_editor.cpp msgid "Find Node Type" -msgstr "Buscar tipo de nodo" +msgstr "Buscar Tipo de Nodo" #: modules/visual_script/visual_script_editor.cpp msgid "Copy Nodes" -msgstr "Copiar nodos" +msgstr "Copiar Nodos" #: modules/visual_script/visual_script_editor.cpp msgid "Cut Nodes" -msgstr "Cortar nodos" +msgstr "Cortar Nodos" #: modules/visual_script/visual_script_editor.cpp msgid "Paste Nodes" -msgstr "Pegar nodos" +msgstr "Pegar Nodos" #: modules/visual_script/visual_script_editor.cpp msgid "Edit Member" @@ -11278,7 +10954,7 @@ msgstr "Establecer %s" #: platform/android/export/export.cpp msgid "Package name is missing." -msgstr "Nombre de paquete faltante." +msgstr "Falta el nombre del paquete." #: platform/android/export/export.cpp msgid "Package segments must be of non-zero length." @@ -11305,28 +10981,35 @@ msgstr "El paquete debe tener al menos un '.' como separador." #: platform/android/export/export.cpp msgid "ADB executable not configured in the Editor Settings." -msgstr "Ejecutable ADB no configurado en Ajustes del Editor." +msgstr "Ejecutable ADB no configurado en Configuración del Editor." #: platform/android/export/export.cpp msgid "OpenJDK jarsigner not configured in the Editor Settings." -msgstr "OpenJDK jarsigner no configurado en Ajustes del Editor." +msgstr "OpenJDK jarsigner no configurado en Configuración del Editor." #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." -msgstr "Keystore debug no configurada en Ajustes del Editor ni en el preset." +msgstr "" +"Keystore debug no configurada en Configuración del Editor ni en el preset." #: platform/android/export/export.cpp 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." #: 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." #: platform/android/export/export.cpp msgid "" "Android project is not installed for compiling. Install from Editor menu." msgstr "" +"El proyecto Android no está instalado para la compilación. Instálalo desde " +"el menú Editor." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -11341,6 +11024,9 @@ msgid "" "Trying to build from a custom built template, but no version info for it " "exists. Please reinstall from the 'Project' menu." msgstr "" +"Intentando construir a partir de una plantilla personalizada, pero no existe " +"información de la versión para ello. Por favor, reinstala desde el menú " +"'Proyecto'." #: platform/android/export/export.cpp msgid "" @@ -11349,20 +11035,28 @@ msgid "" " Godot Version: %s\n" "Please reinstall Android build template from 'Project' menu." msgstr "" +"La versión de compilación de Android no coincide:\n" +" Plantilla instalada: %s\n" +" Versión de Godot: %s\n" +"Por favor, reinstala la plantilla de compilación de Android desde el menú " +"'Proyecto'." #: platform/android/export/export.cpp msgid "Building Android Project (gradle)" -msgstr "" +msgstr "Construir Proyecto Android (gradle)" #: platform/android/export/export.cpp msgid "" "Building of Android project failed, check output for the error.\n" "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" +"La construcción del proyecto Android falló, comprueba la salida del error.\n" +"También puedes visitar docs.godotengine.org para consultar la documentación " +"de compilación de Android." #: platform/android/export/export.cpp msgid "No build apk generated at: " -msgstr "" +msgstr "No se ha generado ninguna compilación apk en: " #: platform/iphone/export/export.cpp msgid "Identifier is missing." @@ -11407,7 +11101,7 @@ msgstr "El icono requerido no está especificado en el preset." #: platform/javascript/export/export.cpp msgid "Run in Browser" -msgstr "Ejecutar en navegador" +msgstr "Ejecutar en Navegador" #: platform/javascript/export/export.cpp msgid "Run exported HTML in the system's default browser." @@ -11495,12 +11189,13 @@ msgstr "" "Las dimensiones de la imagen del splash son inválidas (deberÃa ser 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" -"Se debe crear un recurso SpriteFrames o asignar uno en la propiedad 'Frames' " -"para que AnimatedSprite pueda mostrar fotogramas." +"Se debe crear o establecer un recurso SpriteFrames en la propiedad 'Frames' " +"para que AnimatedSprite pueda mostrar frames." #: scene/2d/canvas_modulate.cpp msgid "" @@ -11564,8 +11259,9 @@ msgstr "" "\"Particles Animation\" activado." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Se debe asignar una textura con la forma de la luz a la propiedad 'texture'." @@ -11578,7 +11274,8 @@ msgstr "" "tenga efecto." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "El polÃgono oclusor para este oclusor esta vacÃo. Por favor, ¡dibuja un " "polÃgono!" @@ -11669,50 +11366,57 @@ msgstr "" "Este hueso no tiene una pose de DESCANSO adecuada. Ve al nodo Skeleton2D y " "asÃgnale una." +#: 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 "" +"TileMap con Use Parent activado necesita un CollisionObject2D padre para " +"darle forma. Por favor, úsalo como hijo de Area2D, StaticBody2D, " +"RigidBody2D, KinematicBody2D, etc. para que puedan tener forma." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D funciona mejor cuando se usa directamente con la raÃz de " "la escena editada como padre." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera tiene que tener un nodo ARVROrigin como padre" #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRController must have an ARVROrigin node as its parent." -msgstr "ARVRController tiene que tener un nodo ARVROrigin como padre" +msgstr "ARVRController debe tener un nodo ARVROrigin como padre." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The controller ID must not be 0 or this controller won't be bound to an " "actual controller." msgstr "" -"El id del controlador no puede ser 0 o este controlador no será asignado a " -"un controlador de verdad" +"El ID del controlador no debe ser 0 o este controlador no estará asociado a " +"un controlador real." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRAnchor must have an ARVROrigin node as its parent." -msgstr "ARVRAnchor tiene que tener un nodo ARVROrigin como padre" +msgstr "ARVRAnchor debe tener un nodo ARVROrigin como su padre." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The anchor ID must not be 0 or this anchor won't be bound to an actual " "anchor." msgstr "" -"El id del ancla no puede ser 0 o este ancla no será asignada a un ancla de " -"verdad" +"El ID del ancla no puede ser 0 o este ancla no estará asociada a una ancla " +"real." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVROrigin requires an ARVRCamera child node." -msgstr "ARVROrigin necesita un nodo ARVRCamera hijo" +msgstr "ARVROrigin requiere un nodo hijo ARVRCamera." #: scene/3d/baked_lightmap.cpp msgid "%d%%" @@ -11724,19 +11428,19 @@ msgstr "(Tiempo restante: %d:%02d s)" #: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " -msgstr "Trazando mallas: " +msgstr "Trazando Meshes: " #: scene/3d/baked_lightmap.cpp msgid "Plotting Lights:" -msgstr "Trazando iluminación:" +msgstr "Trazando Iluminación:" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Finishing Plot" -msgstr "Desentramado final" +msgstr "Finalizar Trazado" #: scene/3d/baked_lightmap.cpp msgid "Lighting Meshes: " -msgstr "Iluminando mallas: " +msgstr "Iluminando Meshes: " #: scene/3d/collision_object.cpp msgid "" @@ -11774,9 +11478,10 @@ msgstr "" "RigidBody, KinematicBody, etc. para darles dicha forma." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Se debe proveer de una forma a CollisionShape para que funcione. Por favor, " "¡crea un recurso \"shape\"!" @@ -11794,17 +11499,16 @@ msgid "Nothing is visible because no mesh has been assigned." msgstr "Nada visible ya que no se asignó ningún mesh." #: scene/3d/cpu_particles.cpp -#, fuzzy msgid "" "CPUParticles animation requires the usage of a SpatialMaterial whose " "Billboard Mode is set to \"Particle Billboard\"." msgstr "" -"La animación CPUParticles requiere el uso de un SpatialMaterial con " -"\"Billboard Particles\" activado." +"La animación de CPUParticles requiere el uso de un SpatialMaterial cuyo Modo " +"Billboard esté ajustado a \"Particle Billboard\"." #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" -msgstr "Trazando mallas" +msgstr "Trazando Meshes" #: scene/3d/gi_probe.cpp msgid "" @@ -11814,6 +11518,10 @@ msgstr "" "Las GIProbes no están soportadas por el controlador de video GLES2.\n" "Usa un BakedLightmap en su lugar." +#: 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 "" @@ -11846,13 +11554,12 @@ msgstr "" "Nada es visible porque las mallas no se han asignado a los pases de dibujo." #: scene/3d/particles.cpp -#, fuzzy msgid "" "Particles animation requires the usage of a SpatialMaterial whose Billboard " "Mode is set to \"Particle Billboard\"." msgstr "" -"La animación de partÃculas requiere el uso de un SpatialMaterial con " -"\"Billboard Particles\" activado." +"La animación de partÃculas requiere el uso de un SpatialMaterial cuyo Modo " +"Billboard esté ajustado a \"Particle Billboard\"." #: scene/3d/path.cpp msgid "PathFollow only works when set as a child of a Path node." @@ -11860,9 +11567,10 @@ msgstr "" "PathFollow solo funciona cuando está asignado como hijo de un nodo Path." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED requiere que \"Up Vector\" esté activo en el " "recurso Curve de su Path padre." @@ -11878,14 +11586,16 @@ msgstr "" "En lugar de esto, cambie el tamaño en las formas de colisión hijas." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "La propiedad Path debe apuntar a un nodo Spatial válido para funcionar." #: scene/3d/soft_body.cpp -#, fuzzy msgid "This body will be ignored until you set a mesh." -msgstr "Este cuerpo sera ignorado hasta que le asignes un mesh" +msgstr "Este cuerpo será ignorado hasta que se establezca un mesh." #: scene/3d/soft_body.cpp msgid "" @@ -11898,12 +11608,13 @@ msgstr "" "En su lugar, cambia el tamaño de los collision shapes hijos." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" -"Se debe crear un recurso \"SpriteFrames\" y asignarlo en la propiedad " -"'Frames' para que AnimatedSprite3D pueda mostrar fotogramas." +"Se debe crear o establecer un recurso SpriteFrames en la propiedad 'Frames' " +"para que AnimatedSprite3D pueda mostrar frames." #: scene/3d/vehicle_body.cpp msgid "" @@ -11914,8 +11625,10 @@ msgstr "" "Por favor, úselo como hijo de un VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment necesita un recurso Environment." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11954,7 +11667,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Nada conectado a la entrada '%s' del nodo '%s'." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "No hay asignado ningún nodo AnimationNode raÃz para el gráfico." #: scene/animation/animation_tree.cpp @@ -11968,7 +11682,8 @@ msgstr "" "La ruta asignada al AnimationPlayer no apunta a un nodo AnimationPlayer." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "La raÃz del AnimationPlayer no es un nodo válido." #: scene/animation/animation_tree_player.cpp @@ -11980,8 +11695,12 @@ msgid "Pick a color from the screen." msgstr "Selecciona un color de la pantalla." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Modo Raw" +msgid "HSV" +msgstr "HSV" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "Raw" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11994,15 +11713,23 @@ msgstr "Añadir el color actual como preset." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." +msgstr "" +"Container por sà mismo no sirve para nada a menos que un script defina el " +"comportamiento de colocación de sus hijos.\n" +"Si no tienes intención de añadir un script, utiliza un nodo 'Control' " +"sencillo." + +#: 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 "" -"El contenedor por sà mismo no sirve para nada a menos que un script " -"configure el comportamiento de posicionamiento de sus hijos.\n" -"Si no tienes intención de añadir un script, utiliza en su lugar un nodo " -"'Control' sencillo." +"Los Tooltip de Ayuda no se mostrarán cuando los controles del Filtro del " +"Ratón estén configurados en \"Ignore\". Para solucionarlo, establece el " +"Filtro del Ratón en \"Stop\" o \"Pass\"." #: scene/gui/dialogs.cpp msgid "Alert!" @@ -12010,26 +11737,29 @@ msgstr "¡Alerta!" #: scene/gui/dialogs.cpp msgid "Please Confirm..." -msgstr "Por favor, confirma..." +msgstr "Por favor, Confirma..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Los popups se esconderán por defecto a menos que llames a popup() o " "cualquiera de las funciones popup*(). Sin embargo, no hay problema con " "hacerlos visibles para editar, aunque se esconderán al ejecutar." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Si exp_edit es `true` min_value debe ser > 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer está pensado para funcionar con un control hijo únicamente.\n" @@ -12081,6 +11811,11 @@ msgid "Input" msgstr "Entrada" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Fuente inválida para el shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Fuente inválida para el shader." @@ -12098,7 +11833,242 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice." #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "Las constantes no pueden modificarse." + +#~ msgid "Generating solution..." +#~ msgstr "Generando solución..." + +#~ msgid "Generating C# project..." +#~ msgstr "Generando proyecto C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "Fallo al crear solución." + +#~ 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#." + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "Sobre el soporte de C#" + +#~ msgid "Create C# solution" +#~ msgstr "Crear solución C#" + +#~ msgid "Builds" +#~ msgstr "Compilaciones" + +#~ msgid "Build Project" +#~ msgstr "Compilar proyecto" + +#~ msgid "View log" +#~ msgstr "Ver registro" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment necesita un recurso Environment." + +#~ msgid "Enabled Classes" +#~ msgstr "Clases Activadas" + +#~ msgid "Update Always" +#~ msgstr "Actualizar Siempre" + +#~ msgid "'camera' input parameter for all shader modes." +#~ msgstr "Parámetro de entrada de 'camera' para todos los modos de shader." + +#~ msgid "'inv_camera' input parameter for all shader modes." +#~ msgstr "Parámetro de entrada 'inv_camera' para todos los modos de shader." + +#~ msgid "'inv_projection' input parameter for all shader modes." +#~ msgstr "" +#~ "Parámetro de entrada' inv_projection' para todos los modos de shader." + +#~ msgid "'normal' input parameter for all shader modes." +#~ msgstr "Parámetro de entrada 'normal' para todos los modos de shader." + +#~ msgid "'projection' input parameter for all shader modes." +#~ msgstr "Parámetro de entrada 'projection' para todos los modos de shader." + +#~ msgid "'time' input parameter for all shader modes." +#~ msgstr "Parámetro de entrada 'time' para todos los modos de shader." + +#~ msgid "'viewport_size' input parameter for all shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'viewport_size' para todos los modos de shader." + +#~ msgid "'world' input parameter for all shader modes." +#~ msgstr "Parámetro de entrada 'world' para todos los modos de shader." + +#~ msgid "'alpha' input parameter for all shader modes." +#~ msgstr "Parámetro de entrada 'alpha' para todos los modos de shader." + +#~ msgid "'color' input parameter for all shader modes." +#~ msgstr "Parámetro de entrada 'color' para todos los modos de shader." + +#~ msgid "'texture_pixel_size' input parameter for all shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'texture_pixel_size' para todos los modos de shader." + +#~ msgid "'alpha' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'alpha' para vértices y fragmentos en modo shader." + +#~ msgid "'binormal' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'binormal' para vértices y fragmentos en modo shader." + +#~ msgid "'color' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'color' para vértices y fragmentos en modo shader." + +#~ msgid "'fragcoord' input parameter for fragment and light shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'fragcoord' para fragmentos y luces en modo shader." + +#~ msgid "'point_coord' input parameter for fragment shader mode." +#~ msgstr "" +#~ "Parámetro de entrada 'point_coord' para fragmentos en modo de shader." + +#~ msgid "'screen_uv' input parameter for fragment shader mode." +#~ msgstr "Parámetro de entrada 'screen_uv' para fragmentos en modo de shader." + +#~ msgid "'tangent' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'tangent' para vértices y fragmentos en modo shader." + +#~ msgid "'uv2' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'uv2' para vértices y fragmentos en modo shader." + +#~ msgid "'vertex' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'vertex' para vértices y fragmentos en modo shader." + +#~ msgid "'albedo' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'albedo' para luces en modo shader." + +#~ msgid "'attenuation' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'attenuation' para luces en modo shader." + +#~ msgid "'light' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'light' para luces en modo shader." + +#~ msgid "'light_color' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'light_color' para luces en modo shader." + +#~ msgid "'roughness' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'roughness' para luces en modo shader." + +#~ msgid "'specular' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'specular' para luces en modo shader." + +#~ msgid "'transmission' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'transmission' para luces en modo shader." + +#~ msgid "'modelview' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'modelview' para vértices en modo shader." + +#~ msgid "'point_size' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'point_size' para vértices en modo shader." + +#~ msgid "'tangent' input parameter for vertex and fragment shader mode." +#~ msgstr "" +#~ "Parámetro de entrada 'tangent' para vértices y fragmentos en modo shader." + +#~ msgid "'light_pass' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'light_pass' para vértices y fragmentos en modo " +#~ "shader." + +#~ msgid "'point_coord' input parameter for fragment and light shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'point_coord' para fragmentos y luces en modo shader." + +#~ msgid "'screen_pixel_size' input parameter for fragment shader mode." +#~ msgstr "" +#~ "Parámetro de entrada 'screen_pixel_size' para fragmentos en modo de " +#~ "shader." + +#~ msgid "'screen_uv' input parameter for fragment and light shader modes." +#~ msgstr "" +#~ "Parámetro de entrada 'screen_uv' para fragmentos y luces en modo shader." + +#~ msgid "'light_alpha' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'light_alpha' para luces en modo shader." + +#~ msgid "'light_height' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'light_height' para luces en modo shader." + +#~ msgid "'light_uv' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'light_uv' para luces en modo shader." + +#~ msgid "'light_vec' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'light_vec' para luces en modo shader." + +#~ msgid "'normal' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'normal' para luces en modo shader." + +#~ msgid "'shadow_color' input parameter for light shader mode." +#~ msgstr "Parámetro de entrada 'shadow_color' para luces en modo shader." + +#~ msgid "'extra' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'extra' para vértices en modo shader." + +#~ msgid "'projection' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'projection' para vértices en modo shader." + +#~ msgid "'vertex' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'vertex' para vértices en modo shader." + +#~ msgid "'world' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'world' para vértices en modo shader." + +#~ msgid "'active' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'active' para vértices en modo shader." + +#~ msgid "'alpha' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'alpha' para vértices en modo shader." + +#~ msgid "'color' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'color' para vértices en modo shader." + +#~ msgid "'custom_alpha' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'custom_alpha' para vértices en modo shader." + +#~ msgid "'delta' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'delta' para vértices en modo shader." + +#~ msgid "'emission_transform' input parameter for vertex shader mode." +#~ msgstr "" +#~ "Parámetro de entrada 'emission_transform' para vértices en modo shader." + +#~ msgid "'index' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'index' para vértices en modo shader." + +#~ msgid "'lifetime' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'lifetime' para vértices en modo shader." + +#~ msgid "'restart' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'restart' para vértices en modo shader." + +#~ msgid "'time' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'time' para vértices en modo shader." + +#~ msgid "'transform' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'transform' para vértices en modo shader." + +#~ msgid "'velocity' input parameter for vertex shader mode." +#~ msgstr "Parámetro de entrada 'velocity' para vértices en modo shader." + +#~ msgid "Raw Mode" +#~ msgstr "Modo Raw" #~ msgid "Path to Node:" #~ msgstr "Ruta al nodo:" @@ -12663,9 +12633,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Act/desact. Spatial visible" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Act/desact. CanvasItem visible" - #~ msgid "Condition" #~ msgstr "Condición" @@ -13638,9 +13605,6 @@ msgstr "" #~ msgid "Images:" #~ msgstr "Imágenes:" -#~ msgid "Select None" -#~ msgstr "Deseleccionar todo" - #~ msgid "Group" #~ msgstr "Grupo" diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po index cc6522a41a..185b50f0c6 100644 --- a/editor/translations/es_AR.po +++ b/editor/translations/es_AR.po @@ -16,7 +16,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-05-28 10:40+0000\n" +"PO-Revision-Date: 2019-07-09 10:47+0000\n" "Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n" "Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/" "godot-engine/godot/es_AR/>\n" @@ -25,7 +25,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -85,9 +85,8 @@ msgid "Time:" msgstr "Tiempo:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Valor" +msgstr "Valor:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -443,10 +442,28 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Esta animación pertenece a una escena importada, por lo que los cambios en " +"las pistas importadas no se guardarán.\n" +"\n" +"Para habilitar la capacidad de añadir pistas personalizadas, andá a la " +"configuración de importación de la escena y establece\n" +"\"Animation > Storage\" a \"Files\", activa \"Animation > Keep Custom Tracks" +"\", y luego reimporta.\n" +"También podés usar un preset de importación que importa animaciones a " +"archivos separados." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Advertencia: Se esta editando una animación importada" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Seleccionar Todo" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "No Seleccionar Ninguno" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -622,6 +639,10 @@ msgstr "Ir a LÃnea" msgid "Line Number:" msgstr "Numero de LÃnea:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Sin Coincidencias" @@ -671,7 +692,7 @@ msgstr "Alejar Zoom" msgid "Reset Zoom" msgstr "Resetear el Zoom" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Advertencias" @@ -680,38 +701,32 @@ msgid "Line and column numbers." msgstr "Números de lÃnea y columna." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "El método en el Nodo objetivo debe ser especificado!" +msgstr "El método en el nodo objetivo debe ser especificado." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"El método objetivo no fue encontrado! Especificá un método válido o agregá " -"un script al Nodo objetivo." +"El método objetivo no fue encontrado. Especificá un método válido o agregá " +"un script al nodo objetivo." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "Conectar a Nodo:" +msgstr "Conectar al Nodo:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "No se puede conectar al host:" +msgstr "Conectar al Script:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Señales:" +msgstr "Desde la Señal:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "El nodo no contiene geometrÃa." +msgstr "La escena no contiene ningún script." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -739,9 +754,8 @@ msgid "Extra Call Arguments:" msgstr "Argumentos de Llamada Extras:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Opciones avanzadas" +msgstr "Avanzado" #: editor/connections_dialog.cpp msgid "Deferred" @@ -751,6 +765,8 @@ msgstr "Diferido" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Difiere la señal, almacenándola en una cola y solo disparándola en tiempo de " +"inactividad." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -758,12 +774,11 @@ msgstr "Oneshot" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Desconecta la señal después de su primera emisión." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Conectar Señal: " +msgstr "No se puede conectar la señal" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -784,6 +799,11 @@ msgid "Connect" msgstr "Conectar" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Señales:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Conectar '%s' a '%s'" @@ -805,14 +825,12 @@ msgid "Disconnect" msgstr "Desconectar" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Conectar Señal: " +msgstr "Conectar una Señal a un Método" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Editar Conexión: " +msgstr "Editar Conexión:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -889,20 +907,20 @@ msgid "Dependencies For:" msgstr "Dependencias Para:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" -"La Escena '%s' esté siendo editada actualmente.\n" -"Los cambios no tendrán efecto hasta recargarlo." +"La Escena '%s' está siendo editada.\n" +"Los cambios solo tendrán efecto al recargarla." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." -msgstr "El recurso '%s' está en uso. Los cambios tendrán efecto al recargarlo." +msgstr "" +"El recurso '%s' está en uso.\n" +"Los cambios solo tendrán efecto al recargarlo." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -924,7 +942,7 @@ msgstr "Dependencias:" #: editor/dependency_editor.cpp msgid "Fix Broken" -msgstr "Arreglar Rota(s)" +msgstr "Corregir Errores" #: editor/dependency_editor.cpp msgid "Dependency Editor" @@ -949,7 +967,8 @@ msgid "Owners Of:" msgstr "Dueños De:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Quitar los archivos seleccionados del proyecto? (imposible deshacer)" #: editor/dependency_editor.cpp @@ -976,28 +995,27 @@ msgstr "Fallo la carga debido a dependencias faltantes:" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Open Anyway" -msgstr "Abrir de Todos Modos" +msgstr "Abrir Igualmente" #: editor/dependency_editor.cpp msgid "Which action should be taken?" -msgstr "Que Acción Se DeberÃa Tomar?" +msgstr "¿Qué acciones se deberÃan tomar?" #: editor/dependency_editor.cpp msgid "Fix Dependencies" -msgstr "Arreglar Dependencias" +msgstr "Corregir Dependencias" #: editor/dependency_editor.cpp msgid "Errors loading!" -msgstr "Errores al cargar!" +msgstr "¡Errores al cargar!" #: editor/dependency_editor.cpp msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Eliminar permanentemente %d item(s)? (Imposible deshacer!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "Dependencias" +msgstr "Mostrar Dependencias" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1130,7 +1148,7 @@ msgstr "El Paquete se instaló exitosamente!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Success!" -msgstr "¡Conseguido!" +msgstr "¡Éxito!" #: editor/editor_asset_installer.cpp editor/editor_node.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -1163,7 +1181,7 @@ msgstr "Act./Desact. Solo de Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Mute" -msgstr "Slienciar/Desilenciar Bus de Audio" +msgstr "Act./Desact. Silencio de Bus de Audio" #: editor/editor_audio_buses.cpp msgid "Toggle Audio Bus Bypass Effects" @@ -1260,7 +1278,7 @@ msgstr "Abrir Layout de Bus de Audio" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "No hay ningún archivo `%s'." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1306,7 +1324,7 @@ msgstr "Cargar el Bus Layout predeterminado." #: editor/editor_audio_buses.cpp msgid "Create a new Bus Layout." -msgstr "Crear un nuevo Layout Bus." +msgstr "Crear un nuevo Bus Layout." #: editor/editor_autoload_settings.cpp msgid "Invalid name." @@ -1317,29 +1335,20 @@ msgid "Valid characters:" msgstr "Caracteres válidos:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"Nombre inválido. No debe colisionar con un nombre existente de clases del " -"engine." +msgstr "No debe coincidir con el nombre de una clase ya existente del motor." #: editor/editor_autoload_settings.cpp -#, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "" -"Nombre inválido. No debe colisionar con un nombre existente de un tipo built-" -"in." +msgid "Must not collide with an existing built-in type name." +msgstr "No debe coincidir con el nombre de un tipo built-in ya existente." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." -msgstr "" -"Nombre inválido. No debe colisionar con un nombre de constante global " -"existente." +msgstr "No debe coincidir con un nombre de constante global existente." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "La palabra clave no se puede utilizar como nombre de autoload." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1370,7 +1379,6 @@ msgid "Rearrange Autoloads" msgstr "Reordenar Autoloads" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "Ruta inválida." @@ -1425,9 +1433,8 @@ msgid "[unsaved]" msgstr "[sin guardar]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Por favor elegà un directorio base primero" +msgstr "Por favor elegà un directorio base primero." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1511,122 +1518,111 @@ msgstr "Plantilla release personalizada no encontrada." msgid "Template file not found:" msgstr "Plantilla no encontrada:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Editor" +msgstr "Editor 3D" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Abrir en Editor de Script" +msgstr "Editor de Scripts" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Abrir Biblioteca de Assets" +msgstr "Biblioteca de Assets" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Arbol de Escenas (Nodos):" +msgstr "Edición de Ãrbol de Escenas" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Importar" +msgstr "Dock de Importación" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "Nodo Movido" +msgstr "Dock de Nodos" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Filesystem Dock" -msgstr "Sistema de Archivos" +msgid "FileSystem and Import Docks" +msgstr "Docks de Sistema de Archivos e Importación" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Reemplazar todo (no se puede deshacer)" +msgstr "¿Borrar perfil '%s'? (no se puede deshacer)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" msgstr "" +"El perfil debe tener un nombre de archivo válido y no debe contener '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Un archivo o carpeta con este nombre ya existe." +msgstr "Ya existe un perfil con este nombre." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Editor Desactivado, Propiedades Desactivadas)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Solo Propiedades" +msgstr "(Propiedades Desactivadas)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Clip Desactivado" +msgstr "(Editor Desactivado)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Descripción de Clase:" +msgstr "Opciones de Clase:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Abrir el Editor siguiente" +msgstr "Activar el Editor Contextual" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Propiedades:" +msgstr "Propiedades Activadas:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "CaracterÃsticas" +msgstr "CaracterÃsticas Activadas:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Buscar Clases" +msgstr "Clases Activadas:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." msgstr "" +"El formato '%s' del archivo no es válido, la importación ha sido cancelada." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"El perfil '%s' ya existe. Eliminalo primero antes de importar, la " +"importación ha sido cancelada." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Error al cargar la plantilla '%s'" +msgstr "Error al guardar el perfil en la ruta: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Desactivar" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Current Profile" -msgstr "Version Actual:" +msgid "Current Profile:" +msgstr "Perfil Actual:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Actual:" +msgstr "Hacer Actual" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1644,44 +1640,32 @@ msgid "Export" msgstr "Exportar" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Available Profiles" -msgstr "Nodos Disponibles:" +msgid "Available Profiles:" +msgstr "Perfiles Disponibles:" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Buscar Clases" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Descripción de Clase" +msgstr "Opciones de Clase" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Nuevo nombre:" +msgstr "Nuevo nombre de perfil:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Borrar Ãrea" +msgstr "Borrar Perfil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Proyecto Importado" +msgstr "Importar Perfil(es)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Exportar Proyecto" +msgstr "Exportar Perfil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "Gestionar Plantillas de Exportación" +msgstr "Administrar Perfiles de CaracterÃsticas del Editor" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1718,7 +1702,7 @@ msgstr "Refrescar" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Recognized" -msgstr "Todas Reconocidas" +msgstr "Todos Reconocidos" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Files (*)" @@ -1804,9 +1788,8 @@ msgid "(Un)favorite current folder." msgstr "Quitar carpeta actual de favoritos." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Act/Desact. Archivos Ocultos" +msgstr "Ver/Ocultar archivos ocultos." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1836,13 +1819,15 @@ msgstr "Debe ser una extensión válida." #: editor/editor_file_system.cpp msgid "ScanSources" -msgstr "EscanearFuentes" +msgstr "Escanear Fuentes" #: editor/editor_file_system.cpp msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"Hay varios importadores para diferentes tipos que apuntan al archivo %s, " +"importación abortada" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -1967,7 +1952,7 @@ msgid "" "There is currently no description for this method. Please help us by [color=" "$color][url=$url]contributing one[/url][/color]!" msgstr "" -"Actualmente no existe descripción para este método. Por favor ayudanos " +"Actualmente no existe descripción para este método. Por favor ayúdanos " "[color=$color][url=$url]contribuyendo una[/url][/color]!" #: editor/editor_help_search.cpp editor/editor_node.cpp @@ -2080,11 +2065,11 @@ msgstr "No se puede abrir el archivo para escribir:" #: editor/editor_node.cpp msgid "Requested file format unknown:" -msgstr "Formato requerido de archivo desconocido:" +msgstr "Formato de archivo requerido desconocido:" #: editor/editor_node.cpp msgid "Error while saving." -msgstr "Error al grabar." +msgstr "Error al guardar." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Can't open '%s'. The file could have been moved or deleted." @@ -2101,7 +2086,7 @@ msgstr "Final de archivo inesperado en '%s'." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." -msgstr "No se encuentra '%s' o sus dependecias." +msgstr "No se encuentra '%s' o sus dependencias." #: editor/editor_node.cpp msgid "Error while loading '%s'." @@ -2166,7 +2151,7 @@ msgstr "Error al tratar de guardar el layout!" #: editor/editor_node.cpp msgid "Default editor layout overridden." -msgstr "Layout por defecto del editor sobreescrito." +msgstr "Se ha sobreescrito el layout del editor por defecto." #: editor/editor_node.cpp msgid "Layout name not found!" @@ -2188,13 +2173,13 @@ msgstr "" "mejor este workflow." #: editor/editor_node.cpp -#, fuzzy msgid "" "This resource belongs to a scene that was instanced or inherited.\n" "Changes to it won't be kept when saving the current scene." msgstr "" -"Este recurso pertenece a una escena que fue instanciada o heredada.\n" -"Los cambios que se le realicen no perduraran al guardar la escena actual." +"Este recurso pertenece a una escena instanciada o heredada.\n" +"Los cambios realizados sobre éste no se mantendrán al guardar la escena " +"actual." #: editor/editor_node.cpp msgid "" @@ -2205,28 +2190,25 @@ msgstr "" "el panel de importación y luego reimportá." #: editor/editor_node.cpp -#, fuzzy msgid "" "This scene was imported, so changes to it won't be kept.\n" "Instancing it or inheriting will allow making changes to it.\n" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" -"Esta escena fue importada, por tanto los cambios que se le realicen no " -"perduraran.\n" -"Instancia o hereda para poder realizar cambios.\n" -"Por favor lee la documentación relevante a importar escenas para entender " -"mejor este workflow." +"Esta escena fue importada, por lo que los cambios no se mantendrán.\n" +"Instanciarla o heredarla permitirá realizar cambios en esta.\n" +"Por favor, lee la documentación relevante para importar escenas para " +"entender mejor este flujo de trabajo." #: editor/editor_node.cpp -#, fuzzy msgid "" "This is a remote object, so changes to it won't be kept.\n" "Please read the documentation relevant to debugging to better understand " "this workflow." msgstr "" -"Este es un objeto remoto, los cambios que se hagan no se van a mantener.\n" -"Lea la documentación relacionada con la depuración para comprender mejor " +"Este es un objeto remoto, por lo que los cambios en él no se mantendrán.\n" +"Por favor, lee la documentación relativa a la depuración para entender mejor " "este workflow." #: editor/editor_node.cpp @@ -2251,17 +2233,16 @@ msgid "Open Base Scene" msgstr "Abrir Escena Base" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Abrir Escena Rapido..." +msgstr "Apertura Rápida..." #: editor/editor_node.cpp msgid "Quick Open Scene..." -msgstr "Abrir Escena Rapido..." +msgstr "Apertura Rápida de Escena..." #: editor/editor_node.cpp msgid "Quick Open Script..." -msgstr "Abrir Script Rapido..." +msgstr "Apertura Rápida de Script..." #: editor/editor_node.cpp msgid "Save & Close" @@ -2329,11 +2310,11 @@ msgstr "Revertir" #: editor/editor_node.cpp msgid "This action cannot be undone. Revert anyway?" -msgstr "Esta acción no se puede deshacer. Revertir de todos modos?" +msgstr "Esta acción no se puede deshacer. ¿Revertir de todos modos?" #: editor/editor_node.cpp msgid "Quick Run Scene..." -msgstr "Ejecutar Escena Rapido..." +msgstr "Ejecución Rápida de Escena..." #: editor/editor_node.cpp msgid "Quit" @@ -2442,9 +2423,9 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"No se ha definido ninguna escena principal, ¿elegir una?\n" +"No se ha definido ninguna escena principal, ¿seleccionar una?\n" "Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categorÃa " -"'aplicación'." +"'application'." #: editor/editor_node.cpp msgid "" @@ -2452,9 +2433,9 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"La escena '%s' seleccionada no existe, ¿seleccionar una válida?\n" -"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categoria " -"'aplicacion'." +"La escena seleccionada '%s' no existe, ¿seleccionar una válida?\n" +"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categorÃa " +"'application'." #: editor/editor_node.cpp msgid "" @@ -2464,8 +2445,8 @@ msgid "" msgstr "" "La escena '%s' seleccionada no es un archivo de escena, ¿seleccionar uno " "válido?\n" -"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categoria " -"'aplicacion'." +"Es posible cambiarla más tarde en \"Ajustes del Proyecto\" bajo la categorÃa " +"'application'." #: editor/editor_node.cpp msgid "Save Layout" @@ -2499,12 +2480,11 @@ msgstr "Cerrar Otras Pestañas" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Cerrar Pestañas a la Derecha" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Cerrar Todos" +msgstr "Cerrar Todas las Pestañas" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2638,7 +2618,7 @@ msgstr "Abrir Carpeta de Datos del Proyecto" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Instalar plantilla de compilación de Android" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2750,10 +2730,30 @@ msgid "Editor Layout" msgstr "Layout del Editor" #: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "Tomar Captura de Pantalla" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Las capturas se almacenan en la carpeta Editor Datta/Settings." + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "Abrir Capturas de Pantalla Automaticamente" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "Abrir en editor de imagenes externo." + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Act./Desact. Pantalla Completa" #: editor/editor_node.cpp +msgid "Toggle System Console" +msgstr "Act/Desact. Consola de Sistema" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Abrir Carpeta de Datos/Configuración del Editor" @@ -2766,9 +2766,8 @@ msgid "Open Editor Settings Folder" msgstr "Abrir Carpeta de Configuración del Editor" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "Gestionar Plantillas de Exportación" +msgstr "Administrar CaracterÃsticas del Editor" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2821,7 +2820,7 @@ msgstr "Pausar la escena" #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "Pausar la Escena" +msgstr "Pausar Escena" #: editor/editor_node.cpp msgid "Stop the scene." @@ -2861,16 +2860,16 @@ msgid "Spins when the editor window redraws." msgstr "Gira cuando la ventana del editor se redibuja." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Siempre Actualizar" +msgid "Update Continuously" +msgstr "Actualizar Continuamente" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "Actualizar Cambios" +msgid "Update When Changed" +msgstr "Actualizar Al Cambiar" #: editor/editor_node.cpp -msgid "Disable Update Spinner" -msgstr "Desactivar Update Spinner" +msgid "Hide Update Spinner" +msgstr "Ocultar Spinner de Actualización" #: editor/editor_node.cpp msgid "FileSystem" @@ -2899,17 +2898,21 @@ msgstr "No Guardar" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." msgstr "" +"Falta la plantilla de compilación de Android, por favor, instala las " +"plantillas correspondientes." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Gestionar Plantillas de Exportación" +msgstr "Administrar Plantillas" #: editor/editor_node.cpp msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"Esto instalará el proyecto de Android para compilaciones personalizadas.\n" +"Tené en cuenta que, para usarlo, necesita estar activado por cada preset de " +"exportación." #: editor/editor_node.cpp msgid "" @@ -2917,6 +2920,10 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"La plantilla de compilación de Android ya está instalada y no se " +"sobrescribirá.\n" +"Eliminá el directorio \"build\" manualmente antes de intentar esta operación " +"nuevamente." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3026,7 +3033,7 @@ msgstr "Medida:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" -msgstr "Duracion de Frame (seg)" +msgstr "Duración de Frame (seg)" #: editor/editor_profiler.cpp msgid "Average Time (sec)" @@ -3060,7 +3067,7 @@ msgstr "Tiempo" msgid "Calls" msgstr "Llamadas" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "On" @@ -3166,6 +3173,11 @@ msgid "Page: " msgstr "Página: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Remover Item" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Nueva Clave:" @@ -3177,11 +3189,6 @@ msgstr "Nuevo Valor:" msgid "Add Key/Value Pair" msgstr "Agregar Par Clave/Valor" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Remover Item" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3389,9 +3396,8 @@ msgid "SSL Handshake Error" msgstr "Error de Handshake SSL" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "Descomprimiendo Assets" +msgstr "Descomprimiendo Fuentes de Compilación Android" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3410,9 +3416,8 @@ msgid "Remove Template" msgstr "Remover Plantilla" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" -msgstr "Elegir archivo de plantilla" +msgstr "Elegir Archivo de Plantilla" #: editor/export_template_manager.cpp msgid "Export Template Manager" @@ -3473,9 +3478,8 @@ msgid "No name provided." msgstr "No se indicó ningún nombre." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "El nombre indicado contiene caracteres inválidos" +msgstr "El nombre indicado contiene caracteres inválidos." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3502,28 +3506,24 @@ msgid "Duplicating folder:" msgstr "Duplicando carpeta:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Nueva Escena Heredada..." +msgstr "Nueva Escena Heredada" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Abrir Escena" +msgstr "Abrir Escenas" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Instancia" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" -msgstr "Agregar a favoritos" +msgstr "Agregar a Favoritos" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "Quitar de favoritos" +msgstr "Quitar de Favoritos" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." @@ -3571,23 +3571,20 @@ msgid "Rename" msgstr "Renombrar" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Carpeta Anterior" +msgstr "Carpeta/Archivo Anterior" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Carpeta Siguiente" +msgstr "Carpeta/Archivo Siguiente" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "Reexaminar Sistema de Archivos" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" -msgstr "Act/Desact. Modo Partido" +msgstr "Act/Desact. Modo Dividido" #: editor/filesystem_dock.cpp msgid "Search files" @@ -3638,6 +3635,8 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Incluye los archivos con las siguientes extensiones. Agregalos o eliminalos " +"en Ajustes del proyecto." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3689,6 +3688,7 @@ msgid "Nodes not in Group" msgstr "Nodos fuera del Grupo" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtrar nodos" @@ -4078,9 +4078,8 @@ msgid "Open Animation Node" msgstr "Abrir Nodo de Animación" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "El triángulo ya existe" +msgstr "El triángulo ya existe." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4228,9 +4227,8 @@ msgid "Edit Filtered Tracks:" msgstr "Editar Pistas Filtradas:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" -msgstr "Habilitar filtrado" +msgstr "Habilitar Filtrado" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" @@ -4366,9 +4364,8 @@ msgid "Enable Onion Skinning" msgstr "Activar Onion Skinning" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "Papel Cebolla" +msgstr "Opciones de Papel Cebolla" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4412,7 +4409,7 @@ msgstr "Incluir Gizmos (3D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pin AnimationPlayer" -msgstr "Pinear el AnimationPlayer" +msgstr "Fijar AnimationPlayer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" @@ -4935,6 +4932,8 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Cuando está activo, mover nodos Control cambia sus anclajes en vez de sus " +"márgenes." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -4950,27 +4949,23 @@ msgstr "Cambiar Anclas" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "Seleccionar Herramienta" +msgstr "Bloqueo Seleccionado" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "Eliminar Seleccionados" +msgstr "Desbloquear Seleccionados" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Copiar Selección" +msgstr "Agrupar Seleccionados" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Copiar Selección" +msgstr "Desagrupar Seleccionados" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" @@ -4982,9 +4977,8 @@ msgid "Create Custom Bone(s) from Node(s)" msgstr "Crear Hueso(s) Personalizados a partir de Nodo(s)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "Restablecer Pose" +msgstr "Restablecer Huesos" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -5072,9 +5066,8 @@ msgid "Snapping Options" msgstr "Opciones de Alineado" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" -msgstr "Alinear a la grilla" +msgstr "Ajustar a la Grilla" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" @@ -5094,49 +5087,42 @@ msgid "Use Pixel Snap" msgstr "Usar Pixel Snap" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" -msgstr "Alineado inteligente" +msgstr "Ajuste inteligente" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" -msgstr "Alinear al Padre" +msgstr "Ajustar al Padre" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" -msgstr "Alinear al ancla de nodo" +msgstr "Ajustar al Ancla de Nodo" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" -msgstr "Alinear a los lados del nodo" +msgstr "Ajustar a los Lados del Nodo" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" -msgstr "Alinear al centro del nodo" +msgstr "Ajustar al Centro del Nodo" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" -msgstr "Alinear a otros nodos" +msgstr "Ajustar a Otros Nodos" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" -msgstr "Alinear a guÃas" +msgstr "Ajustar a las GuÃas" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Lock the selected object in place (can't be moved)." -msgstr "Inmovilizar Objeto." +msgstr "Bloquear el objeto seleccionado en su sitio (no se puede mover)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "Unlock the selected object (can be moved)." -msgstr "Desinmovilizar Objeto." +msgstr "Desbloquear el objeto seleccionado (puede ser movido)." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5207,9 +5193,8 @@ msgid "Frame Selection" msgstr "Encuadrar Selección" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Preview Canvas Scale" -msgstr "Vista Previa de Atlas" +msgstr "Vista Previa de Escala de Canvas" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -5265,9 +5250,8 @@ msgid "Divide grid step by 2" msgstr "Dividir step de grilla por 2" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Pan View" -msgstr "Vista Anterior" +msgstr "Panear Vista" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" @@ -5292,9 +5276,8 @@ msgid "Error instancing scene from %s" msgstr "Error al instanciar escena desde %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" -msgstr "Cambiar typo por defecto" +msgstr "Cambiar Tipo por Defecto" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -5336,6 +5319,13 @@ msgid "Load Emission Mask" msgstr "Cargar Máscara de Emisión" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Restart" +msgstr "Reiniciar" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Limpiar Máscara de Emisión" @@ -5381,14 +5371,12 @@ msgid "Create Emission Points From Node" msgstr "Crear Puntos de Emisión Desde Nodo" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "Flat0" +msgstr "Flat 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "Flat1" +msgstr "Flat 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -5415,29 +5403,24 @@ msgid "Load Curve Preset" msgstr "Cargar Preset de Curva" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" -msgstr "Agregar punto" +msgstr "Agregar Punto" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" -msgstr "Quitar punto" +msgstr "Quitar Punto" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" -msgstr "Lineal izquierda" +msgstr "Lineal Izquierda" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" -msgstr "Lineal derecha" +msgstr "Lineal Derecha" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" -msgstr "Cargar preset" +msgstr "Cargar Preset" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove Curve Point" @@ -5481,33 +5464,31 @@ msgstr "¡El Mesh está vacÃo!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" -msgstr "Crear Trimesh Body Estático" +msgstr "Crear Static Trimesh Body" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Convex Body" -msgstr "Crear Body Convexo Estático" +msgstr "Crear Static Convex Body" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "This doesn't work on scene root!" msgstr "Esto no funciona en una escena raiz!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Crear Trimesh Shape" +msgstr "Crear Trimesh Static Shape" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "¡Fallo al crear shapes!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "Crear Shape Convexa" +msgstr "Crear Shape(s) Convexo(s)" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" -msgstr "Crear Mesh de Navegación" +msgstr "Crear Navigation Mesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Contained Mesh is not of type ArrayMesh." @@ -5559,9 +5540,8 @@ msgid "Create Trimesh Collision Sibling" msgstr "Crear Trimesh Collision Sibling" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Collision Sibling(s)" -msgstr "Crear Collision Sibling Convexo" +msgstr "Crear Convex Collision Hemano(s)" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." @@ -5922,9 +5902,8 @@ msgid "Split Segment (in curve)" msgstr "Partir Segmento (en curva)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" -msgstr "Mover unión" +msgstr "Mover Unión" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" @@ -6257,10 +6236,18 @@ msgid "Find Next" msgstr "Encontrar Siguiente" #: editor/plugins/script_editor_plugin.cpp +msgid "Filter scripts" +msgstr "Filtrar scripts" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "Alternar la ordenación alfabética de la lista de métodos." #: editor/plugins/script_editor_plugin.cpp +msgid "Filter methods" +msgstr "Filtrar métodos" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Ordenar" @@ -6371,18 +6358,16 @@ msgid "Debug with External Editor" msgstr "Depurar con Editor Externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Abrir la documentación online de Godot" +msgstr "Abrir la documentación en lÃnea de Godot." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" msgstr "Solicitar Docum." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "Ayudá a mejorar la documentación de Godot dando feedback" +msgstr "Ayudá a mejorar la documentación de Godot dando feedback." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6427,19 +6412,16 @@ msgid "Search Results" msgstr "Resultados de la Búsqueda" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "Conectar a Nodo:" +msgstr "Conexiones al método:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Fuente:" +msgstr "Fuente" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Señales" +msgstr "Señal" #: editor/plugins/script_text_editor.cpp msgid "Target" @@ -6473,11 +6455,11 @@ msgstr "Buscar SÃmbolo" #: editor/plugins/script_text_editor.cpp msgid "Pick Color" -msgstr "Elegir Color" +msgstr "Seleccionar Color" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Convert Case" -msgstr "Convertir Mayusculas" +msgstr "Convertir Mayúsculas" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Uppercase" @@ -6493,23 +6475,27 @@ msgstr "Capitalizar" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Syntax Highlighter" -msgstr "Resaltador de sintaxis" +msgstr "Resaltador de Sintaxis" + +#: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" #: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "Marcadores" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Crear puntos." #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Cortar" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Seleccionar Todo" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Eliminar LÃnea" @@ -6527,24 +6513,20 @@ msgid "Toggle Comment" msgstr "Act/Desact. Comentario" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "Act./Desact. Vista Libre" +msgstr "Act./Desact. Marcador" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "Ir al Breakpoint Siguiente" +msgstr "Ir al Siguiente Marcador" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Previous Bookmark" -msgstr "Ir al Breakpoint Anterior" +msgstr "Ir al Marcador Anterior" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "Quitar Todos los Ãtems" +msgstr "Eliminar Todos los Marcadores" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -6620,13 +6602,12 @@ msgid "Contextual Help" msgstr "Ayuda Contextual" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"Los siguientes archivos son nuevos en disco.\n" -"¿Qué acción se deberÃa tomar?:" +"Este shader ha sido modificado en disco.\n" +"¿Qué acciones deben tomarse?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -6706,7 +6687,7 @@ msgstr "Escalando: " #: editor/plugins/spatial_editor_plugin.cpp msgid "Translating: " -msgstr "Trasladando: " +msgstr "Trasladar: " #: editor/plugins/spatial_editor_plugin.cpp msgid "Rotating %s degrees." @@ -6826,7 +6807,7 @@ msgstr "Mostrar Overdraw" #: editor/plugins/spatial_editor_plugin.cpp msgid "Display Unshaded" -msgstr "Mostrar sin Sombreado" +msgstr "Mostrar Sin Sombreado" #: editor/plugins/spatial_editor_plugin.cpp msgid "View Environment" @@ -6971,9 +6952,8 @@ msgid "Right View" msgstr "Vista Derecha" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" -msgstr "Intercambiar entre vista Perspectiva/Orthogonal" +msgstr "Intercambiar entre Vista Perspectiva/Orthogonal" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" @@ -7017,9 +6997,8 @@ msgid "Transform" msgstr "Transform" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" -msgstr "Ajustar objeto al suelo" +msgstr "Ajustar Objeto al Suelo" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Dialog..." @@ -7207,14 +7186,12 @@ msgid "Settings:" msgstr "Configuración:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "Encuadrar Selección" +msgstr "No hay Frames Seleccionados" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "Agregar Frame" +msgstr "Agregar %d Frame(s)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" @@ -7265,13 +7242,12 @@ msgid "Animation Frames:" msgstr "Fotogramas de animación:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Agregar Textura(s) al TileSet." +msgstr "Añadir Textura desde Archivo" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "Añadir Frames desde un Sprite Sheet" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7290,29 +7266,24 @@ msgid "Move (After)" msgstr "Mover (Despues)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "Frames del Stack" +msgstr "Seleccionar Frames" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Espejar horizontalmente" +msgstr "Horizontal:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "Vértices" +msgstr "Vertical:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "Seleccionar Todo" +msgstr "Seleccionar/Reestablecer Todos los Frames" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "Crear desde Escena" +msgstr "Crear Frames a partir de Sprite Sheet" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" @@ -7345,7 +7316,7 @@ msgstr "Snap de Grilla" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Auto Slice" -msgstr "Auto Rebanar" +msgstr "Corte Automático" #: editor/plugins/texture_region_editor_plugin.cpp msgid "Offset:" @@ -7384,9 +7355,8 @@ msgid "Remove All" msgstr "Quitar Todos" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "Editar tema..." +msgstr "Editar Tema" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7398,7 +7368,7 @@ msgstr "Agregar Items de Clases" #: editor/plugins/theme_editor_plugin.cpp msgid "Remove Class Items" -msgstr "Quitar Items de Clases" +msgstr "Quitar Ãtems de Clases" #: editor/plugins/theme_editor_plugin.cpp msgid "Create Empty Template" @@ -7413,23 +7383,20 @@ msgid "Create From Current Editor Theme" msgstr "Crear Desde Tema de Editor Actual" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Toggle Button" -msgstr "Botón de Mouse" +msgstr "Botón de Conmutación" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Botón del Medio" +msgstr "Botón Desactivado" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" -msgstr "Item" +msgstr "Ãtem" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "Desactivado" +msgstr "Desactivar Ãtem" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -7437,33 +7404,31 @@ msgstr "Tildar Item" #: editor/plugins/theme_editor_plugin.cpp msgid "Checked Item" -msgstr "Item Tildado" +msgstr "Ãtem Tildado" #: editor/plugins/theme_editor_plugin.cpp msgid "Radio Item" -msgstr "Radio Item" +msgstr "Radio Ãtem" #: editor/plugins/theme_editor_plugin.cpp msgid "Checked Radio Item" -msgstr "Radio Item Tildado" +msgstr "Radio Ãtem Tildado" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "Separador con nombre." #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Submenú" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "Item" +msgstr "Ãtem 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "Item" +msgstr "Ãtem 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -7474,9 +7439,8 @@ msgid "Many" msgstr "Muchas" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled LineEdit" -msgstr "Desactivado" +msgstr "LineEdit Desactivado" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -7491,13 +7455,12 @@ msgid "Tab 3" msgstr "Tab 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "Hijos Editables" +msgstr "Ãtem Editable" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "Subárbol" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7554,7 +7517,7 @@ msgstr "Pintar Rectángulo" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Bucket Fill" -msgstr "Balde" +msgstr "Bote de Relleno" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Erase TileMap" @@ -7577,14 +7540,12 @@ msgid "Mirror Y" msgstr "Espejar Y" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "Autotiles" +msgstr "Desactivar Autotile" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "Editar Prioridad de Tile" +msgstr "Activar Prioridad" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7595,35 +7556,32 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift + Clic derecho: Dibujar lÃnea\n" +"Shift + Ctrl + Clic derecho: Pintar Rectángulo" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" msgstr "Elegir Tile" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" -msgstr "Rotar a la izquierda" +msgstr "Rotar a la Izquierda" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" -msgstr "Rotar a la derecha" +msgstr "Rotar a la Derecha" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Horizontally" -msgstr "Espejar horizontalmente" +msgstr "Espejar Horizontalmente" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Vertically" -msgstr "Espejar verticalmente" +msgstr "Espejar Verticalmente" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" -msgstr "Reestablecer transform" +msgstr "Reestablecer Transform" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Add Texture(s) to TileSet." @@ -7658,44 +7616,36 @@ msgid "Select the previous shape, subtile, or Tile." msgstr "Seleccionar la forma, subtile o Tile anterior." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "Modo de Ejecución:" +msgstr "Modo Región" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "Modo de Interpolación" +msgstr "Modo Colisión" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "Editar PolÃgono de Oclusión" +msgstr "Modo Oclusión" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "Crear Mesh de Navegación" +msgstr "Modo Navegación" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "Modo Rotar" +msgstr "Modo Bitmask" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "Modo de Exportación:" +msgstr "Modo Prioridad" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "Modo Paneo" +msgstr "Modo Icono" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "Modo Paneo" +msgstr "Modo Ãndice Z" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7740,11 +7690,11 @@ msgstr "No elegiste una textura para remover." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create from scene? This will overwrite all current tiles." -msgstr "¿Crear desde escena? Esto sobreescribirá todos los tiles actuales." +msgstr "¿Crear desde escena? Esto sobrescribirá todos los tiles actuales." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Merge from scene?" -msgstr "¿Mergear desde escena?" +msgstr "¿Unir desde escena?" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove Texture" @@ -7779,16 +7729,16 @@ msgid "Delete polygon." msgstr "Eliminar polÃgono." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy 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 "" -"Click izq: Activar bit.\n" -"Click der: Desactivar bit.\n" -"Click en otro Tile para editarlo." +"Clic Izquierdo: Activar bit.\n" +"Clic Derecho: Desactivar bit.\n" +"Shift + Clic Izquierdo: Establecer valor de bit comodÃn.\n" +"Hacé clic en otro Tile para editarlo." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -7854,11 +7804,11 @@ msgstr "Reestablecer Máscara de Bits de Tile" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Make Polygon Concave" -msgstr "Hacer el PolÃgono Cóncavo" +msgstr "Crear PolÃgono Cóncavo" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Make Polygon Convex" -msgstr "Hacer el Póligono Convexo" +msgstr "Crear PolÃgono Convexo" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Remove Tile" @@ -7901,77 +7851,64 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input +" -msgstr "Agregar Entrada" +msgstr "Añadir entrada +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add output +" -msgstr "Agregar Entrada" +msgstr "Añadir salida +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "Escala:" +msgstr "Escalar" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Inspector" +msgstr "Vector" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Booleano" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "Agregar Entrada" +msgstr "Agregar puerto de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Añadir puerto de salida" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "Cambiar typo por defecto" +msgstr "Cambiar tipo de puerto de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "Cambiar typo por defecto" +msgstr "Cambiar tipo de puerto de salida" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "Cambiar Nombre de Entrada" +msgstr "Cambiar nombre del puerto de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "Cambiar Nombre de Entrada" +msgstr "Cambiar nombre del puerto de salida" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "Quitar punto" +msgstr "Eliminar puerto de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "Quitar punto" +msgstr "Eliminar puerto de salida" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "Cambiar Expresión" +msgstr "Establecer expresión" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "VisualShader" +msgstr "Redimensionar nodo VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" @@ -8010,9 +7947,8 @@ msgid "Light" msgstr "Luz" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "Crear Nodo" +msgstr "Crear Nodo Shader" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8109,51 +8045,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8162,203 +8054,27 @@ msgid "Input parameter." msgstr "Alinear al Padre" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8872,7 +8588,7 @@ msgstr "Editar Propiedad Visual" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Visual Shader Mode Changed" -msgstr "Se cambió el Modo de Visual Shader" +msgstr "Cambiar Modo de Visual Shader" #: editor/project_export.cpp msgid "Runnable" @@ -10096,6 +9812,11 @@ msgid "Add Child Node" msgstr "Agregar Nodo Hijo" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Colapsar Todos" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Cambiar Tipo" @@ -10124,7 +9845,8 @@ msgid "Delete (No Confirm)" msgstr "Eliminar (Sin Confirmación)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Agregar/Crear un Nuevo Nodo" #: editor/scene_tree_dock.cpp @@ -10395,7 +10117,7 @@ msgstr "Stack Trace" msgid "Pick one or more items from the list to display the graph." msgstr "Elegir uno o mas items de la lista para mostrar el gráfico." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Errores" @@ -10800,54 +10522,6 @@ msgstr "Elegir Instancia:" msgid "Class name can't be a reserved keyword" msgstr "El nombre de la clase no puede ser una palabra reservada" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Generando solución..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "Generando proyecto en C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "No se pudo crear la solución." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "No se pudo guardar la solución." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Hecho" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "No se pudo crear el proyecto en C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "Sobre el soporte de C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Crear solución en C#" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Builds" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Construir Proyecto" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Ver registro" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Fin del stack trace de excepción interna" @@ -11458,8 +11132,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "Dimensiones de la imagen del splash inválidas (deberÃa ser 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Un recurso SpriteFrames debe ser creado o seteado en la propiedad 'Frames' " @@ -11526,8 +11201,9 @@ msgstr "" "\"Particles Animation\" activado." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Se debe proveer una textura con la forma de la luz a la propiedad 'texture'." @@ -11540,7 +11216,8 @@ msgstr "" "efecto." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "El polÃgono de este oclusor está vacÃo. ¡Dibuja un polÃgono!" #: scene/2d/navigation_polygon.cpp @@ -11628,16 +11305,28 @@ msgstr "" "Este hueso no tiene una pose de DESCANSO adecuada. Andá al nodo Skeleton2D y " "asÃgnale una." +#: 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 "" +"TileMap con Use Parent activado necesita un CollisionObject2D padre para " +"darle forma. Por favor, úsalo como hijo de Area2D, StaticBody2D, " +"RigidBody2D, KinematicBody2D, etc. para que puedan tener forma." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D funciona mejor cuando se usa con la raÃz de escena " "editada directamente como padre." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera debe tener un nodo ARVROrigin como su padre" #: scene/3d/arvr_nodes.cpp @@ -11683,15 +11372,15 @@ msgstr "(Tiempo Restante: %d:%02d s)" #: scene/3d/baked_lightmap.cpp msgid "Plotting Meshes: " -msgstr "Ploteando Meshes: " +msgstr "Trazando Meshes: " #: scene/3d/baked_lightmap.cpp msgid "Plotting Lights:" -msgstr "Ploteando Luces:" +msgstr "Trazando Luces:" #: scene/3d/baked_lightmap.cpp scene/3d/gi_probe.cpp msgid "Finishing Plot" -msgstr "Terminando Ploteo" +msgstr "Finalizar Trazado" #: scene/3d/baked_lightmap.cpp msgid "Lighting Meshes: " @@ -11733,9 +11422,10 @@ msgstr "" "RigidBody, KinematicBody, etc. para darles un shape." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Se debe proveer un shape para que CollisionShape funcione. Creale un recurso " "shape!" @@ -11763,7 +11453,7 @@ msgstr "" #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" -msgstr "Ploteando Meshes" +msgstr "Trazando Meshes" #: scene/3d/gi_probe.cpp msgid "" @@ -11773,6 +11463,10 @@ msgstr "" "Las GIProbes no están soportadas por el controlador de video GLES2.\n" "Usá un BakedLightmap en su lugar." +#: 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 "" @@ -11817,9 +11511,10 @@ msgstr "" "PathFollow solo funciona cuando está asignado como hijo de un nodo Path." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED requiere que \"Up Vector\" esté activo en el " "recurso Curve de su Path padre." @@ -11835,7 +11530,10 @@ msgstr "" "Cambiá el tamaño de los collision shapes hijos." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "La propiedad Path debe apuntar a un nodo Spatial valido para funcionar." @@ -11855,8 +11553,9 @@ msgstr "" "En su lugar, cambiá el tamaño de los collision shapes hijos." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Un recurso SpriteFrames debe ser creado o asignado en la propiedad 'Frames' " @@ -11871,8 +11570,10 @@ msgstr "" "favor usálo como hijo de VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment necesita un recurso Environment." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11911,7 +11612,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Nada conectado a la entrada '%s' del nodo '%s'." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "No hay asignado ningún nodo AnimationNode raÃz para el gráfico." #: scene/animation/animation_tree.cpp @@ -11925,7 +11627,8 @@ msgstr "" "La ruta asignada al AnimationPlayer no apunta a un nodo AnimationPlayer." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "La raÃz del AnimationPlayer no es un nodo válido." #: scene/animation/animation_tree_player.cpp @@ -11937,8 +11640,13 @@ msgid "Pick a color from the screen." msgstr "Elegir un color de la pantalla." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Modo Raw" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +#, fuzzy +msgid "Raw" +msgstr "Yaw" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11951,16 +11659,21 @@ msgstr "Agregar color actual como preset." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" "El contenedor en sà mismo no sirve ningún propósito a menos que un script " "configure el comportamiento de posicionamiento de sus hijos.\n" "Si no tenés pensado usar un script, entonces simplemente usá un nodo " "'Control' en su lugar." +#: scene/gui/control.cpp +msgid "" +"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to " +"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"." +msgstr "" + #: scene/gui/dialogs.cpp msgid "Alert!" msgstr "Alerta!" @@ -11970,23 +11683,26 @@ msgid "Please Confirm..." msgstr "Confirmá, por favor..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Los popups se esconderán por defecto a menos que llames a popup() o " "cualquiera de las funciones popup*(). Sin embargo, no hay problema con " "hacerlos visibles para editar, aunque se esconderán al ejecutar." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Si exp_edit es verdadero min_value debe ser > 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer está diseñado para trabajar con un único control hijo.\n" @@ -12038,6 +11754,11 @@ msgid "Input" msgstr "Entrada" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Fuente inválida para el shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Fuente inválida para el shader." @@ -12057,6 +11778,55 @@ msgstr "Solo se pueden asignar variaciones en funciones de vértice." msgid "Constants cannot be modified." msgstr "" +#~ msgid "Generating solution..." +#~ msgstr "Generando solución..." + +#~ msgid "Generating C# project..." +#~ msgstr "Generando proyecto en C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "No se pudo crear la solución." + +#~ 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#" + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "Sobre el soporte de C#" + +#~ msgid "Create C# solution" +#~ msgstr "Crear solución en C#" + +#~ msgid "Builds" +#~ msgstr "Builds" + +#~ msgid "Build Project" +#~ msgstr "Construir Proyecto" + +#~ msgid "View log" +#~ msgstr "Ver registro" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment necesita un recurso Environment." + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Buscar Clases" + +#~ msgid "Update Always" +#~ msgstr "Siempre Actualizar" + +#~ msgid "Raw Mode" +#~ msgstr "Modo Raw" + #~ msgid "Path to Node:" #~ msgstr "Ruta al Nodo:" @@ -12620,9 +12390,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Act/Desact. Espacial Visible" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Act/Desact. CanvasItem Visible" - #~ msgid "Condition" #~ msgstr "Condición" @@ -13564,9 +13331,6 @@ msgstr "" #~ msgid "Images:" #~ msgstr "Imágenes:" -#~ msgid "Select None" -#~ msgstr "No Seleccionar Ninguno" - #~ msgid "Group" #~ msgstr "Grupo" diff --git a/editor/translations/et.po b/editor/translations/et.po index 9733b52c71..5e5c7e153b 100644 --- a/editor/translations/et.po +++ b/editor/translations/et.po @@ -421,6 +421,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -595,6 +604,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -644,7 +657,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -747,6 +760,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -905,7 +922,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1269,7 +1286,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1440,6 +1457,10 @@ msgstr "" 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 "" @@ -1465,7 +1486,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1518,7 +1539,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1531,7 +1552,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1554,11 +1575,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2564,10 +2581,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2674,15 +2711,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2872,7 +2909,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2970,20 +3007,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3468,6 +3505,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5047,6 +5085,13 @@ 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 "" @@ -5947,10 +5992,18 @@ msgid "Find Next" 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 "" @@ -6178,18 +6231,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7709,51 +7765,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7761,203 +7773,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9584,6 +9420,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9612,7 +9452,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9849,7 +9689,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10249,54 +10089,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10873,7 +10665,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10922,7 +10714,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10932,7 +10724,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -10999,14 +10791,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11085,7 +10884,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11114,6 +10913,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11148,8 +10951,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11160,7 +10963,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11176,7 +10981,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11187,7 +10992,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11222,7 +11029,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11234,7 +11041,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11246,7 +11053,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11259,10 +11070,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11276,18 +11092,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11330,6 +11146,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/fa.po b/editor/translations/fa.po index bd1c52ff57..fb41413eb2 100644 --- a/editor/translations/fa.po +++ b/editor/translations/fa.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" +"PO-Revision-Date: 2019-07-09 10:47+0000\n" "Last-Translator: hpn33 <hamed.hpn332@gmail.com>\n" "Language-Team: Persian <https://hosted.weblate.org/projects/godot-engine/" "godot/fa/>\n" @@ -24,10 +24,11 @@ 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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp +#, fuzzy msgid "Invalid type argument to convert(), use TYPE_* constants." msgstr "" "نوع آرگومان برای متد ()convert ‌ نامعتبر است ،‌ از ثابت های *_TYPE‌ Ø§Ø³ØªÙØ§Ø¯Ù‡ " @@ -43,7 +44,7 @@ msgstr "" #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "" +msgstr "ورودی نامعتبر i% (تایید نشده) در عبارت" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -465,6 +466,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "انتخاب همه" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "گره انتخاب" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -646,6 +657,10 @@ msgstr "برو به خط" msgid "Line Number:" msgstr "شماره خط:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "تطبیقی ندارد" @@ -695,7 +710,7 @@ msgstr "بزرگنمایی کمتر" msgid "Reset Zoom" msgstr "بازنشانی بزرگنمایی" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -807,6 +822,11 @@ msgid "Connect" msgstr "اتصال" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "سیگنال ها:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "'s%' را به 's%' متصل Ú©Ù†" @@ -977,7 +997,8 @@ msgid "Owners Of:" msgstr "مالکانÙ:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "آیا پرونده‌های انتخاب شده از پروژه ØØ°Ù شوند؟ (بدون undo)" #: editor/dependency_editor.cpp @@ -1353,7 +1374,7 @@ msgstr "نام نامعتبر. نباید با یک نام کلاس موجود Ø #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "نام نامعتبر. نباید یا یک نام نوع توکار برخوردی داشته باشد." #: editor/editor_autoload_settings.cpp @@ -1527,6 +1548,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1558,7 +1583,7 @@ msgstr "نام گره:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "سامانه پرونده" #: editor/editor_feature_profile.cpp @@ -1620,7 +1645,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1635,7 +1660,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "نسخه اخیر:" #: editor/editor_feature_profile.cpp @@ -1660,16 +1685,11 @@ msgstr "صدور" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "گره های موجود:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "جستجوی کلاسها" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "ØªÙˆØ¶ÛŒØØ§Øª" @@ -2715,12 +2735,35 @@ msgid "Editor Layout" msgstr "" #: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "ویرایشگر ØªØ±Ø¬ÛŒØØ§Øª" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "گشودن ویرایشگر متن" + +#: editor/editor_node.cpp #, fuzzy msgid "Toggle Fullscreen" msgstr "ØØ§Ù„ت تمام ØµÙØÙ‡" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "یک Breakpoint درج Ú©Ù†" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "ویرایشگر ØªØ±Ø¬ÛŒØØ§Øª" @@ -2830,15 +2873,17 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "به روز رسانی دامی" +#, fuzzy +msgid "Update Continuously" +msgstr "مستمر" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "" +#, fuzzy +msgid "Update When Changed" +msgstr "تغییر بده" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -3033,7 +3078,7 @@ msgstr "زمان:" msgid "Calls" msgstr "ÙØ±Ø§Ø®ÙˆØ§Ù†ÛŒ" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3135,20 +3180,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3671,6 +3716,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "صاÙÛŒ کردن گره‌ها" @@ -5329,6 +5375,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "راه اندازی دوباره" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6267,11 +6321,21 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 #, fuzzy +msgid "Filter methods" +msgstr "ØØ§Ù„ت صاÙÛŒ:" + +#: editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Sort" msgstr "مرتب‌سازی:" @@ -6514,20 +6578,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +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 #, fuzzy msgid "Delete Line" @@ -8161,51 +8229,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8213,203 +8237,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10099,6 +9947,11 @@ msgid "Add Child Node" msgstr "Ø§ÙØ²ÙˆØ¯Ù† گره ÙØ±Ø²Ù†Ø¯" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "بستن" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "تغییر نوع" @@ -10128,7 +9981,8 @@ msgid "Delete (No Confirm)" msgstr "ØØ°Ù (بدون تأیید)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Ø§ÙØ²ÙˆØ¯Ù†/ساختن گره جدید" #: editor/scene_tree_dock.cpp @@ -10389,7 +10243,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10811,59 +10665,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "ناتوان در ساختن پوشه." - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to save solution." -msgstr "انتخاب شده را تغییر مقیاس بده" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "انتخاب شده را تغییر مقیاس بده" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "پروژه" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "نمایش پرونده ها" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11480,8 +11281,9 @@ 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 " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "یک منبع SpriteFrames باید در دارایی Frames ایجاد یا تنظیم شود تا " @@ -11544,8 +11346,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "یک Ø¨Ø§ÙØª با Ø´Ú©Ù„ نور باید برای دارایی texture ÙØ±Ø§Ù‡Ù… شده باشد." @@ -11557,7 +11360,8 @@ msgstr "" "تأثیرگذار باشد." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "چندضلعی مسدود برای این مسدودکننده، خالی است. Ù„Ø·ÙØ§ یک چندضلعی رسم کنید!" #: scene/2d/navigation_polygon.cpp @@ -11632,16 +11436,29 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 Ùˆ غیره Ø§Ø³ØªÙØ§Ø¯Ù‡ کنید تا به آن‌ها " +"یک Ø´Ú©Ù„ بدهید." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D زمانی بهتر کار می‌کند Ú©Ù‡ در یک ریشه‌ی صØÙ†Ù‡â€ŒÛŒ ویرایش شده به " "صورت پدر (parent) Ø§Ø³ØªÙØ§Ø¯Ù‡ شود." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11726,9 +11543,10 @@ msgstr "" "بدهید." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "باید یک Ø´Ú©Ù„ برای CollisionShape ÙØ±Ø§Ù‡Ù… شده باشد تا عمل کند. Ù„Ø·ÙØ§ یک منبع Ø´Ú©Ù„ " "برای آن ایجاد کنید!" @@ -11759,6 +11577,10 @@ msgid "" "Use a BakedLightmap instead." 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 "یک منبع NavigationMesh باید برای یک گره تنظیم یا ایجاد شود تا کار کند." @@ -11798,8 +11620,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11811,7 +11633,9 @@ msgstr "" #: scene/3d/remote_transform.cpp #, fuzzy -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "دارایی Path باید به یک گره Particles2D معتبر اشاره کند تا کار کند." #: scene/3d/soft_body.cpp @@ -11826,8 +11650,9 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "یک منبع SpriteFrames باید در دارایی Frames ایجاد شده باشد تا " @@ -11840,7 +11665,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11880,7 +11707,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "'s%' را از 's%' جدا Ú©Ù†" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11894,7 +11721,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11906,7 +11733,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11919,10 +11750,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11934,23 +11770,24 @@ msgid "Please Confirm..." msgstr "Ù„Ø·ÙØ§Ù‹ تأیید کنید…" #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Popup ها به صورت Ù¾ÛŒØ´â€ŒÙØ±Ø¶ مخÙÛŒ می‌شوند مگر اینکه ()popup یا یکی از توابع " "()*popup را ÙØ±Ø§Ø®ÙˆØ§Ù†ÛŒ کنید. در هر صورت نمایان کردن آن‌ها برای ویرایش خوب است، " "اما به Ù…ØØ¶ اجرا مخÙÛŒ می‌شوند." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11998,6 +11835,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "اندازهٔ قلم نامعتبر." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "اندازهٔ قلم نامعتبر." @@ -12017,6 +11859,33 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "ناتوان در ساختن پوشه." + +#, fuzzy +#~ msgid "Failed to save solution." +#~ msgstr "انتخاب شده را تغییر مقیاس بده" + +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "انتخاب شده را تغییر مقیاس بده" + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "پروژه" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "نمایش پرونده ها" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "جستجوی کلاسها" + +#~ msgid "Update Always" +#~ msgstr "به روز رسانی دامی" + #~ msgid "Path to Node:" #~ msgstr "مسیر به سمت گره:" diff --git a/editor/translations/fi.po b/editor/translations/fi.po index 6347cfe06f..c62d874f1b 100644 --- a/editor/translations/fi.po +++ b/editor/translations/fi.po @@ -13,7 +13,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-05-30 03:41+0000\n" +"PO-Revision-Date: 2019-07-09 10:47+0000\n" "Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n" "Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/" "godot/fi/>\n" @@ -22,7 +22,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -82,9 +82,8 @@ msgid "Time:" msgstr "Aika:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Arvo" +msgstr "Arvo:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -434,10 +433,28 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Tämä animaatio kuuluu tuotuun skeneen, joten muutoksia tuotuihin raitoihin " +"ei tallenneta.\n" +"\n" +"Lisätäksesi mukautettuja raitoja, mene skenen tuontiasetuksiin ja aseta\n" +"\"Animation > Storage\" arvoksi \"Files\", kytke päälle \"Animation > Keep " +"Custom Tracks\" ja tee tuonti sen jälkeen uudelleen.\n" +"Vaihtoehtoisesti, käytä sellaisia tuonnin esiasetuksia, jotka tuovat " +"animaatiot erillisiin tiedostoihin." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Varoitus: muokataan tuotua animaatiota" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Valitse kaikki" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Valitse solmu" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -613,6 +630,10 @@ msgstr "Mene riville" msgid "Line Number:" msgstr "Rivinumero:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Ei osumia" @@ -662,7 +683,7 @@ msgstr "Loitonna" msgid "Reset Zoom" msgstr "Palauta oletuslähennystaso" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Varoitukset" @@ -671,38 +692,32 @@ msgid "Line and column numbers." msgstr "Rivi- ja sarakenumerot." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Kohdesolmun metodi täytyy määrittää!" +msgstr "Kohdesolmun metodi täytyy määrittää." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Kohdemetodia ei löytynyt! Määrittele voimassa oleva metodi tai kiinnitä " -"skripti solmuun." +"Kohdemetodia ei löytynyt. Määrittele kelvollinen metodi tai kiinnitä " +"kohdesolmulle skripti." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" msgstr "Yhdistä solmuun:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Isäntään yhdistäminen epäonnistui:" +msgstr "Yhdistä skriptiin:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Signaalit:" +msgstr "Signaalista:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "Solmu ei sisällä geometriaa." +msgstr "Skene ei sisällä yhtään skriptiä." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -730,9 +745,8 @@ msgid "Extra Call Arguments:" msgstr "Ylimääräiset argumentit:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Edistyneet asetukset" +msgstr "Edistyneet" #: editor/connections_dialog.cpp msgid "Deferred" @@ -742,6 +756,7 @@ msgstr "Lykätty" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Lykkää signaalia, tallentaen sen jonoon ja laukaisten sen vain joutoajalla." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -749,12 +764,11 @@ msgstr "Ainutkertainen" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Katkaisee signaalin ensimmäisen lähetyksen jälkeen." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Yhdistä signaali: " +msgstr "Ei voida yhdistää signaalia" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -775,6 +789,11 @@ msgid "Connect" msgstr "Yhdistä" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signaalit:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Yhdistä solmu '%s' solmuun '%s'" @@ -796,14 +815,12 @@ msgid "Disconnect" msgstr "Katkaise yhteys" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Yhdistä signaali: " +msgstr "Yhdistä signaali metodiin" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Muokkaa yhteyttä: " +msgstr "Muokkaa yhteyttä:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -879,22 +896,20 @@ msgid "Dependencies For:" msgstr "Riippuvuudet:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" "Skeneä '%s' muokataan parhaillaan.\n" -"Muutokset tulevat voimaan vasta päivityksen jälkeen." +"Muutokset tulevat voimaan vasta uudelleenlatauksen jälkeen." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" "Resurssi '%s' on käytössä.\n" -"Muutokset tulevat voimaan päivitettäessä." +"Muutokset tulevat voimaan uudelleenlatauksen jälkeen." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -941,7 +956,8 @@ msgid "Owners Of:" msgstr "Omistajat kohteelle:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Poista valitut tiedostot projektista? (ei voi kumota)" #: editor/dependency_editor.cpp @@ -987,9 +1003,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Poista pysyvästi %d kohdetta? (Ei voi kumota!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "Riippuvuudet" +msgstr "Näytä riippuvuudet" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1252,7 +1267,7 @@ msgstr "Avaa ääniväylän asettelu" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Tiedostoa '%s' ei ole." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1309,29 +1324,24 @@ msgid "Valid characters:" msgstr "Kelvolliset merkit:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"Virheellinen nimi. Ei saa mennä päällekkäin olemassa olevan luokan nimen " -"kanssa." +msgstr "Ei saa mennä päällekkäin olemassa olevan engine-luokkanimen kanssa." #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" -"Virheellinen nimi. Ei saa mennä päällekkäin jo olemassa olevan, " -"sisäänrakennetun tyypin nimen kanssa." +"Ei saa mennä päällekkäin olemassa olevan sisäänrakennetun tyypin nimen " +"kanssa." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." msgstr "" -"Virheellinen nimi. Ei saa mennä päällekkäin jo olemassa olevan globaalin " -"vakion nimen kanssa." +"Ei saa mennä päällekkäin olemassa olevan globaalin vakion nimen kanssa." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "Avainsanaa ei voi käyttää automaattisesti latautuvien nimenä." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1362,7 +1372,6 @@ msgid "Rearrange Autoloads" msgstr "Järjestele uudelleen automaattiset lataukset" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "Virheellinen polku." @@ -1417,9 +1426,8 @@ msgid "[unsaved]" msgstr "[tallentamaton]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Valitse ensin päähakemisto" +msgstr "Ole hyvä ja valitse ensin päähakemisto." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1502,122 +1510,114 @@ msgstr "Mukautettua release-vientimallia ei löytynyt." msgid "Template file not found:" msgstr "Mallitiedostoa ei löytynyt:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Editori" +msgstr "3D-editori" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Avaa skriptieditori" +msgstr "Skriptieditori" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Avaa asset-kirjasto" +msgstr "Asset-kirjasto" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Skenepuu (solmut):" +msgstr "Skenepuun muokkaus" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Tuo" +msgstr "Tuontitelakka" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "Solmu siirretty" +msgstr "Solmutelakka" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" -msgstr "Tiedostojärjestelmä" +msgid "FileSystem and Import Docks" +msgstr "Tiedostojärjestelmätelakka" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Korvaa kaikki (ei voi perua)" +msgstr "Poista profiili '%s'? (ei voi perua)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" msgstr "" +"Profiilin täytyy olla kelvollinen tiedostonimi ja se ei voi sisältää merkkiä " +"'.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Tällä nimellä löytyy jo kansio tai tiedosto." +msgstr "Tällä nimellä löytyy jo profiili." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Editori pois käytöstä, ominaisuudet pois käytöstä)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Vain ominaisuudet" +msgstr "(Ominaisuudet pois käytöstä)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Leikkaus pois käytöstä" +msgstr "(Editori pois käytöstä)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Luokan kuvaus:" +msgstr "Luokan valinnat:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Avaa seuraava editori" +msgstr "Ota asiayhteydellinen editori käyttöön" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Ominaisuudet:" +msgstr "Käytössä olevat ominaisuudet:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "Ominaisuudet" +msgstr "Käytössä olevat ominaisuudet:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Etsi luokkia" +msgstr "Käytössä olevat luokat:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Tiedoston '%s' tiedostomuoto on virheellinen, tuonti keskeytetty." #: editor/editor_feature_profile.cpp +#, fuzzy msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"Profiili '%s' on jo olemassa. Poista se ensin ennen tuontia, tuonti " +"keskeytetty." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Virhe ladattaessa mallia '%s'" +msgstr "Virhe tallennettaessa profiilia polkuun: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Poista asetus" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" -msgstr "Nykyinen versio:" +msgid "Current Profile:" +msgstr "Nykyinen profiili" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Nykyinen:" +msgstr "Aseta nykyiseksi" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1636,43 +1636,32 @@ msgstr "Vie" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" -msgstr "Saatavilla olevat solmut:" +msgid "Available Profiles:" +msgstr "Saatavilla olevat profiilit" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Etsi luokkia" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Luokan kuvaus" +msgstr "Luokan valinnat" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Uusi nimi:" +msgstr "Uusi profiilin nimi:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Tyhjennä alue" +msgstr "Tyhjennä profiili" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Tuotu projekti" +msgstr "Tuo profiileja" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Vie projekti" +msgstr "Vie profiili" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "Hallinnoi vientimalleja" +msgstr "Hallinnoi editorin ominaisuusprofiileja" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1795,9 +1784,8 @@ msgid "(Un)favorite current folder." msgstr "Kansio suosikkeihin." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Näytä piilotiedostot" +msgstr "Aseta piilotiedostojen näyttäminen." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1834,6 +1822,7 @@ msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"Tiedostoon %s osoittaville eri tyypeille on useita tuojia, tuonti keskeytetty" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2176,14 +2165,13 @@ msgstr "" "Lue ohjeet skenejen tuomisesta, jotta ymmärrät paremmin tämän työnkulun." #: editor/editor_node.cpp -#, fuzzy 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 "" "Tämä resurssi kuuluu skeneen, josta on luotu ilmentymä, tai joka on " -"periytyvä.\n" -"Muutokset siihen eivät ole pysyviä, kun tallennat nykyisen skenen." +"peritty.\n" +"Siihen tehtyjä muutoksia ei säilytetä, kun tallennat nykyisen skenen." #: editor/editor_node.cpp msgid "" @@ -2194,7 +2182,6 @@ msgstr "" "paneelista ja tuo se uudelleen." #: editor/editor_node.cpp -#, fuzzy 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" @@ -2208,7 +2195,6 @@ msgstr "" "ymmärrät paremmin tämän työnkulun." #: editor/editor_node.cpp -#, fuzzy 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 " @@ -2239,9 +2225,8 @@ msgid "Open Base Scene" msgstr "Avaa kantaskene" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Skenen pika-avaus..." +msgstr "Pika-avaus..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2474,12 +2459,11 @@ msgstr "Sulje muut välilehdet" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Sulje oikealla olevat välilehdet" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Sulje kaikki" +msgstr "Sulje kaikki välilehdet" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2613,7 +2597,7 @@ msgstr "Avaa projektin datakansio" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Asenna Androidin käännösmalli" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2723,10 +2707,34 @@ msgid "Editor Layout" msgstr "Editorin ulkoasu" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Tee skenen juuri" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Avaa editorin data/asetuskansio" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Avaa seuraava editori" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Siirry koko näytön tilaan" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Aseta CanvasItem näkyvyys päälle/pois" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Avaa editorin data/asetuskansio" @@ -2739,9 +2747,8 @@ msgid "Open Editor Settings Folder" msgstr "Avaa editorin asetuskansio" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "Hallinnoi vientimalleja" +msgstr "Hallinnoi editorin ominaisuuksia" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2834,15 +2841,18 @@ msgid "Spins when the editor window redraws." msgstr "Pyörii kun editorin ikkuna päivittyy." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Päivitä aina" +#, fuzzy +msgid "Update Continuously" +msgstr "Jatkuva" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Päivitä muutokset" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Poista päivitysanimaatio" #: editor/editor_node.cpp @@ -2871,18 +2881,20 @@ msgstr "Älä tallenna" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." -msgstr "" +msgstr "Androidin käännösmalli puuttuu, ole hyvä ja asenna olennaiset mallit." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Hallinnoi vientimalleja" +msgstr "Hallinnoi malleja" #: editor/editor_node.cpp msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"Tämä asentaa Android-projektin mukautettuja käännöksiä varten.\n" +"Huomaa, että käyttääksesi sitä, se täytyy ottaa käyttöön kussakin " +"vientiesiasetuksessa." #: editor/editor_node.cpp msgid "" @@ -2890,6 +2902,9 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"Androidin käännösmalli on jo asennettu, eikä sitä ylikirjoiteta.\n" +"Poista \"build\" hakemisto käsin ennen kuin yrität tätä toimenpidettä " +"uudelleen." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3033,7 +3048,7 @@ msgstr "Aika" msgid "Calls" msgstr "Kutsuja" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Päällä" @@ -3140,6 +3155,11 @@ msgid "Page: " msgstr "Sivu: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Poista" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Uusi avain:" @@ -3151,11 +3171,6 @@ msgstr "Uusi arvo:" msgid "Add Key/Value Pair" msgstr "Lisää avain/arvopari" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Poista" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3362,9 +3377,8 @@ msgid "SSL Handshake Error" msgstr "Virhe SSL kättelyssä" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "Puretaan assetteja" +msgstr "Puretaan Android-käännöksen lähdetiedostoja" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3383,9 +3397,8 @@ msgid "Remove Template" msgstr "Poista malli" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" -msgstr "Valitse mallin tiedosto" +msgstr "Valitse mallitiedosto" #: editor/export_template_manager.cpp msgid "Export Template Manager" @@ -3445,9 +3458,8 @@ msgid "No name provided." msgstr "Nimeä ei annettu." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "Annettu nimi sisältää virheellisiä kirjainmerkkejä" +msgstr "Annettu nimi sisältää virheellisiä kirjainmerkkejä." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3474,26 +3486,22 @@ msgid "Duplicating folder:" msgstr "Kahdennetaan kansio:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Uusi peritty skene..." +msgstr "Uusi periytetty skene" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Avaa skene" +msgstr "Avaa skenejä" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Luo ilmentymä" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" msgstr "Lisää suosikkeihin" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" msgstr "Poista suosikeista" @@ -3543,21 +3551,18 @@ msgid "Rename" msgstr "Nimeä uudelleen" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Edellinen kansio" +msgstr "Edellinen kansio/tiedosto" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Seuraava kansio" +msgstr "Seuraava kansio/tiedosto" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "Skannaa tiedostojärjestelmä uudelleen" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" msgstr "Aseta jaettu tila" @@ -3610,6 +3615,8 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Sisällä tiedostot seuraavilla tiedostopäätteillä. Lisää tai poista niitä " +"projektin asetuksista." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3661,6 +3668,7 @@ msgid "Nodes not in Group" msgstr "Ryhmään kuulumattomat solmut" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Suodata solmuja" @@ -4051,9 +4059,8 @@ msgid "Open Animation Node" msgstr "Avaa animaatiosolmu" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "Kolmio on jo olemassa" +msgstr "Kolmio on jo olemassa." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4198,7 +4205,6 @@ msgid "Edit Filtered Tracks:" msgstr "Muokkaa suodatettuja raitoja:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" msgstr "Kytke suodatus" @@ -4334,9 +4340,8 @@ msgid "Enable Onion Skinning" msgstr "Käytä onion skinningiä" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "Onion skinning" +msgstr "Onion skinning -valinnat" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4904,6 +4909,8 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Aktiivisena ollessaan, Control solmujen siirtäminen muuttaa niiden " +"ankkureita marginaalien sijaan." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -4919,41 +4926,35 @@ msgstr "Muuta ankkureita" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "Valintatyökalu" +msgstr "Lukitse valitut" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "Poista valitut" +msgstr "Vapauta valitut" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Kopioi valinta" +msgstr "Ryhmitä valitut" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Kopioi valinta" +msgstr "Poista ryhmitys valituilta" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" msgstr "Liitä asento" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" msgstr "Luo mukautetut luut solmuista" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "Tyhjennä asento" +msgstr "Poista luut" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -5041,7 +5042,6 @@ msgid "Snapping Options" msgstr "Tarttumisen asetukset" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" msgstr "Tartu ruudukkoon" @@ -5063,37 +5063,30 @@ msgid "Use Pixel Snap" msgstr "Tartu pikseleihin" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" msgstr "Älykäs tarttuminen" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" msgstr "Tartu isäntään" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" msgstr "Tartu solmun ankkuriin" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" msgstr "Tartu solmun reunoihin" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" msgstr "Tartu solmun keskipisteeseen" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" msgstr "Tartu muihin solmuihin" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" msgstr "Tartu apuviivoihin" @@ -5177,7 +5170,7 @@ msgstr "Rajaa valintaan" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "" +msgstr "Esikatsele kankaan skaalausta" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -5233,9 +5226,8 @@ msgid "Divide grid step by 2" msgstr "Jaa ruudukon välistys kahdella" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Pan View" -msgstr "Takanäkymä" +msgstr "Panorointinäkymä" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" @@ -5260,7 +5252,6 @@ msgid "Error instancing scene from %s" msgstr "Virhe luotaessa ilmentymää kohteesta %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" msgstr "Muuta oletustyyppiä" @@ -5304,6 +5295,14 @@ msgid "Load Emission Mask" msgstr "Lataa emissiomaski" #: 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 +#, fuzzy +msgid "Restart" +msgstr "Käynnistä uudelleen nyt" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Tyhjennä emissiomaski" @@ -5349,14 +5348,12 @@ msgid "Create Emission Points From Node" msgstr "Luo säteilypisteet solmusta" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "Tasainen0" +msgstr "Tasainen 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "Tasainen1" +msgstr "Tasainen 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -5383,27 +5380,22 @@ msgid "Load Curve Preset" msgstr "Lataa käyrän esiasetus" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" msgstr "Lisää piste" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" msgstr "Poista piste" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" msgstr "Vasen lineaarinen" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" msgstr "Oikea lineaarinen" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" msgstr "Lataa esiasetus" @@ -5460,18 +5452,16 @@ msgid "This doesn't work on scene root!" msgstr "Tämä ei toimi skenen juuressa!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Luo konkaavi muoto" +msgstr "Luo staattinen konkaavi muoto" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "Muotojen luonti epäonnistui!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "Luo konveksi muoto" +msgstr "Luo konvekseja muotoja" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -5527,9 +5517,8 @@ msgid "Create Trimesh Collision Sibling" msgstr "Luo konkaavi törmäysmuoto sisareksi" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Collision Sibling(s)" -msgstr "Luo konveksi törmäysmuoto sisareksi" +msgstr "Luo konvekseja törmäysmuotoja sisariksi" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." @@ -5891,7 +5880,6 @@ msgid "Split Segment (in curve)" msgstr "Puolita osa (käyrässä)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" msgstr "Siirrä liitosta" @@ -6225,10 +6213,20 @@ msgid "Find Next" msgstr "Etsi seuraava" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Suodata ominaisuuksia" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "Käytä metodilistalla aakkosellista järjestystä." #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Suodatustila:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Lajittele" @@ -6339,18 +6337,16 @@ msgid "Debug with External Editor" msgstr "Debuggaa ulkoisella editorilla" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Avaa Godotin online-dokumentaatio" +msgstr "Avaa Godotin online-dokumentaatio." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" msgstr "Pyydä dokumentaatiota" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "Auta parantamaan Godotin dokumentaatiota antamalla palautetta" +msgstr "Auta parantamaan Godotin dokumentaatiota antamalla palautetta." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6395,30 +6391,26 @@ msgid "Search Results" msgstr "Haun tulokset" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "Yhdistä solmuun:" +msgstr "Yhteydet metodiin:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Lähde:" +msgstr "Lähde" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Signaalit" +msgstr "Signaali" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Target" -msgstr "Kohdepolku:" +msgstr "Kohde" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "Mitään ei ole yhdistetty syötteeseen '%s' solmussa '%s'." +msgstr "" +"Yhdistetty metodi '%s' signaalille '%s' puuttuu solmusta '%s' solmuun '%s'." #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6465,20 +6457,24 @@ msgid "Syntax Highlighter" msgstr "Syntaksin korostaja" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "Kirjanmerkit" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Luo pisteitä." #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Leikkaa" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Valitse kaikki" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Poista rivi" @@ -6496,24 +6492,20 @@ msgid "Toggle Comment" msgstr "Lisää tai poista kommentit" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "Kytke liikkuminen päälle/pois" +msgstr "Aseta kirjanmerkki" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "Mene seuraavaan keskeytyskohtaan" +msgstr "Mene seuraavaan kirjanmerkkiin" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Previous Bookmark" -msgstr "Mene edelliseen keskeytyskohtaan" +msgstr "Mene edelliseen kirjanmerkkiin" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "Poista kaikki" +msgstr "Poista kaikki kirjanmerkit" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -6589,13 +6581,12 @@ msgid "Contextual Help" msgstr "Asiayhteydellinen ohje" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"Seuraavat tiedostot ovat uudempia levyllä.\n" -"Mikä toimenpide tulisi suorittaa?:" +"Tätä sävytintä on muokattu levyllä.\n" +"Mikä toimenpide tulisi suorittaa?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -6940,7 +6931,6 @@ msgid "Right View" msgstr "Oikea näkymä" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" msgstr "Vaihda perspektiiviseen/ortogonaaliseen näkymään" @@ -6986,7 +6976,6 @@ msgid "Transform" msgstr "Muunna" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" msgstr "Kohdista objekti lattiaan" @@ -7176,22 +7165,20 @@ msgid "Settings:" msgstr "Asetukset:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "Rajaa valintaan" +msgstr "Ei valittuja ruutuja" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "Lisää frame" +msgstr "Lisää %d ruutua" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" -msgstr "Lisää frame" +msgstr "Lisää ruutu" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "ERROR: Couldn't load frame resource!" -msgstr "VIRHE: Ei voitu ladata framen resurssia!" +msgstr "VIRHE: Ei voitu ladata ruudun resurssia!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Resource clipboard is empty or not a texture!" @@ -7199,7 +7186,7 @@ msgstr "Resurssileikepöytä on tyhjä tai ei sisällä tekstuuria!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Paste Frame" -msgstr "Liitä frame" +msgstr "Liitä ruutu" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Empty" @@ -7234,13 +7221,12 @@ msgid "Animation Frames:" msgstr "Animaatioruudut:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Lisää tekstuurit ruutuvalikoimaan." +msgstr "Lisää tekstuuri tiedostosta" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "Lisää ruudut Sprite Sheetistä" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7259,29 +7245,24 @@ msgid "Move (After)" msgstr "Siirrä (jälkeen)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "Pinokehykset" +msgstr "Valitse ruudut" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Käännä vaakasuorasti" +msgstr "Vaakasuora:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "Kärkipisteet" +msgstr "Pystysuora:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "Valitse kaikki" +msgstr "Valitse tai tyhjää kaikki ruudut" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "Luo skenestä" +msgstr "Luo ruudut Sprite Sheetistä" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" @@ -7353,9 +7334,8 @@ msgid "Remove All" msgstr "Poista kaikki" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "Muokkaa teemaa..." +msgstr "Muokkaa teemaa" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7382,23 +7362,20 @@ msgid "Create From Current Editor Theme" msgstr "Luo nykyisestä editorin teemasta" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Toggle Button" -msgstr "Hiiren painike" +msgstr "Vaihtopainike" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Keskipainike" +msgstr "Toimintakyvytön painike" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" msgstr "Osanen" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "Poistettu käytöstä" +msgstr "Toimintakyvytön osanen" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -7418,21 +7395,19 @@ msgstr "Valittu valintapainike" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "Nimetty erotin" #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Alivalikko" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "Osanen" +msgstr "Osanen 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "Osanen" +msgstr "Osanen 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -7443,9 +7418,8 @@ msgid "Many" msgstr "Useita" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled LineEdit" -msgstr "Poistettu käytöstä" +msgstr "Toimintakyvytön LineEdit" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -7460,13 +7434,12 @@ msgid "Tab 3" msgstr "Välilehti 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "Muokattavat alisolmut" +msgstr "Muokattava osanen" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "Alipuu" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7546,14 +7519,12 @@ msgid "Mirror Y" msgstr "Peilaa Y" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "Automaattiruudutus" +msgstr "Poista automaattiruudutus käytöstä" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "Muokkaa ruudun prioriteettia" +msgstr "Ota prioriteetti käyttöön" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7564,33 +7535,30 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift+Hiiren oikea: Piirrä viiva\n" +"Shift+Ctrl+Hiiren oikea: Suorakaidemaalaus" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" msgstr "Poimi ruutu" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" msgstr "Kierrä vasemmalle" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" msgstr "Kierrä oikealle" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Horizontally" msgstr "Käännä vaakasuorasti" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Vertically" msgstr "Käännä pystysuorasti" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" msgstr "Tyhjennä muunnos" @@ -7627,44 +7595,36 @@ msgid "Select the previous shape, subtile, or Tile." msgstr "Valitse edellinen muoto, aliruutu tai ruutu." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "Käynnistystila:" +msgstr "Aluetila" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "Interpolaatiotila" +msgstr "Törmäystila" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "Muokkaa peittopolygonia" +msgstr "Peittotila" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "Luo navigointiverkko" +msgstr "Siirtymistila" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "Kääntötila" +msgstr "Bittimaskitila" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "Vientitila:" +msgstr "Prioriteettitila" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "Panorointitila" +msgstr "Kuvaketila" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "Panorointitila" +msgstr "Z-indeksitila" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7748,7 +7708,6 @@ msgid "Delete polygon." msgstr "Poista polygoni." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "LMB: Set bit on.\n" "RMB: Set bit off.\n" @@ -7757,6 +7716,7 @@ msgid "" msgstr "" "Hiiren vasen: aseta bitti päälle.\n" "Hiiren oikea: aseta bitti pois päältä.\n" +"Shift+Hiiren vasen: aseta jokeribitti.\n" "Napsauta toista ruutua muokataksesi sitä." #: editor/plugins/tile_set_editor_plugin.cpp @@ -7870,77 +7830,64 @@ msgid "TileSet" msgstr "Ruutuvalikoima" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input +" -msgstr "Lisää syöte" +msgstr "Lisää tulo +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add output +" -msgstr "Lisää syöte" +msgstr "Lisää lähtö +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "Skaalaus:" +msgstr "Skalaari" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Tarkastelu" +msgstr "Vektori" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Totuusarvo" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "Lisää syöte" +msgstr "Lisää tuloportti" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Lisää lähtöportti" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "Muuta oletustyyppiä" +msgstr "Muuta tuloportin tyyppiä" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "Muuta oletustyyppiä" +msgstr "Muuta lähtöportin tyyppiä" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "Vaihda syötteen nimi" +msgstr "Vaihda tuloportin nimi" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "Vaihda syötteen nimi" +msgstr "Vaihda lähtöportin nimi" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "Poista piste" +msgstr "Poista tuloportti" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "Poista piste" +msgstr "Poista lähtöportti" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "Vaihda lauseketta" +msgstr "Aseta lauseke" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "VisualShader" +msgstr "Muuta VisualShader solmun kokoa" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" @@ -7979,83 +7926,77 @@ msgid "Light" msgstr "Valo" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "Luo solmu" +msgstr "Luo Shader solmu" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "Mene funktioon" +msgstr "Värifunktio." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "Värioperaattori." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "Tee funktio" +msgstr "Harmaasävyfunktio." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "Muuntaa HSV-vektorin RGB-vastaavaksi." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "Muuntaa RGB-vektori HSV-vastaavaksi." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "Nimeä funktio uudelleen" +msgstr "Seepia-funktio." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "Poltto-operaattori." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "Tummennusoperaattori." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Difference operator." -msgstr "Vain eroavaisuudet" +msgstr "Eroavaisuusoperaattori." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." -msgstr "" +msgstr "Värinväistöoperaattori." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "HardLight operator" -msgstr "" +msgstr "HardLight-operaattori." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." -msgstr "" +msgstr "Vaalennusoperaattori." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." -msgstr "" +msgstr "Peitto-operaattori." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Screen operator." -msgstr "" +msgstr "Näyttöoperaattori." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "SoftLight operator." -msgstr "" +msgstr "SoftLight-operaattori." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color constant." -msgstr "Muuttumaton" +msgstr "Värivakio." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color uniform." -msgstr "Tyhjennä muunnos" +msgstr "Väri-uniform." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8078,52 +8019,9 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for all shader modes." +msgstr "'normal' syöteparametri valosävytintilaan." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8131,388 +8029,220 @@ msgid "Input parameter." msgstr "Tartu isäntään" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "'custom' syöteparametri kärkipistesävytintilaan." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "'normal' syöteparametri valosävytintilaan." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for fragment shader mode." +msgstr "'custom' syöteparametri kärkipistesävytintilaan." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for light shader mode." +msgstr "'normal' syöteparametri valosävytintilaan." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for vertex shader mode." +msgstr "'custom' syöteparametri kärkipistesävytintilaan." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." -msgstr "" +#, fuzzy +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "'custom' syöteparametri kärkipistesävytintilaan." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar function." -msgstr "Muuta skalaarifunktiota" +msgstr "Skalaarifunktio." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar operator." -msgstr "Muuta skalaarioperaattoria" +msgstr "Skalaarioperaattori." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "E-vakio (2.718282). Kuvastaa luonnollisen logaritmin kantalukua." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "Epsilon-vakio (0.00001). Pienin mahdollinen skaalariluku." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "Fii-vakio (1.618034). Kultainen leikkaus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "Pii/4-vakio (0.785398) eli 45 astetta." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "Pii/2-vakio (1.570796) eli 90 astetta." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "Pii-vakio (3.141593) eli 180 astetta." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "Tau-vakio (6.283185) eli 360 astetta." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "Sqrt2-vakio (1.414214). Kahden neliöjuuri." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "Palauttaa parametrin absoluuttisen arvon." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "Palauttaa parametrin arkuskosinin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Vain GLES3) Palauttaa parametrin käänteisen hyperbolisen kosinin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "Palauttaa parametrin arkussinin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "(Vain GLES3) Palauttaa parametrin käänteisen hyperbolisen sinin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "Palauttaa parametrin arkustangentin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "Palauttaa parametrien arkustangentin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Vain GLES3) Palauttaa parametrin käänteisen hyperbolisen tangentin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." msgstr "" +"Etsii lähimmän kokonaisluvun, joka on suurempi tai yhtä suuri kuin parametri." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "Rajoittaa arvon kahden muun arvon rajoittamaan väliin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "Palauttaa parametrin kosinin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Vain GLES3) Palauttaa parametrin hyperbolisen kosinin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "Muuntaa suureen radiaaneista asteiksi." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "E-kantainen eksponentti." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "2-kantainen eksponentti." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." msgstr "" +"Etsii lähimmän kokonaisluvun, joka on vähemmän tai yhtä suuri kuin parametri." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "Laskee argumentin desimaaliosan." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "Palauttaa parametrin käänteisen neliöjuuren." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "Luonnollinen logaritmi." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "2-kantainen logaritmi." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "Palauttaa suuremman kahdesta arvosta." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "Palauttaa pienemmän kahdesta arvosta." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "Lineaari-interpolaatio kahden skalaarin välillä." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "Palauttaa parametrin vasta-arvon." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - skalaari" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." msgstr "" +"Palauttaa arvon, joka on ensimmäisen parametrin arvo potenssiin toisen " +"parametrin arvo." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "Muuntaa suureen asteista radiaaneiksi." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / skalaari" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(Vain GLES3) Etsii parametria lähinnä olevan kokonaisluvun." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(Vain GLES3) Etsii parametria lähinnä olevan parillisen kokonaisluvun." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "Rajaa arvon 0.0 ja 1.0 välille." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "Poimii parametrin etumerkin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "Palauttaa parametrin sinin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(Vain GLES3) Palauttaa parametrin hyperbolisen sinin." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "Palauttaa parametrin neliöjuuren." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -10052,6 +9782,11 @@ msgid "Add Child Node" msgstr "Lisää alisolmu" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Tiivistä kaikki" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Muuta tyyppiä" @@ -10080,7 +9815,8 @@ msgid "Delete (No Confirm)" msgstr "Poista (ei varmistusta)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Lisää/Luo uusi solmu" #: editor/scene_tree_dock.cpp @@ -10350,7 +10086,7 @@ msgstr "Pinojäljitys" msgid "Pick one or more items from the list to display the graph." msgstr "Valitse yksi tai useampi kohde listasta näyttääksesi graafin." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Virheet" @@ -10756,54 +10492,6 @@ msgstr "Poimintaetäisyys:" msgid "Class name can't be a reserved keyword" msgstr "Luokan nimi ei voi olla varattu avainsana" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Luodaan ratkaisua..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "Luodaan C# projekti..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Ratkaisun luonti epäonnistui." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Ratkaisun tallennus epäonnistui." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Valmis" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "C# projektin luonti epäonnistui." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "Lisätietoja C# tuesta" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Luo C# ratkaisu" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Käännökset" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Käännä projekti" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Näytä loki" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Sisemmän poikkeuksen kutsupinon loppu" @@ -11397,8 +11085,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "Virheellinen käynnistyskuvan kuvakoko (pitäisi olla 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "SpriteFrames resurssi on luotava tai asetettava 'Frames' ominaisuudelle, " @@ -11464,8 +11153,9 @@ msgstr "" "\"Particles Animation\" on kytketty päälle." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Tekstuuri, jolta löytyy valon muoto, täytyy antaa 'texture' ominaisuudella." @@ -11478,7 +11168,8 @@ msgstr "" "peittopolygoni." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "Tämän peittäjän peittopolygoni on tyhjä. Ole hyvä ja piirrä polygoni!" #: scene/2d/navigation_polygon.cpp @@ -11566,16 +11257,29 @@ msgstr "" "Tältä luulta puuttuu kunnollinen lepoasento (REST). Mene Skeleton2D solmuun " "ja aseta sellainen." +#: 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 toimii törmäysmuotona ainoastaan CollisionObject2D solmusta " +"perityille solmuille. Käytä sitä ainoastaan Area2D, StaticBody2D, " +"RigidBody2D, KinematicBody2D, jne. alla antaaksesi niille muodon." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D toimii parhaiten, kun sitä käytetään suoraan muokatun " "skenen juuren isäntänä." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera solmun isännän täytyy olla ARVROrigin solmu" #: scene/3d/arvr_nodes.cpp @@ -11671,9 +11375,10 @@ msgstr "" "KinematicBody, jne. solmujen alla antaaksesi niille muodon." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "CollisionShape solmulle täytyy antaa muoto, jotta se toimisi. Ole hyvä ja " "luo sille muotoresurssi!" @@ -11711,6 +11416,10 @@ msgstr "" "GIProbe ei ole tuettu GLES2 näyttöajurissa.\n" "Käytä sen sijaan BakedLightmap resurssia." +#: 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 "" @@ -11756,9 +11465,10 @@ msgid "PathFollow only works when set as a child of a Path node." msgstr "PathFollow toimii ainoastaan ollessaan asetettuna Path solmun alle." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED edellyttää, että sen Path isäntäsolmun Curve " "resurssin \"Up Vector\" on asetettu päälle." @@ -11774,7 +11484,10 @@ msgstr "" "Muuta sen sijaan solmun alla olevia törmäysmuotoja." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "Polkuominaisuuden täytyy osoittaa Spatial solmuun toimiakseen." #: scene/3d/soft_body.cpp @@ -11792,8 +11505,9 @@ msgstr "" "Muuta kokoa sen sijaan alisolmujen törmäysmuodoissa." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "AnimatedSprite3D solmulle täytyy luoda tai asettaa 'Frames' ominaisuudeksi " @@ -11808,8 +11522,10 @@ msgstr "" "ja käytä sitä VehicleBody solmun alla." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment tarvitsee Environment resurssin." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11848,7 +11564,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Mitään ei ole yhdistetty syötteeseen '%s' solmussa '%s'." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "Graafille ei ole asetettu AnimationNode juurisolmua." #: scene/animation/animation_tree.cpp @@ -11860,7 +11577,8 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "AnimationPlayerille asetettu polku ei johda AnimationPlayer solmuun." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "AnimationPlayer juuri ei ole kelvollinen solmu." #: scene/animation/animation_tree_player.cpp @@ -11873,8 +11591,13 @@ msgid "Pick a color from the screen." msgstr "Valitse väri ruudulta." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Raakatila" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +#, fuzzy +msgid "Raw" +msgstr "Käännös (yaw)" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11887,16 +11610,21 @@ msgstr "Lisää nykyinen väri esiasetukseksi." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" "Säilöllä ei ole itsessään mitään merkitystä ellei jokin skripti säädä sen " "alisolmujen sijoitustapaa.\n" "Jos et aio lisätä skriptiä, ole hyvä ja käytä sen sijaan tavallista " "'Control' solmua." +#: 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 "Huomio!" @@ -11906,23 +11634,26 @@ msgid "Please Confirm..." msgstr "Ole hyvä ja vahvista..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Pop-upit piilotetaan oletusarvoisesti ellet kutsu popup() tai jotain muuta " "popup*() -funktiota. Ne saadaan näkyville muokatessa, mutta eivät näy " "suoritettaessa." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Jos exp_edit on tosi, min_value täytyy olla > 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer on tarkoitettu toimimaan yhdellä lapsikontrollilla.\n" @@ -11974,6 +11705,11 @@ msgid "Input" msgstr "Syöte" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Virheellinen lähde sävyttimelle." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Virheellinen lähde sävyttimelle." @@ -11993,6 +11729,111 @@ msgstr "Varying tyypin voi sijoittaa vain vertex-funktiossa." msgid "Constants cannot be modified." msgstr "" +#~ msgid "Generating solution..." +#~ msgstr "Luodaan ratkaisua..." + +#~ msgid "Generating C# project..." +#~ msgstr "Luodaan C# projekti..." + +#~ msgid "Failed to create solution." +#~ msgstr "Ratkaisun luonti epäonnistui." + +#~ 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." + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "Lisätietoja C# tuesta" + +#~ msgid "Create C# solution" +#~ msgstr "Luo C# ratkaisu" + +#~ msgid "Builds" +#~ msgstr "Käännökset" + +#~ msgid "Build Project" +#~ msgstr "Käännä projekti" + +#~ msgid "View log" +#~ msgstr "Näytä loki" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment tarvitsee Environment resurssin." + +#~ msgid "Enabled Classes" +#~ msgstr "Käytössä olevat luokat" + +#~ msgid "Update Always" +#~ msgstr "Päivitä aina" + +#~ msgid "'light_uv' input parameter for light shader mode." +#~ msgstr "'light_uv' syöteparametri valosävytintilaan." + +#~ msgid "'light_vec' input parameter for light shader mode." +#~ msgstr "'light_vec' syöteparametri valosävytintilaan." + +#~ msgid "'shadow_color' input parameter for light shader mode." +#~ msgstr "'shadow_color' syöteparametri valosävytintilaan." + +#~ msgid "'extra' input parameter for vertex shader mode." +#~ msgstr "'extra' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'projection' input parameter for vertex shader mode." +#~ msgstr "'projection' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'vertex' input parameter for vertex shader mode." +#~ msgstr "'vertex' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'world' input parameter for vertex shader mode." +#~ msgstr "'world' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'active' input parameter for vertex shader mode." +#~ msgstr "'active' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'alpha' input parameter for vertex shader mode." +#~ msgstr "'alpha' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'color' input parameter for vertex shader mode." +#~ msgstr "'color' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'custom_alpha' input parameter for vertex shader mode." +#~ msgstr "'custom_alpha' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'delta' input parameter for vertex shader mode." +#~ msgstr "'delta' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'emission_transform' input parameter for vertex shader mode." +#~ msgstr "'emission_transform' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'index' input parameter for vertex shader mode." +#~ msgstr "'index' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'lifetime' input parameter for vertex shader mode." +#~ msgstr "'lifetime' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'restart' input parameter for vertex shader mode." +#~ msgstr "'restart' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'time' input parameter for vertex shader mode." +#~ msgstr "'time' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'transform' input parameter for vertex shader mode." +#~ msgstr "'transform' syöteparametri kärkipistesävytintilaan." + +#~ msgid "'velocity' input parameter for vertex shader mode." +#~ msgstr "'velocity' syöteparametri kärkipistesävytintilaan." + +#~ msgid "Raw Mode" +#~ msgstr "Raakatila" + #~ msgid "Path to Node:" #~ msgstr "Polku solmuun:" @@ -12541,9 +12382,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Aseta Spatial näkyvyys päälle/pois" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Aseta CanvasItem näkyvyys päälle/pois" - #~ msgid "Condition" #~ msgstr "Ehtolause" diff --git a/editor/translations/fil.po b/editor/translations/fil.po index 0e8ec31005..81f6a159a4 100644 --- a/editor/translations/fil.po +++ b/editor/translations/fil.po @@ -427,6 +427,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -601,6 +610,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -650,7 +663,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -753,6 +766,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -911,7 +928,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1275,7 +1292,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1446,6 +1463,10 @@ msgstr "" 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 "" @@ -1471,7 +1492,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1524,7 +1545,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1537,7 +1558,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1560,11 +1581,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2570,10 +2587,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2680,15 +2717,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "Tuloy-tuloy" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2878,7 +2916,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2976,20 +3014,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3474,6 +3512,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5053,6 +5092,13 @@ 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 "" @@ -5956,10 +6002,18 @@ msgid "Find Next" 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 "" @@ -6187,18 +6241,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7719,51 +7776,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7771,203 +7784,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9595,6 +9432,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9623,7 +9464,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9860,7 +9701,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10260,54 +10101,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10884,7 +10677,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10933,7 +10726,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10943,7 +10736,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11010,14 +10803,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11096,7 +10896,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11125,6 +10925,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11159,8 +10963,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11171,7 +10975,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11187,7 +10993,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11198,7 +11004,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11233,7 +11041,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11245,7 +11053,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11257,7 +11065,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11270,10 +11082,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11287,18 +11104,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11341,6 +11158,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/fr.po b/editor/translations/fr.po index 3c504aed8c..587a8b078a 100644 --- a/editor/translations/fr.po +++ b/editor/translations/fr.po @@ -6,7 +6,7 @@ # ARocherVj <a.rocher.vj@gmail.com>, 2017. # Arthur Templé <tuturtemple@gmail.com>, 2018. # Brice <bbric@free.fr>, 2016. -# Chenebel Dorian <LoubiTek54@gmail.com>, 2016-2017. +# Chenebel Dorian <LoubiTek54@gmail.com>, 2016-2017, 2019. # Cindy Dallaire <c.dallaire93@gmail.com>, 2018. # derderder77 <derderder77380@gmail.com>, 2016. # finkiki <specialpopol@gmx.fr>, 2016. @@ -36,7 +36,7 @@ # Robin Arys <robinarys@hotmail.com>, 2017. # Roger BR <drai_kin@hotmail.com>, 2016. # salty64 <cedric.arrabie@univ-pau.fr>, 2018. -# Thomas Baijot <thomasbaijot@gmail.com>, 2016. +# Thomas Baijot <thomasbaijot@gmail.com>, 2016, 2019. # Tommy Melançon-Roy <tommel1234@hotmail.com>, 2017-2018. # Willow <theotimefd@aol.com>, 2018. # Xananax <xananax@yelostudio.com>, 2017-2018. @@ -60,8 +60,8 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-05-20 11:49+0000\n" -"Last-Translator: Caye Pierre <pierrecaye@laposte.net>\n" +"PO-Revision-Date: 2019-07-02 10:50+0000\n" +"Last-Translator: Chenebel Dorian <LoubiTek54@gmail.com>\n" "Language-Team: French <https://hosted.weblate.org/projects/godot-engine/" "godot/fr/>\n" "Language: fr\n" @@ -69,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -129,9 +129,8 @@ msgid "Time:" msgstr "Temps :" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Valeur" +msgstr "Valeur :" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -490,10 +489,29 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Cette animation appartient à une scène importée, donc les changements " +"apportés aux pistes importées ne seront pas sauvegardés.\n" +"\n" +"Pour activer la possibilité d'ajouter des pistes personnalisées, naviguez " +"dans les paramètres d'importation de la scène et définissez\n" +"\"Animation > Stockage\" à \"Fichiers\", activez \"Animation > Garder Pistes " +"Courantes\" puis ré-importez.\n" +"Alternativement, utilise un préréglage d'import qui importe les animations " +"dans des fichiers différents." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Avertissement : Édition d'une animation importée" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Tout sélectionner" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Sélectionner un nÅ“ud" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -544,7 +562,7 @@ msgstr "Mettre à l'échelle la sélection" #: editor/animation_track_editor.cpp msgid "Scale From Cursor" -msgstr "Mettre à l’échelle depuis le curseur" +msgstr "Mettre à l’échelle à partir du curseur" #: editor/animation_track_editor.cpp modules/gridmap/grid_map_editor_plugin.cpp msgid "Duplicate Selection" @@ -661,7 +679,7 @@ msgstr "Modifier le type de valeurs du tableau" #: editor/array_property_edit.cpp msgid "Change Array Value" -msgstr "Modifier la valeur du tableau" +msgstr "Changer la valeur du tableau" #: editor/code_editor.cpp msgid "Go to Line" @@ -671,6 +689,10 @@ msgstr "Aller à la ligne" msgid "Line Number:" msgstr "Numéro de ligne :" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Pas de correspondances" @@ -720,7 +742,7 @@ msgstr "Dézoomer" msgid "Reset Zoom" msgstr "Réinitialiser le zoom" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Avertissements" @@ -729,38 +751,32 @@ msgid "Line and column numbers." msgstr "Numéros de ligne et de colonne." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "La méthode du nÅ“ud cible doit être spécifiée !" +msgstr "La méthode du nÅ“ud cible doit être spécifiée." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"La méthode cible n'a pas été trouvée ! Spécifiez une méthode valide ou " +"La méthode cible n'a pas été trouvée. Spécifiez une méthode valide ou " "attachez un script au nÅ“ud cible." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" msgstr "Connecter au nÅ“ud :" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Connexion à l'hôte impossible :" +msgstr "Connecter au script :" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Signaux :" +msgstr "Depuis le signal :" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "Le nÅ“ud ne contient pas de géométrie." +msgstr "La scène ne comprend pas de script." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -788,7 +804,6 @@ msgid "Extra Call Arguments:" msgstr "Arguments supplémentaires :" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" msgstr "Options avancées" @@ -800,6 +815,8 @@ msgstr "Différé" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Diffère le signal, le stockant dans une file d'attente et l'active pendant " +"un temps d'inactivité." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -807,12 +824,11 @@ msgstr "One-shot" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Déconnecte le signal après sa première émission." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Signal de connexion : " +msgstr "Impossible de connecter le signal" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -833,6 +849,11 @@ msgid "Connect" msgstr "Connecter" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signaux :" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Connecter « %s » à « %s »" @@ -854,14 +875,12 @@ msgid "Disconnect" msgstr "Déconnecter" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Signal de connexion : " +msgstr "Connecter un signal à une méthode" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Modifier les connexions : " +msgstr "Modifier la connexion :" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -937,22 +956,20 @@ msgid "Dependencies For:" msgstr "Dépendances pour :" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" "La scène « %s » est actuellement en cours de modification.\n" -"Les changements n'auront pas d'effet avant un rechargement." +"Les changements ne prendront effet qu'après un rechargement." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" "La ressource « %s » est utilisée.\n" -"Les changements n'auront pas d'effet avant un rechargement." +"Les changements ne prendront effet qu'après un rechargement." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -999,7 +1016,8 @@ msgid "Owners Of:" msgstr "Propriétaires de :" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" "Supprimer les fichiers sélectionnés de ce projet ? (annulation impossible)" @@ -1046,9 +1064,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Supprimer de manière permanente %d objet(s) ? (Annulation impossible!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "Dépendances" +msgstr "Afficher les dépendances" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1311,7 +1328,7 @@ msgstr "Ouvrir une disposition de bus audio" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "'%s' n'existe pas." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1368,29 +1385,24 @@ msgid "Valid characters:" msgstr "Caractères valides :" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." msgstr "" -"Nom invalide. Le nom ne doit pas rentrer en conflit avec le nom d'une classe " -"moteur existante." +"Ne doit pas entrer en collision avec un nom de classe du moteur existant." #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" -"Nom invalide. Le nom ne doit pas rentrer en conflit avec le nom d'un type " -"intégré au moteur." +"Ne doit pas entrer en collision avec un nom de type intégré au moteur " +"existant." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." -msgstr "" -"Nom invalide. Le nom ne doit pas rentrer en conflit avec le nom d'une " -"constante globale." +msgstr "Ne doit pas entrer en collision avec une constante globale existante." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "Un mot-clé ne peut pas être utilisé comme nom de chargement auto." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1421,7 +1433,6 @@ msgid "Rearrange Autoloads" msgstr "Ré-organiser les AutoLoads" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "Chemin invalide." @@ -1476,9 +1487,8 @@ msgid "[unsaved]" msgstr "[non enregistré]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Veuillez sélectionner un répertoire de base en premier" +msgstr "Veuillez sélectionner un répertoire de base en premier." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1562,107 +1572,97 @@ msgstr "Modèle de version personnalisée introuvable." msgid "Template file not found:" msgstr "Fichier modèle introuvable :" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Éditeur" +msgstr "Éditeur 3D" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Ouvrir l'éditeur de script" +msgstr "Éditeur de Script" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Ouvrir bibliothèque de ressource" +msgstr "Bibliothèque d'assets" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Arbre de scène (nÅ“uds) :" +msgstr "Édition de l'arbre de scène" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Importer" +msgstr "Dock d'importation" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "NÅ“ud déplacé" +msgstr "Dock nÅ“ud" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" -msgstr "Système de fichiers" +msgid "FileSystem and Import Docks" +msgstr "Dock système de fichiers" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Remplacer tout (pas de retour en arrière)" +msgstr "Effacer le profil '%s' ? (pas d'annulation)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" msgstr "" +"Le profil doit être un nom de fichier valide et ne doit pas contenir '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Un fichier ou un dossier avec ce nom existe déjà ." +msgstr "Un profil avec ce nom existe déjà ." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Éditeur désactivé, Propriétés désactivées)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Propriétés seulement" +msgstr "(Propriétés désactivées)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Âgrafe désactivée" +msgstr "(Éditeur désactivé)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Description de la classe :" +msgstr "Options de classe :" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Ouvrir l'éditeur suivant" +msgstr "Ouvrir l'éditeur contextuel" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Propriétés :" +msgstr "Propriétés activées :" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "Fonctionnalités" +msgstr "Fonctionnalités activées :" #: editor/editor_feature_profile.cpp msgid "Enabled Classes:" -msgstr "" +msgstr "Classes activées :" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Le format du fichier '%s' est invalide, fin de l'import." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Erreur lors du chargement du modèle « %s »" +msgstr "Erreur lors de l'enregistrement du profil au chemin: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" @@ -1670,8 +1670,8 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" -msgstr "Version courante :" +msgid "Current Profile:" +msgstr "Profil actuel" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1695,38 +1695,28 @@ msgstr "Exporter" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" -msgstr "NÅ“uds disponibles :" - -#: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Activer l'alignement" +msgid "Available Profiles:" +msgstr "Profils disponibles" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Description de la classe" +msgstr "Options de classe" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Nouveau nom :" +msgstr "Nouveau nom de profil :" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Effacer zone" +msgstr "Effacer le profil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Projet importé" +msgstr "Profil(s) d'importation" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Exporter le projet" +msgstr "Profil d'exportation" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1854,9 +1844,8 @@ msgid "(Un)favorite current folder." msgstr "Ajouter ou supprimer des favoris le dossier courant." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Basculer les fichiers cachés" +msgstr "Activer / désactiver la visibilité des fichiers cachés." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -2059,7 +2048,7 @@ msgstr "Type de membre" #: editor/editor_help_search.cpp msgid "Class" -msgstr "Classe" +msgstr "Classe :" #: editor/editor_inspector.cpp editor/project_settings_editor.cpp msgid "Property:" @@ -2237,7 +2226,6 @@ msgstr "" "comprendre le processus." #: editor/editor_node.cpp -#, fuzzy 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." @@ -2268,7 +2256,6 @@ msgstr "" "mieux comprendre ce processus." #: editor/editor_node.cpp -#, fuzzy 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 " @@ -2277,7 +2264,7 @@ msgstr "" "Ceci est un objet distant, les changements qui y sont faits ne seront pas " "sauvegardés.\n" "Merci de lire la section de la documentation portant sur le débogage pour " -"mieux comprendre ce mécanisme." +"mieux comprendre ce flux de travail." #: editor/editor_node.cpp msgid "There is no defined scene to run." @@ -2302,9 +2289,8 @@ msgid "Open Base Scene" msgstr "Ouvrir scène de base" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Ouvrir une scène rapidement…" +msgstr "Ouverture Rapide..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2558,9 +2544,8 @@ msgid "Close Tabs to the Right" msgstr "" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Fermer tout" +msgstr "Fermer tous les onglets" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2807,10 +2792,34 @@ msgid "Editor Layout" msgstr "Disposition de l'éditeur" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Choisir comme racine de scène" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Ouvrir le dossier de données/paramètres de l'éditeur" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Ouvrir l'éditeur suivant" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Activer/Désactiver le plein écran" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Activer/désactiver le mode scindé" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Ouvrir le dossier de données/paramètres de l'éditeur" @@ -2823,9 +2832,8 @@ msgid "Open Editor Settings Folder" msgstr "Ouvrir le dossier des paramètres de l'éditeur" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "Gérer les modèles d'exportation" +msgstr "Gérer les fonctionnalités de l'éditeur" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2918,15 +2926,18 @@ msgid "Spins when the editor window redraws." msgstr "Tourne lorsque la fenêtre de l'éditeur est redessinée." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Toujours repeindre" +#, fuzzy +msgid "Update Continuously" +msgstr "Continu" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Repeindre quand modifié" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Désactiver l'indicateur d'activité" #: editor/editor_node.cpp @@ -2958,9 +2969,8 @@ msgid "Android build template is missing, please install relevant templates." msgstr "" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Gérer les modèles d'exportation" +msgstr "Gérer les modèles" #: editor/editor_node.cpp msgid "" @@ -3117,7 +3127,7 @@ msgstr "Temps" msgid "Calls" msgstr "Appels" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Activé" @@ -3224,6 +3234,11 @@ msgid "Page: " msgstr "Page : " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Supprimer l'item" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Nouvelle Clé :" @@ -3235,11 +3250,6 @@ msgstr "Nouvelle Valeur :" msgid "Add Key/Value Pair" msgstr "Ajouter une paire clé/valeur" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Supprimer l'item" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3449,7 +3459,7 @@ msgstr "Erreurs de la négociation SSL" #: editor/export_template_manager.cpp #, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "Décompression des assets" +msgstr "Décompresser les sources de compilation Android" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3468,7 +3478,6 @@ msgid "Remove Template" msgstr "Supprimer le modèle" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" msgstr "Sélectionner le fichier de modèle" @@ -3533,9 +3542,8 @@ msgid "No name provided." msgstr "Aucun nom renseigné." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "Le nom renseigné contient des caractères invalides" +msgstr "Le nom renseigné contient des caractères invalides." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3562,9 +3570,8 @@ msgid "Duplicating folder:" msgstr "Duplication du dossier :" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Nouvelle scène héritée…" +msgstr "Nouvelle scène héritée" #: editor/filesystem_dock.cpp #, fuzzy @@ -3576,12 +3583,10 @@ msgid "Instance" msgstr "Instance" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" msgstr "Ajouter aux favoris" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" msgstr "Supprimer des favoris" @@ -3631,21 +3636,18 @@ msgid "Rename" msgstr "Renommer" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Dossier précédent" +msgstr "Dossier/Fichier précédent" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Dossier suivant" +msgstr "Dossier/Fichier suivant" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "Analyser à nouveau le système de fichiers" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" msgstr "Activer/désactiver le mode scindé" @@ -3750,6 +3752,7 @@ msgid "Nodes not in Group" msgstr "NÅ“uds non groupés" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtrer les nÅ“uds" @@ -4141,9 +4144,8 @@ msgid "Open Animation Node" msgstr "Ouvrir le NÅ“ud Animation" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "Le triangle existe déjà " +msgstr "Le triangle existe déjà ." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4292,7 +4294,6 @@ msgid "Edit Filtered Tracks:" msgstr "Modifier les pistes filtrées :" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" msgstr "Activer le filtrage" @@ -4429,9 +4430,8 @@ msgid "Enable Onion Skinning" msgstr "Activer l'effet « pelure d'oignon »" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "Effet pelure d'oignon" +msgstr "Options effet pelure d'oignon" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -5015,41 +5015,35 @@ msgstr "Modifier les ancres" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "Outil sélection" +msgstr "Verrouillage Sélectionné" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "Supprimer la selection" +msgstr "Déverrouillage Sélectionné" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Copier la sélection" +msgstr "Groupe sélectionné" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Copier la sélection" +msgstr "Dégrouper Sélectionné" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" msgstr "Coller la pose" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" msgstr "Créer des os personnalisés à partir d'un ou de plusieurs nÅ“uds" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "Vider la pose" +msgstr "Effacer les os" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -5137,9 +5131,8 @@ msgid "Snapping Options" msgstr "Options de magnétisme" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" -msgstr "Accrocher à la grille" +msgstr "Aimanter à la grille" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" @@ -5159,39 +5152,32 @@ msgid "Use Pixel Snap" msgstr "Aligner au pixel près" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" msgstr "Magnétisme intelligent" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" msgstr "Aimanter au parent" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" -msgstr "Accrocher à l'ancre du nÅ“ud" +msgstr "Aimanter à l'ancre du nÅ“ud" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" -msgstr "Accrocher aux flancs du nÅ“ud" +msgstr "Aimanter aux flancs du nÅ“ud" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" -msgstr "Accrocher au centre du nÅ“ud" +msgstr "Aimanter au centre du nÅ“ud" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" -msgstr "Accrocher aux autres nÅ“uds" +msgstr "Aimanter aux autres nÅ“uds" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" -msgstr "Accrocher aux guides" +msgstr "Aimanter aux guides" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5356,7 +5342,6 @@ msgid "Error instancing scene from %s" msgstr "Erreur d'instanciation de la scène depuis %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" msgstr "Changer le type par défaut" @@ -5400,6 +5385,14 @@ msgid "Load Emission Mask" msgstr "Charger Masque d'Émission" #: 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 +#, fuzzy +msgid "Restart" +msgstr "Redémarrer maintenant" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Effacer Masque d'Émission" @@ -5445,14 +5438,12 @@ msgid "Create Emission Points From Node" msgstr "Créer des points d'émission depuis le nÅ“ud" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "Plat0" +msgstr "Plat 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "Plat1" +msgstr "Plat 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -5479,29 +5470,24 @@ msgid "Load Curve Preset" msgstr "Charger un pré-réglage de courbe" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" msgstr "Ajouter un point" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" -msgstr "Supprimer point" +msgstr "Supprimer un point" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" msgstr "Linéaire gauche" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" msgstr "Linéaire droite" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" -msgstr "Charger prérèglage" +msgstr "Charger un préréglage" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove Curve Point" @@ -5556,18 +5542,16 @@ msgid "This doesn't work on scene root!" msgstr "Cela ne fonctionne pas sur la racine de la scène !" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Créer une forme Trimesh" +msgstr "Créer une forme Trimesh statique" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "Créer une forme convexe" +msgstr "Créer une(des) forme(s) convexe(s)" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -5626,9 +5610,8 @@ msgid "Create Trimesh Collision Sibling" msgstr "Créer une collision Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Collision Sibling(s)" -msgstr "Créer une collision convexe" +msgstr "Créer une(des) collision(s) convexe(s) sÅ“ur(s)" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." @@ -5993,7 +5976,6 @@ msgid "Split Segment (in curve)" msgstr "Diviser le segment (en courbe)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" msgstr "Déplacer la jointure" @@ -6328,10 +6310,20 @@ msgid "Find Next" msgstr "Correspondance suivante" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filtrer les propriétés" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "Basculer le tri alphabétique de la liste de méthodes." #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Mode de filtre :" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Trier" @@ -6442,18 +6434,16 @@ msgid "Debug with External Editor" msgstr "Déboguer avec un éditeur externe" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Ouvrir la documentation Godot en ligne" +msgstr "Ouvrir la documentation de Godot en ligne." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" msgstr "Demande de documentation" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "Aider à améliorer la documentation de Godot en donnant vos réactions" +msgstr "Aider à améliorer la documentation de Godot en donnant vos réactions." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6498,17 +6488,14 @@ msgid "Search Results" msgstr "Résultats de recherche" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "Connecter au nÅ“ud :" +msgstr "Connexions à la méthode :" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Ressource" +msgstr "Source" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" msgstr "Signaux" @@ -6567,20 +6554,24 @@ msgid "Syntax Highlighter" msgstr "Coloration syntaxique" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +msgstr "Créer des points." + #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Couper" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Tout sélectionner" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Supprimer ligne" @@ -6691,13 +6682,12 @@ msgid "Contextual Help" msgstr "Aide contextuelle" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"Les fichiers suivants sont plus récents sur le disque.\n" -"Quelle action doit être prise ? :" +"Ce shader a été modifié sur le disque.\n" +"Quelles sont les mesures à prendre ?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -7045,7 +7035,6 @@ msgid "Right View" msgstr "Vue de droite" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" msgstr "Basculer entre la vue perspective et orthogonale" @@ -7091,9 +7080,8 @@ msgid "Transform" msgstr "Transformation" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" -msgstr "Aligner l'objet sur le sol" +msgstr "Aimanter l'objet au sol" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Dialog..." @@ -7341,9 +7329,8 @@ msgid "Animation Frames:" msgstr "Trames d'animation :" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Ajouter des textures au TileSet." +msgstr "Ajouter une texture à partir d'un fichier" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" @@ -7371,14 +7358,12 @@ msgid "Select Frames" msgstr "Pile des appels" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Retourner horizontalement" +msgstr "Horizontal :" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "Vertex" +msgstr "Vertical :" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy @@ -7460,9 +7445,8 @@ msgid "Remove All" msgstr "Supprimer tout" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "Modifier le thème…" +msgstr "Modifier le thème" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7494,18 +7478,16 @@ msgid "Toggle Button" msgstr "Bouton de souris" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Bouton du milieu" +msgstr "Bouton désactivé" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" msgstr "Item" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "Supprimer élément" +msgstr "Élément Désactivé" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -7532,14 +7514,12 @@ msgid "Submenu" msgstr "" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "Item" +msgstr "Élément 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "Item" +msgstr "Élément 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -7567,9 +7547,8 @@ msgid "Tab 3" msgstr "Onglet 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "Enfants modifiables" +msgstr "Élément modifiable" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" @@ -7657,9 +7636,8 @@ msgid "Disable Autotile" msgstr "" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "Modifier la priorité de la tuile" +msgstr "Activer la priorité" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7676,27 +7654,22 @@ msgid "Pick Tile" msgstr "Sélectionner une case" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" -msgstr "Rotation à gauche" +msgstr "Rotation vers la gauche" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" -msgstr "Rotation à droite" +msgstr "Rotation vers la droite" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Horizontally" msgstr "Retourner horizontalement" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Vertically" msgstr "Retourner verticalement" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" msgstr "Supprimer la transformation" @@ -7733,29 +7706,24 @@ msgid "Select the previous shape, subtile, or Tile." msgstr "Sélectionner la forme précédente, sous-tuile, ou tuile." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "Mode d'exécution :" +msgstr "Mode Région" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "Mode d'interpolation" +msgstr "Mode collision" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "Modifier le polygone d'occlusion" +msgstr "Mode Occlusion" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "Créer un maillage de navigation" +msgstr "Mode Navigation" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "Mode rotation" +msgstr "Mode Bitmask" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -7763,14 +7731,12 @@ msgid "Priority Mode" msgstr "Mode d'exportation :" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "Mode navigation" +msgstr "Mode Icône" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "Mode navigation" +msgstr "Mode Index Z" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7993,9 +7959,8 @@ msgid "Scalar" msgstr "Échelle :" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Inspecteur" +msgstr "Vecteur" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" @@ -8185,51 +8150,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8238,203 +8159,27 @@ msgid "Input parameter." msgstr "Aimanter au parent" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10163,6 +9908,11 @@ msgid "Add Child Node" msgstr "Ajouter un nÅ“ud enfant" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Réduire tout" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Changer le type" @@ -10191,7 +9941,8 @@ msgid "Delete (No Confirm)" msgstr "Effacer (pas de confirmation)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Ajouter/Créer un nouveau nÅ“ud" #: editor/scene_tree_dock.cpp @@ -10463,7 +10214,7 @@ msgid "Pick one or more items from the list to display the graph." msgstr "" "Sélectionnez un ou plusieurs éléments de la liste pour afficher le graphique." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Erreurs" @@ -10869,54 +10620,6 @@ msgstr "Choisissez distance :" msgid "Class name can't be a reserved keyword" msgstr "Le nom de classe ne peut pas être un mot-clé réservé" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Génération de la solution en cours..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "Création du projet C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Impossible de créer la solution." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Impossible de sauvegarder la solution." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Terminé" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "Impossible de créer le projet C#." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "À propos du support C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Créer la solution C#" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Constructions" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Compiler le projet" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Voir les fichiers log" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Fin de la trace d'appel (stack trace) intrinsèque" @@ -11534,8 +11237,9 @@ msgstr "" "Les dimensions du splash screen sont invalides (doivent être de 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Une ressource SpriteFrames doit être créée ou assignée à la propriété « " @@ -11601,8 +11305,9 @@ msgstr "" "« Particles Animation » activé." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Une texture avec la forme de la lumière doit être fournie dans la propriété " @@ -11616,7 +11321,8 @@ msgstr "" "occulteur ait un effet." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "Le polygone d'occultation pour cet occulteur est vide. Veuillez dessiner un " "polygone !" @@ -11711,16 +11417,29 @@ msgstr "" "Cet os ne dispose pas d'une position de repos appropriée. Accédez au nÅ“ud " "Skeleton2D et définissez-en une." +#: 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 "" +"Un CollisionShape2D n'est utile que lorsqu'il est enfant d'un nÅ“ud dérivé de " +"CollisionObject2D, comme Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, " +"etc." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "Un VisibilityEnable2D fonctionne mieux lorsqu'il est directement enfant du " "nÅ“ud racine de la scène." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera doit avoir un nÅ“ud ARVROrigin comme parent" #: scene/3d/arvr_nodes.cpp @@ -11814,9 +11533,10 @@ msgstr "" "CollisionObject, comme Area, StaticBody, RigidBody, KinematicBody, etc." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Une CollisionShape nécessite une forme pour fonctionner. Créez une ressource " "de forme pour cette CollisionShape !" @@ -11854,6 +11574,10 @@ msgstr "" "Les GIProps ne sont pas supporter par le pilote de vidéos GLES2.\n" "A la place utilisez une BakedLightMap." +#: 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 "" @@ -11902,9 +11626,10 @@ msgstr "" "nÅ“ud de type Path." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "L'option ROTATION_ORIENTED de PathFollow nécessite l'activation de « Up " "Vector » dans la ressource Curve de son parent Path." @@ -11920,7 +11645,10 @@ msgstr "" "Modifiez la taille dans les formes de collision enfants à la place." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "La propriété Path doit pointer vers un nÅ“ud Spatial valide pour fonctionner." @@ -11940,8 +11668,9 @@ msgstr "" "Modifiez les tailles dans les formes de collision enfants à la place." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Une ressource de type SampleFrames doit être créée ou définie dans la " @@ -11956,8 +11685,10 @@ msgstr "" "l'utiliser comme enfant d'un VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment requiert une ressource de type Environment." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11996,7 +11727,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Rien n'est connecté à l'entrée « %s » du nÅ“ud « %s »." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "Un AnimationNode racine pour le graphique n'est pas défini." #: scene/animation/animation_tree.cpp @@ -12011,7 +11743,8 @@ msgstr "" "Le chemin défini pour AnimationPlayer ne mène pas à un nÅ“ud AnimationPlayer." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "La racine AnimationPlayer n'est pas un nÅ“ud valide." #: scene/animation/animation_tree_player.cpp @@ -12023,8 +11756,13 @@ msgid "Pick a color from the screen." msgstr "Échantillonner une couleur depuis l'écran." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Mode brut" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +#, fuzzy +msgid "Raw" +msgstr "Lacet (hauteur)" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -12037,16 +11775,21 @@ msgstr "Ajouter la couleur courante comme pré-réglage." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" "Le conteneur en lui-même ne sert à rien à moins qu'un script ne configure " "son comportement de placement de ses enfants.\n" "Si vous n'avez pas l'intention d'ajouter un script, utilisez plutôt un nÅ“ud " "'Control'." +#: 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 "Alerte !" @@ -12056,10 +11799,11 @@ msgid "Please Confirm..." msgstr "Veuillez confirmer…" #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Les pop-ups seront cachés par défaut jusqu'à ce que vous appelez une " "fonction popup() ou une des fonctions popup*(). Les rendre visibles pour " @@ -12067,13 +11811,15 @@ msgstr "" "l'exécution." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Si exp_edit est vrai min_value doit être > 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer est conçu pour fonctionner avec un unique nÅ“ud enfant de " @@ -12126,6 +11872,11 @@ msgid "Input" msgstr "Entrée" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Source invalide pour la forme." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Source invalide pour la forme." @@ -12145,6 +11896,54 @@ msgstr "Les variations ne peuvent être affectées que dans la fonction vertex." msgid "Constants cannot be modified." msgstr "" +#~ msgid "Generating solution..." +#~ msgstr "Génération de la solution en cours..." + +#~ msgid "Generating C# project..." +#~ msgstr "Création du projet C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "Impossible de créer la solution." + +#~ 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#." + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "À propos du support C#" + +#~ msgid "Create C# solution" +#~ msgstr "Créer la solution C#" + +#~ msgid "Builds" +#~ msgstr "Constructions" + +#~ msgid "Build Project" +#~ msgstr "Compiler le projet" + +#~ msgid "View log" +#~ msgstr "Voir les fichiers log" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment requiert une ressource de type Environment." + +#~ msgid "Enabled Classes" +#~ msgstr "Classes activées" + +#~ msgid "Update Always" +#~ msgstr "Toujours repeindre" + +#~ msgid "Raw Mode" +#~ msgstr "Mode brut" + #~ msgid "Path to Node:" #~ msgstr "Chemin vers le nÅ“ud :" diff --git a/editor/translations/he.po b/editor/translations/he.po index 13c06339a6..eadb7cad94 100644 --- a/editor/translations/he.po +++ b/editor/translations/he.po @@ -8,12 +8,13 @@ # Yaron Shahrabani <sh.yaron@gmail.com>, 2018, 2019. # RaikaRakka <shaiyatta@gmail.com>, 2018. # Ido Dana <idodana01@gmail.com>, 2019. +# Daniel Dovgun <daniel.dovgun@gmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-03-28 09:36+0000\n" -"Last-Translator: Yaron Shahrabani <sh.yaron@gmail.com>\n" +"PO-Revision-Date: 2019-07-02 10:49+0000\n" +"Last-Translator: Daniel Dovgun <daniel.dovgun@gmail.com>\n" "Language-Team: Hebrew <https://hosted.weblate.org/projects/godot-engine/" "godot/he/>\n" "Language: he\n" @@ -22,7 +23,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=4; plural=(n == 1) ? 0 : ((n == 2) ? 1 : ((n > 10 && " "n % 10 == 0) ? 2 : 3));\n" -"X-Generator: Weblate 3.6-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -33,7 +34,7 @@ msgstr "" #: 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 "" +msgstr "×ין מספיק ×‘×ª×™× ×œ×¤×¢× ×•×— בתי×, ×ו פורמט ×œ× ×ª×§×™×Ÿâ€â€." #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" @@ -45,15 +46,16 @@ msgstr "" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." -msgstr "" +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 +#, fuzzy msgid "Invalid named index '%s' for base type %s" -msgstr "" +msgstr "×©× ××™× ×“×§×¡ ×œ× ×ª×§×™×Ÿ '%s' לסוג בסיס '%s'" #: core/math/expression.cpp #, fuzzy @@ -84,7 +86,7 @@ msgstr "זמן:" #: editor/animation_bezier_editor.cpp msgid "Value:" -msgstr "" +msgstr "ערך:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -100,26 +102,29 @@ msgstr "למחוק ×ת ×”×§×‘×¦×™× ×”× ×‘×—×¨×™×" #: editor/animation_bezier_editor.cpp msgid "Add Bezier Point" -msgstr "הוסף × ×§×•×“×”" +msgstr "הוסף × ×§×•×“×ª בזייה" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Move Bezier Points" -msgstr "הזזת × ×§×•×“×”" +msgstr "הזזת × ×§×•×“×•×ª בזייה" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Duplicate Keys" -msgstr "" +msgstr "שכפול מפתחות ×”× ×¤×©×”" #: editor/animation_bezier_editor.cpp editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Delete Keys" -msgstr "" +msgstr "מחיקת מפתחות ×”× ×¤×©×”" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Change Keyframe Time" msgstr "×©×™× ×•×™ זמן פריי×-מפתח ×× ×™×ž×¦×™×”" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Change Transition" msgstr "×©×™× ×•×™ ×ž×™×§×•× ×× ×™×ž×¦×™×”" @@ -138,7 +143,7 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Change Animation Length" -msgstr "החלפת ערך ×× ×™×ž×¦×™×”" +msgstr "×©× ×” ×ורך ×× ×™×ž×¦×™×”" #: editor/animation_track_editor.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp @@ -148,48 +153,49 @@ msgstr "×©×™× ×•×™ לופ ×× ×™×ž×¦×™×”" #: editor/animation_track_editor.cpp msgid "Property Track" -msgstr "" +msgstr "רצועת מ×פיין" #: editor/animation_track_editor.cpp #, fuzzy msgid "3D Transform Track" -msgstr "התמרה" +msgstr "רצועת ×©×™× ×•×™ 3D" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Call Method Track" -msgstr "" +msgstr "רצועת שיטה" #: editor/animation_track_editor.cpp msgid "Bezier Curve Track" -msgstr "" +msgstr "רצועת ×¢×§×•× ×‘×–×™×™×”" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Audio Playback Track" -msgstr "" +msgstr "רצועת שמע" #: editor/animation_track_editor.cpp #, fuzzy msgid "Animation Playback Track" -msgstr "שקופיות ×”×”× ×¤×©×”" +msgstr "רצועת ×”× ×¤×©×”" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (frames)" -msgstr "משך ×”×”× ×¤×©×” (×‘×©× ×™×•×ª)" +msgstr "משך ×”×”× ×¤×©×” (פריימי×)" #: editor/animation_track_editor.cpp #, fuzzy msgid "Animation length (seconds)" -msgstr "משך ×”×”× ×¤×©×” (×‘×©× ×™×•×ª)" +msgstr "משך ×”×”× ×¤×©×” (×©× ×™×•×ª)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Track" -msgstr "הוספת רצועות חדשות." +msgstr "הוספת רצועה" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Animation Looping" -msgstr "תקריב ×”× ×¤×©×”" +msgstr "לול×ת ×”× ×¤×©×”" #: editor/animation_track_editor.cpp #: modules/visual_script/visual_script_editor.cpp @@ -211,12 +217,10 @@ msgid "Change Track Path" msgstr "החלפת ערך רצועה" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Toggle this track on/off." msgstr "הפעל/כבה רצועה" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Update Mode (How this property is set)" msgstr "עדכן מצב (×יך המ×פיין ×”×–×” × ×§×‘×¢)" @@ -258,7 +262,7 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Nearest" -msgstr "" +msgstr "הקרוב ביותר" #: editor/animation_track_editor.cpp editor/plugins/curve_editor_plugin.cpp #: editor/property_editor.cpp @@ -268,7 +272,7 @@ msgstr "×œ×™× ×™×רי" #: editor/animation_track_editor.cpp msgid "Cubic" -msgstr "" +msgstr "מעוקב" #: editor/animation_track_editor.cpp msgid "Clamp Loop Interp" @@ -285,17 +289,16 @@ msgstr "×”×›× ×¡ מפתח" #: editor/animation_track_editor.cpp msgid "Duplicate Key(s)" -msgstr "שכפול מפתח" +msgstr "שכפול מפתח(ות)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Delete Key(s)" -msgstr "מחיקת שורה" +msgstr "מחיקת מפתח(ות)" #: editor/animation_track_editor.cpp #, fuzzy msgid "Change Animation Update Mode" -msgstr "החלפת ערך מילון" +msgstr "×©×™× ×•×™ מצב עדכון ×”× ×¤×©×”" #: editor/animation_track_editor.cpp #, fuzzy @@ -305,7 +308,7 @@ msgstr "החלפת ערך מילון" #: editor/animation_track_editor.cpp #, fuzzy msgid "Change Animation Loop Mode" -msgstr "×©× ×”× ×¤×©×” חדשה:" +msgstr "×©×™× ×•×™ מצב לול×ת ×”× ×¤×©×”" #: editor/animation_track_editor.cpp #, fuzzy @@ -313,7 +316,6 @@ msgid "Remove Anim Track" msgstr "מחק רצועת ×”× ×¤×©×”" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Create NEW track for %s and insert key?" msgstr "ליצור רצועה חדשה ל%s ×•×œ×”×›× ×™×¡ מפתח?" @@ -333,12 +335,14 @@ msgid "Create" msgstr "יצירה" #: editor/animation_track_editor.cpp +#, fuzzy msgid "Anim Insert" -msgstr "" +msgstr "הוסף ×”× ×¤×©×”" #: editor/animation_track_editor.cpp +#, fuzzy msgid "AnimationPlayer can't animate itself, only other players." -msgstr "" +msgstr "× ×’×Ÿ ×”× ×¤×©×•×ª ×œ× ×™×›×•×œ ×œ×”× ×¤×™×© ×ת עצמו, רק ×©×—×§× ×™× ×חרי×." #: editor/animation_track_editor.cpp #, fuzzy @@ -464,6 +468,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "לבחור הכול" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "בחירה" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -646,6 +660,10 @@ msgstr "מעבר לשורה" msgid "Line Number:" msgstr "מספר השורה:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "×ין תוצ×ות" @@ -695,7 +713,7 @@ msgstr "להתרחק" msgid "Reset Zoom" msgstr "×יפוס התקריב" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "×זהרות" @@ -802,6 +820,11 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "×ותות:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -965,7 +988,8 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "להסיר ×ת ×”×§×‘×¦×™× ×”× ×‘×—×¨×™× ×ž×”×ž×™×–×? (××™ ×פשר לשחזר)" #: editor/dependency_editor.cpp @@ -1335,7 +1359,7 @@ msgstr "×©× ×©×’×•×™. ×œ× ×™×›×•×œ לחפוף ×œ×©× ×ž×—×œ×§×ª ×ž× ×•×¢ ×§×™× #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "×©× ×©×’×•×™. ×œ× ×™×›×•×œ לחפוף ×œ×©× ×¡×•×’ ×ž×•×‘× ×” ×§×™×™×." #: editor/editor_autoload_settings.cpp @@ -1510,6 +1534,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1541,7 +1569,7 @@ msgstr "×©× ×”×ž×¤×¨×§:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "מערכת קבצי×" #: editor/editor_feature_profile.cpp @@ -1602,7 +1630,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1617,7 +1645,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "גרסה × ×•×›×—×™×ª:" #: editor/editor_feature_profile.cpp @@ -1641,13 +1669,9 @@ msgid "Export" msgstr "ייצו×" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "חיפוש במחלקות" +msgid "Available Profiles:" +msgstr "מ××¤×™×™× ×™×" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2702,11 +2726,35 @@ msgid "Editor Layout" msgstr "פריסת עורך" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "שמירת ×¡×¦× ×”" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "הגדרות עורך" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "פתיחת העורך הב×" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "×›× ×™×¡×” ×ל/יצי××” ממסך מל×" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "החלפת מצב" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "הגדרות עורך" @@ -2747,7 +2795,7 @@ msgstr "×ž×¡×ž×›×™× ×ž×§×•×•× ×™×" #: editor/editor_node.cpp msgid "Q&A" -msgstr "שו״ת" +msgstr "ש×לות ותשובות × ×¤×•×¦×•×ª" #: editor/editor_node.cpp msgid "Issue Tracker" @@ -2759,7 +2807,7 @@ msgstr "קהילה" #: editor/editor_node.cpp msgid "About" -msgstr "על ×ודות" +msgstr "על" #: editor/editor_node.cpp msgid "Play the project." @@ -2817,15 +2865,18 @@ msgid "Spins when the editor window redraws." msgstr "מסתובב ×›×שר חלון העורך מצויר מחדש!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "לעדכן תמיד" +#, fuzzy +msgid "Update Continuously" +msgstr "מתמשך" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "עדכון ×©×™× ×•×™×™×" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "השבתת שבשבת עדכון" #: editor/editor_node.cpp @@ -3019,7 +3070,7 @@ msgstr "זמן" msgid "Calls" msgstr "קרי×ות" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3119,20 +3170,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3649,6 +3700,7 @@ msgid "Nodes not in Group" msgstr "הוספה לקבוצה" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5305,6 +5357,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "להפעיל מחדש כעת" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6239,10 +6299,20 @@ msgid "Find Next" msgstr "×יתור הב×" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 +#, fuzzy +msgid "Filter methods" +msgstr "מ××¤×™×™× ×™ פריט." + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "מיון" @@ -6483,20 +6553,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +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 "מחיקת שורה" @@ -8119,51 +8193,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8171,203 +8201,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10040,6 +9894,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "×œ×¦×ž×¦× ×”×›×•×œ" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10070,8 +9929,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "יצירת %s חדש" #: editor/scene_tree_dock.cpp msgid "" @@ -10325,7 +10185,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10730,54 +10590,6 @@ msgstr "בחירת מרחק:" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "הפתרון × ×•×¦×¨â€¦" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "× ×•×¦×¨ ×ž×™×–× C#‎…" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "יצירת הפתרון × ×›×©×œ×”." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "שמירת הפתרון × ×›×©×œ×”." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "בוצע" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "יצירת ×ž×™×–× C#‎ × ×›×©×œ×”." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "יצירת פתרון C#‎" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11365,7 +11177,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11414,7 +11226,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11424,7 +11236,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11492,14 +11304,22 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ל־ARVRCamera חייב להיות מפרק ARVROrigin כהורה שלו" #: scene/3d/arvr_nodes.cpp @@ -11581,7 +11401,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11610,6 +11430,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11645,8 +11469,8 @@ msgstr "PathFollow2D עובד רק ×›×שר ×”×•× ×ž×•×’×“×¨ כצ××¦× ×©×œ מ #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11657,7 +11481,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11673,7 +11499,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11684,7 +11510,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11721,7 +11549,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11733,7 +11561,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11745,8 +11573,12 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "מצב גולמי" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11759,10 +11591,15 @@ msgstr "הוספת הצבע ×”× ×•×›×—×™ כערכה" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11776,18 +11613,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11831,6 +11668,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "גודל הגופן שגוי." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "גודל הגופן שגוי." @@ -11850,6 +11692,37 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Generating solution..." +#~ msgstr "הפתרון × ×•×¦×¨â€¦" + +#~ msgid "Generating C# project..." +#~ msgstr "× ×•×¦×¨ ×ž×™×–× C#‎…" + +#~ msgid "Failed to create solution." +#~ msgstr "יצירת הפתרון × ×›×©×œ×”." + +#~ msgid "Failed to save solution." +#~ msgstr "שמירת הפתרון × ×›×©×œ×”." + +#~ msgid "Done" +#~ msgstr "בוצע" + +#~ msgid "Failed to create C# project." +#~ msgstr "יצירת ×ž×™×–× C#‎ × ×›×©×œ×”." + +#~ msgid "Create C# solution" +#~ msgstr "יצירת פתרון C#‎" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "חיפוש במחלקות" + +#~ msgid "Update Always" +#~ msgstr "לעדכן תמיד" + +#~ msgid "Raw Mode" +#~ msgstr "מצב גולמי" + #~ msgid "Path to Node:" #~ msgstr "× ×ª×™×‘ המפרק:" diff --git a/editor/translations/hi.po b/editor/translations/hi.po index 601d09371e..7fa0ae91a0 100644 --- a/editor/translations/hi.po +++ b/editor/translations/hi.po @@ -34,7 +34,7 @@ msgstr "डीकोडिंग बाइटà¥à¤¸, या अमानà¥à¤¯ à #: core/math/expression.cpp msgid "Invalid input %i (not passed) in expression" -msgstr "अà¤à¤¿à¤µà¥à¤¯à¤•à¥à¤¤à¤¿ में अमानà¥à¤¯ इनपà¥à¤Ÿ % i (पारित नहीं)" +msgstr "अà¤à¤¿à¤µà¥à¤¯à¤•à¥à¤¤à¤¿ में अमानà¥à¤¯ इनपà¥à¤Ÿ %i (पारित नहीं)" #: core/math/expression.cpp msgid "self can't be used because instance is null (not passed)" @@ -58,7 +58,7 @@ msgstr "'%s' बनाने के लिठअवैध तरà¥à¤•" #: core/math/expression.cpp msgid "On call to '%s':" -msgstr "'% s ' को कॉल करने पर:" +msgstr "'%s ' को कॉल करने पर:" #: editor/animation_bezier_editor.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -449,6 +449,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "डà¥à¤ªà¥à¤²à¤¿à¤•ेट चयन" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -626,6 +636,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -675,7 +689,7 @@ msgstr "छोटा करो" msgid "Reset Zoom" msgstr "रीसेट आकार" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -790,6 +804,11 @@ msgstr "जà¥à¤¡à¤¿à¤¯à¥‡" #: editor/connections_dialog.cpp #, fuzzy +msgid "Signal:" +msgstr "संकेत" + +#: editor/connections_dialog.cpp +#, fuzzy msgid "Connect '%s' to '%s'" msgstr "जà¥à¤¡à¤¿à¤¯à¥‡ '%s' to '%s'" @@ -965,7 +984,8 @@ msgid "Owners Of:" msgstr "के सà¥à¤µà¤¾à¤®à¥€:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "परियोजना से चयनित फ़ाइलें निकालें? (कोई पूरà¥à¤µà¤µà¤¤ नहीं)" #: editor/dependency_editor.cpp @@ -1348,7 +1368,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1520,6 +1540,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1547,7 +1571,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1602,7 +1626,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1616,7 +1640,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1639,11 +1663,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2663,10 +2683,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2773,15 +2813,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2971,7 +3011,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3071,20 +3111,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3586,6 +3626,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5192,6 +5233,13 @@ 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 "" @@ -6108,10 +6156,18 @@ msgid "Find Next" 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 "" @@ -6346,18 +6402,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "à¤à¤• नया बनाà¤à¤‚" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7921,51 +7981,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7973,203 +7989,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9811,6 +9651,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9839,8 +9683,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "à¤à¤• नया बनाà¤à¤‚" #: editor/scene_tree_dock.cpp msgid "" @@ -10082,7 +9927,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10485,55 +10330,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "सदसà¥à¤¯à¤¤à¤¾ बनाà¤à¤‚" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11115,7 +10911,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11164,7 +10960,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11174,7 +10970,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11241,14 +11037,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11327,7 +11130,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11356,6 +11159,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11390,8 +11197,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11402,7 +11209,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11418,7 +11227,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11429,7 +11238,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11466,7 +11277,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "जà¥à¤¡à¤¿à¤¯à¥‡ '%s' to '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11478,7 +11289,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11490,7 +11301,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11503,10 +11318,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11520,18 +11340,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11575,6 +11395,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "गलत फॉणà¥à¤Ÿ का आकार |" + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "गलत फॉणà¥à¤Ÿ का आकार |" @@ -11594,6 +11419,10 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "सदसà¥à¤¯à¤¤à¤¾ बनाà¤à¤‚" + #~ msgid "Line:" #~ msgstr "रेखा:" diff --git a/editor/translations/hr.po b/editor/translations/hr.po index 89729b2173..4f05208f9b 100644 --- a/editor/translations/hr.po +++ b/editor/translations/hr.po @@ -430,6 +430,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "Pokaži samo staze Ävorova oznaÄenih u stablu." @@ -604,6 +613,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -653,7 +666,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -757,6 +770,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -915,7 +932,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1279,7 +1296,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1450,6 +1467,10 @@ msgstr "" 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 "" @@ -1475,7 +1496,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1528,7 +1549,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1541,7 +1562,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1564,11 +1585,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2574,10 +2591,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2684,15 +2721,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "Kontinuirano" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2882,7 +2920,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2980,20 +3018,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3478,6 +3516,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5057,6 +5096,13 @@ 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 "" @@ -5962,10 +6008,18 @@ msgid "Find Next" 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 "" @@ -6193,18 +6247,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7728,51 +7785,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7780,203 +7793,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9603,6 +9440,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9631,7 +9472,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9870,7 +9711,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10270,54 +10111,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10894,7 +10687,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10943,7 +10736,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10953,7 +10746,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11020,14 +10813,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11106,7 +10906,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11135,6 +10935,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11169,8 +10973,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11181,7 +10985,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11197,7 +11003,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11208,7 +11014,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11243,7 +11051,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11255,7 +11063,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11267,7 +11075,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11280,10 +11092,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11297,18 +11114,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11351,6 +11168,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/hu.po b/editor/translations/hu.po index fe752d1863..a7033084d3 100644 --- a/editor/translations/hu.po +++ b/editor/translations/hu.po @@ -469,6 +469,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Összes Kijelölése" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Kiválasztó Mód" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -651,6 +661,10 @@ msgstr "Sorra Ugrás" msgid "Line Number:" msgstr "Sor Száma:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Nincs Találat" @@ -700,7 +714,7 @@ msgstr "KicsinyÃtés" msgid "Reset Zoom" msgstr "NagyÃtás VisszaállÃtása" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -813,6 +827,11 @@ msgid "Connect" msgstr "Csatlakoztatás" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Jelzések:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "'%s' Csatlakoztatása '%s'-hez" @@ -983,7 +1002,8 @@ msgid "Owners Of:" msgstr "Tulajdonosai:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "EltávolÃtja a kiválasztott fájlokat a projektbÅ‘l? (nem visszavonható)" #: editor/dependency_editor.cpp @@ -1359,7 +1379,7 @@ msgstr "Érvénytelen név. Nem ütközhet egy már meglévÅ‘ motor osztálynév #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "Érvénytelen név. Nem ütközhet egy már meglévÅ‘ beépÃtett tÃpusnévvel." #: editor/editor_autoload_settings.cpp @@ -1535,6 +1555,10 @@ msgstr "" msgid "Template file not found:" msgstr "Sablon fájl nem található:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1566,7 +1590,7 @@ msgstr "Mozgás Mód" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "Fájlrendszer" #: editor/editor_feature_profile.cpp @@ -1627,7 +1651,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1642,7 +1666,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Jelenlegi Verzió:" #: editor/editor_feature_profile.cpp @@ -1666,13 +1690,9 @@ msgid "Export" msgstr "Exportálás" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Osztályok Keresése" +msgid "Available Profiles:" +msgstr "Tulajdonságok" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2802,11 +2822,35 @@ msgid "Editor Layout" msgstr "SzerkesztÅ‘ Elrendezés" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Scene mentés" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "SzerkesztÅ‘ BeállÃtások" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "KövetkezÅ‘ SzerkesztÅ‘ Megnyitása" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Teljes KépernyÅ‘" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "Mód Váltása" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "SzerkesztÅ‘ BeállÃtások" @@ -2917,15 +2961,18 @@ msgid "Spins when the editor window redraws." msgstr "Fordul egyet, amikor a szerkesztÅ‘ablak újrarajzolódik!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "FrissÃtés Mindig" +#, fuzzy +msgid "Update Continuously" +msgstr "Folyamatos" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Változások FrissÃtése" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "FrissÃtési Forgó Kikapcsolása" #: editor/editor_node.cpp @@ -3120,7 +3167,7 @@ msgstr "IdÅ‘" msgid "Calls" msgstr "HÃvások" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3220,6 +3267,11 @@ 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 #, fuzzy msgid "New Key:" msgstr "Új név:" @@ -3233,11 +3285,6 @@ msgstr "Új név:" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3761,6 +3808,7 @@ msgid "Nodes not in Group" msgstr "Hozzáadás Csoporthoz" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5457,6 +5505,14 @@ msgid "Load Emission Mask" msgstr "Kibocsátási Maszk Betöltése" #: 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 +#, fuzzy +msgid "Restart" +msgstr "ÚjraindÃtás (mp):" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Kibocsátási Maszk Törlése" @@ -6407,10 +6463,20 @@ msgid "Find Next" msgstr "KövetkezÅ‘ Keresése" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Objektumtulajdonságok." + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Objektumtulajdonságok." + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Rendezés" @@ -6653,20 +6719,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +msgstr "Pontok Törlése" + #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Kivágás" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Összes Kijelölése" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Sor Törlése" @@ -8300,51 +8370,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8353,203 +8379,27 @@ msgid "Input parameter." msgstr "Illesztés szülÅ‘höz" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10225,6 +10075,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Összes összecsukása" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10255,8 +10110,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Új %s Létrehozása" #: editor/scene_tree_dock.cpp msgid "" @@ -10510,7 +10366,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10919,55 +10775,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Fájlok Megtekintése" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11561,7 +11368,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11610,7 +11417,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11620,7 +11427,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11687,14 +11494,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11773,7 +11587,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11802,6 +11616,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11836,8 +11654,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11848,7 +11666,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11864,7 +11684,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11875,7 +11695,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11913,7 +11735,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "'%s' Lecsatlakoztatása '%s'-ról" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11929,7 +11751,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "Az animációs fa érvénytelen." #: scene/animation/animation_tree_player.cpp @@ -11941,7 +11763,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11954,10 +11780,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11971,18 +11802,18 @@ msgstr "Kérem ErÅ‘sÃtse Meg..." #: 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -12031,6 +11862,11 @@ msgstr "Bemenet Hozzáadása" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "Érvénytelen betűtÃpus méret." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "Érvénytelen betűtÃpus méret." @@ -12050,6 +11886,17 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "View log" +#~ msgstr "Fájlok Megtekintése" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Osztályok Keresése" + +#~ msgid "Update Always" +#~ msgstr "FrissÃtés Mindig" + #~ msgid "Path to Node:" #~ msgstr "Út a Node-hoz:" diff --git a/editor/translations/id.po b/editor/translations/id.po index 283c0e3e61..f88fff02e5 100644 --- a/editor/translations/id.po +++ b/editor/translations/id.po @@ -9,9 +9,9 @@ # Damar S. M <the.last.walla@gmail.com>, 2017. # Fajar Ru <kzofajar@gmail.com>, 2018. # Khairul Hidayat <khairulcyber4rt@gmail.com>, 2016. -# Reza Hidayat Bayu Prabowo <rh.bayu.prabowo@gmail.com>, 2018. +# Reza Hidayat Bayu Prabowo <rh.bayu.prabowo@gmail.com>, 2018, 2019. # Romi Kusuma Bakti <romikusumab@gmail.com>, 2017, 2018. -# Sofyan Sugianto <sofyanartem@gmail.com>, 2017-2018. +# Sofyan Sugianto <sofyanartem@gmail.com>, 2017-2018, 2019. # Tito <ijavadroid@gmail.com>, 2018. # Tom My <tom.asadinawan@gmail.com>, 2017. # yursan9 <rizal.sagi@gmail.com>, 2016. @@ -19,12 +19,13 @@ # Guntur Sarwohadi <gsarwohadi@gmail.com>, 2019. # Alphin Albukhari <alphinalbukhari5@gmail.com>, 2019. # I Dewa Agung Adhinata <agungnata2003@gmail.com>, 2019. +# herri siagian <herry.it.2007@gmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-04-05 13:04+0000\n" -"Last-Translator: I Dewa Agung Adhinata <agungnata2003@gmail.com>\n" +"PO-Revision-Date: 2019-07-09 10:47+0000\n" +"Last-Translator: herri siagian <herry.it.2007@gmail.com>\n" "Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/" "godot/id/>\n" "Language: id\n" @@ -32,13 +33,13 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 3.6-dev\n" +"X-Generator: Weblate 3.8-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 "" -"Tipe argument salah dalam menggunakan convert(), gunakan konstanta TYPE_*." +"Tipe argumen salah dalam menggunakan convert(), gunakan konstanta TYPE_*." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp @@ -53,15 +54,15 @@ msgstr "Masukkan tidak sah %i (tidak diberikan) dalam ekspresi" #: core/math/expression.cpp #, fuzzy msgid "self can't be used because instance is null (not passed)" -msgstr "self tidak dapat digunakan karena instansi adalah null (not passed)" +msgstr "self tidak dapat digunakan karena tidak memiliki instance (not passed)" #: core/math/expression.cpp msgid "Invalid operands to operator %s, %s and %s." -msgstr "operan untuk operator %s, %s dan %s tidak sah." +msgstr "operan salah untuk operator %s, %s dan %s." #: core/math/expression.cpp msgid "Invalid index of type %s for base type %s" -msgstr "index tipe %s tidak sah untuk tipe dasar %s" +msgstr "Tipe index %s tidak valid untuk tipe dasar %s" #: core/math/expression.cpp msgid "Invalid named index '%s' for base type %s" @@ -93,9 +94,8 @@ msgid "Time:" msgstr "Waktu:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Nama baru:" +msgstr "Nilai:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -179,12 +179,10 @@ msgid "Animation Playback Track" msgstr "Track Pemutar Animasi" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (frames)" -msgstr "Panjang Animasi (detik)" +msgstr "Panjang Animasi (frame)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (seconds)" msgstr "Panjang Animasi (detik)" @@ -450,10 +448,29 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Animasi ini dimiliki oleh skena yang diimpor, sehingga perubahan track yang " +"diimpor tidak akan disimpan.\n" +"\n" +"Supaya bisa menambahkan track kustom, arahkan ke pengaturan impor skena dan " +"atur\n" +"\"Animasi > Penyimpanan\" ke \"Berkas\", nyalakan \"Animasi > Pertahankan " +"Track Kustom\", lalu impor ulang.\n" +"Sebagai alternatif, gunakan preset impor yang mengimpor animasi ke dalam " +"berkas terpisah." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Peringatan: Menyunting animasi yang diimpor" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Pilih Semua" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Metode Publik:" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -464,9 +481,8 @@ msgid "Group tracks by node or display them as plain list." msgstr "Susun Track-track dengan node atau tampilkan sebagai daftar biasa." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Snap:" -msgstr "Snap (d): " +msgstr "Snap:" #: editor/animation_track_editor.cpp msgid "Animation step value." @@ -474,11 +490,11 @@ msgstr "Nilai Langkah Animasi." #: editor/animation_track_editor.cpp msgid "Seconds" -msgstr "" +msgstr "Detik" #: editor/animation_track_editor.cpp msgid "FPS" -msgstr "" +msgstr "FPS" #: editor/animation_track_editor.cpp editor/editor_properties.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp @@ -630,6 +646,10 @@ msgstr "Pergi ke Baris" msgid "Line Number:" msgstr "Nomor Baris:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Tidak ada yang cocok" @@ -661,7 +681,7 @@ msgstr "Hanya yang Dipilih" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Standar" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -679,7 +699,7 @@ msgstr "Perkecil Pandangan" msgid "Reset Zoom" msgstr "Kebalikan Semula Pandangan" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Peringatan" @@ -688,37 +708,32 @@ msgid "Line and column numbers." msgstr "Nomor baris dan kolom." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Method dalam Node target harus spesifik!" +msgstr "Method dalam node target harus ditentukan." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Target metode tidak ditemukan! Tentukan metode yang sah atau lampirkan skrip " -"ke target Node." +"Target method tidak ditemukan. Tentukan method yang valid atau lampirkan " +"skrip ke target node." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "Sambungkan Ke Node:" +msgstr "Hubungkan ke Node:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Tidak bisa terhubung ke host:" +msgstr "Hubungkan ke Skrip:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Sinyal-sinyal:" +msgstr "Dari Sinyal:" #: editor/connections_dialog.cpp msgid "Scene does not contain any script." -msgstr "" +msgstr "Skena tidak berisi skrip apapun." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -746,9 +761,8 @@ msgid "Extra Call Arguments:" msgstr "Argumen-argumen Panggilan Ekstra:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Seimbang" +msgstr "Lanjut" #: editor/connections_dialog.cpp msgid "Deferred" @@ -758,6 +772,7 @@ msgstr "Ditunda" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Menahan sinyal, menyimpannya dalam antrean dan hanya memicunya saat idle." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -765,12 +780,11 @@ msgstr "Satu Waktu" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Memutuskan sinyal setelah pemicuan pertama." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Sambungkan Sinyal: " +msgstr "Tidak dapat menghubungkan sinyal" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -791,6 +805,11 @@ msgid "Connect" msgstr "Menghubungkan" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Sinyal-sinyal:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Sambungkan '%s' ke '%s'" @@ -812,14 +831,12 @@ msgid "Disconnect" msgstr "Putuskan" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Sambungkan Sinyal: " +msgstr "Hubungkan Sinyal ke Method" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Ubah koneksi: " +msgstr "Sunting Koneksi:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -895,22 +912,20 @@ msgid "Dependencies For:" msgstr "Ketergantungan Untuk:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" -"Scene '%s' sedang disunting saat ini.\n" -"Perubahan-perubahan tidak akan berefek kecuali dimuat ulang." +"Skena '%s' sedang disunting saat ini.\n" +"Perubahan hanya akan berlaku saat dimuat ulang." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" "Resource '%s' sedang digunakan.\n" -"Perubahan-perubahan akan terjadi ketika dimuat ulang." +"Perubahan hanya akan berlaku saat dimuat ulang." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -957,7 +972,8 @@ msgid "Owners Of:" msgstr "Pemilik Dari:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" "Hapus file-file yang dipilih dari proyek? (tidak bisa dibatalkan / undo)" @@ -1004,9 +1020,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Hapus secara permanen %d item? (Tidak dapat dikembalikan!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "Ketergantungan" +msgstr "Tampilkan Ketergantungan" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1269,12 +1284,11 @@ msgstr "Buka Layout Suara Bus" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Tidak ada berkas '%s'." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Layout" -msgstr "Simpan Penampilan" +msgstr "Tata Letak" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -1327,25 +1341,21 @@ msgid "Valid characters:" msgstr "Karakter sah:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"Nama tidak valid. Tidak boleh sama dengan nama kelas bawaan engine yang ada." +msgstr "Tidak boleh sama dengan nama kelas engine yang sudah ada." #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "Nama tidak sah. Tidak boleh serupa dengan nama bawaan." +msgid "Must not collide with an existing built-in type name." +msgstr "Tidak boleh sama dengan nama tipe bawaan yang ada." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." -msgstr "" -"Nama tidak sah. Tidak boleh serupa dengan nama konstanta global yang ada." +msgstr "Tidak boleh sama dengan nama konstanta global yang ada." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "Keyword tidak dapat dijadikan sebagai nama autoload." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1376,9 +1386,8 @@ msgid "Rearrange Autoloads" msgstr "Mengatur kembali Autoload-autoload" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." -msgstr "Path Tidak Sah." +msgstr "Path tidak valid." #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp msgid "File does not exist." @@ -1412,7 +1421,7 @@ msgstr "Singleton" #: editor/editor_data.cpp msgid "Updating Scene" -msgstr "Memperbaharui Scene" +msgstr "Memperbarui Skena" #: editor/editor_data.cpp msgid "Storing local changes..." @@ -1420,7 +1429,7 @@ msgstr "Menyimpan perubahan-perubahan lokal..." #: editor/editor_data.cpp msgid "Updating scene..." -msgstr "Memperbaharui scene..." +msgstr "Memperbarui skena..." #: editor/editor_data.cpp editor/editor_properties.cpp msgid "[empty]" @@ -1431,9 +1440,8 @@ msgid "[unsaved]" msgstr "[belum disimpan]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Slahkan pilih direktori kerja terlebih dahulu" +msgstr "Slahkan pilih direktori kerja terlebih dahulu." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1474,22 +1482,20 @@ msgid "Packing" msgstr "Mengemas" #: editor/editor_export.cpp -#, fuzzy msgid "" "Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " "Etc' in Project Settings." msgstr "" -"Platform target membutuhkan kompressi tekstur 'ETC' untuk GLES2. Aktifkan " -"dukungan di Pengaturan Proyek." +"Platform target membutuhkan kompresi tekstur 'ETC' untuk GLES2. Aktifkan " +"'Impor Lainnya' di Pengaturan Proyek." #: editor/editor_export.cpp -#, fuzzy msgid "" "Target platform requires 'ETC2' texture compression for GLES3. Enable " "'Import Etc 2' in Project Settings." msgstr "" -"Platform target membutuhkan kompressi tekstur 'ETC2' untuk GLES3. Aktifkan " -"dukungan di Pengaturan Proyek." +"Platform target membutuhkan kompresi tekstur 'ETC2' untuk GLES3. Aktifkan " +"'Impor Lainnya 2' di Pengaturan Proyek." #: editor/editor_export.cpp #, fuzzy @@ -1499,8 +1505,9 @@ msgid "" "Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" -"Platform target membutuhkan kompressi tekstur 'ETC' untuk GLES2. Aktifkan " -"dukungan di Pengaturan Proyek." +"Platform target membutuhkan kompressi tekstur 'ETC' untuk mengembalikan " +"driver ke GLES2. Aktifkan 'Impor Lainnya' di Pengaturan Proyek, atau matikan " +"'Driver Fallback Enabled'." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -1518,121 +1525,111 @@ msgstr "Templat rilis kustom tidak ditemukan." msgid "Template file not found:" msgstr "Templat berkas tidak ditemukan:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Editor" +msgstr "Penyunting 3D" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Buka Penyunting Skrip" +msgstr "Penyunting Skrip" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Buka Pustaka Aset" +msgstr "Pustaka Aset" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" -msgstr "" +msgstr "Menyunting Pohon Skena" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Impor" +msgstr "Dok Impor" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "Nama Node:" +msgstr "Dok Node" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" -msgstr "Berkas Sistem" +msgid "FileSystem and Import Docks" +msgstr "Dok Berkas Sistem" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Ganti Semua" +msgstr "Hapus profil '%s'? (tidak bisa dibatalkan)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "Profil harus memiliki nama berkas yang valid dan tidak mengandung '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Sudah ada nama berkas atau folder seperti itu." +msgstr "Sudah ada profil dengan nama seperti ini." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Penyunting Dinonaktifkan, Properti Dinonaktifkan)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Hanya Properti" +msgstr "(Properti Dinonaktifkan)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Dinonaktifkan" +msgstr "(Penyunting Dinonaktifkan)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Deskripsi Kelas:" +msgstr "Opsi Kelas:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Buka Penyunting Selanjutnya" +msgstr "Aktifkan Penyunting Kontekstual" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Properti:" +msgstr "Properti yang Diaktifkan:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "Daftar Fungsi:" +msgstr "Fitur yang Diaktifkan:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Cari Kelas" +msgstr "Kelas yang Diaktifkan:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Format Berkas '%s' tidak valid, impor dibatalkan." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"Sudah ada profil '%s'. Hapus profil ini terlebih dahulu sebelum mengimpor, " +"impor dibatalkan." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Error memuat font." +msgstr "Galat saat menyimpan profil ke: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Tidak diatur" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" -msgstr "Versi sekarang:" +msgid "Current Profile:" +msgstr "Profil Sekarang" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Saat ini:" +msgstr "Jadikan Profil Saat Ini" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1651,43 +1648,32 @@ msgstr "Ekspor" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" -msgstr "Node-node yang Tersedia:" - -#: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Cari Kelas" +msgid "Available Profiles:" +msgstr "Profil yang Tersedia" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Deskripsi Kelas" +msgstr "Opsi Kelas" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Nama baru:" +msgstr "Nama profil baru:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Beri Skala Seleksi" +msgstr "Hapus Profil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "%d file lagi" +msgstr "Impor Profil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Ekspor Projek" +msgstr "Ekspor Profil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "Mengatur Templat Ekspor" +msgstr "Kelola Penyunting Fitur Profil" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1794,28 +1780,24 @@ msgid "Move Favorite Down" msgstr "Pindahkan Favorit Kebawah" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Previous Folder" -msgstr "Tab sebelumnya" +msgstr "Direktori Sebelumnya" #: editor/editor_file_dialog.cpp msgid "Next Folder" msgstr "Folder Berikutnya" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Go to parent folder." -msgstr "Pergi ke direktori induk" +msgstr "Pergi ke direktori atasnya." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "(Un)favorite current folder." -msgstr "Tidak dapat membuat folder." +msgstr "Hapus favorit direktori saat ini." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Beralih File Tersembunyi" +msgstr "Beralih visibilitas berkas yang tersembunyi." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1852,6 +1834,8 @@ msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"Ada beberapa importir untuk berbagai tipe yang mengacu pada berkas %s, impor " +"dibatalkan" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2037,9 +2021,8 @@ msgid "Output:" msgstr "Keluaran:" #: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Copy Selection" -msgstr "Hapus Pilihan" +msgstr "Salin Seleksi" #: editor/editor_log.cpp editor/editor_profiler.cpp #: editor/editor_properties.cpp @@ -2057,12 +2040,11 @@ msgstr "Bersihkan Luaran" #: editor/editor_node.cpp msgid "Project export failed with error code %d." -msgstr "Ekspor proyek gagal dengan kode kesalahan% d." +msgstr "Ekspor proyek gagal dengan kode kesalahan %d." #: editor/editor_node.cpp -#, fuzzy msgid "Imported resources can't be saved." -msgstr "Resource yang telah diimpor tidak dapat disimpan." +msgstr "Sumber daya yang diimpor tidak dapat disimpan." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: scene/gui/dialogs.cpp @@ -2074,13 +2056,12 @@ msgid "Error saving resource!" msgstr "Error menyimpan resource!" #: editor/editor_node.cpp -#, fuzzy msgid "" "This resource can't be saved because it does not belong to the edited scene. " "Make it unique first." msgstr "" -"Resourse ini tidak dapat disimpan karena bukan di scene yang diedit. Buat " -"unik dahulu." +"Sumber daya ini tidak dapat disimpan karena bukan milik skena yang " +"disunting. Buatlah unik terlebih dahulu." #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Save Resource As..." @@ -2120,7 +2101,7 @@ msgstr "Terjadi kesalahan saat memuat '%s'." #: editor/editor_node.cpp msgid "Saving Scene" -msgstr "Menyimpan Scene" +msgstr "Menyimpan Skena" #: editor/editor_node.cpp msgid "Analyzing" @@ -2139,7 +2120,7 @@ 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 "" -"Scene ini tidak bisa disimpan karena ada inklusi penginstansian yang " +"Skena ini tidak bisa disimpan karena ada inklusi penginstansian yang " "siklik.\n" "Mohon betulkan dan coba simpan lagi." @@ -2148,12 +2129,12 @@ msgid "" "Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " "be satisfied." msgstr "" -"Tidak dapat menyimpan scene. Dependensi (instance atau turunannya) mungkin " +"Tidak dapat menyimpan skena Dependensi (instance atau turunannya) mungkin " "tidak terpenuhi." #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "Can't overwrite scene that is still open!" -msgstr "Tidak bisa menimpa scene yang masih terbuka!" +msgstr "Tidak bisa menimpa skena yang masih terbuka!" #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" @@ -2193,86 +2174,82 @@ msgid "" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" -"Sumber ini termasuk pada scene yang telah terimpor, jadi tidak dapat " -"diubah.\n" -"Tolong baca dokumentasi yang relevan dalam impor scenes untuk pemahaman cara " -"kerja." +"Sumber daya ini milik skena yang telah diimpor, jadi tidak dapat disunting.\n" +"Harap baca dokumentasi yang relevan dalam mengimpor skena untuk lebih " +"memahami alur kerjanya." #: editor/editor_node.cpp -#, fuzzy 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 "" -"Sumber ini termasuk ke scene warisan.\n" -"Perubahan tidak akan tersimpan ke scene ini." +"Sumber daya ini milik skena yang di-instance atau diwariskan.\n" +"Perubahan tidak akan disimpan ketika menyimpan skena saat ini." #: 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 "" -"Sumber ini telah terimpor, jadi tidak dapat diubah. Umbah pengaturan pada " -"panel impor dan impor kembali." +"Sumber daya ini telah diimpor, jadi tidak dapat disunting. Ubah " +"pengaturannya pada panel impor kemudian impor kembali." #: editor/editor_node.cpp -#, fuzzy 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 "" -"Scene ini telah terimpor, jadi pengubahan tidak tersimpan.\n" -"Instansi atau warisan membuat perubahan diperbolehkan.\n" -"Baca dokumentasi yang relevan untuk impor scene dan pemahaman lebih lanjut " -"tentang workflow ini." +"Skena ini telah diimpor, jadi perubahan itu tidak akan tersimpan.\n" +"Meng-instansi atau Mewariskannya akan memungkinkan melakukan perubahan " +"padanya.\n" +"Harap baca dokumentasi yang relevan untuk mengimpor skena untuk lebih " +"memahami alur kerjanya." #: editor/editor_node.cpp -#, fuzzy 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 "" -"Ini merupakan objek remote, jadi perubahan tidak tersimpan.\n" -"Baca dokumentasi yang relevan untuk pemahaman lebih lanjut tentang workflow " -"ini." +"Ini merupakan objek jarak jauh, jadi perubahan tidak akan tersimpan.\n" +"Harap baca dokumentasi yang relevan dalam mengawakutu untuk lebih memahami " +"alur kerjanya." #: editor/editor_node.cpp msgid "There is no defined scene to run." -msgstr "Tidak ada definisi scene untuk dijalankan." +msgstr "Tidak ada skena yang didefinisikan untuk dijalankan." #: editor/editor_node.cpp msgid "Current scene was never saved, please save it prior to running." msgstr "" -"Scene saat ini belum pernah disimpan, mohon simpat dahulu untuk " +"Skena saat ini belum pernah disimpan, harap simpan terlebih dahulu sebelum " "menjalankannya." #: editor/editor_node.cpp msgid "Could not start subprocess!" -msgstr "Tidak dapat memulai subprocess!" +msgstr "Tidak dapat memulai subproses!" #: editor/editor_node.cpp editor/filesystem_dock.cpp msgid "Open Scene" -msgstr "Buka Scene" +msgstr "Buka Skena" #: editor/editor_node.cpp msgid "Open Base Scene" -msgstr "Buka Scene Dasar" +msgstr "Buka Skena Dasar" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Buka Cepat Scene..." +msgstr "Buka Cepat..." #: editor/editor_node.cpp msgid "Quick Open Scene..." -msgstr "Buka Cepat Scene..." +msgstr "Buka Cepat Skena..." #: editor/editor_node.cpp msgid "Quick Open Script..." -msgstr "Buka Cepat Script..." +msgstr "Buka Cepat Skrip..." #: editor/editor_node.cpp msgid "Save & Close" @@ -2280,19 +2257,19 @@ msgstr "Simpan & Tutup" #: editor/editor_node.cpp msgid "Save changes to '%s' before closing?" -msgstr "Simpan perubahan '%s' sebelum tutup?" +msgstr "Simpan perubahan '%s' sebelum menutupnya?" #: editor/editor_node.cpp msgid "Saved %s modified resource(s)." -msgstr "Tersimpan %s resource berubah." +msgstr "Menyimpan sumber daya %s yang diubah." #: editor/editor_node.cpp msgid "A root node is required to save the scene." -msgstr "Node akar diperlukan untuk menyimpan scene." +msgstr "Node akar diperlukan untuk menyimpan skena." #: editor/editor_node.cpp msgid "Save Scene As..." -msgstr "Simpan Scene Sebagai..." +msgstr "Simpan Skena Sebagai..." #: editor/editor_node.cpp msgid "No" @@ -2304,19 +2281,19 @@ msgstr "Ya" #: editor/editor_node.cpp msgid "This scene has never been saved. Save before running?" -msgstr "Scene ini belum pernah disimpan. Simpan sebelum menjalankan?" +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 scene." +msgstr "Operasi ini tidak dapat diselesaikan tanpa skena." #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "Ekspor Mesh Library" +msgstr "Ekspor Pustaka Mesh" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." -msgstr "Tindakan ini tidak bisa dilakukan tanpa node dasar." +msgstr "Tindakan ini tidak bisa dilakukan tanpa node akar." #: editor/editor_node.cpp msgid "Export Tile Set" @@ -2328,11 +2305,11 @@ msgstr "Operasi ini tidak dapat diselesaikan tanpa node yang terpilih." #: editor/editor_node.cpp msgid "Current scene not saved. Open anyway?" -msgstr "Scene saat ini tidak disimpan. Buka saja?" +msgstr "Skena saat ini belum disimpan. Buka saja?" #: editor/editor_node.cpp msgid "Can't reload a scene that was never saved." -msgstr "Tidak bisa memuat ulang scene yang tidak pernah disimpan." +msgstr "Tidak bisa memuat ulang skena yang belum pernah disimpan." #: editor/editor_node.cpp msgid "Revert" @@ -2344,7 +2321,7 @@ msgstr "Tindakan ini tidak dapat dibatalkan. Pulihkan saja?" #: editor/editor_node.cpp msgid "Quick Run Scene..." -msgstr "Jalankan Cepat Scene..." +msgstr "Jalankan Cepat Skena..." #: editor/editor_node.cpp msgid "Quit" @@ -2364,11 +2341,11 @@ msgstr "Simpan & Keluar" #: editor/editor_node.cpp msgid "Save changes to the following scene(s) before quitting?" -msgstr "Simpan perubahan scene saat ini sebelum keluar?" +msgstr "Simpan perubahan skena saat ini sebelum keluar?" #: editor/editor_node.cpp msgid "Save changes the following scene(s) before opening Project Manager?" -msgstr "Simpan perubahan scene saat ini sebelum membuka Manajer Projek?" +msgstr "Simpan perubahan skena saat ini sebelum membuka Manajer Proyek?" #: editor/editor_node.cpp msgid "" @@ -2380,7 +2357,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Pick a Main Scene" -msgstr "Pilih sebuah Scene Utama" +msgstr "Pilih Skena Utama" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." @@ -2422,20 +2399,20 @@ 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 "" -"Scene '%s' terimpor otomatis, jadi tidak dapat diubah.\n" -"Untuk melakukan perubahan, warisan baru scene dapat dibuat." +"Skena '%s' terimpor otomatis, jadi tidak dapat dimodifikasi.\n" +"Untuk melakukan perubahan, skena warisan baru 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 "" -"Gagal memuat scene, harus dalam alamat proyek. Gunakan 'Impor\" untuk " -"membuka scene tersebut, kemudian simpan di dalam alamat proyek." +"Gagal memuat skena, harus dalam lokasi proyek. Gunakan 'Impor\" untuk " +"membuka skena tersebut, kemudian simpan di dalam lokasi proyek." #: editor/editor_node.cpp msgid "Scene '%s' has broken dependencies:" -msgstr "Scene '%s' memiliki dependensi yang rusak:" +msgstr "Skena '%s' memiliki dependensi yang rusak:" #: editor/editor_node.cpp msgid "Clear Recent Scenes" @@ -2447,9 +2424,9 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Tidak ada scene utama yang pernah didefinisikan, pilih satu?\n" -"Anda dapat mengubahnya nanti di \"Project Settings\" di bawah kategori " -"'application'." +"Tidak ada skena utama yang pernah didefinisikan, pilih satu?\n" +"Anda dapat mengubahnya nanti di \"Pengaturan Proyek\" di bawah kategori " +"'aplikasi'." #: editor/editor_node.cpp msgid "" @@ -2457,8 +2434,8 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Scene '%s' tidak tersedia, pilih yang sah?\n" -"Anda dapat menggantinya kemudian di \"Pengaturan Proyek\" di bawah kategori " +"Skena '%s' tidak ada, pilih yang valid?\n" +"Anda dapat mengubahnya nanti di \"Pengaturan Proyek\" di bawah kategori " "'aplikasi'." #: editor/editor_node.cpp @@ -2467,8 +2444,8 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Scene '%s' bukanlah sebuah file scene, pilih yang sah?\n" -"Anda dapat menggantinya kemudian di \"Pengaturan Proyek\" di bawah kategori " +"Skena yang dipilih '%s' bukanlah berkas skena, pilih yang valid?\n" +"Anda dapat menggantinya nanti di \"Pengaturan Proyek\" di bawah kategori " "'aplikasi'." #: editor/editor_node.cpp @@ -2491,7 +2468,7 @@ msgstr "Tampilkan dalam FileSystem" #: editor/editor_node.cpp msgid "Play This Scene" -msgstr "Mainkan Scene Ini" +msgstr "Mainkan Skena Ini" #: editor/editor_node.cpp msgid "Close Tab" @@ -2499,20 +2476,19 @@ msgstr "Tutup Tab" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" -msgstr "" +msgstr "Tutup Tab Lainnya" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Tutup Tab Sebelah Kanan" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Tutup Semua" +msgstr "Tutup Semua Tab" #: editor/editor_node.cpp msgid "Switch Scene Tab" -msgstr "Pilih Tab Scene" +msgstr "Beralih Tab Skena" #: editor/editor_node.cpp msgid "%d more files or folders" @@ -2540,7 +2516,7 @@ msgstr "Toggle mode tanpa gangguan." #: editor/editor_node.cpp msgid "Add a new scene." -msgstr "Tambah scene baru." +msgstr "Tambah skena baru." #: editor/editor_node.cpp msgid "Scene" @@ -2548,7 +2524,7 @@ msgstr "Suasana" #: editor/editor_node.cpp msgid "Go to previously opened scene." -msgstr "Pergi ke scene yang dibuka sebelumnya." +msgstr "Pergi ke skena yang sebelumnya dibuka." #: editor/editor_node.cpp msgid "Next tab" @@ -2564,31 +2540,31 @@ msgstr "Saring berkas..." #: editor/editor_node.cpp msgid "Operations with scene files." -msgstr "Operasi dengan file scene." +msgstr "Operasi dengan berkas skena." #: editor/editor_node.cpp msgid "New Scene" -msgstr "Scene Baru" +msgstr "Skena Baru" #: editor/editor_node.cpp msgid "New Inherited Scene..." -msgstr "Scene Turunan Baru..." +msgstr "Skena Warisan Baru..." #: editor/editor_node.cpp msgid "Open Scene..." -msgstr "Buka Scene..." +msgstr "Buka Skena..." #: editor/editor_node.cpp msgid "Save Scene" -msgstr "Simpan Scene" +msgstr "Simpan Skena" #: editor/editor_node.cpp msgid "Save All Scenes" -msgstr "Simpan Semua Scene" +msgstr "Simpan Semua Skena" #: editor/editor_node.cpp msgid "Close Scene" -msgstr "Tutup Scene" +msgstr "Tutup Skena" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Open Recent" @@ -2618,11 +2594,11 @@ msgstr "Ulangi" #: editor/editor_node.cpp msgid "Revert Scene" -msgstr "Kembalikan Scene" +msgstr "Kembalikan Skena" #: editor/editor_node.cpp msgid "Miscellaneous project or scene-wide tools." -msgstr "Macam-macam proyek atau alat scene-wide." +msgstr "Perkakas macam-macam proyek atau lingkup skena." #: editor/editor_node.cpp msgid "Project" @@ -2642,7 +2618,7 @@ msgstr "Buka Project Data Manager" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Pasang Templat Build Android" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2710,7 +2686,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Sync Scene Changes" -msgstr "Sinkronkan Perubahan Scene" +msgstr "Sinkronkan Perubahan Skena" #: editor/editor_node.cpp msgid "" @@ -2753,27 +2729,46 @@ msgid "Editor Layout" msgstr "Tata Letak Editor" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Jadikan Skena Dasar" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Screenshot disimpan di folder Editor Data/Settings" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "Buka Screenshoots secara otomatis" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "Buka di pengolah gambar lainnya" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Mode Layar Penuh" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "Beralih Mode Split" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" -msgstr "Buka Editor Data/Folder Pengaturan" +msgstr "Buka Penyunting Direktori Data/Pengaturan" #: editor/editor_node.cpp msgid "Open Editor Data Folder" msgstr "Buka Folder Data Editor" #: editor/editor_node.cpp -#, fuzzy msgid "Open Editor Settings Folder" -msgstr "Buka Folder Pengaturan Editor" +msgstr "Buka Penyunting Direktori Pengaturan" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "Mengatur Templat Ekspor" +msgstr "Kelola Penyunting Fitur" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2822,15 +2817,15 @@ msgstr "Mainkan" #: editor/editor_node.cpp msgid "Pause the scene" -msgstr "Hentikan sementara scene ini" +msgstr "Hentikan sementara skena ini" #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "Hentikan Sementara Scene" +msgstr "Hentikan Sementara Skena" #: editor/editor_node.cpp msgid "Stop the scene." -msgstr "Hentikan scene." +msgstr "Hentikan skena." #: editor/editor_node.cpp editor/editor_profiler.cpp msgid "Stop" @@ -2842,15 +2837,15 @@ msgstr "Mainkan scene redaksi." #: editor/editor_node.cpp msgid "Play Scene" -msgstr "Mainkan Scene" +msgstr "Mainkan Skena" #: editor/editor_node.cpp msgid "Play custom scene" -msgstr "Mainkan custom scene" +msgstr "Mainkan skena kustom" #: editor/editor_node.cpp msgid "Play Custom Scene" -msgstr "Mainkan Custom Scene" +msgstr "Mainkan Skena Kustom" #: editor/editor_node.cpp msgid "Changing the video driver requires restarting the editor." @@ -2862,20 +2857,22 @@ msgid "Save & Restart" msgstr "Simpan & Mulai Ulang" #: editor/editor_node.cpp -#, fuzzy msgid "Spins when the editor window redraws." -msgstr "Putar ketika jendela editor cat ulang!" +msgstr "Putar ketika jendela penyunting digambar ulang." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Selalu Perbarui" +#, fuzzy +msgid "Update Continuously" +msgstr "Lanjut" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Perbarui Perubahan" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Nonaktifkan Perbaruan Spinner" #: editor/editor_node.cpp @@ -2904,18 +2901,19 @@ msgstr "Jangan Simpan" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." -msgstr "" +msgstr "Templat build Android tidak ada, harap pasang templat yang relevan." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Mengatur Templat Ekspor" +msgstr "Kelola Templat" #: editor/editor_node.cpp msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"Ini akan memasang proyek Android untuk build kustom.\n" +"Sebagai catatan, untuk menggunakannya, harus diaktifkan per preset ekspor." #: editor/editor_node.cpp msgid "" @@ -2923,6 +2921,9 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"Templat build Android sudah terpasang sebelumnya dan tidak akan ditimpa.\n" +"Hapus direktori \"build\" secara manual sebelum menjalankan perintah ini " +"lagi." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3066,7 +3067,7 @@ msgstr "Waktu" msgid "Calls" msgstr "Panggil" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Nyala" @@ -3083,14 +3084,12 @@ msgid "[Empty]" msgstr "[Kosong]" #: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp -#, fuzzy msgid "Assign..." msgstr "Terapkan.." #: editor/editor_properties.cpp -#, fuzzy msgid "Invalid RID" -msgstr "Path Tidak Sah." +msgstr "RID tidak valid" #: editor/editor_properties.cpp msgid "" @@ -3105,9 +3104,9 @@ msgid "" "Can't create a ViewportTexture on resources saved as a file.\n" "Resource needs to belong to a scene." msgstr "" -"Tidak dapat membuat ViewportTexture pada sumber yang tersimpan sebagai " +"Tidak dapat membuat ViewportTexture pada sumber daya yang disimpan sebagai " "berkas.\n" -"Sumber harus dimiliki oleh sebuah scene." +"Sumber daya harus dimiliki oleh sebuah skena." #: editor/editor_properties.cpp msgid "" @@ -3116,10 +3115,10 @@ msgid "" "Please switch on the 'local to scene' property on it (and all resources " "containing it up to a node)." msgstr "" -"Tidak dapat membuat ViewportTexture karena resource ini tidak dibuat lokal " -"untuk scene.\n" -"Mohon ubah properti 'lokal untuk scene' resource ini (dan semua resource " -"yang memuatnya sampai satu node ke atas)." +"Tidak dapat membuat ViewportTexture pada resource ini karena tidak dibuat " +"lokal ke skena.\n" +"Silakan aktifkan properti 'lokal ke skena' di atasnya (dan semua sumber daya " +"yang memuatnya sampai node)." #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Pick a Viewport" @@ -3134,9 +3133,8 @@ msgid "New %s" msgstr "%s baru" #: editor/editor_properties.cpp editor/property_editor.cpp -#, fuzzy msgid "Make Unique" -msgstr "Membuat sub-Resource Unik" +msgstr "Jadikan Unik" #: editor/editor_properties.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp @@ -3153,17 +3151,15 @@ msgid "Paste" msgstr "Tempel" #: editor/editor_properties.cpp editor/property_editor.cpp -#, fuzzy msgid "Convert To %s" -msgstr "Sambungkan Ke Node:" +msgstr "Konversikan ke %s" #: 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 -#, fuzzy msgid "Open Editor" -msgstr "Buka Editor" +msgstr "Buka Penyunting" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Selected node is not a Viewport!" @@ -3178,24 +3174,22 @@ msgid "Page: " msgstr "Halaman: " #: editor/editor_properties_array_dict.cpp -#, fuzzy +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Hapus item" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" -msgstr "Nama baru:" +msgstr "Key Baru:" #: editor/editor_properties_array_dict.cpp -#, fuzzy msgid "New Value:" -msgstr "Nama baru:" +msgstr "Nilai Baru:" #: editor/editor_properties_array_dict.cpp msgid "Add Key/Value Pair" msgstr "Tambahkan pasangan Key/Value" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Hapus item" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3210,7 +3204,7 @@ msgstr "Tulis logika di dalam fungsi _run()." #: editor/editor_run_script.cpp msgid "There is an edited scene already." -msgstr "Ada scene yang disunting." +msgstr "Sudah ada skena yang disunting." #: editor/editor_run_script.cpp msgid "Couldn't instance script:" @@ -3234,11 +3228,11 @@ msgstr "Pilih node untuk diimpor" #: editor/editor_sub_scene.cpp editor/project_manager.cpp msgid "Browse" -msgstr "" +msgstr "Telusur" #: editor/editor_sub_scene.cpp msgid "Scene Path:" -msgstr "Lokasi Scene:" +msgstr "Lokasi Skena:" #: editor/editor_sub_scene.cpp msgid "Import From Node:" @@ -3282,9 +3276,8 @@ msgid "Can't open export templates zip." msgstr "Tidak dapat membuka ekspor template-template zip." #: editor/export_template_manager.cpp -#, fuzzy msgid "Invalid version.txt format inside templates: %s." -msgstr "Format version.txt tidak valid dalam berkas templat." +msgstr "Format version.txt tidak valid dalam berkas templat: %s." #: editor/export_template_manager.cpp msgid "No version.txt found inside templates." @@ -3332,9 +3325,8 @@ msgstr "Permintaan Gagal." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Redirect Loop." -msgstr "Mengarahkan Loop" +msgstr "Mengalihkan Loop." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -3425,7 +3417,6 @@ msgid "Remove Template" msgstr "Hapus Templat" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" msgstr "Pilih berkas templat" @@ -3438,9 +3429,8 @@ msgid "Download Templates" msgstr "Unduh Templat" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select mirror from list: (Shift+Click: Open in Browser)" -msgstr "Pilih cermin dari daftar: " +msgstr "Pilih cermin dari daftar: (Shift+Click: Buka di Peramban)" #: editor/file_type_cache.cpp msgid "Can't open file_type_cache.cch for writing, not saving file type cache!" @@ -3449,9 +3439,8 @@ msgstr "" "disimpan!" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Favorites" -msgstr "Favorit:" +msgstr "Favorit" #: editor/filesystem_dock.cpp msgid "Cannot navigate to '%s' as it has not been found in the file system!" @@ -3489,9 +3478,8 @@ msgid "No name provided." msgstr "Nama masih kosong." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "Nama yang dimasukkan tidak valid" +msgstr "Nama yang dimasukkan mengandung karakter tidak valid." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3518,28 +3506,24 @@ msgid "Duplicating folder:" msgstr "Menggandakan folder:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Scene Turunan Baru..." +msgstr "Skena Warisan Baru" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Buka Scene" +msgstr "Buka Skena" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Instansi" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" -msgstr "Favorit:" +msgstr "Tambahkan ke Favorit" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "Hapus dari Grup" +msgstr "Hapus dari Favorit" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." @@ -3562,26 +3546,23 @@ msgid "Move To..." msgstr "Pindahkan ke..." #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "New Script..." -msgstr "Scene Baru" +msgstr "Skrip Baru..." #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Resource..." -msgstr "Simpan Resource Sebagai..." +msgstr "Sumber Daya Baru..." #: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Expand All" -msgstr "Perluas semua" +msgstr "Bentangkan Semua" #: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp #, fuzzy msgid "Collapse All" -msgstr "Ciutkan semua" +msgstr "Ciutkan Semua" #: editor/filesystem_dock.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -3591,14 +3572,12 @@ msgid "Rename" msgstr "Ubah Nama" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Tab sebelumnya" +msgstr "Berkas/Direktori sebelumnya" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Folder Berikutnya" +msgstr "Berkas/DIrektori Berikutnya" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" @@ -3607,12 +3586,11 @@ msgstr "Pindai Ulang Berkas Sistem" #: editor/filesystem_dock.cpp #, fuzzy msgid "Toggle Split Mode" -msgstr "Beralih Mode" +msgstr "Beralih Mode Split" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Search files" -msgstr "Cari Kelas" +msgstr "Cari berkas" #: editor/filesystem_dock.cpp msgid "" @@ -3627,9 +3605,8 @@ msgid "Move" msgstr "Pindahkan" #: editor/filesystem_dock.cpp -#, fuzzy msgid "There is already file or folder with the same name in this location." -msgstr "Sudah ada nama berkas atau folder seperti itu." +msgstr "Sudah ada nama berkas atau folder seperti itu di lokasi ini." #: editor/filesystem_dock.cpp msgid "Overwrite" @@ -3640,30 +3617,29 @@ msgid "Create Script" msgstr "Buat Script" #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Find in Files" -msgstr "%d file lagi" +msgstr "Cari dalam Berkas" #: editor/find_in_files.cpp -#, fuzzy msgid "Find:" -msgstr "Cari" +msgstr "Cari:" #: editor/find_in_files.cpp -#, fuzzy msgid "Folder:" -msgstr "Buat Folder" +msgstr "Direktori:" #: editor/find_in_files.cpp -#, fuzzy msgid "Filters:" msgstr "Filter:" #: editor/find_in_files.cpp +#, fuzzy msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Muat berkas dengan ekstensi berikut. Tambah atau Buang dalam " +"PengaturanProyek." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3723,6 +3699,7 @@ msgid "Nodes not in Group" msgstr "Tambahkan ke Grup" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp #, fuzzy msgid "Filter nodes" msgstr "Filter:" @@ -3747,7 +3724,7 @@ msgstr "Grup" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" -msgstr "Impor sebagai Scene Tunggal" +msgstr "Impor sebagai Skena Tunggal" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Animations" @@ -3779,20 +3756,20 @@ msgstr "Impor dengan Objek+Material+Animasi Terpisah" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes" -msgstr "Impor sebagai Beberapa Scene" +msgstr "Impor sebagai Beberapa Skena" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" -msgstr "Impor Beberapa Scene+Material" +msgstr "Impor sebagai Beberapa Skena+Material" #: editor/import/resource_importer_scene.cpp #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Import Scene" -msgstr "Impor Scene" +msgstr "Impor Skena" #: editor/import/resource_importer_scene.cpp msgid "Importing Scene..." -msgstr "Mengimpor scene..." +msgstr "Mengimpor Skena..." #: editor/import/resource_importer_scene.cpp msgid "Generating Lightmaps" @@ -3848,7 +3825,7 @@ msgstr "Impor ulang" #: editor/import_dock.cpp msgid "Save scenes, re-import and restart" -msgstr "Simpan scene-scene, impor ulang dan mulai ulang" +msgstr "Simpan skena, impor ulang, dan mulai ulang" #: editor/import_dock.cpp #, fuzzy @@ -4253,7 +4230,7 @@ msgstr "Metode Publik:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" -msgstr "" +msgstr "Hapus Node" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #, fuzzy @@ -4917,15 +4894,14 @@ 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." msgstr "" -"Tidak dapat menentukan lokasi penyimpanan untuk gambar lightmap\n" -"Simpan scene-mu (untuk gambar silakan simpan di direktori yang sama dengan " -"scene), atau tentukan lokasi penyimpanan dari properti BakedLightmap" +"Tidak dapat menentukan lokasi penyimpanan untuk gambar lightmap.\n" +"Simpan skena Anda (untuk gambar yang akan disimpan di direktori yang sama), " +"atau pilih lokasi penyimpanan dari properti BakedLightmap." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -5047,6 +5023,8 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Ketika aktif, memindahkan node Control akan mengubah jangkarnya daripada " +"batasnya." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -5094,9 +5072,8 @@ msgid "Create Custom Bone(s) from Node(s)" msgstr "Buat Tulang Kustom(satu/lebih) dari Node(satu/lebih)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "Mainkan Custom Scene" +msgstr "Bersihkan Pertulangan" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -5276,9 +5253,8 @@ msgid "Make Custom Bone(s) from Node(s)" msgstr "Buat Tulang Kustom(satu/lebih) dari Node(satu/lebih)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Custom Bones" -msgstr "Mainkan Custom Scene" +msgstr "Bersihkan Pertulangan Kustom" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5316,27 +5292,27 @@ msgstr "Tampilkan Ikon Kunci Dan Grup" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Center Selection" -msgstr "" +msgstr "Seleksi Tengah" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Frame Selection" -msgstr "" +msgstr "Seleksi Bingkai" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "" +msgstr "Pratinjau Skala Kanvas" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." -msgstr "" +msgstr "Masker translasi untuk menyisipkan key." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation mask for inserting keys." -msgstr "" +msgstr "Masker rotasi untuk menyisipkan key." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Scale mask for inserting keys." -msgstr "" +msgstr "Masker skala untuk menyisipkan key." #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5350,6 +5326,11 @@ msgid "" "Keys are only added to existing tracks, no new tracks will be created.\n" "Keys must be inserted manually for the first time." msgstr "" +"Menyisipkan key otomatis ketika objek ditranslasi, dirotasi atau diskala " +"(berdasarkan masker).\n" +"Key hanya ditambahkan ke trek yang ada, tidak ada trek baru yang akan " +"dibuat.\n" +"Key harus disisipkan secara manual untuk pertama kali." #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5358,23 +5339,23 @@ msgstr "Sisipkan Key Anim" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key (Existing Tracks)" -msgstr "" +msgstr "Sisip Key (ke Trek yang Ada)" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Copy Pose" -msgstr "" +msgstr "Salin Pose" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Pose" -msgstr "" +msgstr "Hapus Pose" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Multiply grid step by 2" -msgstr "" +msgstr "Gandakan langkah kisi demi 2" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Divide grid step by 2" -msgstr "" +msgstr "Bagi langkah kisi demi 2" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5383,25 +5364,26 @@ msgstr "Tampilan Belakang." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" -msgstr "" +msgstr "Tambah %s" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Adding %s..." -msgstr "" +msgstr "Menambahkan %s..." #: editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "Cannot instantiate multiple nodes without root." -msgstr "" +msgstr "Tidak dapat menginstansiasi beberapa node tanpa root." #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Create Node" -msgstr "" +msgstr "Buat Node" #: 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 "" +msgstr "Gagal meng-instance skena dari %s" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5413,6 +5395,8 @@ msgid "" "Drag & drop + Shift : Add node as sibling\n" "Drag & drop + Alt : Change node type" msgstr "" +"Seret & lepas + Shift : Tambahkan node sebagai saudara\n" +"Seret & lepas + Alt : Ubah tipe node" #: editor/plugins/collision_polygon_editor_plugin.cpp #, fuzzy @@ -5429,8 +5413,9 @@ msgid "Edit Poly (Remove Point)" msgstr "Sunting Bidang (Hapus Titik)" #: editor/plugins/collision_shape_2d_editor_plugin.cpp +#, fuzzy msgid "Set Handle" -msgstr "" +msgstr "Atur Pegangan" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5440,17 +5425,25 @@ msgstr "Galat saat memuat gambar:" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "No pixels with transparency > 128 in image..." -msgstr "" +msgstr "Tidak ada piksel dengan transparansi > 128 di dalam gambar..." #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Load Emission Mask" -msgstr "" +msgstr "Muat Masker Emisi" + +#: 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 +#, fuzzy +msgid "Restart" +msgstr "Mulai Ulang:" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" -msgstr "" +msgstr "Hapus Masker Emisi" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5461,22 +5454,22 @@ msgstr "Partikel" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Generated Point Count:" -msgstr "" +msgstr "Jumlah Titik yang Dihasilkan:" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Mask" -msgstr "" +msgstr "Masker Emisi" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Capture from Pixel" -msgstr "" +msgstr "Tangkap dari Piksel" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Colors" -msgstr "" +msgstr "Warna Emisi" #: editor/plugins/cpu_particles_editor_plugin.cpp #, fuzzy @@ -5486,44 +5479,44 @@ msgstr "Partikel" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Mesh" -msgstr "" +msgstr "Buat Titik Emisi dari Mesh" #: editor/plugins/cpu_particles_editor_plugin.cpp #: editor/plugins/particles_editor_plugin.cpp msgid "Create Emission Points From Node" -msgstr "" +msgstr "Buat Titik Emisi dari Node" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat 0" -msgstr "" +msgstr "Flat 0" #: editor/plugins/curve_editor_plugin.cpp msgid "Flat 1" -msgstr "" +msgstr "Flat 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" -msgstr "" +msgstr "Perlahan Masuk" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease Out" -msgstr "" +msgstr "Perlahan Keluar" #: editor/plugins/curve_editor_plugin.cpp msgid "Smoothstep" -msgstr "" +msgstr "Tingkat Kemulusan" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Point" -msgstr "" +msgstr "Modifikasi Titik Kurva" #: editor/plugins/curve_editor_plugin.cpp msgid "Modify Curve Tangent" -msgstr "" +msgstr "Modifikasi Tangen Kurva" #: editor/plugins/curve_editor_plugin.cpp msgid "Load Curve Preset" -msgstr "" +msgstr "Muat Preset Kurva" #: editor/plugins/curve_editor_plugin.cpp #, fuzzy @@ -5557,7 +5550,7 @@ msgstr "Hapus Sinyal" #: editor/plugins/curve_editor_plugin.cpp msgid "Toggle Curve Linear Tangent" -msgstr "" +msgstr "Beralih Kurva Linear Tangen" #: editor/plugins/curve_editor_plugin.cpp #, fuzzy @@ -5574,11 +5567,11 @@ msgstr "" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" -msgstr "" +msgstr "Item %d" #: editor/plugins/item_list_editor_plugin.cpp msgid "Items" -msgstr "" +msgstr "Item" #: editor/plugins/item_list_editor_plugin.cpp #, fuzzy @@ -5587,15 +5580,15 @@ msgstr "Penyunting Daftar Item" #: editor/plugins/light_occluder_2d_editor_plugin.cpp msgid "Create Occluder Polygon" -msgstr "" +msgstr "Buat Poligon Occluder" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh is empty!" -msgstr "" +msgstr "Mesh kosong!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Trimesh Body" -msgstr "" +msgstr "Buat Badan Trimesh Statis" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Static Convex Body" @@ -5603,15 +5596,15 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "This doesn't work on scene root!" -msgstr "" +msgstr "Ini tidak bekerja di skena akar!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Shape" -msgstr "" +msgstr "Buat Bentuk Trimesh Statis" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "Gagal membuat bentuk!" #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy @@ -5620,15 +5613,15 @@ msgstr "Buat Baru %s" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" -msgstr "" +msgstr "Buat Mesh Navigasi" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Contained Mesh is not of type ArrayMesh." -msgstr "" +msgstr "Mesh yang terkandung bukan bertipe ArrayMesh." #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "UV Unwrap failed, mesh may not be manifold?" -msgstr "" +msgstr "UV Unwrap gagal, mesh mungkin tidak bermacam-macam?" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "No mesh to debug." @@ -5637,11 +5630,11 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp #: editor/plugins/sprite_editor_plugin.cpp msgid "Model has no UV in this layer" -msgstr "" +msgstr "Model tidak memiliki UV dalam lapisan ini" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "MeshInstance lacks a Mesh!" -msgstr "" +msgstr "MeshInstance tidak memiliki Mesh!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh has not surface to create outlines from!" @@ -5649,15 +5642,16 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh primitive type is not PRIMITIVE_TRIANGLES!" -msgstr "" +msgstr "Jenis Mesh primitif bukan PRIMITIVE_TRIANGLES!" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Could not create outline!" -msgstr "" +msgstr "Tidak dapat membuat garis!" #: editor/plugins/mesh_instance_editor_plugin.cpp +#, fuzzy msgid "Create Outline" -msgstr "" +msgstr "Buat Garis" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Mesh" @@ -5665,11 +5659,12 @@ msgstr "" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Trimesh Static Body" -msgstr "" +msgstr "Buat Tubuh Statis Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp +#, fuzzy msgid "Create Trimesh Collision Sibling" -msgstr "" +msgstr "Buat Saudara Tabrakan Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy @@ -5678,7 +5673,7 @@ msgstr "Buat Bidang" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." -msgstr "" +msgstr "Buat Garis Mesh..." #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy @@ -5692,72 +5687,75 @@ msgstr "File:" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Unwrap UV2 for Lightmap/AO" -msgstr "" +msgstr "Buka UV2 untuk Lightmap/AO" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh" -msgstr "" +msgstr "Buat Garis Mesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Outline Size:" -msgstr "" +msgstr "Ukuran Garis Tepi:" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Remove item %d?" -msgstr "" +msgstr "Hapus item %d?" #: editor/plugins/mesh_library_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp msgid "Add Item" -msgstr "" +msgstr "Tambah Item" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Remove Selected Item" -msgstr "" +msgstr "Hapus Item yang Dipilih" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Import from Scene" -msgstr "" +msgstr "Impor dari Skena" #: editor/plugins/mesh_library_editor_plugin.cpp msgid "Update from Scene" -msgstr "" +msgstr "Perbarui dari Skena" #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and no MultiMesh set in node)." msgstr "" +"Tidak ada sumber mesh yang ditentukan (dan tidak ada MultiMesh yang diatur " +"dalam node)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No mesh source specified (and MultiMesh contains no Mesh)." msgstr "" +"Tidak ada sumber mesh yang ditentukan (dan MultiMesh tidak mengandung Mesh)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (invalid path)." -msgstr "" +msgstr "Sumber mesh tidak valid (salah lokasi)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (not a MeshInstance)." -msgstr "" +msgstr "Sumber mesh tidak valid (bukan MeshInstance)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Mesh source is invalid (contains no Mesh resource)." -msgstr "" +msgstr "Sumber mesh tidak valid (tidak mengandung resource Mesh)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "No surface source specified." -msgstr "" +msgstr "Sumber permukaan tidak ditentukan." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (invalid path)." -msgstr "" +msgstr "Sumber permukaan tidak valid (salah lokasi)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (no geometry)." -msgstr "" +msgstr "Sumber permukaan tidak valid (tidak ada geometri)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Surface source is invalid (no faces)." -msgstr "" +msgstr "Sumber permukaan tidak valid (tidak ada bidang)." #: editor/plugins/multimesh_editor_plugin.cpp msgid "Parent has no solid faces to populate." @@ -6256,16 +6254,16 @@ msgstr "" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Rename Resource" -msgstr "" +msgstr "Ubah Nama Sumber Daya" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Delete Resource" -msgstr "" +msgstr "Hapus Sumber Daya" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Resource clipboard is empty!" -msgstr "" +msgstr "Papan klip sumber daya kosong!" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Paste Resource" @@ -6273,14 +6271,15 @@ msgstr "Tempel Resource" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/scene_tree_editor.cpp +#, fuzzy msgid "Instance:" -msgstr "" +msgstr "Instansi:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/plugins/theme_editor_plugin.cpp editor/project_settings_editor.cpp #: editor/scene_tree_editor.cpp msgid "Type:" -msgstr "" +msgstr "Jenis:" #: editor/plugins/resource_preloader_editor_plugin.cpp #: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp @@ -6290,7 +6289,7 @@ msgstr "Buka dalam Penyunting" #: editor/plugins/resource_preloader_editor_plugin.cpp msgid "Load Resource" -msgstr "" +msgstr "Muat Sumber Daya" #: editor/plugins/resource_preloader_editor_plugin.cpp #, fuzzy @@ -6299,20 +6298,19 @@ msgstr "Resource" #: editor/plugins/root_motion_editor_plugin.cpp msgid "AnimationTree has no path set to an AnimationPlayer" -msgstr "" +msgstr "AnimationTree tidak memiliki jalur yang diatur ke AnimationPlayer" #: editor/plugins/root_motion_editor_plugin.cpp msgid "Path to AnimationPlayer is invalid" -msgstr "" +msgstr "Jalur ke AnimationPlayer tidak valid" #: editor/plugins/script_editor_plugin.cpp msgid "Clear Recent Files" -msgstr "" +msgstr "Bersihkan Berkas Akhir-akhir ini" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Close and save changes?" -msgstr "Tutup scene? (Perubahan-perubahan yang belum disimpan akan hilang)" +msgstr "Tutup dan simpan perubahan?" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -6371,23 +6369,23 @@ msgstr "Simpan Sebagai..." #: editor/plugins/script_editor_plugin.cpp msgid "Import Theme" -msgstr "" +msgstr "Impor Tema" #: editor/plugins/script_editor_plugin.cpp msgid "Error while saving theme" -msgstr "" +msgstr "Gagal saat menyimpan tema" #: editor/plugins/script_editor_plugin.cpp msgid "Error saving" -msgstr "" +msgstr "Gagal menyimpan" #: editor/plugins/script_editor_plugin.cpp msgid "Save Theme As..." -msgstr "" +msgstr "Simpan Tema sebagai..." #: editor/plugins/script_editor_plugin.cpp msgid "%s Class Reference" -msgstr "" +msgstr "Referensi Kelas %s" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -6395,8 +6393,18 @@ msgid "Find Next" msgstr "Pencarian Selanjutnya" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filter:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." -msgstr "" +msgstr "Beralih penyortiran alfabetis dari daftar fungsi." + +#: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Filter:" #: editor/plugins/script_editor_plugin.cpp #, fuzzy @@ -6407,21 +6415,21 @@ msgstr "Sortir:" #: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Move Up" -msgstr "" +msgstr "Naikkan" #: 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 "" +msgstr "Turunkan" #: editor/plugins/script_editor_plugin.cpp msgid "Next script" -msgstr "" +msgstr "Skrip berikutnya" #: editor/plugins/script_editor_plugin.cpp msgid "Previous script" -msgstr "" +msgstr "Skrip sebelumnya" #: editor/plugins/script_editor_plugin.cpp msgid "File" @@ -6461,9 +6469,8 @@ msgid "Theme" msgstr "Simpan Tema" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Import Theme..." -msgstr "Mengimpor scene..." +msgstr "Impor Tema..." #: editor/plugins/script_editor_plugin.cpp msgid "Reload Theme" @@ -6644,20 +6651,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +msgstr "Hapus Titik" + #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Potong" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Pilih Semua" - #: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Delete Line" @@ -6791,9 +6802,8 @@ msgid "This skeleton has no bones, create some children Bone2D nodes." msgstr "" #: editor/plugins/skeleton_2d_editor_plugin.cpp -#, fuzzy msgid "Create Rest Pose from Bones" -msgstr "Mainkan Custom Scene" +msgstr "Buat Pose Istirahat dari Pertulangan" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Set Rest Pose to Bones" @@ -8088,9 +8098,8 @@ msgid "Create Occlusion Polygon" msgstr "Buat Bidang" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "This property can't be changed." -msgstr "Operasi ini tidak dapat diselesaikan tanpa scene." +msgstr "Properti ini tidak dapat diubah." #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8310,51 +8319,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8363,203 +8328,27 @@ msgid "Input parameter." msgstr "Snap ke orang-tua" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9187,9 +8976,8 @@ msgid "Feature List:" msgstr "Daftar Fungsi:" #: editor/project_export.cpp -#, fuzzy msgid "Script" -msgstr "Scene Baru" +msgstr "Skrip" #: editor/project_export.cpp #, fuzzy @@ -9429,15 +9217,14 @@ msgid "" msgstr "" #: editor/project_manager.cpp -#, fuzzy 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 "" -"Tidak ada scene utama yang pernah didefinisikan, pilih satu?\n" -"Anda dapat mengubahnya nanti di akhir dalam \"Project Settings\" dibawah " -"kategori 'application'." +"Tidak dapat menjalankan proyek: tidak ada skena utama yang didefinisikan.\n" +"Harap sunting proyek Anda dan atur skena utama dalam Pengaturan Proyek di " +"bawah kategori \"Aplikasi\"." #: editor/project_manager.cpp msgid "" @@ -9969,9 +9756,8 @@ msgid "Node type" msgstr "Cari Tipe Node" #: editor/rename_dialog.cpp -#, fuzzy msgid "Current scene name" -msgstr "Scene saat ini tidak disimpan. Buka saja?" +msgstr "Nama skena saat ini" #: editor/rename_dialog.cpp #, fuzzy @@ -10117,9 +9903,8 @@ msgid "Instance Child Scene" msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Clear Script" -msgstr "Scene Baru" +msgstr "Bersihkan Skrip" #: editor/scene_tree_dock.cpp msgid "This operation can't be done on the tree root." @@ -10150,9 +9935,8 @@ msgid "Instantiated scenes can't become root" msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Make node as Root" -msgstr "Simpan Scene" +msgstr "Jadikan node sebagai Dasar" #: editor/scene_tree_dock.cpp msgid "Delete Node(s)?" @@ -10189,9 +9973,8 @@ msgid "Make Local" msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "New Scene Root" -msgstr "Simpan Scene" +msgstr "Skena Dasar Baru" #: editor/scene_tree_dock.cpp #, fuzzy @@ -10226,9 +10009,8 @@ msgid "Can't operate on nodes the current scene inherits from!" msgstr "" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Attach Script" -msgstr "Scene Baru" +msgstr "Lampirkan Skrip" #: editor/scene_tree_dock.cpp msgid "Remove Node(s)" @@ -10267,6 +10049,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Ciutkan Semua" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10276,9 +10063,8 @@ msgid "Extend Script" msgstr "Buka Cepat Script..." #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Make Scene Root" -msgstr "Simpan Scene" +msgstr "Jadikan Skena Dasar" #: editor/scene_tree_dock.cpp msgid "Merge From Scene" @@ -10298,8 +10084,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Buat Baru %s" #: editor/scene_tree_dock.cpp msgid "" @@ -10505,9 +10292,8 @@ msgid "Allowed: a-z, A-Z, 0-9 and _" msgstr "" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Built-in script (into scene file)." -msgstr "Operasi dengan file scene." +msgstr "Skrip tanam (ke dalam berkas skena)." #: editor/script_create_dialog.cpp #, fuzzy @@ -10543,9 +10329,8 @@ msgid "Built-in Script" msgstr "" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Attach Node Script" -msgstr "Scene Baru" +msgstr "Lampirkan Skrip Node" #: editor/script_editor_debugger.cpp #, fuzzy @@ -10564,7 +10349,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10990,60 +10775,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "Gagal memuat resource." - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to save solution." -msgstr "Gagal memuat resource." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create C# project." -msgstr "Gagal memuat resource." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "Buat Subskribsi" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "Proyek" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "File:" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11668,8 +11399,9 @@ 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 " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Sebuah resource SpriteFrames seharusnya diciptakan atau diatur dalam " @@ -11680,9 +11412,9 @@ 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 "" -"Hanya satu visible CanvasModulate yang diizinkan per scene (atau atur pada " -"scene-scene yang diacu). Yang diciptakan pertama akan bekerja, sedangkan " -"sisanya akan diabaikan." +"Hanya satu CanvasModulate yang terlihat diizinkan per skena (atau set skena " +"yang di-instance). Yang pertama dibuat akan bekerja, sedangkan sisanya akan " +"diabaikan." #: scene/2d/collision_object_2d.cpp msgid "" @@ -11733,8 +11465,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Sebuah tekstur dengan bentuk cahaya harus disuplai ke properti 'texture'." @@ -11747,7 +11480,8 @@ msgstr "" "berpengaruh." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "Polygon occluder untuk occluder ini kosong. Mohon gambar dulu sebuah polygon!" @@ -11824,16 +11558,29 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 hanya berfungsi untuk menyediakan sebuah bentuk collision " +"pada sebuah CollisionObject2D node asal. Mohon hanya gunakan itu sebagai " +"sebuah child dari Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, dll. " +"untuk memberikan mereka sebuah bentuk." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D bekerja dengan sangat baik ketika digunakan dengan " -"mengedit root scene secara langsung sebagai parent." +"menyunting skena dasar secara langsung sebagai parent." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11918,9 +11665,10 @@ msgstr "" "bentuk." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Sebuah bentuk harus disediakan untuk CollisionShape untuk fungsi. Mohon " "ciptakan sebuah resource bentuk untuk itu!" @@ -11951,6 +11699,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11992,8 +11744,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -12005,7 +11757,9 @@ msgstr "" #: scene/3d/remote_transform.cpp #, fuzzy -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "Properti path harus menunjuk ke sebuah node Particles2D yang sah agar " "bekerja." @@ -12022,8 +11776,9 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Sebuah resource SpriteFrames harus diciptakan atau diatur didalam properti " @@ -12036,15 +11791,17 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +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 "" -"Hanya satu WorldEnvironment yang diizinkan per scene (atau atur scene-scene " -"yang diacu)." +"Hanya satu WorldEnvironment yang diizinkan per skena (atau set skena yang di-" +"instance)." #: scene/3d/world_environment.cpp msgid "" @@ -12054,7 +11811,7 @@ msgstr "" #: scene/animation/animation_blend_tree.cpp msgid "On BlendTree node '%s', animation not found: '%s'" -msgstr "" +msgstr "Di Node BlendTree '%s', animasi tidak ditemukan: '%s'" #: scene/animation/animation_blend_tree.cpp #, fuzzy @@ -12063,7 +11820,7 @@ msgstr "Perkakas Animasi" #: scene/animation/animation_tree.cpp msgid "In node '%s', invalid animation: '%s'." -msgstr "" +msgstr "Di node '%s', animasi tidak valid: '%s'." #: scene/animation/animation_tree.cpp #, fuzzy @@ -12076,37 +11833,46 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Memutuskan '%s' dari '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." -msgstr "" +#, fuzzy +msgid "No root AnimationNode for the graph is set." +msgstr "Akar AnimationNode untuk grafik belum diatur." #: scene/animation/animation_tree.cpp #, fuzzy msgid "Path to an AnimationPlayer node containing animations is not set." -msgstr "Pilih sebuah AnimationPlayer dari Scene Tree untuk menyunting animasi." +msgstr "" +"Lokasi untuk node AnimationPlayer yang mengandung animasi belum diatur." #: scene/animation/animation_tree.cpp msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" +"Lokasi yang ditetapkan untuk AnimationPlayer tidak mengarah ke node " +"AnimationPlayer." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." -msgstr "" +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." +msgstr "Akar AnimationPlayer bukanlah node yang valid." #: scene/animation/animation_tree_player.cpp msgid "This node has been deprecated. Use AnimationTree instead." -msgstr "" +msgstr "Node ini telah usang. Gunakan AnimationTree sebagai gantinya." #: scene/gui/color_picker.cpp msgid "Pick a color from the screen." +msgstr "Ambil warna dari layar." + +#: scene/gui/color_picker.cpp +msgid "HSV" msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." -msgstr "" +msgstr "Beralih antara nilai heksadesimal dan kode." #: scene/gui/color_picker.cpp #, fuzzy @@ -12114,11 +11880,21 @@ msgid "Add current color as a preset." msgstr "Tambahkan warna yang sekarang sebagai preset" #: scene/gui/container.cpp +#, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." +msgstr "" +"Container dengan dirinya sendiri tidak berguna kecuali ada skrip yang " +"mengkonfigurasi perilaku penempatan anak-anaknya.\n" +"Jika Anda tidak ingin menambahkan skrip, silakan gunakan node 'Control' " +"biasa." + +#: 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 @@ -12130,10 +11906,11 @@ msgid "Please Confirm..." msgstr "Mohon konfirmasi..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Popup-popup akan disembunyikan secara default kecuali anda memanggil fungsi " "popup() atau salah satu dari semua fungsi popup*() yang ada. Membuat mereka " @@ -12141,15 +11918,20 @@ msgstr "" "game dijalankan." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "jika exp_edit adalah true min_value seharusnya > 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" +"ScrollContainer dimaksudkan untuk bekerja dengan kontrol anak tunggal.\n" +"Gunakan satu kontainer sebagai anak (VBox,HBox,dkk), atau Control, dan atur " +"manual ukuran minimumnya." #: scene/gui/tree.cpp msgid "(Other)" @@ -12195,7 +11977,12 @@ msgstr "Ukuran font tidak sah." #: scene/resources/visual_shader.cpp msgid "Input" -msgstr "" +msgstr "Masukan" + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Ukuran font tidak sah." #: scene/resources/visual_shader_nodes.cpp #, fuzzy @@ -12203,20 +11990,56 @@ msgid "Invalid source for shader." msgstr "Ukuran font tidak sah." #: servers/visual/shader_language.cpp +#, fuzzy msgid "Assignment to function." -msgstr "" +msgstr "Penugasan ke fungsi." #: servers/visual/shader_language.cpp +#, fuzzy msgid "Assignment to uniform." -msgstr "" +msgstr "Penugasan untuk menyeragamkan." #: servers/visual/shader_language.cpp +#, fuzzy msgid "Varyings can only be assigned in vertex function." -msgstr "" +msgstr "Variasi hanya bisa ditetapkan dalam fungsi vertex." #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "Konstanta tidak dapat dimodifikasi." + +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "Gagal memuat resource." + +#, fuzzy +#~ msgid "Failed to save solution." +#~ msgstr "Gagal memuat resource." + +#, fuzzy +#~ msgid "Failed to create C# project." +#~ msgstr "Gagal memuat resource." + +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "Buat Subskribsi" + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "Proyek" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "File:" + +#~ msgid "Enabled Classes" +#~ msgstr "Kelas yang Diaktifkan" + +#~ msgid "Update Always" +#~ msgstr "Selalu Perbarui" + +#~ msgid "Raw Mode" +#~ msgstr "Mode Mentah" #~ msgid "Path to Node:" #~ msgstr "Path ke Node:" diff --git a/editor/translations/is.po b/editor/translations/is.po index 88a59309ff..d63db7f02d 100644 --- a/editor/translations/is.po +++ b/editor/translations/is.po @@ -448,6 +448,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Afrita val" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -627,6 +637,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -676,7 +690,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -779,6 +793,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -938,7 +956,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1303,7 +1321,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1474,6 +1492,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1500,7 +1522,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1554,7 +1576,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1567,7 +1589,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1590,11 +1612,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2603,10 +2621,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2713,15 +2751,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "Samfellt" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2911,7 +2950,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3009,20 +3048,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3508,6 +3547,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5101,6 +5141,13 @@ 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 "" @@ -6008,10 +6055,18 @@ msgid "Find Next" 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 "" @@ -6239,18 +6294,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7798,51 +7856,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7850,203 +7864,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9682,6 +9520,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9710,7 +9552,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9948,7 +9790,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10351,54 +10193,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10975,7 +10769,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11024,7 +10818,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11034,7 +10828,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11101,14 +10895,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11187,7 +10988,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11216,6 +11017,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11250,8 +11055,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11262,7 +11067,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11278,7 +11085,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11289,7 +11096,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11324,7 +11133,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11336,7 +11145,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11348,7 +11157,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11361,10 +11174,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11378,18 +11196,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11432,6 +11250,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/it.po b/editor/translations/it.po index 6fd9d77343..41cdd4df93 100644 --- a/editor/translations/it.po +++ b/editor/translations/it.po @@ -34,12 +34,13 @@ # MARCO BANFI <mbanfi@gmail.com>, 2019. # Marco <rodomar705@gmail.com>, 2019. # Davide Giuliano <davidegiuliano00@gmail.com>, 2019. +# Stefano Merazzi <asso99@hotmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" -"Last-Translator: RHC <rhc.throwaway@gmail.com>\n" +"PO-Revision-Date: 2019-07-02 10:50+0000\n" +"Last-Translator: Marco <rodomar705@gmail.com>\n" "Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/" "godot/it/>\n" "Language: it\n" @@ -47,7 +48,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -108,9 +109,8 @@ msgid "Time:" msgstr "Tempo:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Valore" +msgstr "Valore:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -178,9 +178,8 @@ msgid "3D Transform Track" msgstr "Traccia trasformazione 3D" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Call Method Track" -msgstr "Traccia Chiamata di Funzione" +msgstr "Traccia di Chiamata di Metodi" #: editor/animation_track_editor.cpp msgid "Bezier Curve Track" @@ -195,14 +194,12 @@ msgid "Animation Playback Track" msgstr "Traccia di riproduzione animazione" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (frames)" -msgstr "Durata Animazione (in secondi)" +msgstr "Durata Animazione (frames)" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (seconds)" -msgstr "Durata Animazione (in secondi)" +msgstr "Durata Animazione (secondi)" #: editor/animation_track_editor.cpp msgid "Add Track" @@ -467,10 +464,28 @@ 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" +"\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 " +"separati." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Attenzione: stai modificando un'animazione importata" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Seleziona tutti" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "Seleziona Nulla" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -481,16 +496,14 @@ msgid "Group tracks by node or display them as plain list." msgstr "Raggruppa le tracce per nodo o mostra una lista semplice." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Snap:" -msgstr "Snap" +msgstr "Snap:" #: editor/animation_track_editor.cpp msgid "Animation step value." msgstr "Valore del passo dell'animazione." #: editor/animation_track_editor.cpp -#, fuzzy msgid "Seconds" msgstr "Secondi" @@ -648,6 +661,10 @@ msgstr "Va' alla linea" msgid "Line Number:" msgstr "Numero linea:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Nessuna corrispondenza" @@ -697,7 +714,7 @@ msgstr "Rimpicciolisci" msgid "Reset Zoom" msgstr "Azzera ingrandimento" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Avvertenze" @@ -706,38 +723,32 @@ msgid "Line and column numbers." msgstr "Numeri di riga e colonna." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Deve essere specificato il metodo nel nodo di target!" +msgstr "Il metodo del nodo designato deve essere specificato." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Metodo di destinazione non trovato! Specifica un metodo valido o annetti uno " -"script al nodo di destinazione." +"Metodo di destinazione non trovato. Specifica un metodo valido o attribuisci " +"uno script al nodo di destinazione." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "Connetti al nodo:" +msgstr "Connetti al Nodo:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Impossibile connetersi all'host:" +msgstr "Connetti allo Script:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Segnali:" +msgstr "Dal Segnale:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "Il nodo non contiene geometria." +msgstr "La scena non contiene alcuno script." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -765,7 +776,6 @@ msgid "Extra Call Arguments:" msgstr "Argomenti chiamata extra:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" msgstr "Opzioni avanzate" @@ -777,6 +787,8 @@ msgstr "Differita" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Differisce il segnale memorizzandolo in una coda ed emettendolo in fase di " +"inattività ." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -784,12 +796,11 @@ msgstr "Oneshot" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Disconnette il segnale dopo la sua prima emissione." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Connetti il segnale: " +msgstr "Impossibile connettere il segnale" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -810,6 +821,11 @@ msgid "Connect" msgstr "Connetti" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Segnali:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Connetti '%s' a '%s'" @@ -831,14 +847,12 @@ msgid "Disconnect" msgstr "Disconnetti" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Connetti il segnale: " +msgstr "Connetti un Segnale a un Metodo" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Modifica connessione: " +msgstr "Modifica Connessione:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -914,16 +928,14 @@ msgid "Dependencies For:" msgstr "Dipendenze per:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" "La scena '%s' è al momento in modifica.\n" -"I cambiamenti non avranno effetto a meno che venga ricaricata." +"I cambiamenti avranno effetto quando sarà ricaricata." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." @@ -976,7 +988,8 @@ msgid "Owners Of:" msgstr "Proprietari di:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Rimuovi i file selezionati dal progetto? (non annullabile)" #: editor/dependency_editor.cpp @@ -1022,9 +1035,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Eliminare permanentemente %d elementi? (Non annullabile!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "Dipendenze" +msgstr "Mostra Dipendenze" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1072,7 +1084,7 @@ msgstr "Sviluppatore principale" #: editor/editor_about.cpp msgid "Project Manager " -msgstr "Gestione progetto " +msgstr "Gestore progetto " #: editor/editor_about.cpp msgid "Developers" @@ -1279,7 +1291,7 @@ msgstr "Salva disposizione del bus audio come..." #: editor/editor_audio_buses.cpp msgid "Location for New Layout..." -msgstr "Posizione per Nuovo Layout..." +msgstr "Posizione della nuova disposizione…" #: editor/editor_audio_buses.cpp msgid "Open Audio Bus Layout" @@ -1287,15 +1299,15 @@ msgstr "Apri disposizione bus audio" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "File '%s' assente." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" -msgstr "Layout" +msgstr "Disposizione" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." -msgstr "File non valido, non è una disposizione del bus audio." +msgstr "File non valido, non è una disposizione di un bus audio." #: editor/editor_audio_buses.cpp msgid "Add Bus" @@ -1344,29 +1356,23 @@ msgid "Valid characters:" msgstr "Caratteri validi:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." msgstr "" -"Nome non valido. Non deve essere in conflitto con un nome di classe " -"dell'engine esistente." +"Non deve essere in conflitto con un nome di una classe esistente dell'engine." #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "" -"Nome non valido. Non deve essere in conflitto con un nome di tipo built-in " -"esistente." +msgid "Must not collide with an existing built-in type name." +msgstr "Non deve essere in conflitto con un nome di tipo built-in esistente." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." msgstr "" -"Nome non valido. Non deve essere in conflitto con un nome di una costante " -"globale esistente." +"Non deve essere in conflitto con un nome di una costante globale esistente." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "La parola chiave non può essere utilizzata come nome di un Autoload." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1374,7 +1380,7 @@ msgstr "Autoload '%s' esiste già !" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" -msgstr "Rinomina autoload" +msgstr "Rinomina Autoload" #: editor/editor_autoload_settings.cpp msgid "Toggle AutoLoad Globals" @@ -1397,7 +1403,6 @@ msgid "Rearrange Autoloads" msgstr "Riordina gli Autoload" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "Percorso non valido." @@ -1411,7 +1416,7 @@ msgstr "Non è nel percorso risorse." #: editor/editor_autoload_settings.cpp msgid "Add AutoLoad" -msgstr "Aggiungi AutoLoad" +msgstr "Aggiungi Autoload" #: editor/editor_autoload_settings.cpp editor/editor_file_dialog.cpp #: editor/plugins/animation_tree_editor_plugin.cpp scene/gui/file_dialog.cpp @@ -1437,7 +1442,7 @@ msgstr "Aggiornamento scena" #: editor/editor_data.cpp msgid "Storing local changes..." -msgstr "Memorizzazione dei cambiamenti locali..." +msgstr "Memorizzazione dei cambiamenti locali…" #: editor/editor_data.cpp msgid "Updating scene..." @@ -1452,9 +1457,8 @@ msgid "[unsaved]" msgstr "[non salvato]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Si prega di selezionare prima una cartella di base" +msgstr "Si prega di selezionare prima una cartella di base." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1488,7 +1492,7 @@ msgstr "Memorizzazione file:" #: editor/editor_export.cpp msgid "No export template found at the expected path:" -msgstr "Nessun template di esportazione trovato nel percorso previsto:" +msgstr "Nessun modello di esportazione trovato nel percorso previsto:" #: editor/editor_export.cpp msgid "Packing" @@ -1526,37 +1530,37 @@ msgstr "" #: 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 "Template di debug personalizzato non trovato." +msgstr "Modello di debug personalizzato non trovato." #: 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 "Template di release personalizzato non trovato." +msgstr "Modello di release personalizzato non trovato." #: editor/editor_export.cpp platform/javascript/export/export.cpp msgid "Template file not found:" -msgstr "Template non trovato:" +msgstr "Modello non trovato:" + +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Editor" +msgstr "Editor 3D" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Apri Editor Script" +msgstr "Editor degli script" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Apri Libreria degli Asset" +msgstr "Libreria degli asset" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Scene Tree (Nodi):" +msgstr "Editor delle scene" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1564,96 +1568,87 @@ msgid "Import Dock" msgstr "Importa" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "Nodo Spostato" +msgstr "Nodo" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "Filesystem" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Sostituisci tutto (no undo)" +msgstr "Eliminare il profilo '%s'? (non annullabile)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "Il profilo deve essere un nome di file valido e non può contenere '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Un file o cartella con questo nome é già esistente." +msgstr "Esiste già un profilo con questo nome." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(editor disabilitato, proprietà disabilitate)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Solo le proprietà " +msgstr "(proprietà disabilitate)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Clip Disabilitata" +msgstr "(editor disabilitato)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Descrizione della classe:" +msgstr "Opzioni della classe:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Apri l'Editor successivo" +msgstr "Abilita l'editor contestuale" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Proprietà :" +msgstr "Proprietà abilitate:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "Funzionalità " +msgstr "Funzionalità abilitate:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Cerca Classi" +msgstr "Classi abilitate:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Il formato del file '%s' non è valido, importazione annullata." #: editor/editor_feature_profile.cpp +#, fuzzy msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"Il profilo '%s' è già presente, rimuovilo prima dell'importazione. " +"Operazione annullata." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Errore caricamento template '%s'" +msgstr "Errore di salvataggio del profilo nel percorso: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Disattiva" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" -msgstr "Versione Corrente:" +msgid "Current Profile:" +msgstr "Profilo attuale" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Corrente:" +msgstr "Rendi attuale" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1672,43 +1667,32 @@ msgstr "Esporta" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" -msgstr "Nodi Disponibili:" +msgid "Available Profiles:" +msgstr "Profili disponibili" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Cerca Classi" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Descrizione della classe" +msgstr "Opzioni della classe" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Nuovo nome:" +msgstr "Nome del nuovo profilo:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Cancella Area" +msgstr "Cancella profilo" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Progetto Importato" +msgstr "Importa profili" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Esporta progetto" +msgstr "Esporta profilo" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "Gestisci template d'esportazione" +msgstr "Gestisci i profili delle funzionalità dell'editor" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1745,7 +1729,7 @@ msgstr "Aggiorna" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Recognized" -msgstr "Tutti Riconosciuti" +msgstr "Tutti i risconosciuti" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Files (*)" @@ -1792,19 +1776,19 @@ msgstr "Va' su" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Toggle Hidden Files" -msgstr "Commuta visibilità file nascosti" +msgstr "Attiva/disattiva file nascosti" #: editor/editor_file_dialog.cpp msgid "Toggle Favorite" -msgstr "Commuta preferito" +msgstr "Attiva/disattiva preferito" #: editor/editor_file_dialog.cpp msgid "Toggle Mode" -msgstr "Modalità Attivazione" +msgstr "Modalità Attivazione/Disattivazione" #: editor/editor_file_dialog.cpp msgid "Focus Path" -msgstr "Percorso Di Fuoco" +msgstr "Percorso di Focus" #: editor/editor_file_dialog.cpp msgid "Move Favorite Up" @@ -1824,24 +1808,23 @@ msgstr "Cartella successiva" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Go to parent folder." -msgstr "Vai alla cartella genitore." +msgstr "Va' alla cartella superiore." #: editor/editor_file_dialog.cpp msgid "(Un)favorite current folder." msgstr "Aggiungi/rimuovi cartella attuale dai preferiti." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Commuta visibilità file nascosti" +msgstr "Attiva/disattiva visibilità dei file nascosti." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." -msgstr "Visualizza elementi come una griglia di miniature." +msgstr "Visualizza elementi in una griglia di miniature." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a list." -msgstr "Visualizza elementi come una lista." +msgstr "Visualizza elementi in una lista." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Directories & Files:" @@ -1863,21 +1846,23 @@ msgstr "È necessaria un'estensione valida." #: editor/editor_file_system.cpp msgid "ScanSources" -msgstr "ScansionaSorgenti" +msgstr "Scansiona sorgenti" #: editor/editor_file_system.cpp msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"Ci sono importatori multipli per tipi differenti che puntano al file %s, " +"importazione annullata" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" -msgstr "(Re)Importando gli asset" +msgstr "Reimportazione degli asset" #: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp msgid "Top" -msgstr "Alto" +msgstr "In alto" #: editor/editor_help.cpp msgid "Class:" @@ -1953,7 +1938,7 @@ msgstr "Descrizione della classe:" #: editor/editor_help.cpp msgid "Online Tutorials:" -msgstr "Tutorial online:" +msgstr "Guide online:" #: editor/editor_help.cpp msgid "" @@ -1967,19 +1952,19 @@ msgstr "" #: editor/editor_help.cpp msgid "Property Descriptions" -msgstr "Descrizione proprietà " +msgstr "Descrizioni delle proprietà " #: editor/editor_help.cpp msgid "Property Descriptions:" -msgstr "Descrizione proprietà :" +msgstr "Descrizioni delle proprietà :" #: 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 "" -"Al momento una descrizione per questa proprietà non esiste. Aiutaci [color=" -"$color][url=$url]aggiungendone una[/url][/color]!" +"Al momento non esiste alcuna descrizione per questa proprietà . Aiutaci " +"[color=$color][url=$url]aggiungendone una[/url][/color]!" #: editor/editor_help.cpp msgid "Method Descriptions" @@ -2056,7 +2041,7 @@ msgstr "Output:" #: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp msgid "Copy Selection" -msgstr "Copia Selezione" +msgstr "Copia selezione" #: editor/editor_log.cpp editor/editor_profiler.cpp #: editor/editor_properties.cpp @@ -2066,7 +2051,7 @@ msgstr "Copia Selezione" #: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Clear" -msgstr "Rimuovi" +msgstr "Rimuovi tutto" #: editor/editor_log.cpp msgid "Clear Output" @@ -2124,7 +2109,7 @@ msgstr "Errore durante l'elaborazione di '%s'." #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." -msgstr "Fine file '%s' non prevista." +msgstr "Fine del file '%s' non prevista." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." @@ -2140,7 +2125,7 @@ msgstr "Salvataggio scena" #: editor/editor_node.cpp msgid "Analyzing" -msgstr "Analizzo" +msgstr "Analizzando" #: editor/editor_node.cpp msgid "Creating Thumbnail" @@ -2178,7 +2163,7 @@ msgstr "Impossibile caricare MeshLibrary per l'unione!" #: editor/editor_node.cpp msgid "Error saving MeshLibrary!" -msgstr "Errore nel salvataggio di MeshLibrary!" +msgstr "Errore nel salvataggio della MeshLibrary!" #: editor/editor_node.cpp msgid "Can't load TileSet for merging!" @@ -2186,23 +2171,23 @@ msgstr "Impossibile caricare TileSet per unione!" #: editor/editor_node.cpp msgid "Error saving TileSet!" -msgstr "Errore di salvataggio TileSet!" +msgstr "Errore di salvataggio del TileSet!" #: editor/editor_node.cpp msgid "Error trying to save layout!" -msgstr "Errore nel salvataggio del layout!" +msgstr "Errore nel salvataggio della disposizione!" #: editor/editor_node.cpp msgid "Default editor layout overridden." -msgstr "Layout predefinito dell'editor sovrascritto." +msgstr "Disposizione predefinita dell'editor sovrascritta." #: editor/editor_node.cpp msgid "Layout name not found!" -msgstr "Nome layout non trovato!" +msgstr "Nome della disposizione non trovato!" #: editor/editor_node.cpp msgid "Restored default layout to base settings." -msgstr "Ripristinato il layout di default alle impostazioni originali." +msgstr "Ripristinata la disposizione predefinita alle impostazioni originali." #: editor/editor_node.cpp msgid "" @@ -2216,7 +2201,6 @@ msgstr "" "scene per comprendere al meglio questo workflow." #: editor/editor_node.cpp -#, fuzzy 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." @@ -2233,7 +2217,6 @@ msgstr "" "impostazioni nel pannello di importazione e re-importala." #: editor/editor_node.cpp -#, fuzzy 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" @@ -2242,12 +2225,11 @@ msgid "" msgstr "" "Questa scena è stata importata, pertanto i cambiamenti ad essa non verranno " "mantenuti.\n" -"Istanziarla o ereditarla permetterà modificarla.\n" +"Istanziarla o ereditarla permetterà di modificarla.\n" "Si consiglia di leggere la documentazione relativa all'importazione delle " "scene per comprendere meglio questo workflow." #: editor/editor_node.cpp -#, fuzzy 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 " @@ -2256,7 +2238,7 @@ msgstr "" "Questa risorsa appartiene a una scena che è stata importata, di conseguenza " "non è modificabile.\n" "Si consiglia di leggere la documentazione riguardante l'importazione delle " -"scene per comprendere al meglio questa procedura." +"scene per comprendere al meglio questo workflow." #: editor/editor_node.cpp msgid "There is no defined scene to run." @@ -2270,7 +2252,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Could not start subprocess!" -msgstr "Impossibile avviare sottoprocesso!" +msgstr "Impossibile avviare il sottoprocesso!" #: editor/editor_node.cpp editor/filesystem_dock.cpp msgid "Open Scene" @@ -2278,20 +2260,19 @@ msgstr "Apri scena" #: editor/editor_node.cpp msgid "Open Base Scene" -msgstr "Apri scena base" +msgstr "Apri scena di base" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Apri scena rapidamente..." +msgstr "Apri scena rapidamente…" #: editor/editor_node.cpp msgid "Quick Open Scene..." -msgstr "Apri scena rapidamente..." +msgstr "Apri scena rapidamente…" #: editor/editor_node.cpp msgid "Quick Open Script..." -msgstr "Apri script rapidamente..." +msgstr "Apri script rapidamente…" #: editor/editor_node.cpp msgid "Save & Close" @@ -2311,7 +2292,7 @@ msgstr "È necessario un nodo radice per salvare la scena." #: editor/editor_node.cpp msgid "Save Scene As..." -msgstr "Salva scena con nome..." +msgstr "Salva scena come…" #: editor/editor_node.cpp msgid "No" @@ -2323,7 +2304,7 @@ msgstr "Sì" #: editor/editor_node.cpp msgid "This scene has never been saved. Save before running?" -msgstr "Questa scena non è mai stata salvata. Salvare prima di eseguire?" +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." @@ -2331,7 +2312,7 @@ msgstr "Questa operazione non può essere eseguita senza una scena." #: editor/editor_node.cpp msgid "Export Mesh Library" -msgstr "Esporta Libreria Mesh" +msgstr "Esporta libreria di Mesh" #: editor/editor_node.cpp msgid "This operation can't be done without a root node." @@ -2347,7 +2328,7 @@ msgstr "Questa operazione non può essere eseguita senza un nodo selezionato." #: editor/editor_node.cpp msgid "Current scene not saved. Open anyway?" -msgstr "Scena attuale non salvata. Aprirla comunque?" +msgstr "Scena attuale non salvata. Aprire comunque?" #: editor/editor_node.cpp msgid "Can't reload a scene that was never saved." @@ -2363,7 +2344,7 @@ msgstr "Questa azione non può essere annullata. Ripristinare comunque?" #: editor/editor_node.cpp msgid "Quick Run Scene..." -msgstr "Esegui scena rapidamente..." +msgstr "Esegui scena rapidamente…" #: editor/editor_node.cpp msgid "Quit" @@ -2375,7 +2356,7 @@ msgstr "Uscire dall'editor?" #: editor/editor_node.cpp msgid "Open Project Manager?" -msgstr "Aprire Gestione Progetti?" +msgstr "Aprire il gestore dei progetti?" #: editor/editor_node.cpp msgid "Save & Quit" @@ -2388,7 +2369,7 @@ msgstr "Salvare le modifiche alle scene seguenti prima di uscire?" #: editor/editor_node.cpp msgid "Save changes the following scene(s) before opening Project Manager?" msgstr "" -"Salvare le modifiche alle scene seguenti prima di aprire la Gestione " +"Salvare le modifiche alle scene seguenti prima di aprire il gestore dei " "progetti?" #: editor/editor_node.cpp @@ -2396,24 +2377,24 @@ msgid "" "This option is deprecated. Situations where refresh must be forced are now " "considered a bug. Please report." msgstr "" -"Questa opzione è deprecata. Situazioni dove un refresh è obbligatorio sono " -"ora considerate come bug. Si prega di segnalarlo." +"Questa opzione è deprecata. Situazioni in cui si è obbligati a ricaricare " +"sono ora considerate errori. Si prega di segnalarlo." #: editor/editor_node.cpp msgid "Pick a Main Scene" -msgstr "Scegli una Scena principale" +msgstr "Scegli una scena principale" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" -"Non riesco ad abilitare il plugin aggiunto a: '%s' è fallita la lettura " -"della configurazione." +"Impossibile abilitare il componente aggiuntivo in: '%s' lettura della " +"configurazione fallita." #: editor/editor_node.cpp msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." msgstr "" -"Impossibile trovare il campo per lo script del plugin aggiuntivo in: 'res://" -"addons/%s'." +"Impossibile trovare il campo per lo script del componente aggiuntivo in: " +"'res://addons/%s'." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." @@ -2447,15 +2428,15 @@ msgid "" msgstr "" "La scena '%s' è stata automaticamente importata, pertanto non può essere " "modificata.\n" -"Per modificarla, puoi essere creata una nuova scena ereditata." +"Per modificarla, può essere creata una nuova scena ereditata." #: 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 "" -"Errore di caricamento scena, deve essere all'interno del percorso del " -"progetto. Usare 'Importa' per aprire la scena, salvarla poi nel percorso del " +"Errore di caricamento della scena, deve essere all'interno del percorso del " +"progetto. Usare 'Importa' per aprire la scena e salvarla nel percorso del " "progetto." #: editor/editor_node.cpp @@ -2472,8 +2453,8 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Nessuna scena principale è stata definita, selezionarne una?\n" -"Puoi cambiarla successivamente da \"Impostazioni progetto\" sotto la " +"Non è stata definita alcuna scena principale, selezionarne una?\n" +"Potrai cambiarla successivamente da \"Impostazioni progetto\" sotto la " "categoria 'applicazioni'." #: editor/editor_node.cpp @@ -2528,12 +2509,11 @@ msgstr "Chiudi le altre schede" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Chiudi le Schede a Destra" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Chiudi Tutto" +msgstr "Chiudi Tutte le Schede" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2778,10 +2758,34 @@ msgid "Editor Layout" msgstr "Layout dell'editor" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Rendi Scena Radice" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Apri cartella dati/impostazioni editor" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Apri l'Editor successivo" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Abilita/Disabilita modalità a schermo intero" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Abilita CanvasItem Visibile" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Apri cartella dati/impostazioni editor" @@ -2889,15 +2893,18 @@ msgid "Spins when the editor window redraws." msgstr "Gira quando la finestra dell'editor viene ridisegnata." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Aggiorna sempre" +#, fuzzy +msgid "Update Continuously" +msgstr "Continuo" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Aggiorna cambiamenti" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Disabilita l'icona girevole di aggiornamento" #: editor/editor_node.cpp @@ -2934,10 +2941,14 @@ msgid "Manage Templates" msgstr "Gestisci template d'esportazione" #: editor/editor_node.cpp +#, fuzzy msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"Questo installerà il progetto Android per builds personalizzate.\n" +"Nota bene: per essere usato, deve essere abilitato secondo l'esportazione " +"del preset." #: editor/editor_node.cpp msgid "" @@ -3088,7 +3099,7 @@ msgstr "Tempo" msgid "Calls" msgstr "Chiamate" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "On" @@ -3194,6 +3205,11 @@ msgid "Page: " msgstr "Pagina: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Rimuovi Elemento" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Nuova Chiave:" @@ -3205,11 +3221,6 @@ msgstr "Nuovo Valore:" msgid "Add Key/Value Pair" msgstr "Aggiungi Coppia Chiave/Valore" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Rimuovi Elemento" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3438,7 +3449,6 @@ msgid "Remove Template" msgstr "Rimuovi Template" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" msgstr "Seleziona file template" @@ -3500,9 +3510,8 @@ msgid "No name provided." msgstr "Nessun nome fornito." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "Il nome fornito contiene caratteri non validi" +msgstr "Il nome fornito contiene caratteri non validi." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3531,26 +3540,23 @@ msgstr "Duplicando cartella:" #: editor/filesystem_dock.cpp #, fuzzy msgid "New Inherited Scene" -msgstr "Nuova scena ereditata..." +msgstr "Nuova scena ereditata" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Apri scena" +msgstr "Apri scene" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Istanza" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" msgstr "Aggiungi ai preferiti" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "Rimuovi dai preferiti" +msgstr "Rimuovi dai Preferiti" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." @@ -3598,14 +3604,12 @@ msgid "Rename" msgstr "Rinomina" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Cartella precedente" +msgstr "Cartella/File precedente" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Cartella successiva" +msgstr "Cartella/File successivo" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" @@ -3665,6 +3669,8 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Includi i file con le seguenti estensioni. Aggiungile o rimuovile nelle " +"Impostazioni del Progetto." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3716,6 +3722,7 @@ msgid "Nodes not in Group" msgstr "Nodi non in Gruppo" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtra nodi" @@ -3772,7 +3779,6 @@ msgid "Import as Multiple Scenes" msgstr "Importa come Scene Multiple" #: editor/import/resource_importer_scene.cpp -#, fuzzy msgid "Import as Multiple Scenes+Materials" msgstr "Importa come Scene+Materiali Multipli" @@ -4106,9 +4112,8 @@ msgid "Open Animation Node" msgstr "Apri Nodo Animazione" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "Il triangolo è già esistente" +msgstr "Il triangolo esiste già ." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4959,10 +4964,13 @@ msgid "Presets for the anchors and margins values of a Control node." msgstr "Preset per i valori di ancoraggio e margini di un nodo Control." #: editor/plugins/canvas_item_editor_plugin.cpp +#, fuzzy msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Quando è attivo, il movimento dei nodi di Controllo cambia le loro ancore " +"invece dei loro margini." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -4984,15 +4992,13 @@ msgstr "Strumento Seleziona" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "Elimina selezionati" +msgstr "Sblocca selezionati" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Copia Selezione" +msgstr "Gruppo Selezionato" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5005,9 +5011,8 @@ msgid "Paste Pose" msgstr "Incolla Posa" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" -msgstr "Crea ossa personalizzate a partire da uno o più nodi" +msgstr "Crea Ossa personalizzate a partire da uno o più Nodi" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5246,16 +5251,15 @@ msgstr "Maschera di traduzione per inserimento chiavi" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation mask for inserting keys." -msgstr "" +msgstr "Maschera di rotazione per l'inserimento delle chiavi." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Scale mask for inserting keys." -msgstr "" +msgstr "Maschera di scala per l'inserimento delle chiavi." #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Insert keys (based on mask)." -msgstr "Inserisci Keys (Ins)" +msgstr "Inserisci chiavi (in base alla maschera)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -5266,9 +5270,8 @@ msgid "" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Auto Insert Key" -msgstr "Inserisci una chiave d'animazione" +msgstr "Inserimento Automatico Chiave" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key (Existing Tracks)" @@ -5362,6 +5365,14 @@ msgid "Load Emission Mask" msgstr "Carica Maschera Emissione" #: 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 +#, fuzzy +msgid "Restart" +msgstr "Riavvia Ora" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Cancella Maschera Emissione" @@ -5407,14 +5418,12 @@ msgid "Create Emission Points From Node" msgstr "Crea Punti Emissione Da Nodo" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "Flat0" +msgstr "Flat 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "Flat1" +msgstr "Flat 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -5456,7 +5465,6 @@ msgid "Left Linear" msgstr "Lineare sinistra" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" msgstr "Lineare destra" @@ -5518,18 +5526,16 @@ msgid "This doesn't work on scene root!" msgstr "Questo non funziona sulla root della scena!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Crea Forma Trimesh" +msgstr "Crea Forma Statica Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "Errore nella creazione delle forme!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "Crea Forma Convessa" +msgstr "Crea una o più forme Convesse" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -6092,7 +6098,6 @@ msgid "Paint weights with specified intensity." msgstr "Colora i pesi con le intensità specificate." #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Unpaint weights with specified intensity." msgstr "Rimuovi i pesi con le intensità specificate." @@ -6279,9 +6284,8 @@ msgid "Save Theme As..." msgstr "Salva Tema Come..." #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "%s Class Reference" -msgstr " Riferimento di Classe" +msgstr "%s Riferimento di Classe" #: editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -6289,10 +6293,20 @@ msgid "Find Next" msgstr "Trova Successivo" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filtra proprietà " + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "Ordina in ordine alfabetico la lista dei metodi." #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Modalità di filtro:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Ordina" @@ -6403,7 +6417,6 @@ msgid "Debug with External Editor" msgstr "Debug con Editor Esterno" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." msgstr "Apri la documentazione online di Godot" @@ -6412,9 +6425,8 @@ msgid "Request Docs" msgstr "Documentazione richiesta" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "Aiutate a migliorare la documentazione di Godot fornendo feedback" +msgstr "Aiutate a migliorare la documentazione di Godot fornendo feedback." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6459,29 +6471,26 @@ msgid "Search Results" msgstr "Cerca Risultati" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "Connetti al nodo:" +msgstr "Connessioni al metodo:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Sorgente:" +msgstr "Sorgente" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Segnali" +msgstr "Segnale" #: editor/plugins/script_text_editor.cpp msgid "Target" msgstr "Target" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "Nulla collegato all'ingresso '%s' del nodo '%s'." +msgstr "" +"Manca il metodo '%s' connesso per il segnale '%s' dal nodo '%s' al nodo '%s'." #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6528,20 +6537,24 @@ msgid "Syntax Highlighter" msgstr "Evidenziatore di Sintassi" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "Segnalibri" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Crea punti." #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Taglia" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Seleziona tutti" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Elimina Linea" @@ -6559,24 +6572,20 @@ msgid "Toggle Comment" msgstr "Cambia a Commento" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "Abilita/Disabilita Vista libera" +msgstr "Abilita/Disabilita Segnalibri" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "Vai a Breakpoint Successivo" +msgstr "Vai al Segnalibri Successivo" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Previous Bookmark" -msgstr "Vai a Breakpoint Precedente" +msgstr "Vai al Segnalibri Precedente" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "Rimuovi tutti gli elementi" +msgstr "Rimuovi tutti i Segnalibri" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -6652,13 +6661,12 @@ msgid "Contextual Help" msgstr "Aiuto Contestuale" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"I file seguenti sono più recenti su disco.\n" -"Che azione deve essere intrapresa?:" +"Questo shader è stato modificato sul disco.\n" +"Che azione deve essere intrapresa?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -6754,11 +6762,11 @@ msgstr "Key d'Animazione Inserito." #: editor/plugins/spatial_editor_plugin.cpp msgid "Pitch" -msgstr "" +msgstr "Inclinazione" #: editor/plugins/spatial_editor_plugin.cpp msgid "Yaw" -msgstr "" +msgstr "Imbardata" #: editor/plugins/spatial_editor_plugin.cpp msgid "Objects Drawn" @@ -7170,19 +7178,16 @@ msgid "Create Mesh2D" msgstr "Crea Mesh 2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create Polygon2D" -msgstr "Crea Polygon3D" +msgstr "Crea Poligono 2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create CollisionPolygon2D" -msgstr "Crea Poligono di Collisione" +msgstr "Crea Poligono di Collisione 2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create LightOccluder2D" -msgstr "Crea Poligono di occlusione" +msgstr "Crea Occlusore di Luce 2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Sprite is empty!" @@ -7204,34 +7209,28 @@ msgid "Convert to Mesh2D" msgstr "Converti in Mesh 2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Invalid geometry, can't create polygon." -msgstr "Geometria non valida, impossibile sostituirla con una mesh." +msgstr "Geometria non valida, impossibile creare il poligono." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Convert to Polygon2D" -msgstr "Sposta Poligono" +msgstr "Converti in Poligono 2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Invalid geometry, can't create collision polygon." -msgstr "Geometria non valida, impossibile sostituirla con una mesh." +msgstr "Geometria non valida, impossibile creare un poligono di collisione." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create CollisionPolygon2D Sibling" -msgstr "Crea Poligono di Collisione" +msgstr "Crea fratello del Poligono di Collisione 2D" #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Invalid geometry, can't create light occluder." -msgstr "Geometria non valida, impossibile sostituirla con una mesh." +msgstr "Geometria non valida, impossibile creare un occlusore di luce." #: editor/plugins/sprite_editor_plugin.cpp -#, fuzzy msgid "Create LightOccluder2D Sibling" -msgstr "Crea Poligono di occlusione" +msgstr "Crea fratello di Occlusore di Luce 2D" #: editor/plugins/sprite_editor_plugin.cpp msgid "Sprite" @@ -7254,14 +7253,12 @@ msgid "Settings:" msgstr "Impostazioni:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "Selezione Frame" +msgstr "Nessun Frame selezionato" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "Aggiungi frame" +msgstr "Aggiungi %d frame(s)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" @@ -7312,13 +7309,12 @@ msgid "Animation Frames:" msgstr "Frame Animazione:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Aggiungi Texture al TileSet." +msgstr "Aggiungi una Texture da File" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "Aggiungi Frames da uno Spritesheet" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7337,29 +7333,24 @@ msgid "Move (After)" msgstr "Sposta (Dopo)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "Impila Frame" +msgstr "Seleziona Frames" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Ribalta in orizzontale" +msgstr "Orizzontale:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "Vertici" +msgstr "Verticale:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "Seleziona tutti" +msgstr "Seleziona/De-Seleziona tutti i Frame" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "Crea da Scena" +msgstr "Crea Frames da uno Spritesheet" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" @@ -7431,9 +7422,8 @@ msgid "Remove All" msgstr "Rimuovi Tutto" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "Modifica Tema…" +msgstr "Modifica Tema" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7460,23 +7450,20 @@ msgid "Create From Current Editor Theme" msgstr "Crea da Tema Editor corrente" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Toggle Button" -msgstr "Pulsante Mouse" +msgstr "Attiva/Disattiva pulsante" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Pulsante Centrale" +msgstr "Pulsante disabilitato" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" msgstr "Elemento" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "Disabilitato" +msgstr "Oggetto disabilitato" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -7496,21 +7483,19 @@ msgstr "Elemento Radio Controllato" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "Chiamato Sep." #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Sottomenù" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "Elemento" +msgstr "Elemento 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "Elemento" +msgstr "Elemento 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -7521,9 +7506,8 @@ msgid "Many" msgstr "Molte" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled LineEdit" -msgstr "Disabilitato" +msgstr "Editor di Linea disabilitato" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -7538,13 +7522,12 @@ msgid "Tab 3" msgstr "Tab 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "Figlio Modificabile" +msgstr "Elemento Modificabile" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "Sottoalbero" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7624,14 +7607,12 @@ msgid "Mirror Y" msgstr "Specchia Y" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "Auto Divisione" +msgstr "Disabilita Autotile" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "Modifica Priorità Tile" +msgstr "Abilita Priorità Tile" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7642,6 +7623,8 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift + PDM: Traccia una linea\n" +"Shift + Ctrl + PDM: Colora il rettangolo" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" @@ -7710,39 +7693,32 @@ msgid "Region Mode" msgstr "Modalità esecuzione:" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "Modalità di Interpolazione" +msgstr "Modalità di Collisione" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "Modifica Poligono di Occlusione" +msgstr "Modalità di occlusione" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "Crea Mesh di Navigazione" +msgstr "Modalità di navigazione" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "Modalità Rotazione" +msgstr "Modalità Maschera di Bit" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "Modalità d'Esportazione:" +msgstr "Modalità prioritaria" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "Modalità di Pan" +msgstr "Modalità Icona" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "Modalità di Pan" +msgstr "Modalità indice Z" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7766,7 +7742,7 @@ msgstr "Crea un nuovo poligono." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Keep polygon inside region Rect." -msgstr "" +msgstr "Mantieni il poligono all'interno dell'area del rettangolo." #: editor/plugins/tile_set_editor_plugin.cpp msgid "Enable snap and show grid (configurable via the Inspector)." @@ -7809,11 +7785,12 @@ msgid "" "Drag handles to edit Rect.\n" "Click on another Tile to edit it." msgstr "" +"Sposta gli angoli per modificare il rettangolo.\n" +"Clicca su un altro pezzo per modificarlo." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Delete selected Rect." -msgstr "Cancella il ret. selezionato." +msgstr "Cancella il rett. selezionato." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -7828,16 +7805,16 @@ msgid "Delete polygon." msgstr "Elimina poligono." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy 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 "" -"Tasto Sinistro Mouse: Imposta bit on.\n" -"Tasto Destro Mouse: Imposta bit off.\n" -"Clicca su un'altra Tile per modificarla." +"PSM: Imposta bit on.\n" +"PDM: Imposta bit off.\n" +"Shift+PSM: Imposta bit come wildcard.\n" +"Clicca su un'altro pezzo per modificarlo." #: editor/plugins/tile_set_editor_plugin.cpp msgid "" @@ -7950,77 +7927,64 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input +" -msgstr "Aggiungi Input" +msgstr "Aggiungi Input +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add output +" -msgstr "Aggiungi Input" +msgstr "Aggiungi ouput +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "Scala:" +msgstr "Scalare" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Ispettore" +msgstr "Vettore" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Booleano" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "Aggiungi Input" +msgstr "Aggiungi porta di Input" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Aggiungi porta di Output" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "Cambia tipo di default" +msgstr "Cambia tipo di porta di input" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "Cambia tipo di default" +msgstr "Cambia tipo di porta di output" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "Cambia Nome Input" +msgstr "Cambia Nome porta Input" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "Cambia Nome Input" +msgstr "Cambia Nome porta Input" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "Rimuovi punto" +msgstr "Rimuovi porta input" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "Rimuovi punto" +msgstr "Rimuovi porta output" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "Cambia Espressione" +msgstr "Cambia espressione" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "VisualShader" +msgstr "Ridimensiona nodo VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" @@ -8039,9 +8003,8 @@ msgid "Duplicate Nodes" msgstr "Duplica Nodi" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Delete Nodes" -msgstr "Elimina Nodo" +msgstr "Elimina Nodi" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Visual Shader Input Type Changed" @@ -8060,44 +8023,40 @@ msgid "Light" msgstr "Luce" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "Crea Nodo" +msgstr "Crea Nodo Shader" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "Vai a Funzione" +msgstr "Colora funzione." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "Rendi funzione" +msgstr "Funzione Grayscale." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "Converti vettore HSV nell'equivalente RGB." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "Converti vettore RGB nell'equivalente HSV." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "Rinomina Funzione" +msgstr "Funzione seppia." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "Operatore Burn." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "Operatore Darken." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8159,51 +8118,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8212,203 +8127,27 @@ msgid "Input parameter." msgstr "Snap su Genitore" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9357,14 +9096,13 @@ msgstr "" "modificati)" #: editor/project_manager.cpp -#, fuzzy msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." msgstr "" "Lingua cambiata.\n" "L'interfaccia utente sarà aggiornata la prossima volta che l'editor o il " -"project manager si avvia." +"gestore dei progetti sarà avviato." #: editor/project_manager.cpp #, fuzzy @@ -9375,7 +9113,7 @@ msgstr "Stai per esaminare %s cartelle per progetti Godot esistenti. Confermi?" #: editor/project_manager.cpp msgid "Project Manager" -msgstr "Gestione Progetti" +msgstr "Gestore dei progetti" #: editor/project_manager.cpp msgid "Project List" @@ -10141,6 +9879,11 @@ msgid "Add Child Node" msgstr "Aggiungi Nodo Figlio" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Comprimi Tutto" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Cambia Tipo" @@ -10169,7 +9912,8 @@ msgid "Delete (No Confirm)" msgstr "Elimina (Senza Conferma)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Aggiungi/Crea un Nuovo Nodo" #: editor/scene_tree_dock.cpp @@ -10437,7 +10181,7 @@ msgstr "Analisi dello stack" msgid "Pick one or more items from the list to display the graph." msgstr "Scegli uno o più oggetti dalla lista per mostrare il grafico." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Errori" @@ -10840,54 +10584,6 @@ msgstr "Scegli la Distanza:" msgid "Class name can't be a reserved keyword" msgstr "Il nome della classe non può essere una parola chiave riservata" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Generando la soluzione..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "Genero progetto in C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Impossibile creare la soluzione." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Impossibile salvare la soluzione." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Fatto" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "Impossibile creare il progetto C#." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "Riguardo il supporto in C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Crea la soluzione C#" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Compilazioni" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Compila Progetto" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Visualizza log" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11502,8 +11198,9 @@ msgstr "" "620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Una risorsa SpriteFrames deve essere creata o impostata nella proprietà " @@ -11572,8 +11269,9 @@ msgstr "" "\"Animazione Particelle\" abilitata." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Una texture con la forma della luce deve essere fornita nella proprietà " @@ -11587,7 +11285,8 @@ msgstr "" "l'occlusore abbia effetto." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "Il poligono di occlusione per questo occlusore è vuoto. Per favore disegna " "un poligono!" @@ -11680,16 +11379,30 @@ msgstr "" "Questo osso ha bisogno di una corretta postura di RIPOSO. Vai al nodo " "Skeleton2D e impostane una." +#: 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 serve a fornire una forma di collisione ad un nodo derivato " +"di CollisionObject2D. Si prega di utilizzarlo solamente come figlio di " +"Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. in modo da dargli " +"una forma." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D funziona al meglio quando usato direttamente come " "genitore con il root della scena modificata." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera deve avere un nodo ARVROrigin come suo genitore" #: scene/3d/arvr_nodes.cpp @@ -11786,9 +11499,10 @@ msgstr "" "StaticBody, RigidBody, KinematicBody, etc. in modo da dargli una forma." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Perché CollisionShape funzioni deve essere fornita una forma. Si prega di " "creare una risorsa forma (shape)!" @@ -11824,6 +11538,10 @@ msgstr "" "Le GIProbes non sono supportate dal driver video GLES2.\n" "In alternativa, usa una BakedLightmap." +#: 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 "" @@ -11869,8 +11587,8 @@ msgstr "PathFollow funziona solo se impostato come figlio di un nodo Path." #: scene/3d/path.cpp #, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED richiede \"Up Vector\" abilitato nella risorsa " "Path’s Curve del padre." @@ -11886,7 +11604,10 @@ msgstr "" "Modifica invece la dimensione in sagome di collisione figlie." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "La proprietà path deve puntare ad un nodo Spaziale (Spatial) valido per " "poter funzionare." @@ -11907,8 +11628,9 @@ msgstr "" "Cambiare invece le dimensioni nelle forme di collisioni figlie." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Una risorsa SpriteFrames deve essere creata o impostata nella proprietà " @@ -11923,8 +11645,10 @@ msgstr "" "favore usalo come figlio di VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment ha bisogno di una risorsa Ambiente." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11962,7 +11686,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Nulla collegato all'ingresso '%s' del nodo '%s'." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "Una radice AnimationNode per il grafico non è impostata." #: scene/animation/animation_tree.cpp @@ -11977,7 +11702,8 @@ msgstr "" "AnimationPlayer." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "La radice di AnimationPlayer non è un nodo valido." #: scene/animation/animation_tree_player.cpp @@ -11989,8 +11715,13 @@ msgid "Pick a color from the screen." msgstr "Scegliere un colore dallo schermo." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Modalità Raw" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +#, fuzzy +msgid "Raw" +msgstr "Imbardata" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -12003,16 +11734,21 @@ msgstr "Aggiungi il colore corrente come preset." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" "Il Contenitore da solo non serve a nessuno scopo a meno che uno script non " "configuri il suo comportamento di posizionamento per i figli.\n" "Se non avete intenzione di aggiungere uno script, utilizzate invece un " "semplice nodo \"Controllo\"." +#: 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 "Attenzione!" @@ -12022,23 +11758,26 @@ msgid "Please Confirm..." msgstr "Per Favore Conferma..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "I popup saranno nascosti di default a meno che vengano chiamate la funzione " "popup() o qualsiasi altra funzione popup*(). Renderli visibili per la " "modifica nell'editor è okay, ma verranno nascosti una volta in esecuzione." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Se exp_edit è true min_value deve essere > 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer é fatto per funzionare con un solo controllo figlio.\n" @@ -12090,6 +11829,11 @@ msgid "Input" msgstr "Ingresso" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Sorgente non valida per la shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Sorgente non valida per la shader." @@ -12110,6 +11854,54 @@ msgstr "Varyings può essere assegnato solo nella funzione del vertice." msgid "Constants cannot be modified." msgstr "" +#~ msgid "Generating solution..." +#~ msgstr "Generando la soluzione..." + +#~ msgid "Generating C# project..." +#~ msgstr "Genero progetto in C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "Impossibile creare la soluzione." + +#~ 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#." + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "Riguardo il supporto in C#" + +#~ msgid "Create C# solution" +#~ msgstr "Crea la soluzione C#" + +#~ msgid "Builds" +#~ msgstr "Compilazioni" + +#~ msgid "Build Project" +#~ msgstr "Compila Progetto" + +#~ msgid "View log" +#~ msgstr "Visualizza log" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment ha bisogno di una risorsa Ambiente." + +#~ msgid "Enabled Classes" +#~ msgstr "Classi abilitate" + +#~ msgid "Update Always" +#~ msgstr "Aggiorna sempre" + +#~ msgid "Raw Mode" +#~ msgstr "Modalità Raw" + #~ msgid "Path to Node:" #~ msgstr "Percorso per il nodo:" @@ -12673,9 +12465,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Abilita Spatial Visibile" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Abilita CanvasItem Visibile" - #~ msgid "Condition" #~ msgstr "Condizione" @@ -13613,9 +13402,6 @@ msgstr "" #~ msgid "Images:" #~ msgstr "Immagini:" -#~ msgid "Select None" -#~ msgstr "Seleziona Nulla" - #~ msgid "Group" #~ msgstr "Gruppo" diff --git a/editor/translations/ja.po b/editor/translations/ja.po index 91217afd8a..d44fc089e8 100644 --- a/editor/translations/ja.po +++ b/editor/translations/ja.po @@ -22,12 +22,13 @@ # Rob Matych <robertsmatych@gmail.com>, 2018. # Hidetsugu Takahashi <manzyun@gmail.com>, 2019. # Wataru Onuki <watonu@magadou.com>, 2019. +# John Smith <weblater_jp@susa.eek.jp>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-05-16 18:49+0000\n" -"Last-Translator: Wataru Onuki <watonu@magadou.com>\n" +"PO-Revision-Date: 2019-07-02 10:49+0000\n" +"Last-Translator: John Smith <weblater_jp@susa.eek.jp>\n" "Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/" "godot/ja/>\n" "Language: ja\n" @@ -35,7 +36,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -94,9 +95,8 @@ msgid "Time:" msgstr "時間:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "値" +msgstr "値:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -180,9 +180,8 @@ msgid "Animation Playback Track" msgstr "アニメーションå†ç”Ÿãƒˆãƒ©ãƒƒã‚¯" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation length (frames)" -msgstr "アニメーションã®é•·ã• (ç§’)" +msgstr "アニメーションã®é•·ã• (フレーム)" #: editor/animation_track_editor.cpp #, fuzzy @@ -211,9 +210,8 @@ msgid "Anim Clips:" msgstr "アニメーションクリップ:" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Track Path" -msgstr "é…列ã®å€¤ã‚’変更" +msgstr "トラックパスを変更" #: editor/animation_track_editor.cpp msgid "Toggle this track on/off." @@ -240,9 +238,8 @@ msgid "Time (s): " msgstr "時間 (ç§’): " #: editor/animation_track_editor.cpp -#, fuzzy msgid "Toggle Track Enabled" -msgstr "有効ã«ã™ã‚‹" +msgstr "トラックを有効ã«ã™ã‚‹" #: editor/animation_track_editor.cpp msgid "Continuous" @@ -295,14 +292,12 @@ msgid "Delete Key(s)" msgstr "ã‚ーを削除" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Update Mode" -msgstr "アニメーションåを変更:" +msgstr "アニメーション更新モードを変更" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Interpolation Mode" -msgstr "補間モード" +msgstr "アニメーション補間モードã®å¤‰æ›´" #: editor/animation_track_editor.cpp #, fuzzy @@ -396,9 +391,8 @@ msgid "Not possible to add a new track without a root" msgstr "root ãŒç„¡ã‘ã‚Œã°æ–°è¦ãƒˆãƒ©ãƒƒã‚¯ã¯è¿½åŠ ã§ãã¾ã›ã‚“" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Bezier Track" -msgstr "ãƒˆãƒ©ãƒƒã‚¯ã‚’è¿½åŠ " +msgstr "ãƒ™ã‚¸ã‚§ãƒˆãƒ©ãƒƒã‚¯ã‚’è¿½åŠ " #: editor/animation_track_editor.cpp msgid "Track path is invalid, so can't add a key." @@ -409,9 +403,8 @@ msgid "Track is not of type Spatial, can't insert key" msgstr "トラック㌠spatial åž‹ã§ã¯ãªã„ãŸã‚ã€ã‚ーを挿入ã§ãã¾ã›ã‚“" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Add Transform Track Key" -msgstr "3Dトランスフォームトラック" +msgstr "変æ›ãƒˆãƒ©ãƒƒã‚¯ã‚ãƒ¼ã‚’è¿½åŠ " #: editor/animation_track_editor.cpp #, fuzzy @@ -464,10 +457,29 @@ 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 "è¦å‘Š:インãƒãƒ¼ãƒˆã—ãŸã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ã‚’編集ã—ã¦ã„ã¾ã™" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "ã™ã¹ã¦é¸æŠž" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "ãƒŽãƒ¼ãƒ‰ã‚’é¸æŠž" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -489,7 +501,7 @@ msgstr "アニメーションステップã®å€¤ã€‚" #: editor/animation_track_editor.cpp msgid "Seconds" -msgstr "" +msgstr "ç§’" #: editor/animation_track_editor.cpp msgid "FPS" @@ -620,11 +632,11 @@ msgstr "オーディオクリップ:" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip Start Offset" -msgstr "" +msgstr "オーディオトラッククリップã®é–‹å§‹ã‚ªãƒ•セットを変更" #: editor/animation_track_editor_plugins.cpp msgid "Change Audio Track Clip End Offset" -msgstr "" +msgstr "オーディオトラッククリップã®çµ‚了オフセットを変更" #: editor/array_property_edit.cpp msgid "Resize Array" @@ -646,6 +658,10 @@ msgstr "行ã«ç§»å‹•" msgid "Line Number:" msgstr "行番å·:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "一致ãªã—" @@ -695,7 +711,7 @@ msgstr "ズームアウト" msgid "Reset Zoom" msgstr "ズームをリセット" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "è¦å‘Š" @@ -723,14 +739,12 @@ msgid "Connect to Node:" msgstr "ãƒŽãƒ¼ãƒ‰ã«æŽ¥ç¶š:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "ãƒ›ã‚¹ãƒˆã«æŽ¥ç¶šã§ãã¾ã›ã‚“:" +msgstr "ã‚¹ã‚¯ãƒªãƒ—ãƒˆã«æŽ¥ç¶š:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "シグナル:" +msgstr "シグナルã‹ã‚‰:" #: editor/connections_dialog.cpp #, fuzzy @@ -774,7 +788,7 @@ msgstr "é…å»¶" #: editor/connections_dialog.cpp msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." -msgstr "" +msgstr "シグナルをä¿ç•™ã—ã€ã‚ãƒ¥ãƒ¼ã«æ ¼ç´ã—ã¦ã€ã‚¢ã‚¤ãƒ‰ãƒ«æ™‚ã«ã®ã¿èµ·å‹•ã—ã¾ã™ã€‚" #: editor/connections_dialog.cpp msgid "Oneshot" @@ -782,7 +796,7 @@ msgstr "å˜ç™º" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "最åˆã®æ”¾å‡ºå¾Œã«ä¿¡å·ã‚’切æ–ã—ã¾ã™ã€‚" #: editor/connections_dialog.cpp #, fuzzy @@ -808,6 +822,11 @@ msgid "Connect" msgstr "接続" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "シグナル:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "'%s' ã‚’ '%s' ã«æŽ¥ç¶š" @@ -974,7 +993,8 @@ msgid "Owners Of:" msgstr "次ã®ã‚ªãƒ¼ãƒŠãƒ¼:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "é¸æŠžã—ãŸãƒ•ァイルをプãƒã‚¸ã‚§ã‚¯ãƒˆã‹ã‚‰é™¤åŽ»ã—ã¾ã™ã‹ï¼Ÿï¼ˆã€Œå…ƒã«æˆ»ã™ã€ä¸å¯ï¼‰" #: editor/dependency_editor.cpp @@ -1283,7 +1303,7 @@ msgstr "オーディオãƒã‚¹ã®ãƒ¬ã‚¤ã‚¢ã‚¦ãƒˆã‚’é–‹ã" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "'ï¼…s' ファイルãŒã‚りã¾ã›ã‚“。" #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1346,7 +1366,7 @@ msgstr "無効ãªåå‰ã§ã™ã€‚æ—¢å˜ã®ã‚¨ãƒ³ã‚¸ãƒ³ã‚¯ãƒ©ã‚¹åã¨é‡è¤‡ã—㦠#: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "無効ãªåå‰ã§ã™ã€‚æ—¢å˜ã®çµ„è¾¼ã¿åž‹åã¨é‡è¤‡ã—ã¦ã¯ã„ã‘ã¾ã›ã‚“。" #: editor/editor_autoload_settings.cpp @@ -1356,7 +1376,7 @@ msgstr "無効ãªåå‰ã§ã™ã€‚æ—¢å˜ã®ã‚°ãƒãƒ¼ãƒãƒ«å®šæ•°åã¨é‡è¤‡ã—㦠#: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "ã‚ーワードã¯è‡ªå‹•ãƒãƒ¼ãƒ‰åã¨ã—ã¦ä½¿ç”¨ã§ãã¾ã›ã‚“。" #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1527,6 +1547,10 @@ msgstr "カスタムリリーステンプレートãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“。" 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 #, fuzzy msgid "3D Editor" @@ -1538,9 +1562,8 @@ msgid "Script Editor" msgstr "スクリプトエディタを開ã" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "アセットライブラリを開ã" +msgstr "アセットライブラリ" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1559,7 +1582,7 @@ msgstr "è¿½åŠ ã—ãŸã‚ーを移動" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "ファイルシステム" #: editor/editor_feature_profile.cpp @@ -1570,6 +1593,7 @@ msgstr "ã™ã¹ã¦ç½®æ›ï¼ˆã€Œå…ƒã«æˆ»ã™ã€ä¸å¯ï¼‰" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" msgstr "" +"プãƒãƒ•ã‚¡ã‚¤ãƒ«ã¯æœ‰åйãªãƒ•ァイルåã§ãªã‘れã°ãªã‚‰ãšã€ '.' ã‚’å«ã‚“ã§ã¯ã„ã‘ã¾ã›ã‚“" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1578,7 +1602,7 @@ msgstr "åŒåã®ãƒ•ァイルã¾ãŸã¯ãƒ•ォルダãŒã‚りã¾ã™ã€‚" #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(エディタ無効ã€ãƒ—ãƒãƒ‘ティ無効)" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1617,13 +1641,16 @@ msgstr "ã‚¯ãƒ©ã‚¹ã®æ¤œç´¢" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "ファイル '%s' ã®ãƒ•ォーマットãŒç„¡åйã§ã™ã€‚インãƒãƒ¼ãƒˆãŒä¸æ¢ã•れã¾ã—ãŸã€‚" #: editor/editor_feature_profile.cpp +#, fuzzy msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"プãƒãƒ•ァイル '%s' ã¯ã™ã§ã«å˜åœ¨ã—ã¾ã™ã€‚インãƒãƒ¼ãƒˆå‰ã«æœ€åˆã«ãƒªãƒ¢ãƒ¼ãƒˆã§å®Ÿè¡Œã™ã‚‹" +"ã¨ã€ã‚¤ãƒ³ãƒãƒ¼ãƒˆã¯ä¸æ¢ã•れã¾ã™ã€‚" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1632,11 +1659,11 @@ msgstr "テンプレート %s èªã¿è¾¼ã¿ã‚¨ãƒ©ãƒ¼" #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "未è¨å®š" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "ç¾åœ¨ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³:" #: editor/editor_feature_profile.cpp @@ -1661,16 +1688,11 @@ msgstr "エクスãƒãƒ¼ãƒˆ" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "利用å¯èƒ½ãªãƒŽãƒ¼ãƒ‰:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "ã‚¯ãƒ©ã‚¹ã®æ¤œç´¢" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "クラスã®èª¬æ˜Ž" @@ -1863,6 +1885,8 @@ msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"ファイル%sã‚’ãƒã‚¤ãƒ³ãƒˆã—ã¦ã„ã‚‹ç•°ãªã‚‹ã‚¿ã‚¤ãƒ—ã®è¤‡æ•°ã®ã‚¤ãƒ³ãƒãƒ¼ã‚¿ãŒã‚りã¾ã™ã€‚イン" +"ãƒãƒ¼ãƒˆã¯ä¸æ–ã•れã¾ã—ãŸ" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2072,7 +2096,7 @@ msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆã®ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆãŒã‚¨ãƒ©ãƒ¼ã‚³ãƒ¼ãƒ‰ %d ã§å¤±æ• #: editor/editor_node.cpp msgid "Imported resources can't be saved." -msgstr "" +msgstr "インãƒãƒ¼ãƒˆã—ãŸãƒªã‚½ãƒ¼ã‚¹ã¯ä¿å˜ã§ãã¾ã›ã‚“。" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: scene/gui/dialogs.cpp @@ -2088,6 +2112,8 @@ 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..." @@ -2510,7 +2536,7 @@ msgstr "ä»–ã®ã‚¿ãƒ–ã‚’é–‰ã˜ã‚‹" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "タブをå³ã«é–‰ã˜ã‚‹" #: editor/editor_node.cpp #, fuzzy @@ -2649,7 +2675,7 @@ msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆã®ãƒ‡ãƒ¼ã‚¿ãƒ•ォルダを開ã" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Androidビルドテンプレートã®ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2759,10 +2785,34 @@ msgid "Editor Layout" msgstr "エディタレイアウト" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "シーンをルートã«ã™ã‚‹" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "エディタã®ãƒ‡ãƒ¼ã‚¿ãƒ»è¨å®šãƒ•ォルダを開ã" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "次ã®ã‚¨ãƒ‡ã‚£ã‚¿ã‚’é–‹ã" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "フルスクリーン切り替ãˆ" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "分割モード切り替ãˆ" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "エディタã®ãƒ‡ãƒ¼ã‚¿ãƒ»è¨å®šãƒ•ォルダを開ã" @@ -2870,15 +2920,18 @@ msgid "Spins when the editor window redraws." msgstr "エディタ ウィンドウã®å†æç”»æ™‚ã«ã‚¹ãƒ”ンã—ã¾ã™ã€‚" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "å¸¸ã«æ›´æ–°" +#, fuzzy +msgid "Update Continuously" +msgstr "継続的" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "å¤‰æ›´æ™‚ã«æ›´æ–°" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "アップデートスピナーを無効化" #: editor/editor_node.cpp @@ -2908,6 +2961,8 @@ msgstr "ä¿å˜ã—ãªã„" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." msgstr "" +"AndroidビルドテンプレートãŒã‚りã¾ã›ã‚“。関連ã™ã‚‹ãƒ†ãƒ³ãƒ—レートをインストールã—ã¦" +"ãã ã•ã„。" #: editor/editor_node.cpp #, fuzzy @@ -2919,6 +2974,8 @@ msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"ã“れã«ã‚ˆã‚Šã€ã‚«ã‚¹ã‚¿ãƒ ビルド用ã®Androidプãƒã‚¸ã‚§ã‚¯ãƒˆãŒã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¾ã™ã€‚\n" +"使用ã™ã‚‹ã«ã¯ã€ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆãƒ—リセットã”ã¨ã«æœ‰åйã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #: editor/editor_node.cpp msgid "" @@ -2926,6 +2983,8 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"Androidビルドテンプレートã¯ã™ã§ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ãŠã‚Šã€ä¸Šæ›¸ãã•れã¾ã›ã‚“。\n" +"ã“ã®æ“作をå†è©¦è¡Œã™ã‚‹å‰ã«ã€ \"build\"ディレクトリを手動ã§å‰Šé™¤ã—ã¦ãã ã•ã„。" #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3069,7 +3128,7 @@ msgstr "時間" msgid "Calls" msgstr "呼出ã—" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "オン" @@ -3116,6 +3175,10 @@ msgid "" "Please switch on the 'local to scene' property on it (and all resources " "containing it up to a node)." msgstr "" +"ã“ã®ãƒªã‚½ãƒ¼ã‚¹ã¯ã‚·ãƒ¼ãƒ³ã«å¯¾ã—ã¦ãƒãƒ¼ã‚«ãƒ«ã«è¨å®šã•れã¦ã„ãªã„ãŸã‚ã€ViewportTextureã‚’" +"作æˆã§ãã¾ã›ã‚“。\n" +"'シーンã«ãƒãƒ¼ã‚«ãƒ« 'プãƒãƒ‘ティをオンã«ã—ã¦ãã ã•ã„(ノードã¾ã§ã‚’å«ã‚€ã™ã¹ã¦ã®ãƒª" +"ソース)。" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Pick a Viewport" @@ -3171,6 +3234,11 @@ 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 "æ–°è¦ã‚ー:" @@ -3182,11 +3250,6 @@ msgstr "æ–°è¦ã®å€¤:" msgid "Add Key/Value Pair" msgstr "ã‚ー・値ã®ãƒšã‚¢ã‚’è¿½åŠ " -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "アイテムを除去" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3642,6 +3705,7 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"æ¬¡ã®æ‹¡å¼µåã‚’æŒã¤ãƒ•ァイルをå«ã‚ã¾ã™ã€‚ProjectSettingsã§è¿½åŠ ã¾ãŸã¯å‰Šé™¤ã—ã¾ã™ã€‚" #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3693,6 +3757,7 @@ msgid "Nodes not in Group" msgstr "グループã«ãªã„ノード" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "フィルタノード" @@ -3826,6 +3891,8 @@ msgstr "インãƒãƒ¼ãƒˆã—ãŸãƒ•ァイルã®ã‚¿ã‚¤ãƒ—ã®å¤‰æ›´ã«ã¯ã‚¨ãƒ‡ã‚£ã‚¿ msgid "" "WARNING: Assets exist that use this resource, they may stop loading properly." msgstr "" +"è¦å‘Š:ã“ã®ãƒªã‚½ãƒ¼ã‚¹ã‚’使用ã™ã‚‹ã‚¢ã‚»ãƒƒãƒˆãŒå˜åœ¨ã™ã‚‹ãŸã‚ã€æ£ã—ããƒãƒ¼ãƒ‰ã•れãªã„å¯èƒ½æ€§" +"ãŒã‚りã¾ã™ã€‚" #: editor/inspector_dock.cpp msgid "Failed to load resource." @@ -4042,7 +4109,7 @@ msgstr "パスã®ãƒã‚¤ãƒ³ãƒˆã‚’除去" #: editor/plugins/animation_blend_space_1d_editor.cpp msgid "Move BlendSpace1D Node Point" -msgstr "" +msgstr "BlendSpace1Dノードãƒã‚¤ãƒ³ãƒˆã‚’移動" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp @@ -4490,7 +4557,7 @@ msgstr "終りã«" #: editor/plugins/animation_state_machine_editor.cpp msgid "Travel" -msgstr "" +msgstr "トラベル" #: editor/plugins/animation_state_machine_editor.cpp msgid "Start and end nodes are needed for a sub-transition." @@ -4512,7 +4579,7 @@ msgstr "トランジション ノード" #: editor/plugins/animation_state_machine_editor.cpp msgid "Set Start Node (Autoplay)" -msgstr "" +msgstr "開始ノードã®è¨å®š(自動å†ç”Ÿ)" #: editor/plugins/animation_state_machine_editor.cpp msgid "" @@ -4945,16 +5012,19 @@ 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 "" +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 "Anchors only" @@ -5018,7 +5088,7 @@ msgstr "IKãƒã‚§ãƒ¼ãƒ³ã‚’クリア" msgid "" "Warning: Children of a container get their position and size determined only " "by their parent." -msgstr "" +msgstr "è¦å‘Š:コンテナã®åã®ä½ç½®ã¨ã‚µã‚¤ã‚ºã¯ã€è¦ªã«ã‚ˆã£ã¦ã®ã¿æ±ºå®šã•れã¾ã™ã€‚" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -5178,7 +5248,7 @@ msgstr "ボーンを表示ã™ã‚‹" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make Custom Bone(s) from Node(s)" -msgstr "" +msgstr "ノードã‹ã‚‰ã‚«ã‚¹ã‚¿ãƒ ボーンを作æˆ" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Clear Custom Bones" @@ -5216,7 +5286,7 @@ msgstr "ビューãƒãƒ¼ãƒˆã‚’表示" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Group And Lock Icons" -msgstr "" +msgstr "グループアイコンã¨ãƒãƒƒã‚¯ã‚¢ã‚¤ã‚³ãƒ³ã‚’表示" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5230,19 +5300,19 @@ msgstr "é¸æŠžå¯¾è±¡ã‚’ãƒ•ãƒ¬ãƒ¼ãƒ ã®ä¸å¤®ã«" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "" +msgstr "ã‚ャンãƒã‚¹ã‚¹ã‚±ãƒ¼ãƒ«ã®ãƒ—レビュー" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." -msgstr "" +msgstr "ã‚ーを挿入ã™ã‚‹ãŸã‚ã®å¤‰æ›ãƒžã‚¹ã‚¯ã€‚" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotation mask for inserting keys." -msgstr "" +msgstr "ã‚ーを挿入ã™ã‚‹ãŸã‚ã®å›žè»¢ãƒžã‚¹ã‚¯ã€‚" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Scale mask for inserting keys." -msgstr "" +msgstr "ã‚ーを挿入ã™ã‚‹ãŸã‚ã®ã‚¹ã‚±ãƒ¼ãƒ«ãƒžã‚¹ã‚¯ã€‚" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5256,6 +5326,10 @@ msgid "" "Keys are only added to existing tracks, no new tracks will be created.\n" "Keys must be inserted manually for the first time." msgstr "" +"スケール時ã«ã‚ªãƒ–ジェクトを移動ã€å›žè»¢ã™ã‚‹ã¨ã€è‡ªå‹•çš„ã«ã‚ãƒ¼ãŒæŒ¿å…¥ã•れã¾ã™(マスク" +"ã«åŸºã¥ã)。\n" +"ã‚ãƒ¼ã¯æ—¢å˜ã®ãƒˆãƒ©ãƒƒã‚¯ã«ã®ã¿è¿½åŠ ã•ã‚Œã€æ–°ã—ã„トラックã¯ä½œæˆã•れã¾ã›ã‚“。\n" +"åˆã‚ã¦ã‚ãƒ¼ã‚’æ‰‹å‹•ã§æŒ¿å…¥ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #: editor/plugins/canvas_item_editor_plugin.cpp #, fuzzy @@ -5358,6 +5432,14 @@ msgid "Load Emission Mask" msgstr "発光(Emission)マスクをèªã¿è¾¼ã‚€" #: 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 +#, fuzzy +msgid "Restart" +msgstr "今ã™ãå†èµ·å‹•" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp #, fuzzy msgid "Clear Emission Mask" @@ -5482,7 +5564,7 @@ msgstr "ã‚°ãƒãƒ¼ãƒãƒ«ã‚¤ãƒ«ãƒŸãƒãƒ¼ã‚·ãƒ§ãƒ³ã®äº‹å‰è¨ˆç®—" #: editor/plugins/gradient_editor_plugin.cpp msgid "Gradient Edited" -msgstr "" +msgstr "グラデーション編集" #: editor/plugins/item_list_editor_plugin.cpp msgid "Item %d" @@ -5525,7 +5607,7 @@ msgstr "三角形メッシュ ã®ã‚·ã‚§ã‚¤ãƒ—を生æˆ" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "図形ã®ä½œæˆã«å¤±æ•—ã—ã¾ã—ãŸ!" #: editor/plugins/mesh_instance_editor_plugin.cpp #, fuzzy @@ -5935,12 +6017,12 @@ msgstr "オプション" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Mirror Handle Angles" -msgstr "" +msgstr "ミラーãƒãƒ³ãƒ‰ãƒ«è§’度" #: editor/plugins/path_2d_editor_plugin.cpp #: editor/plugins/path_editor_plugin.cpp msgid "Mirror Handle Lengths" -msgstr "" +msgstr "ミラーãƒãƒ³ãƒ‰ãƒ«ã®é•·ã•" #: editor/plugins/path_editor_plugin.cpp msgid "Curve Point #" @@ -5990,7 +6072,7 @@ msgstr "ジョイントを移動" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "" "The skeleton property of the Polygon2D does not point to a Skeleton2D node" -msgstr "" +msgstr "Polygon2Dã®skeletonプãƒãƒ‘ティãŒSkeleton2Dノードを指ã—ã¦ã„ã¾ã›ã‚“" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Sync Bones" @@ -6012,7 +6094,7 @@ msgstr "UVマップを生æˆ" msgid "" "Polygon 2D has internal vertices, so it can no longer be edited in the " "viewport." -msgstr "" +msgstr "ãƒãƒªã‚´ãƒ³2Dã«ã¯å†…éƒ¨é ‚ç‚¹ãŒã‚ã‚‹ãŸã‚ã€ãƒ“ューãƒãƒ¼ãƒˆã§ç·¨é›†ã§ãã¾ã›ã‚“。" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Create Polygon & UV" @@ -6049,7 +6131,7 @@ msgstr "トランスフォーム" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Paint Bone Weights" -msgstr "" +msgstr "ボーンウェイトをペイント" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Open Polygon 2D UV editor." @@ -6119,11 +6201,11 @@ msgstr "" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Paint weights with specified intensity." -msgstr "" +msgstr "指定ã—ãŸå¼·åº¦ã§ã‚¦ã‚§ã‚¤ãƒˆã‚’ペイントã—ã¾ã™ã€‚" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Unpaint weights with specified intensity." -msgstr "" +msgstr "指定ã—ãŸå¼·åº¦ã§ã‚¦ã‚§ã‚¤ãƒˆã®ãƒšã‚¤ãƒ³ãƒˆã‚’解除ã—ã¾ã™ã€‚" #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Radius:" @@ -6239,7 +6321,7 @@ msgstr "リソースã®ãƒ‘ス" #: editor/plugins/root_motion_editor_plugin.cpp msgid "AnimationTree has no path set to an AnimationPlayer" -msgstr "" +msgstr "AnimationTreeã«ã¯AnimationPlayerã¸ã®ãƒ‘スãŒè¨å®šã•れã¦ã„ã¾ã›ã‚“" #: editor/plugins/root_motion_editor_plugin.cpp msgid "Path to AnimationPlayer is invalid" @@ -6330,10 +6412,20 @@ msgid "Find Next" msgstr "次を検索" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 +#, fuzzy +msgid "Filter methods" +msgstr "フィルターモード:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "ソート" @@ -6450,11 +6542,12 @@ msgstr "Godotã®ã‚ªãƒ³ãƒ©ã‚¤ãƒ³æ–‡æ›¸ã‚’é–‹ã" #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" -msgstr "" +msgstr "ドã‚ãƒ¥ãƒ¡ãƒ³ãƒˆã‚’è¦æ±‚" #: editor/plugins/script_editor_plugin.cpp msgid "Help improve the Godot documentation by giving feedback." msgstr "" +"フィードãƒãƒƒã‚¯ã‚’æä¾›ã—ã¦ã€Godotã®ãƒ‰ã‚ãƒ¥ãƒ¡ãƒ³ãƒˆã®æ”¹å–„ã«å½¹ç«‹ã¦ã¦ãã ã•ã„。" #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6571,20 +6664,24 @@ msgid "Syntax Highlighter" msgstr "シンタックスãƒã‚¤ãƒ©ã‚¤ãƒˆ" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "ブックマーク" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +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 "行を削除" @@ -6719,7 +6816,7 @@ msgstr "メッシュã‹ã‚‰æ”¾å‡ºç‚¹ã‚’生æˆ" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Set Rest Pose to Bones" -msgstr "" +msgstr "ボーンã¸ãƒ¬ã‚¹ãƒˆãƒ»ãƒãƒ¼ã‚ºã‚’è¨å®šã™ã‚‹" #: editor/plugins/skeleton_2d_editor_plugin.cpp #, fuzzy @@ -6728,11 +6825,11 @@ msgstr "スケルトン..." #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Make Rest Pose (From Bones)" -msgstr "" +msgstr "レスト・ãƒãƒ¼ã‚ºã®ä½œæˆ(ボーンã‹ã‚‰)" #: editor/plugins/skeleton_2d_editor_plugin.cpp msgid "Set Bones to Rest Pose" -msgstr "" +msgstr "レスト・ãƒãƒ¼ã‚ºã¸ãƒœãƒ¼ãƒ³ã‚’è¨å®šã™ã‚‹" #: editor/plugins/skeleton_editor_plugin.cpp #, fuzzy @@ -6985,6 +7082,8 @@ 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 "" +"注æ„:表示ã•れるFPS値ã¯ã€ã‚¨ãƒ‡ã‚£ã‚¿ã®ãƒ•レームレートã§ã™ã€‚\n" +"ゲーム内ã®ãƒ‘フォーマンスを確実ã«ç¤ºã™ã‚‚ã®ã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。" #: editor/plugins/spatial_editor_plugin.cpp #, fuzzy @@ -7193,7 +7292,7 @@ msgstr "" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Change" -msgstr "" +msgstr "変æ›ã®å¤‰æ›´" #: editor/plugins/spatial_editor_plugin.cpp #, fuzzy @@ -7211,15 +7310,15 @@ msgstr "縮尺(比):" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Type" -msgstr "" +msgstr "変æ›ã‚¿ã‚¤ãƒ—" #: editor/plugins/spatial_editor_plugin.cpp msgid "Pre" -msgstr "" +msgstr "å‰" #: editor/plugins/spatial_editor_plugin.cpp msgid "Post" -msgstr "" +msgstr "後" #: editor/plugins/spatial_editor_plugin.cpp msgid "Nameless gizmo" @@ -7252,11 +7351,11 @@ msgstr "ä¿å˜ã™ã‚‹ãƒ‘スãŒã‚りã¾ã›ã‚“!" #: editor/plugins/sprite_editor_plugin.cpp msgid "Can't convert a sprite using animation frames to mesh." -msgstr "" +msgstr "アニメーションフレームを使用ã—ã¦ã‚¹ãƒ—ライトをメッシュã«å¤‰æ›ã§ãã¾ã›ã‚“。" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't replace by mesh." -msgstr "" +msgstr "ジオメトリãŒç„¡åйã§ã™ã€‚メッシュã«ç½®ãæ›ãˆã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。" #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7265,7 +7364,7 @@ msgstr "2Dメッシュã«å¤‰æ›" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create polygon." -msgstr "" +msgstr "ジオメトリãŒç„¡åйã§ã™ã€‚ãƒãƒªã‚´ãƒ³ã‚’作æˆã§ãã¾ã›ã‚“。" #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7274,7 +7373,7 @@ msgstr "ãƒãƒªã‚´ãƒ³ã‚’移動" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create collision polygon." -msgstr "" +msgstr "ジオメトリãŒç„¡åйã§ã™ã€‚è¡çªãƒãƒªã‚´ãƒ³ã‚’作æˆã§ãã¾ã›ã‚“。" #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7283,7 +7382,7 @@ msgstr "コリジョン ãƒãƒªã‚´ãƒ³ã‚’生æˆ" #: editor/plugins/sprite_editor_plugin.cpp msgid "Invalid geometry, can't create light occluder." -msgstr "" +msgstr "ジオメトリãŒç„¡åйã§ã™ã€‚ライトオクールダーを作æˆã§ãã¾ã›ã‚“。" #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7296,7 +7395,7 @@ msgstr "スプライト" #: editor/plugins/sprite_editor_plugin.cpp msgid "Simplification: " -msgstr "" +msgstr "簡略化:" #: editor/plugins/sprite_editor_plugin.cpp #, fuzzy @@ -7378,7 +7477,7 @@ msgstr "シーンã‹ã‚‰ã®ãƒŽãƒ¼ãƒ‰" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "スプライトシートã‹ã‚‰ãƒ•ãƒ¬ãƒ¼ãƒ ã‚’è¿½åŠ ã™ã‚‹" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7405,7 +7504,7 @@ msgstr "スタックフレーム" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Horizontal:" -msgstr "" +msgstr "æ°´å¹³:" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy @@ -7569,7 +7668,7 @@ msgstr "" #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "サブメニュー" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -7613,7 +7712,7 @@ msgstr "編集å¯èƒ½ãªå" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "サブツリー" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -7672,7 +7771,7 @@ msgstr "ç‰é€Ÿ" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Rectangle Paint" -msgstr "" +msgstr "矩形ペイント" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Bucket Fill" @@ -7694,11 +7793,11 @@ msgstr "転置" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Mirror X" -msgstr "" +msgstr "ミラーX" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Mirror Y" -msgstr "" +msgstr "ミラーY" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -7719,6 +7818,8 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift+å³ãƒžã‚¦ã‚¹ãƒœã‚¿ãƒ³:ç·šã®æç”»\n" +"Shift+Ctrl+å³ãƒžã‚¦ã‚¹ãƒœã‚¿ãƒ³:矩形ペイント" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" @@ -7736,11 +7837,11 @@ msgstr "å³ã«ç§»å‹•" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Flip Horizontally" -msgstr "" +msgstr "å·¦å³å転" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Flip Vertically" -msgstr "" +msgstr "上下å転" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -7772,7 +7873,7 @@ msgstr "次ã®åºŠé¢" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select the next shape, subtile, or Tile." -msgstr "" +msgstr "次ã®ã‚·ã‚§ã‚¤ãƒ—ã€ã‚µãƒ–タイルã€ã¾ãŸã¯ã‚¿ã‚¤ãƒ«ã‚’é¸æŠžã—ã¾ã™ã€‚" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -7781,7 +7882,7 @@ msgstr "å‰ã®åºŠé¢" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Select the previous shape, subtile, or Tile." -msgstr "" +msgstr "å‰ã®ã‚·ã‚§ã‚¤ãƒ—ã€ã‚µãƒ–タイルã€ã¾ãŸã¯ã‚¿ã‚¤ãƒ«ã‚’é¸æŠžã—ã¾ã™ã€‚" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -7825,7 +7926,7 @@ msgstr "パンモード" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." -msgstr "" +msgstr "ビットマスクをコピー。" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Paste bitmask." @@ -7870,6 +7971,7 @@ 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 #, fuzzy @@ -7922,12 +8024,17 @@ msgid "" "bindings.\n" "Click on another Tile to edit it." msgstr "" +"アイコンã¨ã—ã¦ä½¿ç”¨ã™ã‚‹ã‚µãƒ–ã‚¿ã‚¤ãƒ«ã‚’é¸æŠžã—ã¦ãã ã•ã„。ã“れã¯ç„¡åйãªè‡ªå‹•タイルãƒ" +"インドã«ã‚‚使用ã•れã¾ã™ã€‚\n" +"別ã®ã‚¿ã‚¤ãƒ«ã‚’クリックã—ã¦ç·¨é›†ã—ã¾ã™ã€‚" #: editor/plugins/tile_set_editor_plugin.cpp msgid "" "Select sub-tile to change its priority.\n" "Click on another Tile to edit it." msgstr "" +"優先度を変更ã™ã‚‹ã‚µãƒ–ã‚¿ã‚¤ãƒ«ã‚’é¸æŠžã—ã¾ã™ã€‚\n" +"別ã®ã‚¿ã‚¤ãƒ«ã‚’クリックã—ã¦ç·¨é›†ã—ã¾ã™ã€‚" #: editor/plugins/tile_set_editor_plugin.cpp #, fuzzy @@ -8007,7 +8114,7 @@ msgstr "タイル プãƒãƒ‘ティを編集" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Edit Tile Z Index" -msgstr "" +msgstr "タイルã®Zインデックスを編集" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Create Collision Polygon" @@ -8048,7 +8155,7 @@ msgstr "インスペクタ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "ブール" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8057,7 +8164,7 @@ msgstr "å…¥åŠ›ã‚’è¿½åŠ " #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "出力ãƒãƒ¼ãƒˆã‚’è¿½åŠ " #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8125,7 +8232,7 @@ msgstr "ノードを削除" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Visual Shader Input Type Changed" -msgstr "" +msgstr "ビジュアルシェーダã®å…¥åŠ›ã‚¿ã‚¤ãƒ—ãŒå¤‰æ›´ã•れã¾ã—ãŸ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Vertex" @@ -8162,11 +8269,11 @@ msgstr "関数を作æˆ" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "HSVベクトルをRGBベクトルã«å¤‰æ›ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "RGBベクトルをHSVベクトルã«å¤‰æ›ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8225,11 +8332,14 @@ msgid "" "Returns an associated vector if the provided scalars are equal, greater or " "less." msgstr "" +"指定ã•れãŸã‚¹ã‚«ãƒ©ãƒ¼ãŒç‰ã—ã„ã‹ã€ã‚ˆã‚Šå¤§ãã„ã‹ã€ã¾ãŸã¯ã‚ˆã‚Šå°ã•ã„å ´åˆã€é–¢é€£ä»˜ã‘ら" +"れãŸãƒ™ã‚¯ãƒˆãƒ«ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided boolean value is true or false." msgstr "" +"指定ã•れãŸãƒ–ール値ãŒtrueã¾ãŸã¯falseã®å ´åˆã€é–¢é€£ä»˜ã‘られãŸãƒ™ã‚¯ãƒˆãƒ«ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8241,51 +8351,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8294,203 +8360,27 @@ msgid "Input parameter." msgstr "親ã«ã‚¹ãƒŠãƒƒãƒ—" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8537,145 +8427,145 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "パラメータã®çµ¶å¯¾å€¤ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "パラメータã®é€†ã‚³ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ç·šé€†ã‚³ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "パラメータã®é€†ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ç·šé€†ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "パラメータã®é€†ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "複数パラメータã®é€†ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ç·šé€†ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ä»¥ä¸Šã®æœ€ã‚‚è¿‘ã„æ•´æ•°ã‚’検索ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "値をã•らã«2ã¤ã®å€¤ã®é–“ã«ã‚るよã†ã«åˆ¶ç´„ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "パラメータã®ã‚³ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ç·šã‚³ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "ラジアンå˜ä½ã®æ•°é‡ã‚’度ã«å¤‰æ›ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "ベースe指数。" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "2を底ã¨ã™ã‚‹æŒ‡æ•°ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ä»¥ä¸‹ã®æœ€ã‚‚è¿‘ã„æ•´æ•°ã‚’検索ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "引数ã®å°æ•°éƒ¨ã‚’計算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "パラメータã®å¹³æ–¹æ ¹ã®é€†æ•°ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "自然対数。" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "2を底ã¨ã™ã‚‹å¯¾æ•°ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "2ã¤ã®å€¤ã®ã†ã¡å¤§ãã„æ–¹ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "2ã¤ã®å€¤ã®ã†ã¡å°ã•ã„æ–¹ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "2ã¤ã®ã‚¹ã‚«ãƒ©é–“ã®ãƒªãƒ‹ã‚¢è£œé–“。" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "パラメータã®å対ã®å€¤ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - スカラー" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." -msgstr "" +msgstr "最åˆã®ãƒ‘ラメータã®å€¤ã‚’2ã®ã¹ãä¹—ã§è¿”ã—ãŸå€¤ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "度å˜ä½ã®é‡ã‚’ラジアンã«å¤‰æ›ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / スカラー" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(GLES3ã®ã¿)ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã«æœ€ã‚‚è¿‘ã„æ•´æ•°ã‚’検索ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(GLES3ã®ã¿)ãƒ‘ãƒ©ãƒ¡ãƒ¼ã‚¿ã«æœ€ã‚‚è¿‘ã„å¶æ•°ã®æ•´æ•°ã‚’検索ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "値を0.0ã‹ã‚‰1.0ã®é–“ã«å›ºå®šã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "パラメータã®ç¬¦å·ã‚’抽出ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "パラメータã®ç¬¦å·ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ã‚µã‚¤ãƒ³ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "パラメータã®å¹³æ–¹æ ¹ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8685,6 +8575,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep関数(scalar(エッジ0)ã€scalar(エッジ1)ã€scalar (x))。\n" +"\n" +"'x' ㌠'edge0' よりå°ã•ã„å ´åˆã¯0.0ã‚’è¿”ã—ã€x㌠'edge1' より大ãã„å ´åˆã¯1.0ã‚’è¿”" +"ã—ã¾ã™ã€‚ãれ以外ã®å ´åˆã€æˆ»ã‚Šå€¤ã¯ã‚¨ãƒ«ãƒŸãƒ¼ãƒˆå¤šé …å¼ã‚’使用ã—ã¦0.0ã¨1.0ã®é–“ã§è£œé–“" +"ã•れã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8692,38 +8587,41 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Step関数( scalar(edge)ã€scalar(x))。\n" +"\n" +"'x' ㌠'edge' よりå°ã•ã„å ´åˆã¯0.0ã‚’è¿”ã—ã€ãれ以外ã®å ´åˆã¯1.0ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "パラメータã®ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(GLES3ã®ã¿)パラメータã®åŒæ›²ã‚¿ãƒ³ã‚¸ã‚§ãƒ³ãƒˆã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." -msgstr "" +msgstr "(GLES3ã®ã¿)パラメータã®ãƒˆãƒ©ãƒ³ã‚±ãƒ¼ãƒˆã•れãŸå€¤ã‚’検索ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "スカラーã«ã‚¹ã‚«ãƒ©ãƒ¼ã‚’è¿½åŠ ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "スカラーをスカラーã§é™¤ç®—ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "スカラーをスカラーã§ä¹—ç®—ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "2ã¤ã®ã‚¹ã‚«ãƒ©ãƒ¼ã®æ®‹ã‚Šã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "スカラーã‹ã‚‰ã‚¹ã‚«ãƒ©ãƒ¼ã‚’減算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8737,11 +8635,11 @@ msgstr "スカラUniformを変更" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "立体テクスãƒãƒ£ãƒ»ãƒ«ãƒƒã‚¯ã‚¢ãƒƒãƒ—を実行ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the texture lookup." -msgstr "" +msgstr "テクスãƒãƒ£ãƒ»ãƒ«ãƒƒã‚¯ã‚¢ãƒƒãƒ—を実行ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8768,34 +8666,40 @@ msgid "" "whose number of rows is the number of components in 'c' and whose number of " "columns is the number of components in 'r'." msgstr "" +"(GLES3ã®ã¿)ベクトルã®ãƒšã‚¢ã®å¤–ç©ã‚’計算ã—ã¾ã™ã€‚\n" +"\n" +"OuterProductã¯ã€æœ€åˆã®ãƒ‘ラメータ 'c' を列ベクトル(1列ã®è¡Œåˆ—)ã¨ã—ã¦ã€2番目ã®ãƒ‘" +"ラメータ 'r' を行ベクトル(1行ã®è¡Œåˆ—)ã¨ã—ã¦å‡¦ç†ã—ã€ç·šå½¢ä»£æ•°è¡Œåˆ—ä¹—ç®— 'c * r' ã‚’" +"実行ã—ã¦ã€è¡Œã®æ•°ãŒ 'c' ã®ã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆã®æ•°ã§ã€åˆ—ã®æ•°ãŒ 'r' ã®ã‚³ãƒ³ãƒãƒ¼ãƒãƒ³ãƒˆ" +"ã®æ•°ã§ã‚る行列を生æˆã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes transform from four vectors." -msgstr "" +msgstr "4ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«ã‹ã‚‰å¤‰æ›ã‚’作æˆã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes transform to four vectors." -msgstr "" +msgstr "変æ›ã‚’4ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«ã«åˆ†è§£ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the determinant of a transform." -msgstr "" +msgstr "(GLES3ã®ã¿)変æ›ã®è¡Œåˆ—å¼ã‚’計算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the inverse of a transform." -msgstr "" +msgstr "(GLES3ã®ã¿)変æ›ã®é€†é–¢æ•°ã‚’計算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the transpose of a transform." -msgstr "" +msgstr "(GLES3ã®ã¿)変æ›ã®è»¢ç½®ã‚’計算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies transform by transform." -msgstr "" +msgstr "変æ›ã§å¤‰æ›ã‚’ä¹—ç®—ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by transform." -msgstr "" +msgstr "変æ›ã§ãƒ™ã‚¯ãƒˆãƒ«ã‚’ä¹—ç®—ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8819,23 +8723,23 @@ msgstr "ベクトル演算åを変更" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "3ã¤ã®ã‚¹ã‚«ãƒ©ãƒ¼ã‹ã‚‰ãƒ™ã‚¯ãƒˆãƒ«ã‚’作æˆã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "ベクトルã‹ã‚‰3ã¤ã®ã‚¹ã‚«ãƒ©ãƒ¼ã‚’作æˆã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "2ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«ã®å¤–ç©ã‚’計算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "2点間ã®è·é›¢ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "2ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«ã®å†…ç©ã‚’計算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8844,36 +8748,40 @@ msgid "" "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 "" +"å‚照ベクトルã¨åŒã˜æ–¹å‘を指ã™ãƒ™ã‚¯ãƒˆãƒ«ã‚’è¿”ã—ã¾ã™ã€‚ ã“ã®é–¢æ•°ã«ã¯3ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«ãƒ‘" +"ラメータãŒã‚りã¾ã™ã€‚Nã¯é…å‘ã™ã‚‹ãƒ™ã‚¯ãƒˆãƒ«ã€Iã¯å…¥å°„ベクトルã€Nrefã¯å‚照ベクトル" +"ã§ã™ã€‚ Iã¨Nrefã®å†…ç©ãŒ0よりå°ã•ã„å ´åˆã€æˆ»ã‚Šå€¤ã¯Nã§ã™ã€‚ãれ以外ã®å ´åˆã€-NãŒè¿”" +"ã•れã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "ベクトルã®é•·ã•を計算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "2ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«é–“ã®ãƒªãƒ‹ã‚¢è£œé–“。" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." -msgstr "" +msgstr "ãƒ™ã‚¯ãƒˆãƒ«ã®æ£è¦åŒ–ç©ã‚’計算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - vector" -msgstr "" +msgstr "1.0 - ベクトル" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / vector" -msgstr "" +msgstr "1.0 / ベクトル" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns a vector that points in the direction of reflection ( a : incident " "vector, b : normal vector )." -msgstr "" +msgstr "åå°„ã®æ–¹å‘(a:入射ベクトルã€b:法線ベクトル)を指ã™ãƒ™ã‚¯ãƒˆãƒ«ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns a vector that points in the direction of refraction." -msgstr "" +msgstr "å±ˆæŠ˜ã®æ–¹å‘を指ã™ãƒ™ã‚¯ãƒˆãƒ«ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8883,6 +8791,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep関数(vector(エッジ0)ã€vector(エッジ1)ã€vector (x))。\n" +"\n" +"'x' ㌠'edge0' よりå°ã•ã„å ´åˆã¯0.0ã‚’è¿”ã—ã€x㌠'edge1' より大ãã„å ´åˆã¯1.0ã‚’è¿”" +"ã—ã¾ã™ã€‚ãれ以外ã®å ´åˆã€æˆ»ã‚Šå€¤ã¯ã‚¨ãƒ«ãƒŸãƒ¼ãƒˆå¤šé …å¼ã‚’使用ã—ã¦0.0ã¨1.0ã®é–“ã§è£œé–“" +"ã•れã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8892,6 +8805,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep関数(scalar(エッジ0)ã€scalar(エッジ1)ã€vector (x))。\n" +"\n" +"'x' ㌠'edge0' よりå°ã•ã„å ´åˆã¯0.0ã‚’è¿”ã—ã€x㌠'edge1' より大ãã„å ´åˆã¯1.0ã‚’è¿”" +"ã—ã¾ã™ã€‚ãれ以外ã®å ´åˆã€æˆ»ã‚Šå€¤ã¯ã‚¨ãƒ«ãƒŸãƒ¼ãƒˆå¤šé …å¼ã‚’使用ã—ã¦0.0ã¨1.0ã®é–“ã§è£œé–“" +"ã•れã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8899,6 +8817,9 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Step関数( vector(edge)ã€vector(x))。\n" +"\n" +"'x' ㌠'edge' よりå°ã•ã„å ´åˆã¯0.0ã‚’è¿”ã—ã€ãれ以外ã®å ´åˆã¯1.0ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8906,26 +8827,29 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Step関数( scalar(edge)ã€vector(x))。\n" +"\n" +"'x' ㌠'edge' よりå°ã•ã„å ´åˆã¯0.0ã‚’è¿”ã—ã€ãれ以外ã®å ´åˆã¯1.0ã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." -msgstr "" +msgstr "ベクトルã«ãƒ™ã‚¯ãƒˆãƒ«ã‚’åŠ ç®—ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "" +msgstr "ベクトルã§ãƒ™ã‚¯ãƒˆãƒ«ã‚’除算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." -msgstr "" +msgstr "ベクトルã§ãƒ™ã‚¯ãƒˆãƒ«ã‚’ä¹—ç®—ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two vectors." -msgstr "" +msgstr "2ã¤ã®ãƒ™ã‚¯ãƒˆãƒ«ã®æ®‹ã‚Šã‚’è¿”ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts vector from vector." -msgstr "" +msgstr "ベクトルã«ãƒ™ã‚¯ãƒˆãƒ«ã‚’減算ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8943,56 +8867,73 @@ msgid "" "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 "" +"カスタムã®Godotシェーダ言語å¼ã€‚カスタムã®é‡ã®å…¥å‡ºåŠ›ãƒãƒ¼ãƒˆã‚’æŒã¡ã¾ã™ã€‚ ã“れã¯" +"vertex / fragment / light関数ã¸ã®ã‚³ãƒ¼ãƒ‰ã®ç›´æŽ¥æ³¨å…¥ã§ã™ã€‚内部ã§é–¢æ•°å®£è¨€ã‚’書ããŸ" +"ã‚ã«ãれを使用ã—ãªã„ã§ãã ã•ã„。" #: 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 "(GLES3 only) (Fragment/Light mode only) Scalar derivative function." -msgstr "" +msgstr "(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)スカラー導関数。" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function." -msgstr "" +msgstr "(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)ベクトル導関数。" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using " "local differencing." msgstr "" +"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(ベクトル)ãƒãƒ¼ã‚«ãƒ«å·®åˆ†ã‚’使用ã—㦠" +"'x' ã§å¾®åˆ†ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using " "local differencing." msgstr "" +"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(スカラー)ãƒãƒ¼ã‚«ãƒ«å·®åˆ†ã‚’使用ã—㦠" +"'x' ã§å¾®åˆ†ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using " "local differencing." msgstr "" +"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(ベクトル)ãƒãƒ¼ã‚«ãƒ«å·®åˆ†ã‚’使用ã—㦠" +"'y' ã§å¾®åˆ†ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using " "local differencing." msgstr "" +"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(スカラー)ãƒãƒ¼ã‚«ãƒ«å·®åˆ†ã‚’使用ã—㦠" +"'y' ã§å¾®åˆ†ã—ã¾ã™ã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(ベクトル) 'x' 㨠'y' ã®çµ¶å¯¾å°Žé–¢æ•°" +"ã®åˆè¨ˆã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(GLES3ã®ã¿)(フラグメント/ライトモードã®ã¿)(スカラー) 'x' 㨠'y' ã®çµ¶å¯¾å°Žé–¢æ•°" +"ã®åˆè¨ˆã€‚" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -9150,15 +9091,15 @@ msgstr "圧縮" #: editor/project_export.cpp msgid "Encrypted (Provide Key Below)" -msgstr "" +msgstr "æš—å·åŒ–(下ã«ã‚ーを入力)" #: editor/project_export.cpp msgid "Invalid Encryption Key (must be 64 characters long)" -msgstr "" +msgstr "ç„¡åŠ¹ãªæš—å·åŒ–ã‚ー(64æ–‡å—ã§ã‚ã‚‹å¿…è¦ãŒã‚りã¾ã™)" #: editor/project_export.cpp msgid "Script Encryption Key (256-bits as hex):" -msgstr "" +msgstr "スクリプト暗å·åŒ–ã‚ー(16進数ã§256ビット):" #: editor/project_export.cpp msgid "Export PCK/Zip" @@ -9390,6 +9331,8 @@ msgid "" "The project settings were created by a newer engine version, whose settings " "are not compatible with this version." msgstr "" +"プãƒã‚¸ã‚§ã‚¯ãƒˆè¨å®šã¯ã€ã“ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã¨äº’æ›æ€§ã®ãªã„æ–°ã—ã„ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ã‚¨ãƒ³ã‚¸ãƒ³ã§" +"作æˆã•れã¦ã„ã¾ã™ã€‚" #: editor/project_manager.cpp #, fuzzy @@ -9407,6 +9350,8 @@ msgid "" "Can't run project: Assets need to be imported.\n" "Please edit the project to trigger the initial import." msgstr "" +"プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’実行ã§ãã¾ã›ã‚“:アセットをインãƒãƒ¼ãƒˆã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚\n" +"プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’編集ã—ã¦åˆæœŸã‚¤ãƒ³ãƒãƒ¼ãƒˆã‚’é–‹å§‹ã—ã¦ãã ã•ã„。" #: editor/project_manager.cpp #, fuzzy @@ -9451,6 +9396,8 @@ msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." msgstr "" +"æ—¢å˜ã®Godotプãƒã‚¸ã‚§ã‚¯ãƒˆã®%sフォルダをスã‚ャンã—ã¾ã™ã‹?\n" +"ã“れã«ã¯ã—ã°ã‚‰ã時間ãŒã‹ã‹ã‚Šã¾ã™ã€‚" #: editor/project_manager.cpp msgid "Project Manager" @@ -9525,6 +9472,8 @@ msgid "" "Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'" msgstr "" +"アクションåãŒç„¡åйã§ã™ã€‚空ã«ã—ãŸã‚Šã€ã€Œ/ ã€ã€ã€Œ: ã€ã€ã€Œ= ã€ã€ã€Œ\\ ã€ã‚’å«ã‚ã‚‹ã“" +"ã¨ã¯ã§ãã¾ã›ã‚“" #: editor/project_settings_editor.cpp #, fuzzy @@ -9684,7 +9633,7 @@ msgstr "プãƒãƒ‘ティ:" #: editor/project_settings_editor.cpp msgid "Setting '%s' is internal, and it can't be deleted." -msgstr "" +msgstr "è¨å®š 'ï¼…s'ã¯å†…部的ãªã‚‚ã®ã§ã‚りã€å‰Šé™¤ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。" #: editor/project_settings_editor.cpp msgid "Delete Item" @@ -9713,7 +9662,7 @@ msgstr "è¨å®šã®ä¿å˜ã«æˆåŠŸã—ã¾ã—ãŸ." #: editor/project_settings_editor.cpp msgid "Override for Feature" -msgstr "" +msgstr "機能ã®ã‚ªãƒ¼ãƒãƒ¼ãƒ©ã‚¤ãƒ‰" #: editor/project_settings_editor.cpp msgid "Add Translation" @@ -9754,7 +9703,7 @@ msgstr "ブレンドã™ã‚‹æ™‚間を変更" #: editor/project_settings_editor.cpp msgid "Changed Locale Filter Mode" -msgstr "" +msgstr "ãƒã‚±ãƒ¼ãƒ«ãƒ•ィルタモードã®å¤‰æ›´" #: editor/project_settings_editor.cpp msgid "Project Settings (project.godot)" @@ -9787,7 +9736,7 @@ msgstr "アクション" #: editor/project_settings_editor.cpp msgid "Deadzone" -msgstr "" +msgstr "デッドゾーン" #: editor/project_settings_editor.cpp msgid "Device:" @@ -9914,7 +9863,7 @@ msgstr "PVRTCツールを実行ã§ãã¾ã›ã‚“ã§ã—ãŸ:" #: editor/pvrtc_compress.cpp msgid "Can't load back converted image using PVRTC tool:" -msgstr "" +msgstr "PVRTCツールを使用ã—ã¦å¤‰æ›ã•れãŸã‚¤ãƒ¡ãƒ¼ã‚¸ã‚’å…ƒã«æˆ»ã™ã“ã¨ãŒã§ãã¾ã›ã‚“:" #: editor/rename_dialog.cpp editor/scene_tree_dock.cpp #, fuzzy @@ -9936,7 +9885,7 @@ msgstr "アニメーションã®ã‚ªãƒ—ション" #: editor/rename_dialog.cpp msgid "Substitute" -msgstr "" +msgstr "代替" #: editor/rename_dialog.cpp msgid "Node name" @@ -9944,7 +9893,7 @@ msgstr "ノードå" #: editor/rename_dialog.cpp msgid "Node's parent name, if available" -msgstr "" +msgstr "ノードã®è¦ªã®åå‰ (使用å¯èƒ½ãªå ´åˆ)" #: editor/rename_dialog.cpp #, fuzzy @@ -9964,18 +9913,20 @@ msgid "" "Sequential integer counter.\n" "Compare counter options." msgstr "" +"シーケンシャル整数カウンタ。\n" +"カウンタオプションを比較ã—ã¾ã™ã€‚" #: editor/rename_dialog.cpp msgid "Per Level counter" -msgstr "" +msgstr "レベルã”ã¨ã®ã‚«ã‚¦ãƒ³ã‚¿" #: editor/rename_dialog.cpp msgid "If set the counter restarts for each group of child nodes" -msgstr "" +msgstr "è¨å®šã™ã‚‹ã¨ã€åノードã®ã‚°ãƒ«ãƒ¼ãƒ—ã”ã¨ã«ã‚«ã‚¦ãƒ³ã‚¿ãŒå†èµ·å‹•ã—ã¾ã™" #: editor/rename_dialog.cpp msgid "Initial value for the counter" -msgstr "" +msgstr "カウンタã®åˆæœŸå€¤" #: editor/rename_dialog.cpp msgid "Step" @@ -9983,7 +9934,7 @@ msgstr "ステップ" #: editor/rename_dialog.cpp msgid "Amount by which counter is incremented for each node" -msgstr "" +msgstr "å„ノードã®ã‚«ã‚¦ãƒ³ã‚¿ã®å¢—分é‡" #: editor/rename_dialog.cpp msgid "Padding" @@ -9994,6 +9945,8 @@ msgid "" "Minimum number of digits for the counter.\n" "Missing digits are padded with leading zeros." msgstr "" +"ã‚«ã‚¦ãƒ³ã‚¿ã®æœ€å°æ¡æ•°ã€‚\n" +"æ¬ è½ã—ãŸæ•°å—ã¯ã€å…ˆé ã«ã‚¼ãƒãŒåŸ‹ã‚è¾¼ã¾ã‚Œã¾ã™ã€‚" #: editor/rename_dialog.cpp #, fuzzy @@ -10006,7 +9959,7 @@ msgstr "ãƒã‚¹ãƒˆãƒ—ãƒã‚»ã‚¹" #: editor/rename_dialog.cpp msgid "Keep" -msgstr "" +msgstr "ä¿æŒ" #: editor/rename_dialog.cpp msgid "CamelCase to under_scored" @@ -10018,7 +9971,7 @@ msgstr "" #: editor/rename_dialog.cpp msgid "Case" -msgstr "" +msgstr "ケース" #: editor/rename_dialog.cpp msgid "To Lowercase" @@ -10042,11 +9995,11 @@ msgstr "親ノードを変更" #: editor/reparent_dialog.cpp msgid "Reparent Location (Select new Parent):" -msgstr "" +msgstr "親を変更(æ–°ã—ã„è¦ªã‚’é¸æŠž):" #: editor/reparent_dialog.cpp msgid "Keep Global Transform" -msgstr "" +msgstr "ã‚°ãƒãƒ¼ãƒãƒ«å¤‰æ›ã‚’ä¿æŒ" #: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp msgid "Reparent" @@ -10075,7 +10028,7 @@ msgstr "シーン実行ã®è¨å®š" #: editor/scene_tree_dock.cpp msgid "No parent to instance the scenes at." -msgstr "" +msgstr "シーンをインスタンス化ã™ã‚‹è¦ªãŒã‚りã¾ã›ã‚“。" #: editor/scene_tree_dock.cpp #, fuzzy @@ -10125,14 +10078,15 @@ 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 "" +msgstr "ルートã«ã™ã‚‹ã«ã¯ã€ãƒŽãƒ¼ãƒ‰ãŒç·¨é›†ã•れãŸã‚·ãƒ¼ãƒ³ã«å±žã—ã¦ã„ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #: editor/scene_tree_dock.cpp msgid "Instantiated scenes can't become root" -msgstr "" +msgstr "インスタンス化ã•れãŸã‚·ãƒ¼ãƒ³ã¯ãƒ«ãƒ¼ãƒˆã«ã§ãã¾ã›ã‚“" #: editor/scene_tree_dock.cpp #, fuzzy @@ -10162,6 +10116,8 @@ msgid "" "Disabling \"editable_instance\" will cause all properties of the node to be " "reverted to their default." msgstr "" +"\"editable_instance\" を無効ã«ã™ã‚‹ã¨ã€ãƒŽãƒ¼ãƒ‰ã®ã™ã¹ã¦ã®ãƒ—ãƒãƒ‘ティãŒãƒ‡ãƒ•ォルト" +"ã«æˆ»ã‚Šã¾ã™ã€‚" #: editor/scene_tree_dock.cpp msgid "Editable Children" @@ -10169,7 +10125,7 @@ msgstr "編集å¯èƒ½ãªå" #: editor/scene_tree_dock.cpp msgid "Load As Placeholder" -msgstr "" +msgstr "プレースホルダーã¨ã—ã¦ãƒãƒ¼ãƒ‰" #: editor/scene_tree_dock.cpp #, fuzzy @@ -10256,6 +10212,11 @@ msgstr "åãƒŽãƒ¼ãƒ‰ã‚’è¿½åŠ " #: editor/scene_tree_dock.cpp #, fuzzy +msgid "Expand/Collapse All" +msgstr "ã™ã¹ã¦æŠ˜ã‚ŠãŸãŸã‚€" + +#: editor/scene_tree_dock.cpp +#, fuzzy msgid "Change Type" msgstr "åž‹(type)を変更" @@ -10284,7 +10245,8 @@ msgid "Delete (No Confirm)" msgstr "削除 (確èªãªã—)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "æ–°ã—ã„ãƒŽãƒ¼ãƒ‰ã‚’è¿½åŠ /生æˆ" #: editor/scene_tree_dock.cpp @@ -10397,6 +10359,8 @@ msgid "" "AnimationPlayer is pinned.\n" "Click to unpin." msgstr "" +"AnimationPlayerãŒå›ºå®šã•れã¾ã™ã€‚\n" +"クリックã—ã¦å›ºå®šã‚’解除ã—ã¾ã™ã€‚" #: editor/scene_tree_editor.cpp msgid "Invalid node name, the following characters are not allowed:" @@ -10560,7 +10524,7 @@ msgstr "スタックトレース" msgid "Pick one or more items from the list to display the graph." msgstr "グラフを表示ã™ã‚‹ã«ã¯ã€ãƒªã‚¹ãƒˆã‹ã‚‰ã‚¢ã‚¤ãƒ†ãƒ ã‚’1ã¤ä»¥ä¸Šé¸ã‚“ã§ãã ã•ã„。" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "エラー" @@ -10645,15 +10609,15 @@ msgstr "クリックã•れãŸã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ«ã®ã‚¿ã‚¤ãƒ—:" #: editor/script_editor_debugger.cpp msgid "Live Edit Root:" -msgstr "" +msgstr "ルートã®ãƒ©ã‚¤ãƒ–編集:" #: editor/script_editor_debugger.cpp msgid "Set From Tree" -msgstr "" +msgstr "ツリーã‹ã‚‰è¨å®š" #: editor/script_editor_debugger.cpp msgid "Export measures as CSV" -msgstr "" +msgstr "数値データをCSVã¨ã—ã¦ã‚¨ã‚¯ã‚¹ãƒãƒ¼ãƒˆ" #: editor/settings_config_dialog.cpp #, fuzzy @@ -10676,7 +10640,7 @@ msgstr "ショートカット" #: editor/settings_config_dialog.cpp msgid "Binding" -msgstr "" +msgstr "ãƒã‚¤ãƒ³ãƒ‰" #: editor/spatial_editor_gizmos.cpp msgid "Change Light Radius" @@ -10684,7 +10648,7 @@ msgstr "å…‰æºã®åŠå¾„を変更" #: editor/spatial_editor_gizmos.cpp msgid "Change AudioStreamPlayer3D Emission Angle" -msgstr "" +msgstr "AudioStreamPlayer3Dã®æ”¾å°„角度を変更ã™ã‚‹" #: editor/spatial_editor_gizmos.cpp msgid "Change Camera FOV" @@ -10705,7 +10669,7 @@ msgstr "パーティクルã®è»¸å¹³è¡Œå¢ƒç•Œãƒœãƒƒã‚¯ã‚¹ã‚’変更" #: editor/spatial_editor_gizmos.cpp msgid "Change Probe Extents" -msgstr "" +msgstr "プãƒãƒ¼ãƒ–ã®ç¯„囲を変更" #: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp #, fuzzy @@ -10739,7 +10703,7 @@ msgstr "カプセル形状ã®é«˜ã•変更" #: editor/spatial_editor_gizmos.cpp msgid "Change Ray Shape Length" -msgstr "" +msgstr "レイシェイプã®é•·ã•を変更" #: modules/csg/csg_gizmos.cpp #, fuzzy @@ -10763,11 +10727,11 @@ msgstr "å…‰æºã®åŠå¾„を変更" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Select the dynamic library for this entry" -msgstr "" +msgstr "ã“ã®ã‚¨ãƒ³ãƒˆãƒªã®ãƒ€ã‚¤ãƒŠãƒŸãƒƒã‚¯ãƒ©ã‚¤ãƒ–ãƒ©ãƒªã‚’é¸æŠžã—ã¦ãã ã•ã„" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Select dependencies of the library for this entry" -msgstr "" +msgstr "ã“ã®ã‚¨ãƒ³ãƒˆãƒªã®ãƒ©ã‚¤ãƒ–ラリã®ä¾å˜é–¢ä¿‚ã‚’é¸æŠžã—ã¦ãã ã•ã„" #: modules/gdnative/gdnative_library_editor_plugin.cpp #, fuzzy @@ -10792,7 +10756,7 @@ msgstr "ダイナミック ライブラリ" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "Add an architecture entry" -msgstr "" +msgstr "アーã‚テクãƒãƒ£ã‚¨ãƒ³ãƒˆãƒªã‚’è¿½åŠ ã™ã‚‹" #: modules/gdnative/gdnative_library_editor_plugin.cpp msgid "GDNativeLibrary" @@ -10800,7 +10764,7 @@ msgstr "GDNative ライブラリ" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Enabled GDNative Singleton" -msgstr "" +msgstr "有効ãªGDNative Singleton" #: modules/gdnative/gdnative_library_singleton_editor.cpp #, fuzzy @@ -10876,7 +10840,7 @@ msgstr "以å‰ã®ã‚¿ãƒ–" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Plane:" -msgstr "" +msgstr "å¹³é¢:" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Next Floor" @@ -10926,11 +10890,11 @@ msgstr "無効" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Above" -msgstr "" +msgstr "上クリップ" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clip Below" -msgstr "" +msgstr "下クリップ" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Edit X Axis" @@ -10973,7 +10937,7 @@ msgstr "" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Cursor Clear Rotation" -msgstr "" +msgstr "カーソル回転をクリア" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "Clear Selection" @@ -10995,61 +10959,11 @@ msgstr "インスタンス:" #: modules/mono/csharp_script.cpp msgid "Class name can't be a reserved keyword" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Generating solution..." -msgstr "八分木テクスãƒãƒ£ã‚’生æˆ" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "C#プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’生æˆã—ã¦ã„ã¾ã™â€¦" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "アウトラインを生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ!" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "ソリューションã®ä¿å˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "完了" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "C#プãƒã‚¸ã‚§ã‚¯ãƒˆã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "C#ã®ã‚µãƒãƒ¼ãƒˆã«ã¤ã„ã¦" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "C#ソリューションを生æˆ" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "ビルド" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’ビルド" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "ãƒã‚°ã‚’表示" +msgstr "クラスåを予約ã‚ーワードã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“" #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" -msgstr "" +msgstr "内部例外スタックトレースã®çµ‚了" #: modules/recast/navigation_mesh_editor_plugin.cpp msgid "Bake NavMesh" @@ -11129,6 +11043,7 @@ msgid "" "Node yielded, but did not return a function state in the first working " "memory." msgstr "" +"ノードã¯ç”Ÿæˆã—ã¾ã—ãŸãŒã€æœ€åˆã®ä½œæ¥ãƒ¡ãƒ¢ãƒªãƒ¼ã«é–¢æ•°çŠ¶æ…‹ã‚’è¿”ã—ã¾ã›ã‚“ã§ã—ãŸã€‚" #: modules/visual_script/visual_script.cpp #, fuzzy @@ -11261,7 +11176,7 @@ msgstr "Ctrlã‚ãƒ¼ã‚’ä¿æŒã—ã¦å¤‰æ•°ã®setterã‚’è½ã¨ã™." #: modules/visual_script/visual_script_editor.cpp msgid "Add Preload Node" -msgstr "" +msgstr "プリãƒãƒ¼ãƒ‰ãƒŽãƒ¼ãƒ‰ã‚’è¿½åŠ " #: modules/visual_script/visual_script_editor.cpp #, fuzzy @@ -11471,11 +11386,11 @@ msgstr "VisualScriptを検索" #: modules/visual_script/visual_script_property_selector.cpp msgid "Get %s" -msgstr "" +msgstr "%s ã‚’å–å¾—" #: modules/visual_script/visual_script_property_selector.cpp msgid "Set %s" -msgstr "" +msgstr "%s ã‚’è¨å®š" #: platform/android/export/export.cpp msgid "Package name is missing." @@ -11483,7 +11398,7 @@ msgstr "パッケージåãŒã‚りã¾ã›ã‚“。" #: platform/android/export/export.cpp msgid "Package segments must be of non-zero length." -msgstr "" +msgstr "パッケージセグメントã®é•·ã•ã¯0以外ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" #: platform/android/export/export.cpp msgid "The character '%s' is not allowed in Android application package names." @@ -11491,7 +11406,7 @@ msgstr "æ–‡å— '%s' ã¯Androidアプリケーション パッケージåã«ä½¿ç #: platform/android/export/export.cpp msgid "A digit cannot be the first character in a package segment." -msgstr "" +msgstr "æ•°å—をパッケージセグメントã®å…ˆé ã«ä½¿ç”¨ã§ãã¾ã›ã‚“。" #: platform/android/export/export.cpp msgid "The character '%s' cannot be the first character in a package segment." @@ -11503,7 +11418,7 @@ msgstr "パッケージã«ã¯ä¸€ã¤ä»¥ä¸Šã®åŒºåˆ‡ã‚Šæ–‡å— '.' ãŒå¿…è¦ã§ã™ã #: platform/android/export/export.cpp msgid "ADB executable not configured in the Editor Settings." -msgstr "" +msgstr "ADB実行å¯èƒ½ãƒ•ァイルãŒã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§è¨å®šã•れã¦ã„ã¾ã›ã‚“。" #: platform/android/export/export.cpp msgid "OpenJDK jarsigner not configured in the Editor Settings." @@ -11511,20 +11426,22 @@ msgstr "OpenJDK jarsignerãŒã‚¨ãƒ‡ã‚£ã‚¿ãƒ¼è¨å®šã§è¨å®šã•れã¦ã„ã¾ã›ã‚“ã #: platform/android/export/export.cpp msgid "Debug keystore not configured in the Editor Settings nor in the preset." -msgstr "" +msgstr "デãƒãƒƒã‚°ã‚ーストアãŒã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã«ã‚‚プリセットã«ã‚‚è¨å®šã•れã¦ã„ã¾ã›ã‚“。" #: platform/android/export/export.cpp msgid "Custom build requires a valid Android SDK path in Editor Settings." -msgstr "" +msgstr "カスタムビルドã«ã¯ã‚¨ãƒ‡ã‚£ã‚¿è¨å®šã§æœ‰åйãªAndroid SDKパスãŒå¿…è¦ã§ã™ã€‚" #: platform/android/export/export.cpp msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" +msgstr "エディタè¨å®šã®ã‚«ã‚¹ã‚¿ãƒ ビルドã®Android SDKパスãŒç„¡åйã§ã™ã€‚" #: platform/android/export/export.cpp msgid "" "Android project is not installed for compiling. Install from Editor menu." msgstr "" +"Androidプãƒã‚¸ã‚§ã‚¯ãƒˆã¯ã‚³ãƒ³ãƒ‘イル用ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•れã¦ã„ã¾ã›ã‚“。 エディタメ" +"ニューã‹ã‚‰ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¾ã™ã€‚" #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -11539,6 +11456,8 @@ 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 "" @@ -11547,20 +11466,28 @@ msgid "" " Godot Version: %s\n" "Please reinstall Android build template from 'Project' menu." msgstr "" +"Androidビルドãƒãƒ¼ã‚¸ãƒ§ãƒ³ã®ä¸ä¸€è‡´:\n" +"インストールã•れãŸãƒ†ãƒ³ãƒ—レート:%s\n" +"ゴドーãƒãƒ¼ã‚¸ãƒ§ãƒ³:%s\n" +"「プãƒã‚¸ã‚§ã‚¯ãƒˆ ã€ãƒ¡ãƒ‹ãƒ¥ãƒ¼ã‹ã‚‰Androidビルドテンプレートをå†ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã—ã¦ã" +"ã ã•ã„。" #: platform/android/export/export.cpp msgid "Building Android Project (gradle)" -msgstr "" +msgstr "Androidプãƒã‚¸ã‚§ã‚¯ãƒˆã®æ§‹ç¯‰(gradle)" #: platform/android/export/export.cpp msgid "" "Building of Android project failed, check output for the error.\n" "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" +"Androidプãƒã‚¸ã‚§ã‚¯ãƒˆã®ãƒ“ルドã«å¤±æ•—ã—ã¾ã—ãŸã€‚エラーã®å‡ºåŠ›ã‚’ç¢ºèªã—ã¦ãã ã•ã„。\n" +"ã‚ã‚‹ã„ã¯ã€Androidビルドドã‚ュメントã«ã¤ã„ã¦ã¯docs.godotengine.orgã‚’ã”覧ãã ã•" +"ã„。" #: platform/android/export/export.cpp msgid "No build apk generated at: " -msgstr "" +msgstr "ビルドAPKã¯ç”Ÿæˆã•れã¦ã„ã¾ã›ã‚“:" #: platform/iphone/export/export.cpp msgid "Identifier is missing." @@ -11568,7 +11495,7 @@ msgstr "è˜åˆ¥åãŒã‚りã¾ã›ã‚“。" #: platform/iphone/export/export.cpp msgid "Identifier segments must be of non-zero length." -msgstr "" +msgstr "è˜åˆ¥åセグメントã¯ã‚¼ãƒä»¥å¤–ã®é•·ã•ã§ãªã‘れã°ãªã‚Šã¾ã›ã‚“。" #: platform/iphone/export/export.cpp msgid "The character '%s' is not allowed in Identifier." @@ -11576,7 +11503,7 @@ msgstr "æ–‡å— '%s' ã¯è˜åˆ¥åã«ä½¿ç”¨ã§ãã¾ã›ã‚“。" #: platform/iphone/export/export.cpp msgid "A digit cannot be the first character in a Identifier segment." -msgstr "" +msgstr "æ•°å—ã‚’è˜åˆ¥åセグメントã®å…ˆé ã«ä½¿ç”¨ã§ãã¾ã›ã‚“。" #: platform/iphone/export/export.cpp msgid "" @@ -11597,7 +11524,7 @@ msgstr "無効ãªè˜åˆ¥å:" #: platform/iphone/export/export.cpp msgid "Required icon is not specified in the preset." -msgstr "" +msgstr "å¿…é ˆã‚¢ã‚¤ã‚³ãƒ³ãŒãƒ—ãƒªã‚»ãƒƒãƒˆã«æŒ‡å®šã•れã¦ã„ã¾ã›ã‚“。" #: platform/javascript/export/export.cpp msgid "Run in Browser" @@ -11686,8 +11613,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "䏿£ãªã‚¹ãƒ—ラッシュスクリーンイメージ(縦横620x300ã§ãªã„ã¨ã„ã‘ã¾ã›ã‚“)" #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "SpriteFrames リソースを作æˆã¾ãŸã¯ AnimatedSprite フレームを表示ã™ã‚‹ãŸã‚ã«ã¯ " @@ -11708,6 +11636,10 @@ msgid "" "Consider adding a CollisionShape2D or CollisionPolygon2D as a child to " "define its shape." msgstr "" +"ã“ã®ãƒŽãƒ¼ãƒ‰ã«ã¯ã‚·ã‚§ã‚¤ãƒ—ãŒãªã„ãŸã‚ã€ä»–ã®ã‚ªãƒ–ジェクトã¨è¡çªã¾ãŸã¯ç›¸äº’作用ã™ã‚‹ã“" +"ã¨ã¯ã§ãã¾ã›ã‚“。\n" +"CollisionShape2Dã¾ãŸã¯CollisionPolygon2Dã‚’åã¨ã—ã¦è¿½åŠ ã—ã¦ã€ã‚·ã‚§ã‚¤ãƒ—を定義ã™" +"ã‚‹ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„。" #: scene/2d/collision_polygon_2d.cpp #, fuzzy @@ -11750,10 +11682,13 @@ msgid "" "CPUParticles2D animation requires the usage of a CanvasItemMaterial with " "\"Particles Animation\" enabled." msgstr "" +"CPUParticles2Dアニメーションã§ã¯ã€ \"Particles Animation\" を有効ã«ã—ãŸ" +"CanvasItemMaterialを使用ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "å…‰ã®å½¢çжã¨ãƒ†ã‚¯ã‚¹ãƒãƒ£ã¯ã€'texture'プãƒãƒ‘ãƒ†ã‚£ã«æŒ‡å®šã—ã¾ã™ã€‚" @@ -11765,7 +11700,8 @@ msgstr "" "ã™ã€‚" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "ã“ã®é®è”½ã®ã‚ªã‚¯ãƒ«ãƒ¼ãƒ€ ãƒãƒªã‚´ãƒ³ãŒç©ºã§ã™ã€‚多角形をæç”»ã—ã¦ãã ã•ã„!" #: scene/2d/navigation_polygon.cpp @@ -11797,6 +11733,9 @@ msgid "" "Use the CPUParticles2D node instead. You can use the \"Convert to " "CPUParticles\" option for this purpose." msgstr "" +"GPUベースã®ãƒ‘ーティクルã¯ã€GLES2ビデオドライãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。\n" +"代ã‚りã«CPUParticles2Dノードを使用ã—ã¦ãã ã•ã„。 ã“ã®ç›®çš„ã®ãŸã‚ã« \"Convert " +"to CPUParticles\" オプションを使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" #: scene/2d/particles_2d.cpp scene/3d/particles.cpp #, fuzzy @@ -11812,6 +11751,8 @@ msgid "" "Particles2D animation requires the usage of a CanvasItemMaterial with " "\"Particles Animation\" enabled." msgstr "" +"Particles2Dアニメーションã§ã¯ã€ \"Particles Animation\"ãŒæœ‰åйã«ãªã£ã¦ã„ã‚‹" +"CanvasItemMaterialを使用ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #: scene/2d/path_2d.cpp msgid "PathFollow2D only works when set as a child of a Path2D node." @@ -11824,6 +11765,9 @@ msgid "" "by the physics engine when running.\n" "Change the size in children collision shapes instead." msgstr "" +"RigidBody2D(ã‚ャラクタモードã¾ãŸã¯ãƒªã‚¸ãƒƒãƒ‰ãƒ¢ãƒ¼ãƒ‰)ã«å¯¾ã™ã‚‹ã‚µã‚¤ã‚ºå¤‰æ›´ã¯ã€å®Ÿè¡Œæ™‚" +"ã«ç‰©ç†ã‚¨ãƒ³ã‚¸ãƒ³ã«ã‚ˆã£ã¦ã‚ªãƒ¼ãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã•れã¾ã™ã€‚\n" +"代ã‚りã«ã€åã®è¡çªã‚·ã‚§ã‚¤ãƒ—ã®ã‚µã‚¤ã‚ºã‚’変更ã—ã¦ãã ã•ã„。" #: scene/2d/remote_transform_2d.cpp msgid "Path property must point to a valid Node2D node to work." @@ -11832,27 +11776,45 @@ msgstr "" #: scene/2d/skeleton_2d.cpp msgid "This Bone2D chain should end at a Skeleton2D node." -msgstr "" +msgstr "ã“ã®Bone2Dãƒã‚§ã‚¤ãƒ³ã¯Skeleton2Dノードã§çµ‚了ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #: scene/2d/skeleton_2d.cpp msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node." msgstr "" +"Bone2Dã¯ã€Skeleton2Dã¾ãŸã¯åˆ¥ã®Bone2Dを親ノードã¨ã—ã¦ä½¿ç”¨ã—ã¦ã„ã‚‹å ´åˆã«ã®ã¿æ©Ÿ" +"能ã—ã¾ã™ã€‚" #: scene/2d/skeleton_2d.cpp msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." msgstr "" +"ã“ã®ãƒœãƒ¼ãƒ³ã«ã¯é©åˆ‡ãªRESTãƒãƒ¼ã‚ºãŒã‚りã¾ã›ã‚“。 Skeleton2Dノードã«ç§»å‹•ã—ã¦è¨å®šã—" +"ã¾ã™ã€‚" + +#: 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 派生ノードã«ã‚³ãƒªã‚¸ãƒ§ãƒ³ã‚·ã‚§ã‚¤ãƒ—ã‚’æä¾›ã™" +"ã‚‹ãŸã‚ã«ã®ã¿æ©Ÿèƒ½ã—ã¾ã™ã€‚ï¼’Dã®å½¢çŠ¶ï¼ˆã‚·ã‚§ã‚¤ãƒ—ï¼‰ã‚’ä»˜ä¸Žã™ã‚‹ãŸã‚ã«ã¯ Area2Dã€" +"StaticBody2Dã€RigidBody2Dã€KinematicBody2D ãªã©ã®åオブジェクトã¨ã—ã¦åˆ©ç”¨ã—ã¦" +"ãã ã•ã„." #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D ã¯ã€è¦ªã¨ã—ã¦ç›´æŽ¥ç·¨é›†ã•れãŸã‚·ãƒ¼ãƒ³ã®ãƒ«ãƒ¼ãƒˆã‚’使用ã™ã‚‹å ´åˆã«æœ€" "é©ã§ã™ã€‚" #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCameraã¯ARVROriginãƒŽãƒ¼ãƒ‰ã‚’è¦ªã«æŒã¤å¿…è¦ãŒã‚りã¾ã™" #: scene/3d/arvr_nodes.cpp @@ -11865,6 +11827,8 @@ msgid "" "The controller ID must not be 0 or this controller won't be bound to an " "actual controller." msgstr "" +"コントãƒãƒ¼ãƒ©IDã‚’0ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。0ã«ã™ã‚‹ã¨ã€ã“ã®ã‚³ãƒ³ãƒˆãƒãƒ¼ãƒ©ã¯å®Ÿéš›ã®" +"コントãƒãƒ¼ãƒ©ã«ãƒã‚¤ãƒ³ãƒ‰ã•れã¾ã›ã‚“。" #: scene/3d/arvr_nodes.cpp #, fuzzy @@ -11876,6 +11840,8 @@ msgid "" "The anchor ID must not be 0 or this anchor won't be bound to an actual " "anchor." msgstr "" +"アンカーIDã‚’0ã«ã™ã‚‹ã“ã¨ã¯ã§ãã¾ã›ã‚“。0ã«ã™ã‚‹ã¨ã€ã“ã®ã‚¢ãƒ³ã‚«ãƒ¼ã¯å®Ÿéš›ã®ã‚¢ãƒ³ã‚«ãƒ¼" +"ã«ãƒã‚¤ãƒ³ãƒ‰ã•れã¾ã›ã‚“。" #: scene/3d/arvr_nodes.cpp #, fuzzy @@ -11915,6 +11881,10 @@ msgid "" "Consider adding a CollisionShape or CollisionPolygon as a child to define " "its shape." msgstr "" +"ã“ã®ãƒŽãƒ¼ãƒ‰ã«ã¯ã‚·ã‚§ã‚¤ãƒ—ãŒãªã„ãŸã‚ã€ä»–ã®ã‚ªãƒ–ジェクトã¨è¡çªã¾ãŸã¯ç›¸äº’作用ã™ã‚‹ã“" +"ã¨ã¯ã§ãã¾ã›ã‚“。\n" +"CollisionShapeã¾ãŸã¯CollisionPolygonã‚’åã¨ã—ã¦è¿½åŠ ã—ã¦ã€ãã®ã‚·ã‚§ã‚¤ãƒ—を定義ã™" +"ã‚‹ã“ã¨ã‚’検討ã—ã¦ãã ã•ã„。" #: scene/3d/collision_polygon.cpp #, fuzzy @@ -11943,9 +11913,10 @@ msgstr "" "åã¨ã—ã¦ãれを使用ã—ã¦ãã ã•ã„。" #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "関数㮠CollisionShape ã®å½¢çŠ¶ã‚’æŒ‡å®šã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚ãれã®ãŸã‚ã®ã‚·ã‚§ã‚¤ãƒ—リ" "ソースを作æˆã—ã¦ãã ã•ã„!" @@ -11955,6 +11926,8 @@ msgid "" "Plane shapes don't work well and will be removed in future versions. Please " "don't use them." msgstr "" +"å¹³é¢ã‚·ã‚§ã‚¤ãƒ—ã¯ã†ã¾ã機能ã›ãšã€å°†æ¥ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ã§ã¯å‰Šé™¤ã•れる予定ã§ã™ã€‚使ã‚ãª" +"ã„ã§ãã ã•ã„。" #: scene/3d/cpu_particles.cpp #, fuzzy @@ -11966,6 +11939,8 @@ msgid "" "CPUParticles animation requires the usage of a SpatialMaterial whose " "Billboard Mode is set to \"Particle Billboard\"." msgstr "" +"CPUParticlesアニメーションã§ã¯ã€Billboard Mode㌠\"Particle Billboard\" ã«è¨" +"定ã•れã¦ã„ã‚‹SpatialMaterialを使用ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #: scene/3d/gi_probe.cpp #, fuzzy @@ -11977,6 +11952,12 @@ msgid "" "GIProbes are not supported by the GLES2 video driver.\n" "Use a BakedLightmap instead." msgstr "" +"GIProbesã¯GLES2ビデオドライãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。\n" +"代ã‚りã«BakedLightmapを使用ã—ã¦ãã ã•ã„。" + +#: 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." @@ -11998,6 +11979,9 @@ msgid "" "Use the CPUParticles node instead. You can use the \"Convert to CPUParticles" "\" option for this purpose." msgstr "" +"GPUベースã®ãƒ‘ーティクルã¯ã€GLES2ビデオドライãƒã§ã¯ã‚µãƒãƒ¼ãƒˆã•れã¦ã„ã¾ã›ã‚“。\n" +"代ã‚りã«CPUParticlesノードを使用ã—ã¦ãã ã•ã„。 ã“ã®ç›®çš„ã®ãŸã‚ã« \"Convert to " +"CPUParticles\"オプションを使用ã™ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" #: scene/3d/particles.cpp #, fuzzy @@ -12010,16 +11994,21 @@ msgid "" "Particles animation requires the usage of a SpatialMaterial whose Billboard " "Mode is set to \"Particle Billboard\"." msgstr "" +"パーティクルアニメーションã§ã¯ã€Billboard Mode㌠\"Particle Billboard\" ã«è¨" +"定ã•れã¦ã„ã‚‹SpatialMaterialを使用ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #: scene/3d/path.cpp msgid "PathFollow only works when set as a child of a Path node." msgstr "PathFollow ã¯ã€Path ノードã®åã¨ã—ã¦è¨å®šã•れã¦ã„ã‚‹å ´åˆã®ã¿å‹•作ã—ã¾ã™ã€‚" #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" +"PathFollow ROTATION_ORIENTEDã§ã¯ã€è¦ªãƒ‘スã®Curveリソース㧠\"Up Vector\"を有効" +"ã«ã™ã‚‹å¿…è¦ãŒã‚りã¾ã™ã€‚" #: scene/3d/physics_body.cpp msgid "" @@ -12027,17 +12016,22 @@ msgid "" "by the physics engine when running.\n" "Change the size in children collision shapes instead." msgstr "" +"RigidBody(ã‚ャラクタモードã¾ãŸã¯ãƒªã‚¸ãƒƒãƒ‰ãƒ¢ãƒ¼ãƒ‰)ã«å¯¾ã™ã‚‹ã‚µã‚¤ã‚ºå¤‰æ›´ã¯ã€å®Ÿè¡Œæ™‚ã«" +"物ç†ã‚¨ãƒ³ã‚¸ãƒ³ã«ã‚ˆã£ã¦ã‚ªãƒ¼ãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã•れã¾ã™ã€‚\n" +"代ã‚りã«ã€åã®è¡çªã‚·ã‚§ã‚¤ãƒ—ã®ã‚µã‚¤ã‚ºã‚’変更ã—ã¦ãã ã•ã„。" #: scene/3d/remote_transform.cpp #, fuzzy -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "Path プãƒãƒ‘ティã¯ã€å‹•作ã™ã‚‹ã‚ˆã†ã«æœ‰åŠ¹ãª Particles2D ノードを示ã™å¿…è¦ãŒã‚りã¾" "ã™ã€‚" #: scene/3d/soft_body.cpp msgid "This body will be ignored until you set a mesh." -msgstr "" +msgstr "ã“ã®ãƒœãƒ‡ã‚£ã¯ã€ãƒ¡ãƒƒã‚·ãƒ¥ã‚’è¨å®šã™ã‚‹ã¾ã§ç„¡è¦–ã•れã¾ã™ã€‚" #: scene/3d/soft_body.cpp msgid "" @@ -12045,10 +12039,14 @@ msgid "" "running.\n" "Change the size in children collision shapes instead." msgstr "" +"SoftBodyã¸ã®ã‚µã‚¤ã‚ºå¤‰æ›´ã¯ã€å®Ÿè¡Œæ™‚ã«ç‰©ç†ã‚¨ãƒ³ã‚¸ãƒ³ã«ã‚ˆã£ã¦ã‚ªãƒ¼ãƒãƒ¼ãƒ©ã‚¤ãƒ‰ã•れã¾" +"ã™ã€‚\n" +"代ã‚りã«ã€åã®è¡çªã‚·ã‚§ã‚¤ãƒ—ã®ã‚µã‚¤ã‚ºã‚’変更ã—ã¦ãã ã•ã„。" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "SpriteFrames リソースを作æˆã¾ãŸã¯ AnimatedSprite3D フレームを表示ã™ã‚‹ãŸã‚ã«" @@ -12059,9 +12057,13 @@ msgid "" "VehicleWheel serves to provide a wheel system to a VehicleBody. Please use " "it as a child of a VehicleBody." msgstr "" +"VehicleWheelã¯ã€è»Šè¼ªã‚·ã‚¹ãƒ†ãƒ ã‚’VehicleBodyã«æä¾›ã™ã‚‹ãŸã‚ã®ã‚‚ã®ã§ã™ã€‚" +"VehicleBodyã®åã¨ã—ã¦ä½¿ç”¨ã—ã¦ãã ã•ã„。" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -12083,7 +12085,7 @@ msgstr "" #: scene/animation/animation_blend_tree.cpp msgid "On BlendTree node '%s', animation not found: '%s'" -msgstr "" +msgstr "BlendTreeノード 'ï¼…s' ã§ã¯ã€ã‚¢ãƒ‹ãƒ¡ãƒ¼ã‚·ãƒ§ãƒ³ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“: 'ï¼…s'" #: scene/animation/animation_blend_tree.cpp msgid "Animation not found: '%s'" @@ -12103,8 +12105,9 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "'%s' ã‚’ '%s' ã«æŽ¥ç¶š" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." -msgstr "" +#, fuzzy +msgid "No root AnimationNode for the graph is set." +msgstr "グラフã®ãƒ«ãƒ¼ãƒˆAnimationNodeãŒè¨å®šã•れã¦ã„ã¾ã›ã‚“。" #: scene/animation/animation_tree.cpp msgid "Path to an AnimationPlayer node containing animations is not set." @@ -12113,11 +12116,11 @@ msgstr "" #: scene/animation/animation_tree.cpp msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." -msgstr "" +msgstr "AnimationPlayerã«è¨å®šã•れãŸãƒ‘スã‹ã‚‰AnimationPlayerノードãŒè¾¿ã‚Œã¾ã›ã‚“。" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "アニメーションツリーã«å•題ãŒã‚りã¾ã™." #: scene/animation/animation_tree_player.cpp @@ -12130,13 +12133,17 @@ msgid "Pick a color from the screen." msgstr "スクリーンã‹ã‚‰è‰²ã‚’é¸æŠžã—ã¦ãã ã•ã„。" #: scene/gui/color_picker.cpp +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp #, fuzzy -msgid "Raw Mode" -msgstr "パン・モード" +msgid "Raw" +msgstr "ヨー" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." -msgstr "" +msgstr "16進数ã¨ã‚³ãƒ¼ãƒ‰å€¤ã‚’切り替ãˆã¾ã™ã€‚" #: scene/gui/color_picker.cpp #, fuzzy @@ -12144,11 +12151,21 @@ msgid "Add current color as a preset." msgstr "ç¾åœ¨ã®è‰²ã‚’プリセットã¨ã—ã¦è¿½åŠ " #: scene/gui/container.cpp +#, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." +msgstr "" +"コンテナ自体ã¯ã€ã‚¹ã‚¯ãƒªãƒ—トã§åã®é…置動作をè¨å®šã—ãªã„é™ã‚Šã€ä½•ã®å½¹å‰²ã‚‚æžœãŸã—ã¾" +"ã›ã‚“。\n" +"ã‚¹ã‚¯ãƒªãƒ—ãƒˆã‚’è¿½åŠ ã—ãªã„å ´åˆã¯ã€ä»£ã‚りã«ãƒ—レーン「コントãƒãƒ¼ãƒ« ã€ãƒŽãƒ¼ãƒ‰ã‚’使用ã—" +"ã¦ãã ã•ã„。" + +#: 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 @@ -12160,23 +12177,26 @@ msgid "Please Confirm..." msgstr "確èª..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "ãƒãƒƒãƒ—アップã¯ã€popup() ã¾ãŸã¯ popup*() 関数ã®ã„ãšã‚Œã‹ã‚’呼ã³å‡ºã™å ´åˆã‚’除ãã€" "既定ã§ã¯éžè¡¨ç¤ºã«ãªã‚Šã¾ã™ã€‚編集ã®ãŸã‚ã«ãれらをå¯è¦–化ã™ã‚‹ã“ã¨ã¯å¯èƒ½ã§ã™ãŒã€å½¼" "らã¯å®Ÿè¡Œæ™‚ã«éžè¡¨ç¤ºã«ãªã‚Šã¾ã™ã€‚" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "exp_edit ãŒtrueã®å ´åˆã€min_value ã¯0より大ãã„å¿…è¦ãŒã‚りã¾ã™ã€‚" #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainerã¯å˜ä¸€ã®åコントãƒãƒ¼ãƒ«ã§å‹•作ã™ã‚‹ã‚ˆã†ã«æ„図ã•れã¦ã„ã¾ã™ã€‚コンテ" @@ -12230,12 +12250,17 @@ msgid "Input" msgstr "入力" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "無効ãªã‚·ã‚§ãƒ¼ãƒ€ãƒ¼ã®ã‚½ãƒ¼ã‚¹ã§ã™ã€‚" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "無効ãªã‚·ã‚§ãƒ¼ãƒ€ãƒ¼ã®ã‚½ãƒ¼ã‚¹ã§ã™ã€‚" #: servers/visual/shader_language.cpp msgid "Assignment to function." -msgstr "" +msgstr "関数ã¸ã®å‰²ã‚Šå½“ã¦ã€‚" #: servers/visual/shader_language.cpp msgid "Assignment to uniform." @@ -12248,7 +12273,59 @@ msgstr "Varyingã¯é ‚点関数ã«ã®ã¿å‰²ã‚Šå½“ã¦ã‚‹ã“ã¨ãŒã§ãã¾ã™ã€‚" #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "定数ã¯å¤‰æ›´ã§ãã¾ã›ã‚“。" + +#, fuzzy +#~ msgid "Generating solution..." +#~ msgstr "八分木テクスãƒãƒ£ã‚’生æˆ" + +#~ msgid "Generating C# project..." +#~ msgstr "C#プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’生æˆã—ã¦ã„ã¾ã™â€¦" + +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "アウトラインを生æˆã§ãã¾ã›ã‚“ã§ã—ãŸ!" + +#~ msgid "Failed to save solution." +#~ msgstr "ソリューションã®ä¿å˜ã«å¤±æ•—ã—ã¾ã—ãŸã€‚" + +#~ msgid "Done" +#~ msgstr "完了" + +#~ msgid "Failed to create C# project." +#~ msgstr "C#プãƒã‚¸ã‚§ã‚¯ãƒˆã®ç”Ÿæˆã«å¤±æ•—ã—ã¾ã—ãŸã€‚" + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "C#ã®ã‚µãƒãƒ¼ãƒˆã«ã¤ã„ã¦" + +#~ msgid "Create C# solution" +#~ msgstr "C#ソリューションを生æˆ" + +#~ msgid "Builds" +#~ msgstr "ビルド" + +#~ msgid "Build Project" +#~ msgstr "プãƒã‚¸ã‚§ã‚¯ãƒˆã‚’ビルド" + +#~ msgid "View log" +#~ msgstr "ãƒã‚°ã‚’表示" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironmentã«ã¯EnvironmentリソースãŒå¿…è¦ã§ã™ã€‚" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "ã‚¯ãƒ©ã‚¹ã®æ¤œç´¢" + +#~ msgid "Update Always" +#~ msgstr "å¸¸ã«æ›´æ–°" + +#, fuzzy +#~ msgid "Raw Mode" +#~ msgstr "パン・モード" #~ msgid "Path to Node:" #~ msgstr "ノードã¸ã®ãƒ‘ス:" diff --git a/editor/translations/ka.po b/editor/translations/ka.po index 0eff93389d..960bcd13b7 100644 --- a/editor/translations/ka.po +++ b/editor/translations/ka.po @@ -464,6 +464,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "მáƒáƒœáƒ˜áƒ¨áƒ•ნის áƒáƒ¡áƒšáƒ˜áƒ¡ შექმნáƒ" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "მხáƒáƒšáƒáƒ“ áƒáƒ©áƒ•ენე ჩáƒáƒœáƒáƒ¬áƒ”რები კვáƒáƒœáƒ«áƒ”ბიდáƒáƒœ მáƒáƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ˜ ხეში." @@ -643,6 +653,10 @@ msgstr "ხáƒáƒ–ზე გáƒáƒ“áƒáƒ¡áƒ•ლáƒ" msgid "Line Number:" msgstr "ხáƒáƒ–ის ნáƒáƒ›áƒ”რი:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "áƒáƒ áƒáƒ სებáƒáƒ‘ს ტáƒáƒšáƒ˜" @@ -692,7 +706,7 @@ msgstr "ზუმის დáƒáƒžáƒáƒ¢áƒáƒ áƒáƒ•ებáƒ" msgid "Reset Zoom" msgstr "ზუმის სáƒáƒ¬áƒ§áƒ˜áƒ¡áƒ–ე დáƒáƒ§áƒ”ნებáƒ" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -804,6 +818,11 @@ msgid "Connect" msgstr "დáƒáƒ™áƒáƒ•შირებáƒ" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "სიგნáƒáƒšáƒ”ბი" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "'%s' დრ'%s' დáƒáƒ™áƒáƒ•შირებáƒ" @@ -972,7 +991,8 @@ msgid "Owners Of:" msgstr "მფლáƒáƒ‘ელები:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "მáƒáƒ•áƒáƒ¨áƒáƒ áƒáƒ— მáƒáƒœáƒ˜áƒ¨áƒœáƒ£áƒšáƒ˜ ფáƒáƒ˜áƒšáƒ”ბი პრáƒáƒ”ქტიდáƒáƒœ? (უკáƒáƒœ დáƒáƒ‘რუნებრშეუძლებელიáƒ)" #: editor/dependency_editor.cpp @@ -1345,7 +1365,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1517,6 +1537,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1544,7 +1568,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1601,7 +1625,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1615,7 +1639,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1639,12 +1663,9 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" -msgstr "" +#, fuzzy +msgid "Available Profiles:" +msgstr "áƒáƒœáƒ˜áƒ›áƒáƒªáƒ˜áƒ˜áƒ¡ . პáƒáƒ áƒáƒ›áƒ”ტრები." #: editor/editor_feature_profile.cpp #, fuzzy @@ -2666,10 +2687,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2776,15 +2817,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "უწყვეტი" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2974,7 +3016,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3074,20 +3116,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3585,6 +3627,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5197,6 +5240,13 @@ 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 "" @@ -6114,10 +6164,18 @@ msgid "Find Next" 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 "" @@ -6353,18 +6411,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "შექმნáƒ" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7939,51 +8001,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7991,203 +8009,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9829,6 +9671,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "ყველáƒáƒ¡ ჩáƒáƒœáƒáƒªáƒ•ლებáƒ" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9857,8 +9704,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "áƒáƒ®áƒáƒšáƒ˜ %s შექმნáƒ" #: editor/scene_tree_dock.cpp msgid "" @@ -10102,7 +9950,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10505,54 +10353,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11136,7 +10936,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11185,7 +10985,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11195,7 +10995,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11262,14 +11062,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11348,7 +11155,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11377,6 +11184,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11411,8 +11222,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11423,7 +11234,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11439,7 +11252,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11450,7 +11263,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11488,7 +11303,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "'%s' დრ'%s' შáƒáƒ ის კáƒáƒ•შირის გáƒáƒ¬áƒ§áƒ•ეტáƒ" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11501,7 +11316,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11513,7 +11328,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11526,10 +11345,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11543,18 +11367,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11598,6 +11422,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ ი ფáƒáƒœáƒ¢áƒ˜áƒ¡ ზáƒáƒ›áƒ." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "áƒáƒ áƒáƒ¡áƒ¬áƒáƒ ი ფáƒáƒœáƒ¢áƒ˜áƒ¡ ზáƒáƒ›áƒ." diff --git a/editor/translations/ko.po b/editor/translations/ko.po index 44699e75e8..fa3b289864 100644 --- a/editor/translations/ko.po +++ b/editor/translations/ko.po @@ -17,7 +17,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" +"PO-Revision-Date: 2019-07-09 10:47+0000\n" "Last-Translator: ì†¡íƒœì„ <xotjq237@gmail.com>\n" "Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/" "godot/ko/>\n" @@ -26,7 +26,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -86,9 +86,8 @@ msgid "Time:" msgstr "시간:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "ê°’" +msgstr "ê°’:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -440,10 +439,26 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"ì´ ì• ë‹ˆë©”ì´ì…˜ì€ ê°€ì ¸ì˜¨ ì”¬ì— ì†í•´ìžˆìŠµë‹ˆë‹¤, ë”°ë¼ì„œ ê°€ì ¸ì˜¨ 트랙ì—는 변경사í•ì´ " +"ì €ìž¥ë˜ì§€ 않습니다.\n" +"\n" +"커스텀 íŠ¸ëžŸì„ ì¶”ê°€í•˜ê¸° 위해서는, ì”¬ì˜ ê°€ì ¸ì˜¤ê¸° ì„¤ì •ìœ¼ë¡œ 가서\n" +"\"Animation > Storage\"를 \"Files\"로 ì„¤ì •í•˜ê³ \"Animation > Keep Custom " +"Tracks\"ì„ ì¼ ë‹¤ìŒ ë‹¤ì‹œ ê°€ì ¸ì˜¤ì„¸ìš”.\n" +"ë˜ëŠ” ì• ë‹ˆë©”ì´ì…˜ì„ 개별 파ì¼ë¡œ ê°€ì ¸ì˜¤ëŠ” ê°€ì ¸ì˜¤ê¸° í”„ë¦¬ì…‹ì„ ì‚¬ìš©í•˜ì„¸ìš”." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "ê²½ê³ : ê°€ì ¸ì˜¨ ì• ë‹ˆë©”ì´ì…˜ì„ íŽ¸ì§‘í•˜ê³ ìžˆìŒ" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "ì „ì²´ì„ íƒ" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "ëª¨ë“ ì„ íƒ í•´ì œ" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -619,6 +634,10 @@ msgstr "ë¼ì¸ìœ¼ë¡œ ì´ë™" msgid "Line Number:" msgstr "ë¼ì¸ 번호:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "ì¼ì¹˜ ê²°ê³¼ ì—†ìŒ" @@ -668,7 +687,7 @@ msgstr "축소" msgid "Reset Zoom" msgstr "줌 리셋" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "ê²½ê³ " @@ -677,38 +696,32 @@ msgid "Line and column numbers." msgstr "ë¼ì¸ ë° ì»¬ëŸ¼ 번호." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "ëŒ€ìƒ ë…¸ë“œì˜ ë©”ì„œë“œë¥¼ 명시해야 합니다!" +msgstr "ëŒ€ìƒ ë…¸ë“œì˜ ë©”ì„œë“œê°€ 명시ë˜ì–´ì•¼ 합니다." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" "ëŒ€ìƒ ë©”ì„œë“œë¥¼ ì°¾ì„ ìˆ˜ 없습니다! ìœ íš¨í•œ 메서드를 ì§€ì •í•˜ê±°ë‚˜, ëŒ€ìƒ ë…¸ë“œì— ìŠ¤í¬" -"립트를 추가하세요." +"립트를 ë¶™ì´ì„¸ìš”." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "ì—°ê²°í• ë…¸ë“œ:" +msgstr "ë‹¤ìŒ ë…¸ë“œì— ì—°ê²°:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "í˜¸ìŠ¤íŠ¸ì— ì—°ê²°í• ìˆ˜ ì—†ìŒ:" +msgstr "ë‹¤ìŒ ìŠ¤í¬ë¦½íŠ¸ì— ì—°ê²°:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "시그ë„:" +msgstr "ë‹¤ìŒ ì‹œê·¸ë„로부터:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "노드가 지오미트리를 í¬í•¨í•˜ê³ 있지 않습니다." +msgstr "ì”¬ì´ ìŠ¤í¬ë¦½íŠ¸ë¥¼ ê°–ê³ ìžˆì§€ 않습니다." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -736,9 +749,8 @@ msgid "Extra Call Arguments:" msgstr "별ë„ì˜ í˜¸ì¶œ ì¸ìˆ˜:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "ê³ ê¸‰ 옵션" +msgstr "ê³ ê¸‰" #: editor/connections_dialog.cpp msgid "Deferred" @@ -747,7 +759,7 @@ msgstr "지연" #: editor/connections_dialog.cpp msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." -msgstr "" +msgstr "시그ë„ì„ ì§€ì—°í•˜ëŠ” 것으로, íì— ì €ìž¥í•˜ê³ ëŒ€ê¸° ì‹œê°„ì— ì‹¤í–‰í•©ë‹ˆë‹¤." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -755,12 +767,11 @@ msgstr "1회" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "첫 ë°©ì¶œ ì´í›„ 시그ë„ì„ ì—°ê²° í•´ì œí•©ë‹ˆë‹¤." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "ì‹œê·¸ë„ ì—°ê²°: " +msgstr "시그ë„ì„ ì—°ê²°í• ìˆ˜ ì—†ìŒ" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -781,6 +792,11 @@ msgid "Connect" msgstr "ì—°ê²°" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "시그ë„:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "'%s'ì„(를) '%s'ì— ì—°ê²°" @@ -799,21 +815,19 @@ msgstr "연결하기..." #: editor/connections_dialog.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Disconnect" -msgstr "ì—°ê²°í•´ì œ" +msgstr "ì—°ê²° í•´ì œ" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "ì‹œê·¸ë„ ì—°ê²°: " +msgstr "시그ë„ì„ ë©”ì„œë“œì— ì—°ê²°" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "ì—°ê²° 편집 " +msgstr "ì—°ê²° 편집:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" -msgstr "\"%s\" 시그ë„ì—서 ëª¨ë“ ì—°ê²°ì„ ì‚ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?" +msgstr "\"%s\" 시그ë„ì˜ ëª¨ë“ ì—°ê²°ì„ ì‚ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" @@ -885,22 +899,20 @@ msgid "Dependencies For:" msgstr "ì¢…ì† ê´€ê³„:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" "씬 '%s'ì´(ê°€) 현재 편집 중입니다.\n" -"다시 불러올 때 변경 사í•ì´ ì ìš©ë©ë‹ˆë‹¤." +"다시 불러올 때 변경사í•ì´ ì ìš©ë©ë‹ˆë‹¤." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" "리소스 '%s'ì´(ê°€) 사용 중입니다.\n" -"다시 불러올 때 변경 사í•ì´ ì ìš©ë©ë‹ˆë‹¤." +"다시 불러올 때 변경사í•ì´ ì ìš©ë©ë‹ˆë‹¤." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -947,7 +959,8 @@ msgid "Owners Of:" msgstr "ì†Œìœ ìž:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "프로ì 트ì—서 ì„ íƒëœ 파ì¼ë“¤ì„ ì‚ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ? (ë˜ëŒë¦¬ê¸° 불가)" #: editor/dependency_editor.cpp @@ -992,9 +1005,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "%dê°œ í•ëª©ì„ ì˜êµ¬ì 으로 ì‚ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ? (ë˜ëŒë¦¬ê¸° 불가)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "ì¢…ì† ê´€ê³„" +msgstr "ì¢…ì† ê´€ê³„ ë³´ì´ê¸°" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1256,7 +1268,7 @@ msgstr "오디오 버스 ë ˆì´ì•„웃 열기" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "'%s' 파ì¼ì´ 없습니다." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1313,25 +1325,20 @@ msgid "Valid characters:" msgstr "ìœ íš¨í•œ 문ìž:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"ìœ íš¨í•˜ì§€ ì•Šì€ ì´ë¦„입니다. ì—”ì§„ì— ì¡´ìž¬í•˜ëŠ” í´ëž˜ìФ ì´ë¦„ê³¼ ì¶©ëŒí•˜ì§€ 않아야 합니" -"다." +msgstr "ì—”ì§„ì— ì¡´ìž¬í•˜ëŠ” í´ëž˜ìФ ì´ë¦„ê³¼ ì¶©ëŒí•˜ì§€ 않아야 합니다." #: editor/editor_autoload_settings.cpp -#, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ ì´ë¦„입니다. 내장 타입 ì´ë¦„ê³¼ ì¶©ëŒí•˜ì§€ 않아야 합니다." +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 "ìœ íš¨í•˜ì§€ ì•Šì€ ì´ë¦„입니다. ì „ì— ìƒìˆ˜ ì´ë¦„ê³¼ ì¶©ëŒí•˜ì§€ 않아야 합니다." +msgstr "ì „ì— ìƒìˆ˜ ì´ë¦„ê³¼ ì¶©ëŒí•˜ì§€ 않아야 합니다." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "키워드를 ì˜¤í† ë¡œë“œ ì´ë¦„으로 ì‚¬ìš©í• ìˆ˜ 없습니다." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1362,9 +1369,8 @@ msgid "Rearrange Autoloads" msgstr "ì˜¤í† ë¡œë“œ ìž¬ì •ë ¬" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." -msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ ê²½ë¡œ." +msgstr "올바르지 ì•Šì€ ê²½ë¡œ." #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp msgid "File does not exist." @@ -1417,9 +1423,8 @@ msgid "[unsaved]" msgstr "[ì €ìž¥ë˜ì§€ 않ìŒ]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "ë¨¼ì € 기본 ë””ë ‰í† ë¦¬ë¥¼ ì„ íƒí•´ì£¼ì„¸ìš”" +msgstr "ë¨¼ì € 기본 ë””ë ‰í† ë¦¬ë¥¼ ì„ íƒí•´ì£¼ì„¸ìš”." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1503,127 +1508,114 @@ msgstr "커스텀 릴리즈 í…œí”Œë¦¿ì„ ì°¾ì„ ìˆ˜ 없습니다." 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 -#, fuzzy msgid "3D Editor" -msgstr "ì—디터" +msgstr "3D ì—디터" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "스í¬ë¦½íЏ ì—디터 열기" +msgstr "스í¬ë¦½íЏ ì—디터" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "ì—ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬ 열기" +msgstr "ì—ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "씬 트리 (노드):" +msgstr "씬 트리 편집하기" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "ê°€ì ¸ì˜¤ê¸°" +msgstr "ë… ê°€ì ¸ì˜¤ê¸°" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "노드 ì´ë™ë¨" +msgstr "노드 ë…" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Filesystem Dock" -msgstr "íŒŒì¼ ì‹œìŠ¤í…œ" +msgid "FileSystem and Import Docks" +msgstr "íŒŒì¼ ì‹œìŠ¤í…œê³¼ ê°€ì ¸ì˜¤ê¸° ë…" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "ì „ì²´ 바꾸기 (ì·¨ì†Œí• ìˆ˜ ì—†ìŒ)" +msgstr "프로필 '%s'ì„(를) ì§€ìš°ì‹œê² ìŠµë‹ˆê¹Œ? (뒤로가기 ì—†ìŒ)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "í”„ë¡œí•„ì€ ì˜¬ë°”ë¥¸ íŒŒì¼ ì´ë¦„ì´ë©°, '.'ì„ í¬í•¨í•˜ì§€ 않아야 합니다" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "파ì¼ì´ë‚˜ í´ë”ê°€ 해당 ì´ë¦„ì„ ì‚¬ìš©ì¤‘ìž…ë‹ˆë‹¤." +msgstr "ì´ ì´ë¦„ì„ ê°€ì§„ í”„ë¡œí•„ì´ ì´ë¯¸ 존재합니다." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(ì—디터 비활성화ë¨, ì†ì„± 비활성화ë¨)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "ì†ì„±ë§Œ" +msgstr "(ì†ì„± 비활성화ë¨)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "í´ë¦½ 사용 안함" +msgstr "(ì—디터 비활성화ë¨)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "í´ëž˜ìФ 설명:" +msgstr "í´ëž˜ìФ 옵션:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "ë‹¤ìŒ ì—디터 열기" +msgstr "컨í…스트 ì—디터 활성화" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "ì†ì„±:" +msgstr "í™œì„±í™”ëœ ì†ì„±:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "기능" +msgstr "í™œì„±í™”ëœ ê¸°ëŠ¥:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "í´ëž˜ìФ 검색" +msgstr "í™œì„±í™”ëœ í´ëž˜ìФ:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "íŒŒì¼ '%s' 형ì‹ì´ 올바르지 않습니다, ê°€ì ¸ì˜¤ê¸°ê°€ 중단ë˜ì—ˆìŠµë‹ˆë‹¤." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"프로필 '%s'ì´(ê°€) ì´ë¯¸ 존재합니다. ê°€ì ¸ì˜¤ê¸° ì „ì— ì•žì˜ ê²ƒì„ ì‚ì œí•˜ì„¸ìš”, ê°€ì ¸ì˜¤" +"기가 중단ë˜ì—ˆìŠµë‹ˆë‹¤." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "'%s' 템플릿 불러오기 오류" +msgstr "í”„ë¡œí•„ì„ ê²½ë¡œì— ì €ìž¥í•˜ëŠ” 중 오류: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "ë¹„ì„¤ì •" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Current Profile" -msgstr "현재 ë²„ì „:" +msgid "Current Profile:" +msgstr "현재 프로필:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "현재:" +msgstr "현재 만들기" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp msgid "New" -msgstr "새 파ì¼" +msgstr "새 것" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp @@ -1636,44 +1628,32 @@ msgid "Export" msgstr "내보내기" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Available Profiles" -msgstr "사용 가능한 노드:" - -#: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "í´ëž˜ìФ 검색" +msgid "Available Profiles:" +msgstr "사용 가능한 프로필:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "í´ëž˜ìФ 설명" +msgstr "í´ëž˜ìФ 옵션" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "새 ì´ë¦„:" +msgstr "새 프로필 ì´ë¦„:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "ì˜ì— 지우기" +msgstr "프로필 지우기" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "ê°€ì ¸ì˜¨ 프로ì 트" +msgstr "ê°€ì ¸ì˜¨ 프로필" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "프로ì 트 내보내기" +msgstr "프로필 내보내기" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "내보내기 템플릿 관리" +msgstr "ì—디터 기능 프로필 관리" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1796,9 +1776,8 @@ msgid "(Un)favorite current folder." msgstr "현재 í´ë”를 ì¦ê²¨ì°¾ê¸° (안) 합니다." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "숨김 íŒŒì¼ í† ê¸€" +msgstr "숨김 íŒŒì¼ ê°€ì‹œì„± í† ê¸€í•˜ê¸°." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1835,6 +1814,8 @@ msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"íŒŒì¼ %sì„(를) 가리키는 다른 ìœ í˜•ì˜ ê°€ì ¸ì˜¤ê¸°ë“¤ì´ ìžˆìŠ´ë‹ˆë‹¤, ê°€ì ¸ì˜¤ê¸°ê°€ 중단ë˜" +"었습니다" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2177,13 +2158,12 @@ msgstr "" "를 확ì¸í•´ì£¼ì‹ì‹œì˜¤." #: editor/editor_node.cpp -#, fuzzy 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 "" -"ì´ ë¦¬ì†ŒìŠ¤ëŠ” ì¸ìŠ¤í„´ìŠ¤ ë˜ì—ˆê±°ë‚˜ ìƒì†ëœ ê²ƒì— ì†í•©ë‹ˆë‹¤.\n" -"ì´ ë¦¬ì†ŒìŠ¤ì— ëŒ€í•œ ìˆ˜ì •ì€ í˜„ìž¬ ì”¬ì„ ì €ìž¥í•˜ëŠ” 경우 ìœ ì§€ë˜ì§€ 않습니다." +"ì´ ë¦¬ì†ŒìŠ¤ëŠ” ì¸ìŠ¤í„´ìŠ¤ë˜ê±°ë‚˜ ìƒì†ëœ ì”¬ì— ì†í•´ìžˆìŠ´ë‹ˆë‹¤.\n" +"현재 ì”¬ì„ ì €ìž¥í•˜ëŠ” 경우, 변경사í•ì´ ìœ ì§€ë˜ì§€ 않습니다." #: editor/editor_node.cpp msgid "" @@ -2194,28 +2174,25 @@ msgstr "" "변경한 ë’¤ 다시 ê°€ì ¸ì˜¤ì‹ì‹œì˜¤." #: editor/editor_node.cpp -#, fuzzy 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 "" -"ì´ ì”¬ì€ ê°€ì ¸ì˜¤ê¸°ë˜ì—ˆìœ¼ë¯€ë¡œ 변경사í•ì´ ìœ ì§€ë˜ì§€ ì•Šì„ ê²ƒìž…ë‹ˆë‹¤.\n" +"ì´ ì”¬ì€ ê°€ì ¸ì˜¨ 것으로 변경사í•ì´ ìœ ì§€ë˜ì§€ 않습니다.\n" "ì¸ìŠ¤í„´ìŠ¤í™” í˜¹ì€ ìƒì†ì„ 하면 ì”¬ì„ ìˆ˜ì •í• ìˆ˜ 있게 ë©ë‹ˆë‹¤.\n" -"ê´€ë ¨ 작업 ì ˆì°¨ë¥¼ ë” ìž˜ ì´í•´í•˜ë ¤ë©´ 씬 ê°€ì ¸ì˜¤ê¸°(scene importing)와 ê´€ë ¨ëœ ë¬¸ì„œ" -"를 확ì¸í•´ì£¼ì‹ì‹œì˜¤." +"ì´ ì›Œí¬í”Œë¡œë¥¼ ë” ìž˜ ì´í•´í•˜ë ¤ë©´ 씬 ê°€ì ¸ì˜¤ê¸°ì™€ ê´€ë ¨ëœ ë¬¸ì„œë¥¼ 확ì¸í•´ì£¼ì‹ì‹œì˜¤." #: editor/editor_node.cpp -#, fuzzy 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 "" -"ì´ê²ƒì€ ì›ê²© 오브ì íŠ¸ì— ëŒ€í•œ 변경ì´ë©° 변경사í•ì´ ì €ìž¥ë˜ì§€ 않습니다.\n" -"ì´ ì›Œí¬í”Œë¡œì— 대해 ë” ìžì„¸ížˆ ì´í•´í•˜ê¸° 위해서 디버깅 ê´€ë ¨ 문서를 ì½ì–´ë³´ì‹œê¸° ë°”" -"ëžë‹ˆë‹¤." +"ì´ê²ƒì€ ì›ê²© 오브ì 트입니다, 변경사í•ì´ ìœ ì§€ë˜ì§€ 않습니다.\n" +"ì´ ì›Œí¬í”Œë¡œì— 대해 ë” ìžì„¸ížˆ ì´í•´í•˜ë ¤ë©´ 디버깅 ê´€ë ¨ 문서를 ì½ì–´ë³´ì‹œê¸° ë°”ëžë‹ˆ" +"다." #: editor/editor_node.cpp msgid "There is no defined scene to run." @@ -2238,9 +2215,8 @@ msgid "Open Base Scene" msgstr "기본 씬 열기" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "ë¹ ë¥¸ 씬 열기..." +msgstr "ë¹ ë¥¸ 열기..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2474,12 +2450,11 @@ msgstr "다른 íƒ ë‹«ê¸°" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "íƒì„ 오른쪽으로 닫기" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "ëª¨ë‘ ë‹«ê¸°" +msgstr "ëª¨ë“ íƒ ë‹«ê¸°" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2613,7 +2588,7 @@ msgstr "프로ì 트 ë°ì´í„° í´ë” 열기" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "안드로ì´ë“œ 빌드 템플릿 설치하기" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2725,10 +2700,30 @@ 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 Data/Settings í´ë”ì— ì €ìž¥ë˜ì—ˆìŠµë‹ˆë‹¤." + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "스í¬ë¦°ìƒ· ìžë™ 열기" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "ì—디터 ë°ì´í„°/ì„¤ì • í´ë” 열기" @@ -2741,9 +2736,8 @@ msgid "Open Editor Settings Folder" msgstr "ì—디터 ì„¤ì • í´ë” 열기" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "내보내기 템플릿 관리" +msgstr "ì—디터 기능 관리" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2836,16 +2830,16 @@ msgid "Spins when the editor window redraws." msgstr "ì—디터 윈ë„ìš°ê°€ 다시 ê·¸ë ¤ì§ˆ 때 íšŒì „í•©ë‹ˆë‹¤." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "í•ìƒ ì—…ë°ì´íЏ" +msgid "Update Continuously" +msgstr "ì§€ì†ì ì—…ë°ì´íЏ" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "변경사í•ë§Œ ì—…ë°ì´íЏ" +msgid "Update When Changed" +msgstr "변경ë 때 ì—…ë°ì´íЏ" #: editor/editor_node.cpp -msgid "Disable Update Spinner" -msgstr "ì—…ë°ì´íЏ 스피너 비활성화" +msgid "Hide Update Spinner" +msgstr "ì—…ë°ì´íЏ 스피너 숨기기" #: editor/editor_node.cpp msgid "FileSystem" @@ -2874,17 +2868,19 @@ msgstr "ì €ìž¥í•˜ì§€ 않ìŒ" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." msgstr "" +"안드로ì´ë“œ 빌드 í…œí”Œë¦¿ì´ ì¡´ìž¬í•˜ì§€ 않습니다, ê´€ë ¨ í…œí”Œë¦¿ì„ ì„¤ì¹˜í•˜ê¸° ë°”ëžë‹ˆë‹¤." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "내보내기 템플릿 관리" +msgstr "템플릿 관리" #: editor/editor_node.cpp msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"ì´ê²ƒì€ 커스텀 빌드를 위해 안드로ì´ë“œ 프로ì 트를 설치합니다.\n" +"ì‚¬ìš©í•˜ë ¤ë©´ ê°ê° 내보내기 í”„ë¦¬ì…‹ì„ í™œì„±í™”í•´ì•¼ 합니다." #: editor/editor_node.cpp msgid "" @@ -2892,6 +2888,8 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"안드로ì´ë“œ 빌드 í…œí”Œë¦¿ì´ ì´ë¯¸ 설치ë˜ì–´ ìžˆê³ ë®ì–´ 쓸 수 없습니다.\n" +"ëª…ë ¹ì„ ë‹¤ì‹œ 시ë„하기 ì „ì— ìˆ˜ë™ìœ¼ë¡œ \"build\" ë””ë ‰í† ë¦¬ë¥¼ ì‚ì œí•˜ì„¸ìš”." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3035,7 +3033,7 @@ msgstr "시간" msgid "Calls" msgstr "호출" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "사용" @@ -3139,6 +3137,11 @@ 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 "새 키:" @@ -3150,11 +3153,6 @@ msgstr "새 ê°’:" msgid "Add Key/Value Pair" msgstr "키/ê°’ ìŒ ì¶”ê°€" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "ì•„ì´í…œ ì‚ì œ" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3361,9 +3359,8 @@ msgid "SSL Handshake Error" msgstr "SSL 핸드ì‰ì´í¬ 오류" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "ì—ì…‹ ì••ì¶•í•´ì œ" +msgstr "안드로ì´ë“œ 빌드 소스 ì••ì¶• í•´ì œ" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3382,7 +3379,6 @@ msgid "Remove Template" msgstr "템플릿 ì‚ì œ" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" msgstr "템플릿 íŒŒì¼ ì„ íƒ" @@ -3440,9 +3436,8 @@ msgid "No name provided." msgstr "ì´ë¦„ì´ ì œê³µë˜ì§€ 않았습니다." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "ì´ë¦„ì— ìœ íš¨í•˜ì§€ ì•Šì€ ë¬¸ìžê°€ í¬í•¨ë¨" +msgstr "ì œê³µëœ ì´ë¦„ì— ìœ íš¨í•˜ì§€ ì•Šì€ ë¬¸ìžê°€ 있습니다." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3469,12 +3464,10 @@ msgid "Duplicating folder:" msgstr "ë³µì œ ì¤‘ì¸ í´ë”:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "새 ìƒì† 씬..." +msgstr "새 ìƒì† 씬" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" msgstr "씬 열기" @@ -3483,12 +3476,10 @@ msgid "Instance" msgstr "ì¸ìŠ¤í„´ìŠ¤" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" msgstr "ì¦ê²¨ì°¾ê¸°ë¡œ 추가" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" msgstr "ì¦ê²¨ì°¾ê¸°ì—서 ì‚ì œ" @@ -3538,21 +3529,18 @@ msgid "Rename" msgstr "ì´ë¦„ 변경" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "ì´ì „ í´ë”" +msgstr "ì´ì „ í´ë”/파ì¼" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "ë‹¤ìŒ í´ë”" +msgstr "ë‹¤ìŒ í´ë”/파ì¼" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "íŒŒì¼ ì‹œìŠ¤í…œ 재검사" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" msgstr "ë¶„í• ëª¨ë“œ í† ê¸€" @@ -3605,6 +3593,8 @@ 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 @@ -3656,6 +3646,7 @@ msgid "Nodes not in Group" msgstr "ê·¸ë£¹ì— ìžˆì§€ ì•Šì€ ë…¸ë“œ" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "노드 í•„í„°" @@ -4043,9 +4034,8 @@ msgid "Open Animation Node" msgstr "ì• ë‹ˆë©”ì´ì…˜ 노드 열기" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "삼ê°í˜•ì´ ì´ë¯¸ 존재함" +msgstr "삼ê°í˜•ì´ ì´ë¯¸ 존재합니다." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4188,7 +4178,6 @@ msgid "Edit Filtered Tracks:" msgstr "í•„í„° 트랙 편집:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" msgstr "í•„í„° 활성화" @@ -4324,9 +4313,8 @@ msgid "Enable Onion Skinning" msgstr "어니언 ìŠ¤í‚¤ë‹ í™œì„±í™”" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "어니언 스키ë‹" +msgstr "어니언 ìŠ¤í‚¤ë‹ ì„¤ì •" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4888,7 +4876,7 @@ msgstr "Control ë…¸ë“œì˜ ì•µì»¤ì™€ 여백 ê°’ì˜ í”„ë¦¬ì…‹." msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." -msgstr "" +msgstr "활성화하면, 움ì§ì´ëŠ” Control 노드는 ë§ˆì§„ì´ ì•„ë‹Œ 앵커를 변경합니다." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -4904,41 +4892,35 @@ 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 -#, fuzzy msgid "Unlock Selected" -msgstr "ì„ íƒ í•목 ì‚ì œ" +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 "Create Custom Bone(s) from Node(s)" msgstr "노드ì—서 커스텀 본 만들기" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "í¬ì¦ˆ ì •ë¦¬" +msgstr "본 지우기" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -5022,7 +5004,6 @@ msgid "Snapping Options" msgstr "스냅 옵션" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" msgstr "격ìžì— 스냅" @@ -5044,37 +5025,30 @@ msgid "Use Pixel Snap" msgstr "픽셀 스냅 사용" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" msgstr "스마트 스냅" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" msgstr "ë¶€ëª¨ì— ìŠ¤ëƒ…" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" msgstr "노드 ì•µì»¤ì— ìŠ¤ëƒ…" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" -msgstr "노드 ì˜†ì— ìŠ¤ëƒ…" +msgstr "노드 ì˜†ë©´ì— ìŠ¤ëƒ…" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" msgstr "노드 ì¤‘ì‹¬ì— ìŠ¤ëƒ…" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" msgstr "다른 ë…¸ë“œì— ìŠ¤ëƒ…" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" msgstr "ê°€ì´ë“œì— 스냅" @@ -5157,9 +5131,8 @@ msgid "Frame Selection" msgstr "ì„ íƒ í•목 화면 꽉차게 표시" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Preview Canvas Scale" -msgstr "ì•„í‹€ë¼ìФ 미리보기" +msgstr "캔버스 규모 미리보기" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -5213,9 +5186,8 @@ msgid "Divide grid step by 2" msgstr "ê²©ìž ë‹¨ê³„ë¥¼ 반으로 ê°ì†Œ" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Pan View" -msgstr "후면 ë·°" +msgstr "팬 ë·°" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" @@ -5240,7 +5212,6 @@ msgid "Error instancing scene from %s" msgstr "'%s'ì—서 씬 ì¸ìŠ¤í„´ìŠ¤ 중 오류" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" msgstr "기본 타입 변경" @@ -5284,6 +5255,13 @@ 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 "ì—미션 ë§ˆìŠ¤í¬ ì •ë¦¬" @@ -5312,7 +5290,7 @@ msgstr "픽셀로부터 캡ì³" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Colors" -msgstr "ì—미션 ì¹¼ë¼" +msgstr "ë°©ì¶œ 색ìƒ" #: editor/plugins/cpu_particles_editor_plugin.cpp msgid "CPUParticles" @@ -5329,14 +5307,12 @@ msgid "Create Emission Points From Node" msgstr "노드로부터 ì—미터 í¬ì¸íЏ 만들기" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "플랫0" +msgstr "플랫 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "플랫1" +msgstr "플랫 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -5363,27 +5339,22 @@ msgid "Load Curve Preset" msgstr "커브 프리셋 불러오기" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" msgstr "í¬ì¸íЏ 추가" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" msgstr "í¬ì¸íЏ ì‚ì œ" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" msgstr "왼쪽 ì„ í˜•" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" msgstr "오른쪽 ì„ í˜•" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" msgstr "프리셋 불러오기" @@ -5440,18 +5411,16 @@ msgid "This doesn't work on scene root!" msgstr "씬 루트ì—서는 í• ìˆ˜ 없습니다!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Trimesh 모양 만들기" +msgstr "Trimesh Static Shape 만들기" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "Shape 만들기 실패!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "Convex 모양 만들기" +msgstr "Convex Shape 만들기" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -5507,7 +5476,6 @@ msgid "Create Trimesh Collision Sibling" msgstr "Trimesh ì¶©ëŒ í˜•ì œ 만들기" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Collision Sibling(s)" msgstr "Convex ì¶©ëŒ í˜•ì œ 만들기" @@ -5868,7 +5836,6 @@ msgid "Split Segment (in curve)" msgstr "ì„ ë¶„ ë¶„í• (커브)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" msgstr "ê´€ì ˆ ì´ë™" @@ -6201,10 +6168,18 @@ msgid "Find Next" 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 "ì •ë ¬" @@ -6315,18 +6290,16 @@ msgid "Debug with External Editor" msgstr "외부 ì—디터로 디버깅" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Godot 온ë¼ì¸ 문서 열기" +msgstr "Godot 온ë¼ì¸ 문서 열기." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" msgstr "문서 ìš”ì²" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "피드백으로 Godot 문서를 ê°œì„ í•˜ëŠ”ë° ë„ì›€ì„ ì£¼ì„¸ìš”" +msgstr "피드백으로 Godot 문서를 ê°œì„ í•˜ëŠ”ë° ë„와주세요." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6371,17 +6344,14 @@ msgid "Search Results" msgstr "검색 ê²°ê³¼" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "ì—°ê²°í• ë…¸ë“œ:" +msgstr "ë©”ì„œë“œì— ì—°ê²°:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "소스:" +msgstr "소스" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" msgstr "시그ë„" @@ -6390,10 +6360,11 @@ msgid "Target" msgstr "대ìƒ" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "노드 '%s'ì˜ '%s' ìž…ë ¥ì— ì•„ë¬´ê²ƒë„ ì—°ê²°ë˜ì§€ 않ìŒ." +msgstr "" +"노드 '%s'ì—서 노드 '%s'ê¹Œì§€ì˜ ì—°ê²°ì—서 ì‹œê·¸ë„ '%s'ì— ëŒ€í•œ 메서드 '%s'ê°€ 존재" +"하지 않습니ë”." #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6440,20 +6411,24 @@ msgid "Syntax Highlighter" msgstr "구문 ê°•ì¡°" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "ë¶ë§ˆí¬" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +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 "ë¼ì¸ ì‚ì œ" @@ -6471,24 +6446,20 @@ msgid "Toggle Comment" msgstr "ì£¼ì„ í† ê¸€" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "ìžìœ 시ì í† ê¸€" +msgstr "ë¶ë§ˆí¬ í† ê¸€" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "ë‹¤ìŒ ì¤‘ë‹¨ì 으로 ì´ë™" +msgstr "ë‹¤ìŒ ë¶ë§ˆí¬ë¡œ ì´ë™" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Previous Bookmark" -msgstr "ì´ì „ 중단ì 으로 ì´ë™" +msgstr "ì´ì „ ë¶ë§ˆí¬ë¡œ ì´ë™" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "ëª¨ë“ í•목 ì‚ì œ" +msgstr "ëª¨ë“ ë¶ë§ˆí¬ ì‚ì œ" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -6564,13 +6535,12 @@ msgid "Contextual Help" msgstr "ë„ì›€ë§ ë³´ê¸°" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"다ìŒì˜ 파ì¼ë“¤ì´ 디스í¬ìƒ ë” ìµœì‹ ìž…ë‹ˆë‹¤.\n" -"ì–´ë–¤ ìž‘ì—…ì„ ìˆ˜í–‰í•˜ì‹œê² ìŠµë‹ˆê¹Œ?:" +"ì´ ì…°ì´ë”는 디스í¬ì—서 ìˆ˜ì •ë˜ì—ˆìŠµë‹ˆë‹¤.\n" +"ì–´ë–¤ ìž‘ì—…ì„ í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -6916,7 +6886,6 @@ msgid "Right View" msgstr "우측 ë·°" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" msgstr "ì›ê·¼/ì§êµ ë·° ì „í™˜" @@ -6962,7 +6931,6 @@ msgid "Transform" msgstr "변형" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" msgstr "물체를 ë°”ë‹¥ì— ìŠ¤ëƒ…" @@ -7152,14 +7120,12 @@ msgid "Settings:" msgstr "ì„¤ì •:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "ì„ íƒ í•목 화면 꽉차게 표시" +msgstr "í”„ë ˆìž„ì´ ì„ íƒë˜ì§€ 않ìŒ" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "í”„ë ˆìž„ 추가" +msgstr "%d í”„ë ˆìž„ 추가" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" @@ -7210,13 +7176,12 @@ msgid "Animation Frames:" msgstr "ì• ë‹ˆë©”ì´ì…˜ í”„ë ˆìž„:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "TileSetì— í…ìŠ¤ì³ ì¶”ê°€í•˜ê¸°." +msgstr "파ì¼ì—서 í…ìŠ¤ì³ ì¶”ê°€í•˜ê¸°" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "스프ë¼ì´íЏ 시트ì—서 í”„ë ˆìž„ 추가하기" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7235,29 +7200,24 @@ msgid "Move (After)" msgstr "ì´ë™ (ì´í›„)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "ìŠ¤íƒ í”„ë ˆìž„" +msgstr "í”„ë ˆìž„ ì„ íƒ" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "가로로 뒤집기" +msgstr "수í‰:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "버틱스" +msgstr "수ì§:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "ì „ì²´ì„ íƒ" +msgstr "ëª¨ë“ í”„ë ˆìž„ ì„ íƒ/지우기" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "씬으로부터 만들기" +msgstr "스프ë¼ì´íЏ 시트ì—서 í”„ë ˆìž„ 만들기" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" @@ -7329,9 +7289,8 @@ msgid "Remove All" msgstr "ëª¨ë‘ ì‚ì œ" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "테마 편집..." +msgstr "테마 편집" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7358,31 +7317,28 @@ msgid "Create From Current Editor Theme" msgstr "현재 ì—디터 테마로부터 만들기" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Toggle Button" -msgstr "마우스 버튼" +msgstr "í† ê¸€ 버튼" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "ê°€ìš´ë° ë²„íŠ¼" +msgstr "비활성화 버튼" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" msgstr "í•목" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "비활성화ë¨" +msgstr "ë¹„í™œì„±í™”ëœ í•목" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" -msgstr "í•목 확ì¸" +msgstr "ì²´í¬ í•목" #: editor/plugins/theme_editor_plugin.cpp msgid "Checked Item" -msgstr "í•목 확ì¸ë¨" +msgstr "ì²´í¬ëœ í•목" #: editor/plugins/theme_editor_plugin.cpp msgid "Radio Item" @@ -7390,38 +7346,35 @@ msgstr "ë¼ë””오 í•목" #: editor/plugins/theme_editor_plugin.cpp msgid "Checked Radio Item" -msgstr "ë¼ë””오 í•목 확ì¸ë¨" +msgstr "ì²´í¬ëœ ë¼ë””오 í•목" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "ì´ë¦„있는 분기." #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "하위 메뉴" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "í•목" +msgstr "í•목 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "í•목" +msgstr "í•목 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" -msgstr "가진다" +msgstr "갖춤" #: editor/plugins/theme_editor_plugin.cpp msgid "Many" msgstr "ë§Žì€" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled LineEdit" -msgstr "비활성화ë¨" +msgstr "ë¹„í™œì„±í™”ëœ LineEdit" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -7436,13 +7389,12 @@ msgid "Tab 3" msgstr "íƒ 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "ìžì‹ë…¸ë“œ 편집 가능" +msgstr "편집 가능한 í•목" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "하위 트리" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7522,14 +7474,12 @@ msgid "Mirror Y" msgstr "Yì¶• 뒤집기" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "ìžë™ 타ì¼" +msgstr "ì˜¤í† íƒ€ì¼ ë¹„í™œì„±í™”" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "í•„í„° ìš°ì„ ìˆœìœ„ 편집" +msgstr "ìš°ì„ ìˆœìœ„ 편집" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7540,33 +7490,30 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift+ìš°í´ë¦: ì„ ê·¸ë¦¬ê¸°\n" +"Shift+Ctrl+ìš°í´ë¦:사ê°í˜• 페ì¸íЏ" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" msgstr "íƒ€ì¼ ì„ íƒ" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" -msgstr "왼쪽으로 íšŒì „" +msgstr "왼쪽으로 íšŒì „í•˜ê¸°" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" -msgstr "오른쪽으로 íšŒì „" +msgstr "오른쪽으로 íšŒì „í•˜ê¸°" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Horizontally" -msgstr "가로로 뒤집기" +msgstr "수í‰ìœ¼ë¡œ 뒤집기" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Vertically" -msgstr "세로로 뒤집기" +msgstr "수ì§ìœ¼ë¡œ 뒤집기" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" msgstr "변형 지우기" @@ -7603,44 +7550,36 @@ msgid "Select the previous shape, subtile, or Tile." msgstr "ì´ì „ 모양, 하위 타ì¼, í˜¹ì€ íƒ€ì¼ì„ ì„ íƒí•˜ì„¸ìš”." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "실행 모드:" +msgstr "ì§€ì— ëª¨ë“œ" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "ë³´ê°„ 모드" +msgstr "ì¶©ëŒ ëª¨ë“œ" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "ì–´í´ë£¨ì „ í´ë¦¬ê³¤ 편집" +msgstr "ì–´í´ë£¨ì „ 모드" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "내비게ì´ì…˜ 메시 만들기" +msgstr "내비게ì´ì…˜ 모드" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "íšŒì „ 모드" +msgstr "비트 ë§ˆìŠ¤í¬ ëª¨ë“œ" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "내보내기 모드:" +msgstr "ìš°ì„ ìˆœìœ„ 모드" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "팬 모드" +msgstr "ì•„ì´ì½˜ 모드" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "팬 모드" +msgstr "Z ì¸ë±ìФ 모드" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7725,15 +7664,15 @@ msgid "Delete polygon." msgstr "í´ë¦¬ê³¤ ì‚ì œí•˜ê¸°." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy 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 "" -"좌í´ë¦: 비트 켜기를 ì„¤ì •í•¨.\n" -"ìš°í´ë¦: 비트 ë„기를 ì„¤ì •í•¨.\n" +"좌í´ë¦: 비트를 켬.\n" +"ìš°í´ë¦: 비트를 ë”.\n" +"Shift+좌í´ë¦: 와ì¼ë“œì¹´ë“œ 비트를 ì„¤ì •í•¨.\n" "다른 타ì¼ì„ íŽ¸ì§‘í•˜ë ¤ë©´ í´ë¦í•˜ì„¸ìš”." #: editor/plugins/tile_set_editor_plugin.cpp @@ -7847,77 +7786,64 @@ msgid "TileSet" msgstr "타ì¼ì…‹" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input +" -msgstr "ìž…ë ¥ 추가" +msgstr "ìž…ë ¥ 추가 +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add output +" -msgstr "ìž…ë ¥ 추가" +msgstr "ì¶œë ¥ 추가 +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "í¬ê¸°:" +msgstr "스칼ë¼" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "ì¸ìŠ¤íŽ™í„°" +msgstr "벡터" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "불리언" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "ìž…ë ¥ 추가" +msgstr "ìž…ë ¥ í¬íЏ 추가" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "ì¶œë ¥ í¬íЏ 추가" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "기본 타입 변경" +msgstr "ìž…ë « í¬íЏ 타입 변경" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "기본 타입 변경" +msgstr "ì¶œë ¥ í¬íЏ 타입 변경" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "ìž…ë ¥ ì´ë¦„ 변경" +msgstr "ìž…ë ¥ í¬íЏ ì´ë¦„ 변경" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "ìž…ë ¥ ì´ë¦„ 변경" +msgstr "ì¶œë ¥ í¬íЏ ì´ë¦„ 변경" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "í¬ì¸íЏ ì‚ì œ" +msgstr "ìž…ë ¥ í¬íЏ ì‚ì œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "í¬ì¸íЏ ì‚ì œ" +msgstr "ì¶œë ¥ í¬íЏ ì‚ì œ" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "í‘œí˜„ì‹ ë³€ê²½" +msgstr "í‘œí˜„ì‹ ì„¤ì •" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "비주얼 ì…°ì´ë”" +msgstr "비주얼 ì…°ì´ë” 노드 í¬ê¸° ì¡°ì •" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" @@ -7953,543 +7879,312 @@ msgstr "프래그먼트" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Light" -msgstr "ë¹›" +msgstr "조명" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "노드 만들기" +msgstr "ì…°ì´ë” 노드 만들기" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "함수로 ì´ë™" +msgstr "ìƒ‰ìƒ í•¨ìˆ˜." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "ìƒ‰ìƒ ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "함수 만들기" +msgstr "회색조 함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "HSV 벡터를 RGB로 변환합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "RGB 벡터를 HSV로 변환합니다." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "함수명 변경" +msgstr "세피아 함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "번 ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "ì–´ë‘움 ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Difference operator." -msgstr "변경사í•ë§Œ" +msgstr "ì°¨ì´ ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." -msgstr "" +msgstr "ë‹·ì§€ ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "HardLight operator" -msgstr "" +msgstr "하드 ë¼ì´íЏ ì—°ì‚°ìž" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." -msgstr "" +msgstr "ë°ìŒ ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." -msgstr "" +msgstr "ì˜¤ë²„ë ˆì´ ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Screen operator." -msgstr "" +msgstr "화면 ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "SoftLight operator." -msgstr "" +msgstr "소프트 ë¼ì´íЏ ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color constant." -msgstr "ë¹„ì„ í˜•" +msgstr "ìƒ‰ìƒ ìƒìˆ˜." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color uniform." -msgstr "변형 지우기" +msgstr "ìƒ‰ìƒ ìœ ë‹ˆí¼." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided scalars are equal, greater or " "less." -msgstr "" +msgstr "ì œê³µëœ ìŠ¤ì¹¼ë¼ê°€ 같거나, ë” í¬ê±°ë‚˜, ë” ìž‘ìœ¼ë©´ ê´€ë ¨ 벡터를 반환합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided boolean value is true or false." -msgstr "" +msgstr "불리언 ê°’ì´ ì°¸ì´ê±°ë‚˜ ê±°ì§“ì´ë©´ ê´€ë ¨ 벡터를 반환합니다." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Boolean constant." -msgstr "Vec ìƒìˆ˜ 변경" +msgstr "불리언 ìƒìˆ˜." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean uniform." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" +msgstr "불리언 ìœ ë‹ˆí¼." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" +msgid "'%s' input parameter for all shader modes." +msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ '%s' ìž…ë ¥ 매개변수." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Input parameter." -msgstr "ë¶€ëª¨ì— ìŠ¤ëƒ…" +msgstr "ìž…ë ¥ 매개변수." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ '%s' ìž…ë ¥ 매개변수." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ '%s' ìž…ë ¥ 매개변수." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for fragment shader mode." +msgstr "프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ '%s' ìž…ë ¥ 매개변수." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" +msgid "'%s' input parameter for light shader mode." +msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ '%s' ìž…ë ¥ 매개변수." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" +msgid "'%s' input parameter for vertex shader mode." +msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ '%s' ìž…ë ¥ 매개변수." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ '%s' ìž…ë ¥ 매개변수." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar function." -msgstr "Scalar 함수 변경" +msgstr "Scalar 함수." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar operator." -msgstr "Scalar ì—°ì‚°ìž ë³€ê²½" +msgstr "Scalar ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "E ìƒìˆ˜ (2.718282). ìžì—° ë¡œê·¸ì˜ ë°‘ì„ ë‚˜íƒ€ëƒ„." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "Epsilon ìƒìˆ˜ (0.00001). ìŠ¤ì¹¼ë¼ ìˆ˜ì—서 가능한 가장 ìž‘ì€ ìˆ˜." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "Phi ìƒìˆ˜ (1.618034). 황금 비율." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "Pi/4 ìƒìˆ˜ (0.785398) í˜¹ì€ 45ë„." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "Pi/2 ìƒìˆ˜ (1.570796) í˜¹ì€ 90ë„." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "Pi ìƒìˆ˜ (3.141593) í˜¹ì€ 180ë„." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "Tau ìƒìˆ˜ (6.283185) í˜¹ì€ 360ë„." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "Sqrt2 ìƒìˆ˜ (1.414214). 2ì˜ ì œê³±ê·¼." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì ˆëŒ€ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì•„í¬ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "(GLES3ë§Œ 가능) ë§¤ê°œë³€ìˆ˜ì˜ ì—ìŒê³¡ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì•„í¬ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "(GLES3ë§Œ 가능) ë§¤ê°œë³€ìˆ˜ì˜ ì—ìŒê³¡ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì•„í¬íƒ„ì 트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ë“¤ì˜ ì•„í¬íƒ„ì 트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "(GLES3ë§Œ 가능) ë§¤ê°œë³€ìˆ˜ì˜ ì—ìŒê³¡íƒ„ì 트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "매개변수보다 í¬ê±°ë‚˜ ê°™ì€ ê°€ìž¥ 가까운 ì •ìˆ˜ë¥¼ 찾습니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "ë‘ ê°œì˜ ë‹¤ë¥¸ ê°’ 사ì´ì— 놓ì´ëŠ” ê°’ì„ ì œí•œí•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(GLES3ë§Œ 가능) ë§¤ê°œë³€ìˆ˜ì˜ ìŒê³¡ì½”ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "ê°ë„ 단위를 ë¼ë””안ì—서 ë„로 변환합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "eê°€ ë°‘ì¸ ì§€ìˆ˜ 함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "2ê°€ ë°‘ì¸ ì§€ìˆ˜ 함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "매개변수보다 ì 거나 ê°™ì€ ê°€ìž¥ 가까운 ì •ìˆ˜ë¥¼ 찾습니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "ì¸ìˆ˜ì˜ 프랙탈 구조를 계산합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì œê³±ê·¼ ì—함수 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "ìžì—°ë¡œê·¸." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "2ê°€ ë°‘ì¸ ë¡œê·¸ 함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "ë‘ ê°’ 중 ë” í° ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "ë‘ ê°’ 중 ë” ìž‘ì€ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "ë‘ ìŠ¤ì¹¼ë¼ ê°’ ì‚¬ì´ ì„ í˜• ë³´ê°„." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ë°˜ëŒ€ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - 스칼ë¼" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." -msgstr "" +msgstr "첫 번째 매개변수를 ë‘ ë²ˆì§¸ 매개변수로 ì œê³±í•œ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "ê°ë„ 단위를 ë„ì—서 ë¼ë””안으로 변환합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / 스칼ë¼" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(GLES3ë§Œ 가능) 매개변수ì—서 가장 가까운 ì •ìˆ˜ë¥¼ 찾습니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(GLES3ë§Œ 가능) 매개변수ì—서 가장 가까운 ì§ìˆ˜ ì •ìˆ˜ë¥¼ 찾습니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "ê°’ì„ 0.0ì—서 1.0 사ì´ë¡œ ê³ ì •í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ë¶€í˜¸ë¥¼ 추출합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(GLES3ë§Œ 가능) ë§¤ê°œë³€ìˆ˜ì˜ ìŒê³¡ì‚¬ì¸ ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ ì œê³±ê·¼ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8499,6 +8194,10 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep 함수( 스칼ë¼(edge0), 스칼ë¼(edge1), 스칼ë¼(x) ).\n" +"\n" +"'x'ê°€ 'edge0'보다 ìž‘ê³ , 'edge1'보다 í¬ë©´ 0.0ì„ ë°˜í™˜í•©ë‹ˆë‹¤. ê·¸ë ‡ì§€ ì•Šì€ ê²½ìš°, " +"ë°˜í™˜ê°’ì€ ì—르미트 다í•ì‹ì„ 통해 0.0ê³¼ 1.0사ì´ë¡œ ë³´ê°„ë©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8506,71 +8205,69 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Step 함수( 스칼ë¼(edge), 스칼ë¼(x) ).\n" +"\n" +"'x'ê°€ 'edge'보다 작으면 0.0ì„ ë°˜í™˜í•˜ê³ ê·¸ë ‡ì§€ 않으면 1.0ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "ë§¤ê°œë³€ìˆ˜ì˜ íƒ„ì 트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(GLES3ë§Œ 가능) ë§¤ê°œë³€ìˆ˜ì˜ ìŒê³¡íƒ„ì 트 ê°’ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." -msgstr "" +msgstr "(GLES3ë§Œ 가능) ë§¤ê°œë³€ìˆ˜ì˜ ì ˆì‚¬ ê°’ì„ ì°¾ìŠµë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "스칼ë¼ì— 스칼ë¼ë¥¼ ë”합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "스칼ë¼ë¥¼ 스칼ë¼ë¡œ 나눕니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "스칼ë¼ë¥¼ 스칼ë¼ë¡œ 곱합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "ë‘ ìŠ¤ì¹¼ë¼ì˜ 나머지를 반환합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "스칼ë¼ì—서 스칼ë¼ë¥¼ ëºë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar constant." -msgstr "Scalar ìƒìˆ˜ 변경" +msgstr "ìŠ¤ì¹¼ë¼ ìƒìˆ˜." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar uniform." -msgstr "Scalar uniform 변경" +msgstr "ìŠ¤ì¹¼ë¼ ìœ ë‹ˆí¼." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "ì„¸ì œê³± í…ìŠ¤ì³ ë£©ì—…ì„ ìˆ˜í–‰í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the texture lookup." -msgstr "" +msgstr "í…ìŠ¤ì³ ë£©ì—…ì„ ìˆ˜í–‰í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Cubic texture uniform." -msgstr "í…ìŠ¤ì³ uniform 변경" +msgstr "ì„¸ì œê³± í…ìŠ¤ì³ ìœ ë‹ˆí¼." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "2D texture uniform." -msgstr "í…ìŠ¤ì³ uniform 변경" +msgstr "2D í…ìŠ¤ì³ ìœ ë‹ˆí¼." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform function." -msgstr "변형 대화 ìƒìž..." +msgstr "변형 함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8582,74 +8279,76 @@ msgid "" "whose number of rows is the number of components in 'c' and whose number of " "columns is the number of components in 'r'." msgstr "" +"(GLES3ë§Œ 가능) 한 ìŒì˜ ë²¡í„°ì˜ ì™¸ì ì„ ê³„ì‚°í•©ë‹ˆë‹¤.\n" +"\n" +"OuterProduct는 첫 매개변수 'c'를 ì—´ 벡터로 취급합니다 (1열로 ì´ë£¨ì–´ì§„ í–‰ë ¬) " +"ê·¸ë¦¬ê³ ë‘ ë²ˆì§¸ 매개변수 'r'ì„ í–‰ 벡터로 취급합니다 (1행으로 ì´ë£¨ì–´ì§„ í–‰ë ¬) ê·¸" +"ë¦¬ê³ ì„ í˜• 대수 í–‰ë ¬ì— 'c * r'ì„ ê³±í•©ë‹ˆë‹¤, í–‰ë ¬ì„ ì‚°ì¶œí•˜ëŠ”ë°, í–‰ì˜ ìˆ˜ëŠ” 'c'ì˜ " +"구성 요소 수ì´ê³ ì—´ì˜ ìˆ˜ëŠ” 'r'ì˜ êµ¬ì„± 요소 수입니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes transform from four vectors." -msgstr "" +msgstr "4ê°œì˜ ë²¡í„°ë¡œ ë³€í˜•ì„ í•©ì„±í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes transform to four vectors." -msgstr "" +msgstr "ë³€í˜•ì„ 4ê°œì˜ ë²¡í„°ë¡œ 분해합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the determinant of a transform." -msgstr "" +msgstr "(GLES3ë§Œ 가능) ë³€í˜•ì˜ í–‰ë ¬ì‹ì„ 계산합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the inverse of a transform." -msgstr "" +msgstr "(GLES3ë§Œ 가능) ë³€í˜•ì˜ ì—함수를 계산합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the transpose of a transform." -msgstr "" +msgstr "(GLES3ë§Œ 가능) ë³€í˜•ì˜ ì „ì¹˜ë¥¼ 계산합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies transform by transform." -msgstr "" +msgstr "ë³€í˜•ì— ë³€í˜•ì„ ê³±í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by transform." -msgstr "" +msgstr "ë³€í˜•ì— ë²¡í„°ë¥¼ 곱합니다." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform constant." -msgstr "변형 중단." +msgstr "변형 ìƒìˆ˜." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform uniform." -msgstr "변형 중단." +msgstr "변형 ìœ ë‹ˆí¼." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector function." -msgstr "í•¨ìˆ˜ì— ë°°ì¹˜í•¨." +msgstr "벡터 함수." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector operator." -msgstr "Vec ì—°ì‚°ìž ë³€ê²½" +msgstr "벡터 ì—°ì‚°ìž." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "세 ê°œì˜ ìŠ¤ì¹¼ë¼ë¡œ 벡터를 합성합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "벡터를 세 ê°œì˜ ìŠ¤ì¹¼ë¼ë¡œ 분해합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "ë‘ ë²¡í„°ì˜ ë²¡í„°ê³± ê°’ì„ ê³„ì‚°í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "ë‘ ì 사ì´ì˜ 거리를 반환합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "ë‘ ë²¡í„°ì˜ ìŠ¤ì¹¼ë¼ê³± ê°’ì„ ê³„ì‚°í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8658,36 +8357,41 @@ msgid "" "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 "" +"참조 벡터와 ê°™ì€ ë°©í–¥ì„ ê°€ë¦¬í‚¤ëŠ” 벡터를 반환합니다. 함수ì—는 세 ê°œì˜ ë²¡í„° 매" +"개변수가 있습니다 : ë°©í–¥ì„ ì§€ì •í•˜ëŠ” 벡터 N, ì¸ì‹œë˜íЏ 벡터 I, ê·¸ë¦¬ê³ ì°¸ì¡° 벡" +"í„° Nref. I와 Nrefì˜ ìŠ¤ì¹¼ë¼ê³± ê°’ì´ 0보다 작으면 ë°˜í™˜ê°’ì€ Nì´ ë©ë‹ˆë‹¤. ê·¸ë ‡ì§€ 않" +"으면 -Nì´ ë°˜í™˜ë©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "ë²¡í„°ì˜ ê¸¸ì´ë¥¼ 계산합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "ë‘ ë²¡í„° ê°„ì˜ ì„ í˜• ë³´ê°„." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." -msgstr "" +msgstr "ë²¡í„°ì˜ ë…¸ë©€ ê°’ì„ ê³„ì‚°í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - vector" -msgstr "" +msgstr "1.0 - 벡터" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / vector" -msgstr "" +msgstr "1.0 / 벡터" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns a vector that points in the direction of reflection ( a : incident " "vector, b : normal vector )." msgstr "" +"반사 ë°©í–¥ì„ ê°€ë¦¬í‚¤ëŠ” 벡터를 반환합니다 (a : ì¸ì‹œë˜íЏ 벡터, b : 노멀 벡터)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns a vector that points in the direction of refraction." -msgstr "" +msgstr "반사 ë°©í–¥ì„ ê°€ë¦¬í‚¤ëŠ” 벡터를 반환합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8697,6 +8401,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep 함수( 벡터(edge0), 벡터(edge1), 벡터(x) ).\n" +"\n" +"'x'ê°€ 'edge0'보다 작으면 0.0ì„ ë°˜í™˜í•˜ê³ 'x'ê°€ 'edge1'보다 í¬ë©´ 1.0ì„ ë°˜í™˜í•©ë‹ˆ" +"다. ê·¸ë ‡ì§€ 않으면 반환 ê°’ì€ ì—르미트 다í•ì‹ì„ 통해 0.0ê³¼ 1.0 사ì´ë¡œ ë³´ê°„ë©ë‹ˆ" +"다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8706,6 +8415,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"SmoothStep 함수( 스칼ë¼(edge0), 스칼ë¼(edge1), 벡터(x) ).\n" +"\n" +"'x'ê°€ 'edge0'보다 작으면 0.0ì„ ë°˜í™˜í•˜ê³ 'x'ê°€ 'edge1'보다 í¬ë©´ 1.0ì„ ë°˜í™˜í•©ë‹ˆ" +"다. ê·¸ë ‡ì§€ 않으면 반환 ê°’ì€ ì—르미트 다í•ì‹ì„ 통해 0.0ê³¼ 1.0 사ì´ë¡œ ë³´ê°„ë©ë‹ˆ" +"다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8713,6 +8427,9 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Step 함수( 벡터(edge), 벡터(x) ).\n" +"\n" +"'x'ê°€ 'edge'보다 작으면 0.0ì„ ë°˜í™˜í•˜ê³ ê·¸ë ‡ì§€ 않으면 1.0ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8720,36 +8437,37 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Step 함수( 스칼ë¼(edge), 벡터(x) ).\n" +"\n" +"'x'ê°€ 'edge'보다 작으면 0.0ì„ ë°˜í™˜í•˜ê³ ê·¸ë ‡ì§€ 않으면 1.0ì„ ë°˜í™˜í•©ë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." -msgstr "" +msgstr "ë²¡í„°ì— ë²¡í„°ë¥¼ ë”합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "" +msgstr "벡터를 벡터로 나눕니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." -msgstr "" +msgstr "벡터를 벡터로 곱합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two vectors." -msgstr "" +msgstr "ë‘ ë²¡í„°ì˜ ë‚˜ë¨¸ì§€ë¥¼ 반환합니다." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts vector from vector." -msgstr "" +msgstr "벡터ì—서 벡터를 ëºë‹ˆë‹¤." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector constant." -msgstr "Vec ìƒìˆ˜ 변경" +msgstr "벡터 ìƒìˆ˜." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector uniform." -msgstr "ê· ì¼í•˜ê²Œ 배치함." +msgstr "벡터 ìœ ë‹ˆí¼." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8757,56 +8475,73 @@ msgid "" "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 "" +"커스텀 Godot ì…°ì´ë” 언어 ëª…ë ¹ë¬¸ìœ¼ë¡œ, 커스텀 ìž…ë ¥ ë° ì¶œë ¥ í¬íŠ¸ê°€ 있습니다. 버" +"í…스/프래그먼트/조명 í•¨ìˆ˜ì— ì§ì ‘ 코드를 넣는 것ì´ë¯€ë¡œ, 코드 ë‚´ì— í•¨ìˆ˜ ì„ ì–¸ì„ " +"ì 는 ìš©ë„로 ì“°ì§€ 마세요." #: 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 "(GLES3 only) (Fragment/Light mode only) Scalar derivative function." -msgstr "" +msgstr "(GLES3ë§Œ 가능) (프래그먼트/조명 모드만 가능) ìŠ¤ì¹¼ë¼ ë¯¸ë¶„ 함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function." -msgstr "" +msgstr "(GLES3ë§Œ 가능) (프래그먼트/조명 모드만 가능) 벡터 미분 함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using " "local differencing." msgstr "" +"(GLES3ë§Œ 가능) (프래그먼트/조명 모드만 가능) ì§€ì— ì°¨ë¶„ì„ ì´ìš©í•œ 'x'ì˜ (벡터) " +"ë„함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using " "local differencing." msgstr "" +"(GLES3ë§Œ 가능) (프래그먼트/조명 모드만 가능) ì§€ì— ì°¨ë¶„ì„ ì´ìš©í•œ 'x'ì˜ (스칼" +"ë¼) ë„함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using " "local differencing." msgstr "" +"(GLES3ë§Œ 가능) (프래그먼트/조명 모드만 가능) ì§€ì— ì°¨ë¶„ì„ ì´ìš©í•œ 'y'ì˜ (벡터) " +"ë„함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using " "local differencing." msgstr "" +"(GLES3ë§Œ 가능) (프래그먼트/조명 모드만 가능) ì§€ì— ì°¨ë¶„ì„ ì´ìš©í•œ 'y'ì˜ (스칼" +"ë¼) ë„함수." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(GLES3ë§Œ 가능) (프래그먼트/조명 모드만 가능) (벡터) 'x'와 'y'ì˜ ì ˆëŒ€ 미분 ê°’" +"ì˜ í•©." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(GLES3ë§Œ 가능) (프래그먼트/조명 모드만 가능) (스칼ë¼) 'x'와 'y'ì˜ ì ˆëŒ€ 미분 " +"ê°’ì˜ í•©." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "VisualShader" @@ -8814,7 +8549,7 @@ msgstr "비주얼 ì…°ì´ë”" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Edit Visual Property" -msgstr "비주얼 ì†ì„± 편집ë¨" +msgstr "비주얼 ì†ì„± 편집" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Visual Shader Mode Changed" @@ -9141,7 +8876,6 @@ msgid "Are you sure to open more than one project?" msgstr "ë‘ê°œ ì´ìƒì˜ 프로ì 트를 ì—´ë ¤ëŠ” ê²ƒì´ í™•ì‹¤í•©ë‹ˆê¹Œ?" #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file does not specify the version of Godot " "through which it was created.\n" @@ -9153,15 +8887,14 @@ msgid "" "Warning: You won't be able to open the project with previous versions of the " "engine anymore." msgstr "" -"ë‹¤ìŒ í”„ë¡œì 트 ì„¤ì • 파ì¼ì€ ì´ ë²„ì „ì˜ Godot로 ìƒì„±ë˜ì§€ 않았습니다.\n" +"ë‹¤ìŒ í”„ë¡œì 트 ì„¤ì • 파ì¼ì€ 현재 ë²„ì „ì˜ Godotì—서 ìƒì„±í•œ ê²ƒì´ ì•„ë‹™ë‹ˆë‹¤.\n" "↵\n" "%s↵\n" "↵\n" "파ì¼ì„ 연다면, 현재 Godotì˜ êµ¬ì„± íŒŒì¼ í˜•ì‹ìœ¼ë¡œ 변환ë©ë‹ˆë‹¤.\n" -"ê²½ê³ : ì´ì „ ë²„ì „ì˜ ì—”ì§„ìœ¼ë¡œ ë” ì´ìƒ ì—´ 수 없게 ë 것입니다." +"ê²½ê³ : ë” ì´ìƒ ì´ í”„ë¡œì 트를 ì´ì „ ë²„ì „ì˜ ì—”ì§„ì—서 ì—´ 수 없게 ë©ë‹ˆë‹¤." #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file was generated by an older engine " "version, and needs to be converted for this version:\n" @@ -9172,13 +8905,13 @@ msgid "" "Warning: You won't be able to open the project with previous versions of the " "engine anymore." msgstr "" -"다ìŒì˜ 프로ì 트 ì„¤ì • 파ì¼ì€ ì´ì „ ë²„ì „ì—서 ìƒì„±ëœ 것으로, ë‹¤ìŒ ë²„ì „ì— ë§žê²Œ ë³€" +"다ìŒì˜ 프로ì 트 ì„¤ì • 파ì¼ì€ ì´ì „ ë²„ì „ì—서 ìƒì„±ëœ 것으로, 현재 ë²„ì „ì— ë§žê²Œ ë³€" "환해야 합니다:\n" "\n" "%s\n" "\n" "ë³€í™˜í•˜ì‹œê² ìŠµë‹ˆê¹Œ?\n" -"ê²½ê³ : ë” ì´ìƒ ì´ í”„ë¡œì 트를 ì´ì „ ë²„ì „ì—서 ì—´ 수 없게 ë©ë‹ˆë‹¤." +"ê²½ê³ : ë” ì´ìƒ ì´ í”„ë¡œì 트를 ì´ì „ ë²„ì „ì˜ ì—”ì§„ì—서 ì—´ 수 없게 ë©ë‹ˆë‹¤." #: editor/project_manager.cpp msgid "" @@ -9189,15 +8922,14 @@ msgstr "" "ì§€ 않습니다." #: editor/project_manager.cpp -#, fuzzy 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 "" "프로ì 트를 ì‹¤í–‰í• ìˆ˜ 없습니다: ë©”ì¸ ì”¬ì´ ì§€ì •ë˜ì§€ 않았습니다.\n" -"\"프로ì 트 ì„¤ì •\"ì˜ \"Application\" ì¹´í…Œê³ ë¦¬ì—서 ë©”ì¸ ì”¬ì„ ì„¤ì •í•˜ê³ í”„ë¡œì 트" -"를 편집하세요." +"프로ì 트를 íŽ¸ì§‘í•˜ê³ í”„ë¡œì 트 ì„¤ì •ì˜ \"Application\" ì¹´í…Œê³ ë¦¬ì—서 ë©”ì¸ ì”¬ì„ ì„¤" +"ì •í•˜ì„¸ìš”." #: editor/project_manager.cpp msgid "" @@ -9208,49 +8940,48 @@ msgstr "" "프로ì 트를 편집하여 최초 ê°€ì ¸ì˜¤ê¸°ê°€ 실행ë˜ë„ë¡ í•˜ì„¸ìš”." #: editor/project_manager.cpp -#, fuzzy msgid "Are you sure to run %d projects at once?" -msgstr "ë‘ ê°œ ì´ìƒì˜ 프로ì 트를 ì‹¤í–‰í•˜ë ¤ëŠ” ê²ƒì´ í™•ì‹¤í•©ë‹ˆê¹Œ?" +msgstr "한 ë²ˆì— %dê°œì˜ í”„ë¡œì 트를 ì‹¤í–‰í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove %d projects from the list?\n" "The project folders' contents won't be modified." msgstr "" -"목ë¡ì—서 프로ì 트를 ì‚ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ? (í´ë”ì˜ ë‚´ìš©ë¬¼ì€ ì‚¬ë¼ì§€ì§€ 않습니다)" +"%dê°œì˜ í”„ë¡œì 트를 ì‚ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?\n" +"프로ì 트 í´ë”ì˜ ë‚´ìš©ì€ ìˆ˜ì •ë˜ì§€ 않습니다." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove this project from the list?\n" "The project folder's contents won't be modified." msgstr "" -"목ë¡ì—서 프로ì 트를 ì‚ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ? (í´ë”ì˜ ë‚´ìš©ë¬¼ì€ ì‚¬ë¼ì§€ì§€ 않습니다)" +"ì´ í”„ë¡œì 트를 목ë¡ì—서 ì‚ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ?\n" +"프로ì 트 í´ë”ì˜ ë‚´ìš©ì€ ìˆ˜ì •ë˜ì§€ 않습니다." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove all missing projects from the list? (Folders contents will not be " "modified)" msgstr "" -"목ë¡ì—서 프로ì 트를 ì‚ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ? (í´ë”ì˜ ë‚´ìš©ë¬¼ì€ ì‚¬ë¼ì§€ì§€ 않습니다)" +"목ë¡ì—서 ëª¨ë“ ì´ë¦„없는 프로ì 트를 ì‚ì œí•˜ì‹œê² ìŠµë‹ˆê¹Œ? (í´ë”ì˜ ë‚´ìš©ë¬¼ì€ ìˆ˜ì •ë˜" +"ì§€ 않습니다)" #: editor/project_manager.cpp -#, fuzzy msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." msgstr "" "언어가 변경ë˜ì—ˆìŠµë‹ˆë‹¤.\n" -"UI는 ì—디터나 프로ì 트 ë§¤ë‹ˆì €ê°€ ë‹¤ìŒ ë²ˆì— ì‹¤í–‰ë 때 ì—…ë°ì´íЏ ë©ë‹ˆë‹¤." +"ì¸í„°íŽ˜ì´ìŠ¤ëŠ” ì—디터나 프로ì 트 ë§¤ë‹ˆì €ë¥¼ ìž¬ì‹œìž‘í• ë•Œ ì—…ë°ì´íЏë©ë‹ˆë‹¤." #: editor/project_manager.cpp -#, fuzzy msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." -msgstr "%sì—서 기존 Godot 프로ì íŠ¸ë“¤ì„ ìŠ¤ìº”í•˜ë ¤ê³ í•©ë‹ˆë‹¤. ì§„í–‰í•˜ì‹œê² ìŠµë‹ˆê¹Œ?" +msgstr "" +"Godot 프로ì 트가 있는지 %s í´ë”를 ìŠ¤ìº”í•˜ì‹œê² ìŠµë‹ˆê¹Œ?\n" +"약간 ì‹œê°„ì´ ê±¸ë¦´ 수 있습니다." #: editor/project_manager.cpp msgid "Project Manager" @@ -9273,9 +9004,8 @@ msgid "New Project" msgstr "새 프로ì 트" #: editor/project_manager.cpp -#, fuzzy msgid "Remove Missing" -msgstr "í¬ì¸íЏ ì‚ì œ" +msgstr "누ë½ëœ 부분 ì‚ì œ" #: editor/project_manager.cpp msgid "Templates" @@ -9294,12 +9024,11 @@ msgid "Can't run project" msgstr "프로ì 트를 ì‹¤í–‰í• ìˆ˜ ì—†ìŒ" #: editor/project_manager.cpp -#, fuzzy msgid "" "You currently don't have any projects.\n" "Would you like to explore official example projects in the Asset Library?" msgstr "" -"프로ì 트가 현재 í•˜ë‚˜ë„ ì—†ìŠµë‹ˆë‹¤.\n" +"현재 프로ì 트가 í•˜ë‚˜ë„ ì—†ìŠµë‹ˆë‹¤.\n" "ì—ì…‹ ë¼ì´ë¸ŒëŸ¬ë¦¬ì—서 ê³µì‹ ì˜ˆì œ 프로ì 트를 ì°¾ì•„ë³´ì‹œê² ìŠµë‹ˆê¹Œ?" #: editor/project_settings_editor.cpp @@ -9327,9 +9056,8 @@ msgstr "" "안 ë©ë‹ˆë‹¤" #: editor/project_settings_editor.cpp -#, fuzzy msgid "An action with the name '%s' already exists." -msgstr "ì•¡ì…˜ '%s'ì´(ê°€) ì´ë¯¸ 존재합니다!" +msgstr "ì´ë¦„ '%s'ì„(를) 가진 ì•¡ì…˜ì´ ì´ë¯¸ 존재합니다." #: editor/project_settings_editor.cpp msgid "Rename Input Action Event" @@ -9548,9 +9276,8 @@ msgid "Override For..." msgstr "ìž¬ì •ì˜..." #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -#, fuzzy msgid "The editor must be restarted for changes to take effect." -msgstr "변경 사í•ì„ ì ìš©í•˜ë ¤ë©´ ì—디터를 다시 실행해야 합니다" +msgstr "변경 사í•ì„ ì ìš©í•˜ë ¤ë©´ ì—디터를 다시 실행해야 합니다." #: editor/project_settings_editor.cpp msgid "Input Map" @@ -9609,14 +9336,12 @@ msgid "Locales Filter" msgstr "ë¡œì¼€ì¼ í•„í„°" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show All Locales" msgstr "ëª¨ë“ ë¡œì¼€ì¼ ë³´ê¸°" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show Selected Locales Only" -msgstr "ì„ íƒí•œ 로케ì¼ë§Œ 표시" +msgstr "ì„ íƒí•œ 로케ì¼ë§Œ 보기" #: editor/project_settings_editor.cpp msgid "Filter mode:" @@ -9703,7 +9428,6 @@ msgid "Suffix" msgstr "ì ‘ë¯¸ì‚¬" #: editor/rename_dialog.cpp -#, fuzzy msgid "Advanced Options" msgstr "ê³ ê¸‰ 옵션" @@ -9965,9 +9689,8 @@ msgid "User Interface" msgstr "ì‚¬ìš©ìž ì¸í„°íŽ˜ì´ìФ" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Other Node" -msgstr "노드 ì‚ì œ" +msgstr "다른 노드" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" @@ -10009,7 +9732,6 @@ msgid "Clear Inheritance" msgstr "ìƒì† 지우기" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Open Documentation" msgstr "문서 열기" @@ -10018,12 +9740,16 @@ 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 "Extend Script" -msgstr "스í¬ë¦½íЏ 확장" +msgstr "스í¬ë¦½íЏ 펼치기" #: editor/scene_tree_dock.cpp msgid "Make Scene Root" @@ -10046,8 +9772,8 @@ msgid "Delete (No Confirm)" msgstr "ì‚ì œ (í™•ì¸ ì—†ìŒ)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "새 노드 추가/만들기" +msgid "Add/Create a New Node." +msgstr "새 노드 추가/만들기." #: editor/scene_tree_dock.cpp msgid "" @@ -10081,23 +9807,20 @@ 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 -#, fuzzy msgid "(Connecting From)" -msgstr "ì—°ê²° 오류" +msgstr "(ì—°ê²° 시작 ì§€ì )" #: editor/scene_tree_editor.cpp msgid "Node configuration warning:" -msgstr "노드 ë°°ì—´ ê²½ê³ :" +msgstr "노드 구성 ê²½ê³ :" #: editor/scene_tree_editor.cpp msgid "" @@ -10105,15 +9828,15 @@ msgid "" "Click to show signals dock." msgstr "" "노드가 ì—°ê²°ê³¼ ê·¸ë£¹ì„ ê°–ê³ ìžˆìŠµë‹ˆë‹¤.\n" -"í´ë¦í•´ì„œ ì‹œê·¸ë„ ë…ì„ ì—¬ì„¸ìš”." +"ì‹œê·¸ë„ ë…ì„ í´ë¦í•˜ì—¬ 보세요." #: editor/scene_tree_editor.cpp msgid "" "Node has connections.\n" "Click to show signals dock." msgstr "" -"노드가 ì»¤ë„¥ì…˜ë“¤ì„ ê°–ê³ ìžˆìŠµë‹ˆë‹¤\n" -"í´ë¦í•´ì„œ ì‹œê·¸ë„ ë…ì„ ë³´ì‹ì‹œì˜¤." +"노드가 ì—°ê²°ì„ ê°–ê³ ìžˆìŠµë‹ˆë‹¤\n" +"ì‹œê·¸ë„ ë…ì„ í´ë¦í•˜ì—¬ 보세요." #: editor/scene_tree_editor.cpp msgid "" @@ -10121,12 +9844,11 @@ msgid "" "Click to show groups dock." msgstr "" "노드가 그룹 ì•ˆì— ìžˆìŠµë‹ˆë‹¤.\n" -"í´ë¦í•´ì„œ 그룹 ë…ì„ ë³´ì‹ì‹œì˜¤." +"그룹 ë…ì„ í´ë¦í•˜ì—¬ 보세요." #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Open Script:" -msgstr "스í¬ë¦½íЏ 열기" +msgstr "스í¬ë¦½íЏ 열기:" #: editor/scene_tree_editor.cpp msgid "" @@ -10153,8 +9875,8 @@ msgid "" "AnimationPlayer is pinned.\n" "Click to unpin." msgstr "" -"AnimationPlayerê°€ ê³ ì •ë˜ì—ˆìŠµë‹ˆë‹¤.\n" -"í´ë¦í•´ì„œ ê³ ì •ì„ í’‰ë‹ˆë‹¤." +"AnimationPlayerê°€ ê³ ì •ë˜ì–´ìžˆìŠµë‹ˆë‹¤.\n" +"í´ë¦í•˜ì„œ ê³ ì •ì„ í‘¸ì„¸ìš”." #: editor/scene_tree_editor.cpp msgid "Invalid node name, the following characters are not allowed:" @@ -10177,39 +9899,32 @@ msgid "Select a Node" msgstr "노드 ì„ íƒ" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is empty." -msgstr "경로가 비어 있ìŒ" +msgstr "경로가 비었습니다." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Filename is empty." -msgstr "íŒŒì¼ ì´ë¦„ì´ ë¹„ì—ˆìŠµë‹ˆë‹¤" +msgstr "íŒŒì¼ ì´ë¦„ì´ ë¹„ì—ˆìŠµë‹ˆë‹¤." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is not local." -msgstr "경로가 ë¡œì»¬ì´ ì•„ë‹˜" +msgstr "경로가 ë¡œì»¬ì´ ì•„ë‹™ë‹ˆë‹¤." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid base path." -msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ ê¸°ë³¸ 경로" +msgstr "올바르지 ì•Šì€ ê¸°ë³¸ 경로." #: editor/script_create_dialog.cpp -#, fuzzy msgid "A directory with the same name exists." -msgstr "ê°™ì€ ì´ë¦„ì˜ ë””ë ‰í† ë¦¬ê°€ 존재함" +msgstr "ê°™ì€ ì´ë¦„ì˜ ë””ë ‰í† ë¦¬ê°€ 존재합니다." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid extension." -msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ í™•ìž¥ìž" +msgstr "올바르지 ì•Šì€ í™•ìž¥ìž." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Wrong extension chosen." -msgstr "ìž˜ëª»ëœ í™•ìž¥ìž ì„ íƒ" +msgstr "ìž˜ëª»ëœ í™•ìž¥ìž ì„ íƒìž…니다." #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" @@ -10228,52 +9943,44 @@ msgid "N/A" msgstr "해당 ì—†ìŒ" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Open Script / Choose Location" -msgstr "스í¬ë¦½íЏ 열기/위치 ì„ íƒ" +msgstr "스í¬ë¦½íЏ 열기 / 위치 ì„ íƒ" #: editor/script_create_dialog.cpp msgid "Open Script" msgstr "스í¬ë¦½íЏ 열기" #: editor/script_create_dialog.cpp -#, fuzzy msgid "File exists, it will be reused." -msgstr "파ì¼ì´ 존재하여, 재사용합니다" +msgstr "파ì¼ì´ 존재합니다, 재사용ë©ë‹ˆë‹¤." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid class name." -msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ í´ëž˜ìŠ¤ëª…" +msgstr "올바르지 ì•Šì€ í´ëž˜ìŠ¤ëª…." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid inherited parent name or path." -msgstr "ìœ íš¨í•˜ì§€ ì•Šì€ ìƒì†ëœ 부모 ì´ë¦„ ë˜ëŠ” 경로" +msgstr "올바르지 ì•Šì€ ìƒì†ëœ 부모 ì´ë¦„ ë˜ëŠ” 경로." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script is valid." -msgstr "ìœ íš¨í•œ 스í¬ë¦½íЏ" +msgstr "스í¬ë¦½íŠ¸ê°€ ìœ íš¨í•©ë‹ˆë‹¤." #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9 and _" -msgstr "허용ë¨:a-z, A-z, 0-9 ê·¸ë¦¬ê³ _" +msgstr "허용ë¨: a-z, A-z, 0-9 ê·¸ë¦¬ê³ _" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Built-in script (into scene file)." -msgstr "(씬 íŒŒì¼ ì•ˆì—) ë‚´ìž¥ëœ ìŠ¤í¬ë¦½íЏ" +msgstr "내장 스í¬ë¦½íЏ (씬 íŒŒì¼ ì•ˆ)." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will create a new script file." -msgstr "새 스í¬ë¦½íЏ íŒŒì¼ ë§Œë“¤ê¸°" +msgstr "새 스í¬ë¦½íЏ 파ì¼ì„ ë§Œë“니다." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will load an existing script file." -msgstr "기존 스í¬ë¦½íЏ íŒŒì¼ ë¶ˆëŸ¬ì˜¤ê¸°" +msgstr "기존 스í¬ë¦½íЏ 파ì¼ì„ 불러옵니다." #: editor/script_create_dialog.cpp msgid "Language" @@ -10315,7 +10022,7 @@ msgstr "ìŠ¤íƒ ì¶”ì " msgid "Pick one or more items from the list to display the graph." msgstr "목ë¡ì—서 한 ê°œ í˜¹ì€ ì—¬ëŸ¬ ê°œì˜ í•ëª©ì„ ì§‘ì–´ 그래프로 ë³´ì—¬ì¤ë‹ˆë‹¤." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "오류" @@ -10405,7 +10112,7 @@ msgstr "트리로부터 ì„¤ì •" #: editor/script_editor_debugger.cpp msgid "Export measures as CSV" -msgstr "" +msgstr "CSV로 ì¸¡ì • ê°’ 내보내기" #: editor/settings_config_dialog.cpp msgid "Erase Shortcut" @@ -10537,12 +10244,11 @@ msgstr "GD네ì´í‹°ë¸Œ ë¼ì´ë¸ŒëŸ¬ë¦¬" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Enabled GDNative Singleton" -msgstr "" +msgstr "í™œì„±í™”ëœ GDNative 싱글톤" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Disabled GDNative Singleton" -msgstr "ì—…ë°ì´íЏ 스피너 비활성화" +msgstr "ë¹„í™œì„±í™”ëœ GDNative 싱글톤" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Library" @@ -10631,9 +10337,8 @@ msgid "GridMap Fill Selection" msgstr "그리드맵 채우기 ì„ íƒ" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Paste Selection" -msgstr "그리드맵 ì„ íƒ ì‚ì œ" +msgstr "그리드맵 ì„ íƒ ë¶™ì—¬ë„£ê¸°" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Paint" @@ -10719,54 +10424,6 @@ msgstr "거리 ì„ íƒ:" msgid "Class name can't be a reserved keyword" msgstr "í´ëž˜ìФ ì´ë¦„ì€ í‚¤ì›Œë“œê°€ ë 수 없습니다" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "솔루션 ìƒì„± 중..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "C# 프로ì 트 ìƒì„± 중..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "솔루션 ìƒì„± 실패." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "솔루션 ì €ìž¥ 실패." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "완료" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "C# 프로ì 트 ìƒì„± 실패." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "모노" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "C# ì§€ì›ì— 대하여" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "C# 솔루션 만들기" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "빌드" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "프로ì 트 빌드" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "로그 보기" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "ë‚´ë¶€ 예외 ìŠ¤íƒ ì¶”ì ì˜ ë" @@ -11061,9 +10718,8 @@ msgid "Available Nodes:" msgstr "사용 가능한 노드:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Select or create a function to edit its graph." -msgstr "그래프를 편집하기 위한 함수를 ì„ íƒí•˜ê±°ë‚˜ 만들기" +msgstr "그래프를 편집하기 위한 함수를 ì„ íƒí•˜ê±°ë‚˜ 만드세요." #: modules/visual_script/visual_script_editor.cpp msgid "Delete Selected" @@ -11198,15 +10854,18 @@ msgstr "Debug keystoreì´ ì—디터 ì„¤ì • ë˜ëŠ” 프리셋ì—서 구성ë˜ì§€ ì #: platform/android/export/export.cpp msgid "Custom build requires a valid Android SDK path in Editor Settings." msgstr "" +"커스텀 빌드ì—는 ì—디터 ì„¤ì •ì—서 ìœ íš¨í•œ 안드로ì´ë“œ SDK 경로가 필요합니다." #: platform/android/export/export.cpp msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" +msgstr "ì—디터 ì„¤ì •ì—서 커스텀 ë¹Œë“œì— ì˜¬ë°”ë¥´ì§€ ì•Šì€ ì•ˆë“œë¡œì´ë“œ SDK 경로입니다." #: platform/android/export/export.cpp msgid "" "Android project is not installed for compiling. Install from Editor menu." msgstr "" +"컴파ì¼ì„ 하기 위한 안드로ì´ë“œ 프로ì 트가 설치ë˜ì§€ 않았습니다. ì—디터 메뉴ì—" +"서 설치하세요." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -11221,6 +10880,8 @@ 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 "" @@ -11229,20 +10890,26 @@ msgid "" " Godot Version: %s\n" "Please reinstall Android build template from 'Project' menu." msgstr "" +"안드로ì´ë“œ 빌드 ë²„ì „ì´ ë§žì§€ 않습니다:\n" +" ì„¤ì¹˜ëœ í…œí”Œë¦¿: %s\n" +" Godot ë²„ì „: %s\n" +"'프로ì 트' 메뉴ì—서 안드로ì´ë“œ 빌드 í…œí”Œë¦¿ì„ ë‹¤ì‹œ 설치해주세요." #: platform/android/export/export.cpp msgid "Building Android Project (gradle)" -msgstr "" +msgstr "안드로ì´ë“œ 프로ì 트 빌드 중 (gradle)" #: platform/android/export/export.cpp msgid "" "Building of Android project failed, check output for the error.\n" "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" +"안드로ì´ë“œ 프로ì íŠ¸ì˜ ë¹Œë“œì— ì‹¤íŒ¨í–ˆìŠµë‹ˆë‹¤, ì¶œë ¥í•œ 오류를 확ì¸í•˜ì„¸ìš”.\n" +"ë˜ëŠ” docs.godotengine.orgì—서 안드로ì´ë“œ 빌드 문서를 ì°¾ì„ ìˆ˜ 있습니다." #: platform/android/export/export.cpp msgid "No build apk generated at: " -msgstr "" +msgstr "ì—¬ê¸°ì— ë¹Œë“œ apkê°€ ìƒì„±ë˜ì§€ 않았습니다: " #: platform/iphone/export/export.cpp msgid "Identifier is missing." @@ -11359,8 +11026,9 @@ msgstr "" "ìœ íš¨í•˜ì§€ ì•Šì€ ìŠ¤í”Œëž˜ì‰¬ 스í¬ë¦° ì´ë¯¸ì§€ í¬ê¸°ìž…니다 (620x300 ì´ì–´ì•¼ 합니다)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "AnimatedSpriteì´ í”„ë ˆìž„ì„ ë³´ì—¬ì£¼ê¸° 위해서는 'Frames' ì†ì„±ì— SpriteFrames 리소" @@ -11426,8 +11094,9 @@ msgstr "" "CanvasItemMaterialì´ í•„ìš”í•©ë‹ˆë‹¤." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "ë¼ì´íŠ¸ì˜ ëª¨ì–‘ì„ ë‚˜íƒ€ë‚´ëŠ” í…스ì³ë¥¼ 'texture' ì†ì„±ì— ì§€ì •í•´ì•¼í•©ë‹ˆë‹¤." @@ -11438,7 +11107,8 @@ msgstr "" "Occluderê°€ ë™ìž‘하기 위해서는 Occluder í´ë¦¬ê³¤ì„ ì§€ì •í•˜ê±°ë‚˜ ê·¸ë ¤ì•¼ 합니다." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "Occluder í´ë¦¬ê³¤ì´ 비어있습니다. í´ë¦¬ê³¤ì„ 그리세요!" #: scene/2d/navigation_polygon.cpp @@ -11522,46 +11192,54 @@ msgstr "" "ì´ ë³¸ì— ì ì ˆí•œ íœ´ì‹ ìžì„¸ê°€ 없습니다. Skeleton2D 노드로 ê°€ 휴ì‹ìœ¼ë¡œ í• ìžì„¸ë¥¼ " "ì„¤ì •í•˜ì„¸ìš”." +#: 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 "" +"Use Parentê°€ 켜진 TileMapì€ í˜•íƒœë¥¼ 주기 위해 부모 CollisionObject2Dê°€ 필요합" +"니다. 형태를 주기 위해 Area2D, StaticBody2D, RigidBody2D, KinematicBody2D 등" +"ì˜ ìžì‹ 노드로 추가하여 사용합니다." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D는 편집 ì”¬ì˜ ë£¨íŠ¸ì˜ í•˜ìœ„ 노드로 ì¶”ê°€í• ë•Œ 가장 잘 ë™ìž‘합니" "다." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera는 반드시 ARVROrigin 노드를 부모로 ê°€ì§€ê³ ìžˆì–´ì•¼ 함" #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRController must have an ARVROrigin node as its parent." -msgstr "ARVRController는 반드시 ARVROrigin 노드를 부모로 ê°€ì§€ê³ ìžˆì–´ì•¼ 함" +msgstr "ARVRController는 반드시 ARVROrigin 노드를 부모로 ê°€ì§€ê³ ìžˆì–´ì•¼ 합니다." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The controller ID must not be 0 or this controller won't be bound to an " "actual controller." -msgstr "컨트롤러 idê°€ 0ì´ ë˜ë©´ 컨트롤러가 ì‹¤ì œ ì»¨íŠ¸ë¡¤ëŸ¬ì— ë°”ì¸ë”©í•˜ì§€ 않게 ë¨" +msgstr "" +"컨트롤러 IDê°€ 0ì´ ë˜ë©´ 컨트롤러가 ì‹¤ì œ ì»¨íŠ¸ë¡¤ëŸ¬ì— ë°”ì¸ë”©í•˜ì§€ 않게 ë©ë‹ˆë‹¤." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRAnchor must have an ARVROrigin node as its parent." -msgstr "ARVRAnchor는 반드시 ARVROrigin 노드를 부모로 ê°€ì§€ê³ ìžˆì–´ì•¼ 함" +msgstr "ARVRAnchor는 반드시 ARVROrigin 노드를 부모로 ê°€ì§€ê³ ìžˆì–´ì•¼ 합니다." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The anchor ID must not be 0 or this anchor won't be bound to an actual " "anchor." -msgstr "앵커 idê°€ 0ì´ ë˜ë©´ 앵커가 ì‹¤ì œ ì•µì»¤ì— ë°”ì¸ë”©í•˜ì§€ 않게 ë¨" +msgstr "앵커 IDê°€ 0ì´ ë˜ë©´ 앵커가 ì‹¤ì œ ì•µì»¤ì— ë°”ì¸ë”©í•˜ì§€ 않게 ë©ë‹ˆë‹¤." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVROrigin requires an ARVRCamera child node." -msgstr "ARVROriginì€ ARVRCamera ìžì‹ 노드를 요구 함" +msgstr "ARVROriginì€ ìžì‹ìœ¼ë¡œ ARVRCamera 노드가 필요합니다." #: scene/3d/baked_lightmap.cpp msgid "%d%%" @@ -11623,9 +11301,10 @@ msgstr "" "합니다." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "CollisionShapeê°€ ê¸°ëŠ¥ì„ í•˜ê¸° 위해서는 Shapeì´ ì œê³µë˜ì–´ì•¼ 합니다. Shape 리소스" "를 만드세요!" @@ -11643,13 +11322,12 @@ msgid "Nothing is visible because no mesh has been assigned." msgstr "ì§€ì •ëœ ë©”ì‹œê°€ 없으므로 메시를 ë³¼ 수 없습니다." #: scene/3d/cpu_particles.cpp -#, fuzzy msgid "" "CPUParticles animation requires the usage of a SpatialMaterial whose " "Billboard Mode is set to \"Particle Billboard\"." msgstr "" -"CPUParticles ì• ë‹ˆë©”ì´ì…˜ì„ ì‚¬ìš©í•˜ë ¤ë©´ \"Billboard Particles\"ì´ í™œì„±í™”ëœ " -"SpatialMaterialì´ í•„ìš”í•©ë‹ˆë‹¤." +"CPUParticles ì• ë‹ˆë©”ì´ì…˜ì„ ì‚¬ìš©í•˜ë ¤ë©´ Billboard Modeê°€ \"Particle Billboard" +"\"로 ì„¤ì •ëœ SpatialMaterialì´ í•„ìš”í•©ë‹ˆë‹¤." #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" @@ -11663,6 +11341,10 @@ msgstr "" "GIProbe는 GLES2 비디오 드ë¼ì´ë²„ì—서 ì§€ì›í•˜ì§€ 않습니다.\n" "BakedLightmapì„ ì‚¬ìš©í•˜ì„¸ìš”." +#: 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 "" @@ -11693,22 +11375,22 @@ msgid "" msgstr "ë©”ì‹œë“¤ì„ íŒ¨ìŠ¤ë¥¼ 그리ë„ë¡ í• ë‹¹í•˜ì§€ 않았으므로 ë³´ì´ì§€ 않습니다." #: scene/3d/particles.cpp -#, fuzzy msgid "" "Particles animation requires the usage of a SpatialMaterial whose Billboard " "Mode is set to \"Particle Billboard\"." msgstr "" -"Particles ì• ë‹ˆë©”ì´ì…˜ì„ ì‚¬ìš©í•˜ë ¤ë©´ \"Billboard Particles\"ì´ í™œì„±í™”ëœ " -"SpatialMaterialì´ í•„ìš”í•©ë‹ˆë‹¤." +"Particles ì• ë‹ˆë©”ì´ì…˜ì„ ì‚¬ìš©í•˜ë ¤ë©´ Billboard Modeê°€ \"Particle Billboard\"로 " +"ì„¤ì •ëœ SpatialMaterialì´ í•„ìš”í•©ë‹ˆë‹¤." #: scene/3d/path.cpp msgid "PathFollow only works when set as a child of a Path node." msgstr "PathFollow는 Path ë…¸ë“œì˜ ìžì‹ìœ¼ë¡œ ìžˆì„ ë•Œë§Œ ë™ìž‘합니다." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED는 부모 Pathì˜ Curve 리소스ì—서 \"Up Vector\"ê°€ " "활성화ë˜ì–´ 있어야 합니다." @@ -11724,13 +11406,15 @@ msgstr "" "ëŒ€ì‹ ìžì‹ ì¶©ëŒ í˜•íƒœì˜ í¬ê¸°ë¥¼ 변경해보세요." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "Path ì†ì„±ì€ ìœ íš¨í•œ Spatial 노드를 가리켜야 합니다." #: scene/3d/soft_body.cpp -#, fuzzy msgid "This body will be ignored until you set a mesh." -msgstr "ì´ ë°”ë””ëŠ” 메시를 ì„¤ì •í• ë•Œ 까지 무시ë©ë‹ˆë‹¤" +msgstr "ì´ ë°”ë””ëŠ” 메시를 ì„¤ì •í• ë•Œê¹Œì§€ 무시ë©ë‹ˆë‹¤." #: scene/3d/soft_body.cpp msgid "" @@ -11742,8 +11426,9 @@ msgstr "" "ëŒ€ì‹ ìžì‹ì˜ ì¶©ëŒ í¬ê¸°ë¥¼ 변경하세요." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "AnimatedSprite3Dê°€ í”„ë ˆìž„ì„ ë³´ì—¬ì£¼ê¸° 위해서는 'Frames' ì†ì„±ì— SpriteFrames 리" @@ -11758,8 +11443,10 @@ msgstr "" "ì˜ ìžì‹ìœ¼ë¡œ 사용해주세요." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment는 Environment 리소스가 필요합니다." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11795,7 +11482,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "노드 '%s'ì˜ '%s' ìž…ë ¥ì— ì•„ë¬´ê²ƒë„ ì—°ê²°ë˜ì§€ 않ìŒ." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "ê·¸ëž˜í”„ì˜ ë£¨íŠ¸ AnimationNodeê°€ ì„¤ì •ë˜ì§€ 않았습니다." #: scene/animation/animation_tree.cpp @@ -11810,7 +11498,8 @@ msgstr "" "다." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "AnimationPlayer 루트가 ìœ íš¨í•œ 노드가 아닙니다." #: scene/animation/animation_tree_player.cpp @@ -11823,8 +11512,12 @@ msgid "Pick a color from the screen." msgstr "화면ì—서 색ìƒì„ ì„ íƒí•˜ì„¸ìš”." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Raw 모드" +msgid "HSV" +msgstr "HSV" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "Raw" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11837,14 +11530,22 @@ msgstr "현재 색ìƒì„ 프리셋으로 추가합니다." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" -"컨테ì´ë„ˆ ìžì²´ëŠ” ìžì‹ 배치 í–‰ë™ì„ 구성하지 않는 한 ìš©ë„ê°€ 없습니다.\n" +"Container ìžì²´ëŠ” ìžì‹ 배치 ìž‘ì—…ì„ êµ¬ì„±í•˜ëŠ” 스í¬ë¦½íЏ 외ì—는 목ì ì´ ì—†ìŠµë‹ˆë‹¤.\n" "스í¬ë¦½íŠ¸ë¥¼ 추가하지 않는 경우, 순수한 'Control' 노드를 사용해주세요." +#: 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 "" +"Hint Tooltipì€ Controlì˜ Mouse Filterê°€ \"ignore\"로 ì„¤ì •ë˜ì–´ 있기 ë•Œë¬¸ì— ë³´" +"여지지 않습니다. í•´ê²°í•˜ë ¤ë©´, Mouse Filter를 \"Stop\"ì´ë‚˜ \"Pass\"로 ì„¤ì •í•˜ì„¸" +"ìš”." + #: scene/gui/dialogs.cpp msgid "Alert!" msgstr "ê²½ê³ !" @@ -11854,22 +11555,25 @@ msgid "Please Confirm..." msgstr "확ì¸í•´ì£¼ì„¸ìš”..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Popupì€ popup() ë˜ëŠ” 기타 popup*() 함수를 호출하기 ì „ê¹Œì§€ëŠ” 기본ì 으로 숨겨집" "니다. 편집하는 ë™ì•ˆ 보여지ë„ë¡ í• ìˆ˜ëŠ” 있으나, 실행 시ì—는 숨겨집니다." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "exp_editì´ ì°¸ì´ë¼ë©´ min_value는 반드시 > 0 ì´ì–´ì•¼ 합니다." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer는 ë‹¨ì¼ ìžì‹ ì»¨íŠ¸ë¡¤ì„ ìž‘ì—…í•˜ê¸° 위한 것입니다.\n" @@ -11921,6 +11625,11 @@ msgid "Input" msgstr "ìž…ë ¥" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "ì…°ì´ë”ì— ìœ íš¨í•˜ì§€ ì•Šì€ ì†ŒìŠ¤." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "ì…°ì´ë”ì— ìœ íš¨í•˜ì§€ ì•Šì€ ì†ŒìŠ¤." @@ -11938,7 +11647,223 @@ msgstr "Varyings는 ì˜¤ì§ ë²„í…스 함수ì—서만 ì§€ì •í• ìˆ˜ 있습니다. #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "ìƒìˆ˜ëŠ” ìˆ˜ì •í• ìˆ˜ 없습니다." + +#~ msgid "Generating solution..." +#~ msgstr "솔루션 ìƒì„± 중..." + +#~ msgid "Generating C# project..." +#~ msgstr "C# 프로ì 트 ìƒì„± 중..." + +#~ msgid "Failed to create solution." +#~ msgstr "솔루션 ìƒì„± 실패." + +#~ msgid "Failed to save solution." +#~ msgstr "솔루션 ì €ìž¥ 실패." + +#~ msgid "Done" +#~ msgstr "완료" + +#~ msgid "Failed to create C# project." +#~ msgstr "C# 프로ì 트 ìƒì„± 실패." + +#~ msgid "Mono" +#~ msgstr "모노" + +#~ msgid "About C# support" +#~ msgstr "C# ì§€ì›ì— 대하여" + +#~ msgid "Create C# solution" +#~ msgstr "C# 솔루션 만들기" + +#~ msgid "Builds" +#~ msgstr "빌드" + +#~ msgid "Build Project" +#~ msgstr "프로ì 트 빌드" + +#~ msgid "View log" +#~ msgstr "로그 보기" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment는 Environment 리소스가 필요합니다." + +#~ msgid "Enabled Classes" +#~ msgstr "í™œì„±í™”ëœ í´ëž˜ìФ" + +#~ msgid "Update Always" +#~ msgstr "í•ìƒ ì—…ë°ì´íЏ" + +#~ msgid "'camera' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'camera' ìž…ë ¥ 매개변수." + +#~ msgid "'inv_camera' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'inv_camera' ìž…ë ¥ 매개변수." + +#~ msgid "'inv_projection' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'inv_projection' ìž…ë ¥ 매개변수." + +#~ msgid "'normal' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'normal' ìž…ë ¥ 매개변수." + +#~ msgid "'projection' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'projection' ìž…ë ¥ 매개변수." + +#~ msgid "'time' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'time' ìž…ë ¥ 매개변수." + +#~ msgid "'viewport_size' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'viewport_size' ìž…ë ¥ 매개변수." + +#~ msgid "'world' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'world' ìž…ë ¥ 매개변수." + +#~ msgid "'alpha' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'alpha' ìž…ë ¥ 매개변수." + +#~ msgid "'color' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'color' ìž…ë ¥ 매개변수." + +#~ msgid "'texture_pixel_size' input parameter for all shader modes." +#~ msgstr "ëª¨ë“ ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'texture_pixel_size' ìž…ë ¥ 매개변수." + +#~ msgid "'alpha' input parameter for vertex and fragment shader modes." +#~ msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'alpha' ìž…ë ¥ 매개변수." + +#~ msgid "'binormal' input parameter for vertex and fragment shader modes." +#~ msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'binormal' ìž…ë ¥ 매개변수." + +#~ msgid "'color' input parameter for vertex and fragment shader modes." +#~ msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'color' ìž…ë ¥ 매개변수." + +#~ msgid "'fragcoord' input parameter for fragment and light shader modes." +#~ msgstr "프래그먼트와 조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'fragcoord' ìž…ë ¥ 매개변수." + +#~ msgid "'point_coord' input parameter for fragment shader mode." +#~ msgstr "프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'point_coord' ìž…ë ¥ 매개변수." + +#~ msgid "'screen_uv' input parameter for fragment shader mode." +#~ msgstr "프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'screen_uv' ìž…ë ¥ 매개변수." + +#~ msgid "'tangent' input parameter for vertex and fragment shader modes." +#~ msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'tangent' ìž…ë ¥ 매개변수." + +#~ msgid "'uv2' input parameter for vertex and fragment shader modes." +#~ msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'uv2' ìž…ë ¥ 매개변수." + +#~ msgid "'vertex' input parameter for vertex and fragment shader modes." +#~ msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'vertex' ìž…ë ¥ 매개변수." + +#~ msgid "'albedo' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'albedo' ìž…ë ¥ 매개변수." + +#~ msgid "'attenuation' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'attenuation' ìž…ë ¥ 매개변수." + +#~ msgid "'light' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'light' ìž…ë ¥ 매개변수." + +#~ msgid "'light_color' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'light_color' ìž…ë ¥ 매개변수." + +#~ msgid "'roughness' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'roughness' ìž…ë ¥ 매개변수." + +#~ msgid "'specular' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'specular' ìž…ë ¥ 매개변수." + +#~ msgid "'transmission' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'transmission' ìž…ë ¥ 매개변수." + +#~ msgid "'modelview' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'modelview' ìž…ë ¥ 매개변수." + +#~ msgid "'point_size' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'point_size' ìž…ë ¥ 매개변수." + +#~ msgid "'tangent' input parameter for vertex and fragment shader mode." +#~ msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'tangent' ìž…ë ¥ 매개변수." + +#~ msgid "'light_pass' input parameter for vertex and fragment shader modes." +#~ msgstr "ê¼ì§“ì ê³¼ 프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'light_pass' ìž…ë ¥ 매개변수." + +#~ msgid "'point_coord' input parameter for fragment and light shader modes." +#~ msgstr "프래그먼트와 조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'point_coord' ìž…ë ¥ 매개변수." + +#~ msgid "'screen_pixel_size' input parameter for fragment shader mode." +#~ msgstr "프래그먼트 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'screen_pixel_size' ìž…ë ¥ 매개변수." + +#~ msgid "'screen_uv' input parameter for fragment and light shader modes." +#~ msgstr "프래그먼트와 조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'screen_uv' ìž…ë ¥ 매개변수." + +#~ msgid "'light_alpha' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'light_alpha' ìž…ë ¥ 매개변수." + +#~ msgid "'light_height' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'light_height' ìž…ë ¥ 매개변수." + +#~ msgid "'light_uv' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'light_uv' ìž…ë ¥ 매개변수." + +#~ msgid "'light_vec' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'light_vec' ìž…ë ¥ 매개변수." + +#~ msgid "'normal' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'normal' ìž…ë ¥ 매개변수." + +#~ msgid "'shadow_color' input parameter for light shader mode." +#~ msgstr "조명 ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'shadow_color' ìž…ë ¥ 매개변수." + +#~ msgid "'extra' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'extra' ìž…ë ¥ 매개변수." + +#~ msgid "'projection' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'projection' ìž…ë ¥ 매개변수." + +#~ msgid "'vertex' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'vertex' ìž…ë ¥ 매개변수." + +#~ msgid "'world' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'world' ìž…ë ¥ 매개변수." + +#~ msgid "'active' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'active' ìž…ë ¥ 매개변수." + +#~ msgid "'alpha' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'alpha' ìž…ë ¥ 매개변수." + +#~ msgid "'color' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'color' ìž…ë ¥ 매개변수." + +#~ msgid "'custom_alpha' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'custom_alpha' ìž…ë ¥ 매개변수." + +#~ msgid "'delta' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'delta' ìž…ë ¥ 매개변수." + +#~ msgid "'emission_transform' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'emission_transform' ìž…ë ¥ 매개변수." + +#~ msgid "'index' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'index' ìž…ë ¥ 매개변수." + +#~ msgid "'lifetime' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'lifetime' ìž…ë ¥ 매개변수." + +#~ msgid "'restart' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'restart' ìž…ë ¥ 매개변수." + +#~ msgid "'time' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'time' ìž…ë ¥ 매개변수." + +#~ msgid "'transform' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'transform' ìž…ë ¥ 매개변수." + +#~ msgid "'velocity' input parameter for vertex shader mode." +#~ msgstr "ê¼ì§“ì ì…°ì´ë” ëª¨ë“œì— ëŒ€í•œ 'velocity' ìž…ë ¥ 매개변수." + +#~ msgid "Raw Mode" +#~ msgstr "Raw 모드" #~ msgid "Path to Node:" #~ msgstr "노드 경로:" @@ -12496,9 +12421,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Spatial ë³´ì´ê¸° í† ê¸€" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "CanvasItem ë³´ì´ê¸° í† ê¸€" - #~ msgid "Condition" #~ msgstr "ì¡°ê±´" @@ -13382,9 +13304,6 @@ msgstr "" #~ msgid "Images:" #~ msgstr "ì´ë¯¸ì§€:" -#~ msgid "Select None" -#~ msgstr "ëª¨ë“ ì„ íƒ í•´ì œ" - #~ msgid "Group" #~ msgstr "그룹" diff --git a/editor/translations/lt.po b/editor/translations/lt.po index 4fbba5cd26..ab9107801f 100644 --- a/editor/translations/lt.po +++ b/editor/translations/lt.po @@ -449,6 +449,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Pasirinkite Nodus, kuriuos norite importuoti" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -628,6 +638,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -677,7 +691,7 @@ msgstr "Nutolinti" msgid "Reset Zoom" msgstr "Atstatyti PriartinimÄ…" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -787,6 +801,11 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signalai" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Prijungti '%s' prie '%s'" @@ -950,7 +969,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1314,7 +1333,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1486,6 +1505,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1515,7 +1538,7 @@ msgid "Node Dock" msgstr "Naujas pavadinimas:" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1571,7 +1594,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1586,7 +1609,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "PradÄ—ti ProfiliavimÄ…" #: editor/editor_feature_profile.cpp @@ -1610,12 +1633,9 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" -msgstr "" +#, fuzzy +msgid "Available Profiles:" +msgstr "Animacija" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2639,10 +2659,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2749,15 +2789,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2951,7 +2991,7 @@ msgstr "TrukmÄ—:" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3051,6 +3091,11 @@ 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 #, fuzzy msgid "New Key:" msgstr "Naujas pavadinimas:" @@ -3064,11 +3109,6 @@ msgstr "Naujas pavadinimas:" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3568,6 +3608,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5186,6 +5227,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "PradÄ—ti!" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6106,10 +6155,20 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filtrai..." + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Filtrai..." + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "" @@ -6343,18 +6402,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Sukurti" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7930,51 +7993,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7982,203 +8001,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9826,6 +9669,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9855,8 +9702,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Sukurti NaujÄ…" #: editor/scene_tree_dock.cpp msgid "" @@ -10100,7 +9948,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10503,54 +10351,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11135,7 +10935,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11184,7 +10984,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11194,7 +10994,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11261,14 +11061,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11347,7 +11154,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11376,6 +11183,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11412,8 +11223,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11424,7 +11235,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11440,7 +11253,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11451,7 +11264,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11489,7 +11304,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Prijungti '%s' prie '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11503,7 +11318,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11515,7 +11330,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11528,10 +11347,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11545,18 +11369,18 @@ msgstr "PraÅ¡ome Patvirtinti..." #: 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11600,6 +11424,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "Netinkamas Å¡rifto dydis." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "Netinkamas Å¡rifto dydis." diff --git a/editor/translations/lv.po b/editor/translations/lv.po index 88a44ac770..cb6df1de91 100644 --- a/editor/translations/lv.po +++ b/editor/translations/lv.po @@ -447,6 +447,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "DzÄ“st izvÄ“lÄ“tos" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "RÄdÄ«t celiņus tikai no mezgliem izvÄ“lÄ“tajÄ kokÄ." @@ -626,6 +636,10 @@ msgstr "Doties uz Rindu" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -675,7 +689,7 @@ msgstr "AttÄlinÄt" msgid "Reset Zoom" msgstr "AtiestatÄ«t tÄlummaiņu" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -783,6 +797,11 @@ msgid "Connect" msgstr "Savienot" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "SignÄli" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Savienot '%s' pie '%s'" @@ -944,7 +963,7 @@ msgid "Owners Of:" msgstr "ĪpaÅ¡nieki:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1322,7 +1341,7 @@ msgstr "" #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" "NederÄ«gs nosaukums. NedrÄ«kst sadurties ar eksistÄ“joÅ¡u iebÅ«vÄ“to tipa " "nosaukumu." @@ -1499,6 +1518,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1525,7 +1548,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1581,7 +1604,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1595,7 +1618,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1619,12 +1642,9 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" -msgstr "" +#, fuzzy +msgid "Available Profiles:" +msgstr "AnimÄcijas Ä«pašības." #: editor/editor_feature_profile.cpp #, fuzzy @@ -2647,10 +2667,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2757,15 +2797,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "NepÄrtraukti" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2955,7 +2996,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3054,20 +3095,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3565,6 +3606,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5171,6 +5213,13 @@ 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 "" @@ -6089,10 +6138,18 @@ msgid "Find Next" 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 "" @@ -6327,18 +6384,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Izveidot" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7912,51 +7973,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7964,203 +7981,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9798,6 +9639,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9826,8 +9671,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Izveidot Jaunu %s" #: editor/scene_tree_dock.cpp msgid "" @@ -10071,7 +9917,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10474,54 +10320,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11104,7 +10902,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11153,7 +10951,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11163,7 +10961,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11230,14 +11028,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11316,7 +11121,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11345,6 +11150,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11379,8 +11188,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11391,7 +11200,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11407,7 +11218,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11418,7 +11229,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11456,7 +11269,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Atvienot '%s' no '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11468,7 +11281,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11480,7 +11293,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11494,10 +11311,15 @@ msgstr "Pievienot paÅ¡reizÄ“jo krÄsu kÄ iepriekÅ¡noteiktu krÄsu" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11511,18 +11333,18 @@ msgstr "LÅ«dzu Apstipriniet..." #: 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11566,6 +11388,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "NederÄ«gs fonta izmÄ“rs." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "NederÄ«gs fonta izmÄ“rs." diff --git a/editor/translations/mi.po b/editor/translations/mi.po index 96c2290611..5462f66f69 100644 --- a/editor/translations/mi.po +++ b/editor/translations/mi.po @@ -419,6 +419,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -593,6 +602,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -642,7 +655,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -745,6 +758,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -903,7 +920,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1267,7 +1284,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1438,6 +1455,10 @@ msgstr "" 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 "" @@ -1463,7 +1484,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1516,7 +1537,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1529,7 +1550,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1552,11 +1573,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2562,10 +2579,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2672,15 +2709,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2870,7 +2907,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2968,20 +3005,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3466,6 +3503,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5045,6 +5083,13 @@ 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 "" @@ -5945,10 +5990,18 @@ msgid "Find Next" 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 "" @@ -6176,18 +6229,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7707,51 +7763,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7759,203 +7771,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9582,6 +9418,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9610,7 +9450,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9847,7 +9687,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10247,54 +10087,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10871,7 +10663,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10920,7 +10712,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10930,7 +10722,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -10997,14 +10789,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11083,7 +10882,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11112,6 +10911,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11146,8 +10949,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11158,7 +10961,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11174,7 +10979,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11185,7 +10990,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11220,7 +11027,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11232,7 +11039,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11244,7 +11051,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11257,10 +11068,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11274,18 +11090,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11328,6 +11144,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/ml.po b/editor/translations/ml.po index 57bf923ff0..4e120c2412 100644 --- a/editor/translations/ml.po +++ b/editor/translations/ml.po @@ -427,6 +427,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -601,6 +610,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -650,7 +663,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -753,6 +766,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -911,7 +928,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1275,7 +1292,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1446,6 +1463,10 @@ msgstr "" 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 "" @@ -1471,7 +1492,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1524,7 +1545,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1537,7 +1558,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1560,11 +1581,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2570,10 +2587,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2680,15 +2717,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2878,7 +2915,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2976,20 +3013,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3474,6 +3511,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5053,6 +5091,13 @@ 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 "" @@ -5953,10 +5998,18 @@ msgid "Find Next" 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 "" @@ -6184,18 +6237,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7715,51 +7771,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7767,203 +7779,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9590,6 +9426,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9618,7 +9458,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9855,7 +9695,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10255,54 +10095,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10879,7 +10671,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10928,7 +10720,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10938,7 +10730,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11005,14 +10797,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11091,7 +10890,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11120,6 +10919,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11154,8 +10957,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11166,7 +10969,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11182,7 +10987,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11193,7 +10998,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11228,7 +11035,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11240,7 +11047,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11252,7 +11059,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11265,10 +11076,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11282,18 +11098,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11336,6 +11152,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/ms.po b/editor/translations/ms.po index 887415936d..7b7ac1ea61 100644 --- a/editor/translations/ms.po +++ b/editor/translations/ms.po @@ -439,6 +439,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Semua Pilihan" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -615,6 +625,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -664,7 +678,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -767,6 +781,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -925,7 +943,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1289,7 +1307,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1460,6 +1478,10 @@ msgstr "" 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 "" @@ -1485,7 +1507,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1539,7 +1561,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1552,7 +1574,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1575,11 +1597,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2586,10 +2604,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2696,15 +2734,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2894,7 +2932,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2992,20 +3030,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3490,6 +3528,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5080,6 +5119,13 @@ 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 "" @@ -5982,10 +6028,18 @@ msgid "Find Next" 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 "" @@ -6213,18 +6267,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7757,51 +7814,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7809,203 +7822,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9636,6 +9473,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9664,7 +9505,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9901,7 +9742,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10304,54 +10145,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10928,7 +10721,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10977,7 +10770,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10987,7 +10780,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11054,14 +10847,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11140,7 +10940,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11169,6 +10969,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11203,8 +11007,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11215,7 +11019,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11231,7 +11037,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11242,7 +11048,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11277,7 +11085,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11289,7 +11097,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11301,7 +11109,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11314,10 +11126,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11331,18 +11148,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11385,6 +11202,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/nb.po b/editor/translations/nb.po index cc71c187e1..66d1b3952a 100644 --- a/editor/translations/nb.po +++ b/editor/translations/nb.po @@ -7,19 +7,20 @@ # Elias <eliasnykrem@gmail.com>, 2018. # flesk <eivindkn@gmail.com>, 2017, 2019. # Frank T. Rambol <frank@d-fect.com>, 2018. -# Jørgen Aarmo Lund <jorgen.aarmo@gmail.com>, 2016. +# Jørgen Aarmo Lund <jorgen.aarmo@gmail.com>, 2016, 2019. # NicolaiF <nico-fre@hotmail.com>, 2017-2018, 2019. # Norwegian Disaster <stian.furu.overbye@gmail.com>, 2017. # passeride <lukas@passeride.com>, 2017. # Byzantin <kasper-hoel@hotmail.com>, 2018. # Hans-Marius ØverÃ¥s <hansmariusoveras@gmail.com>, 2019. # Revolution <revosw@gmail.com>, 2019. +# Petter Reinholdtsen <pere-weblate@hungry.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-05-04 13:48+0000\n" -"Last-Translator: Allan Nordhøy <epost@anotheragency.no>\n" +"PO-Revision-Date: 2019-07-02 10:51+0000\n" +"Last-Translator: Petter Reinholdtsen <pere-weblate@hungry.com>\n" "Language-Team: Norwegian BokmÃ¥l <https://hosted.weblate.org/projects/godot-" "engine/godot/nb_NO/>\n" "Language: nb\n" @@ -27,12 +28,12 @@ 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 3.7-dev\n" +"X-Generator: Weblate 3.8-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 "Ugyldig typeargument til convert(), bruk TYPE_*-konstantene." +msgstr "Ugyldig argumenttype til convert(), bruk TYPE_*-konstantene." #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/mono/glue/gd_glue.cpp @@ -487,6 +488,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Velg Alle" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Kutt Noder" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "Vis kun spor fra noder valgt i treet." @@ -669,6 +680,10 @@ msgstr "GÃ¥ til Linje" msgid "Line Number:" msgstr "Linjenummer:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Ingen Treff" @@ -718,7 +733,7 @@ msgstr "Zoom Ut" msgid "Reset Zoom" msgstr "Nullstill Zoom" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Advarsler" @@ -830,6 +845,11 @@ msgid "Connect" msgstr "Koble Til" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signaler:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Koble '%s' til '%s'" @@ -969,7 +989,7 @@ msgstr "Ressurs" #: editor/dependency_editor.cpp editor/editor_autoload_settings.cpp #: editor/project_settings_editor.cpp editor/script_create_dialog.cpp msgid "Path" -msgstr "Søkesti" +msgstr "Bane" #: editor/dependency_editor.cpp msgid "Dependencies:" @@ -1003,7 +1023,8 @@ msgid "Owners Of:" msgstr "Eiere Av:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Fjerne valgte filer fra prosjektet? (kan ikke angres)" #: editor/dependency_editor.cpp @@ -1154,7 +1175,7 @@ msgid "" "is an exhaustive list of all such thirdparty components with their " "respective copyright statements and license terms." msgstr "" -"Godot Engine avhenger av en rekke tredjeparts fri og Ã¥pen kildekode-" +"Godot Engine avhenger av en rekke tredjeparts frie og Ã¥pne kildekode-" "biblioteker, alle kompatible med begrepene i MIT-lisensen. Følgende er en " "utfyllende liste over alle slike tredjepartskomponenter med sine respektive " "opphavsrettserklæringer og lisensbegreper." @@ -1383,7 +1404,7 @@ msgstr "" #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" "Ugyldig navn. Kan ikke kollidere med et eksisterende innebygd type navn." @@ -1570,6 +1591,10 @@ msgstr "Tilpasset utgivelsesmal ikke funnet." msgid "Template file not found:" msgstr "Malfil ble ikke funnet:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1601,7 +1626,7 @@ msgstr "Flytt Modus" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "FilSystem" #: editor/editor_feature_profile.cpp @@ -1662,7 +1687,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1677,7 +1702,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Gjeldende Versjon:" #: editor/editor_feature_profile.cpp @@ -1702,16 +1727,11 @@ msgstr "Eksporter" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "Tilgjengelige Noder:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Søk i klasser" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "Beskrivelse" @@ -2837,11 +2857,35 @@ msgid "Editor Layout" msgstr "Redigeringsverktøy Layout" #: editor/editor_node.cpp +#, fuzzy +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" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Ã…pne den neste Editoren" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Skru av/pÃ¥ Fullskjerm" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "Veksle modus" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "Redigeringsverktøy-instillinger" @@ -2954,15 +2998,18 @@ msgid "Spins when the editor window redraws." msgstr "Snurrer nÃ¥r editorvinduet rendrer om!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Oppdater Alltid" +#, fuzzy +msgid "Update Continuously" +msgstr "Kontinuerlig" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Oppdater Endringer" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Deaktiver Oppdateringsspinner" #: editor/editor_node.cpp @@ -3163,7 +3210,7 @@ msgstr "Tid:" msgid "Calls" msgstr "Ring" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "PÃ¥" @@ -3269,6 +3316,11 @@ msgid "Page: " msgstr "Side: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Fjern Gjenstand" + +#: editor/editor_properties_array_dict.cpp #, fuzzy msgid "New Key:" msgstr "Nytt navn:" @@ -3282,11 +3334,6 @@ msgstr "Nytt navn:" msgid "Add Key/Value Pair" msgstr "Legg Til Nøkkel/Verdi Par" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Fjern Gjenstand" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3828,6 +3875,7 @@ msgid "Nodes not in Group" msgstr "Legg til i Gruppe" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp #, fuzzy msgid "Filter nodes" msgstr "Lim inn Noder" @@ -5542,6 +5590,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "Omstart NÃ¥" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6498,10 +6554,20 @@ msgid "Find Next" msgstr "Finn neste" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Lim inn Noder" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Lim inn Noder" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Sorter" @@ -6741,20 +6807,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +msgstr "Slett punkter" + #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Klipp ut" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Velg Alle" - #: editor/plugins/script_text_editor.cpp #, fuzzy msgid "Delete Line" @@ -8402,51 +8472,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8455,203 +8481,27 @@ msgid "Input parameter." msgstr "Snap til foreldre" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10342,6 +10192,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Kollaps alle" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10373,8 +10228,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Lag ny %s" #: editor/scene_tree_dock.cpp msgid "" @@ -10631,7 +10487,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -11047,62 +10903,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Generating solution..." -msgstr "Lager konturer..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "Kunne ikke lage omriss!" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to save solution." -msgstr "Kunne ikke laste ressurs." - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Done" -msgstr "Ferdig!" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create C# project." -msgstr "Kunne ikke laste ressurs." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "Lag Omriss" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "Prosjekt" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Vis Filer" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11711,7 +11511,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11760,7 +11560,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11770,7 +11570,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11837,14 +11637,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11923,7 +11730,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11952,6 +11759,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11986,8 +11797,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11998,7 +11809,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -12014,7 +11827,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -12025,7 +11838,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -12063,7 +11878,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Koble '%s' fra '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -12077,7 +11892,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "Animasjonstre er ugyldig." #: scene/animation/animation_tree_player.cpp @@ -12089,7 +11904,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -12102,10 +11921,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -12119,18 +11943,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -12175,6 +11999,11 @@ msgstr "Legg til Input" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "Ugyldig fontstørrelse." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "Ugyldig fontstørrelse." @@ -12194,6 +12023,45 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Generating solution..." +#~ msgstr "Lager konturer..." + +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "Kunne ikke lage omriss!" + +#, fuzzy +#~ msgid "Failed to save solution." +#~ msgstr "Kunne ikke laste ressurs." + +#, fuzzy +#~ msgid "Done" +#~ msgstr "Ferdig!" + +#, fuzzy +#~ msgid "Failed to create C# project." +#~ msgstr "Kunne ikke laste ressurs." + +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "Lag Omriss" + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "Prosjekt" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "Vis Filer" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Søk i klasser" + +#~ msgid "Update Always" +#~ msgstr "Oppdater Alltid" + #~ msgid "Path to Node:" #~ msgstr "Sti til Node:" diff --git a/editor/translations/nl.po b/editor/translations/nl.po index 63437bc723..d5d9277fe9 100644 --- a/editor/translations/nl.po +++ b/editor/translations/nl.po @@ -472,6 +472,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Alles Selecteren" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Alles Selecteren" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "Toon alleen sporen die horen bij de geselecteerde node in de boom." @@ -647,6 +657,10 @@ msgstr "Ga naar Regel" msgid "Line Number:" msgstr "Regelnummer:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Geen Overeenkomsten" @@ -696,7 +710,7 @@ msgstr "Uitzoomen" msgid "Reset Zoom" msgstr "Initialiseer Zoom" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Waarschuwingen" @@ -809,6 +823,11 @@ msgid "Connect" msgstr "Verbinden" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signalen:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Verbind '%s' met '%s'" @@ -977,7 +996,8 @@ msgid "Owners Of:" msgstr "Eigenaren Van:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" "Verwijder geselecteerde bestanden van het project? (Kan niet ongedaan " "worden.)" @@ -1354,7 +1374,7 @@ msgstr "Ongeldige naam. Moet niet botsen met een bestaande engine klasse naam." #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" "Ongeldige naam. Mag niet botsen met een bestaande ingebouwde type naam." @@ -1533,6 +1553,10 @@ msgstr "Aangepast release pakket niet gevonden." msgid "Template file not found:" msgstr "Template bestand niet gevonden:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1565,7 +1589,7 @@ msgstr "Verplaatsingsmodus" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "Bestandssysteem" #: editor/editor_feature_profile.cpp @@ -1627,7 +1651,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1642,7 +1666,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Huidige Versie:" #: editor/editor_feature_profile.cpp @@ -1667,16 +1691,11 @@ msgstr "Exporteren" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "Beschikbare Nodes:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Zoek Klasses" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "Klassebeschrijving" @@ -2785,10 +2804,34 @@ msgid "Editor Layout" msgstr "Editor Layout" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Klinkt logisch!" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Open Editor Data/Instellingen Map" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Open de volgende Editor" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Schakel Volledig Scherm" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Gesplitste modus omschakelen" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Open Editor Data/Instellingen Map" @@ -2897,15 +2940,18 @@ msgid "Spins when the editor window redraws." msgstr "Draait wanneer het editor venster opnieuw ververst wordt!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Altijd Updaten" +#, fuzzy +msgid "Update Continuously" +msgstr "Doorlopend" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Update Veranderingen" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Schakel Update Draaier Uit" #: editor/editor_node.cpp @@ -3096,7 +3142,7 @@ msgstr "Tijd" msgid "Calls" msgstr "Aanroepen" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Aan" @@ -3203,6 +3249,11 @@ msgid "Page: " msgstr "Pagina: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Verwijder Item" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Nieuwe Sleutel:" @@ -3214,11 +3265,6 @@ msgstr "Nieuwe Waarde:" msgid "Add Key/Value Pair" msgstr "Sleutel-Waarde Paar Toevoegen" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Verwijder Item" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3728,6 +3774,7 @@ msgid "Nodes not in Group" msgstr "Knopen niet in de groep" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filter knopen" @@ -5417,6 +5464,14 @@ msgid "Load Emission Mask" msgstr "Laad Emissie Masker" #: 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 +#, fuzzy +msgid "Restart" +msgstr "Herstart Nu" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Leeg Emissie Masker" @@ -6381,10 +6436,20 @@ msgid "Find Next" msgstr "Vind Volgende" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filter eigenschappen" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "Schakel het alfabetisch sorteren van de methode lijst in of uit." #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Filter:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Sorteren" @@ -6629,20 +6694,24 @@ msgid "Syntax Highlighter" msgstr "Syntax Markeren" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +msgstr "Punten aanmaken." + #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Knippen" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Alles Selecteren" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Verwijder Regel" @@ -8321,51 +8390,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8374,203 +8399,27 @@ msgid "Input parameter." msgstr "Snap naar ouder" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10348,6 +10197,11 @@ msgstr "" #: editor/scene_tree_dock.cpp #, fuzzy +msgid "Expand/Collapse All" +msgstr "Alles inklappen" + +#: editor/scene_tree_dock.cpp +#, fuzzy msgid "Change Type" msgstr "Verander Type" @@ -10380,7 +10234,8 @@ msgid "Delete (No Confirm)" msgstr "Verwijder (Geen bevestiging)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Voeg nieuwe knooppunt aan" #: editor/scene_tree_dock.cpp @@ -10642,7 +10497,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Fouten" @@ -11057,60 +10912,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "Mislukt om resource te laden." - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to save solution." -msgstr "Mislukt om resource te laden." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create C# project." -msgstr "Mislukt om resource te laden." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "Subscriptie Maken" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "Project" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Bekijk Bestanden" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11741,8 +11542,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "Ongeldige afmetingen van splash screen afbeelding (moet 620×300 zijn)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Een SpriteFrames resource moet gemaakt of gekozen worden in de 'Frames' " @@ -11805,8 +11607,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Een textuur met de vorm van het licht moet worden aangeboden in de 'texture' " @@ -11820,7 +11623,8 @@ msgstr "" "laten werken." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "De occluder polygoon van deze occluder is leeg. Teken alsjeblieft een " "polygoon!" @@ -11896,16 +11700,29 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 dient enkel om een bots vorm te koppelen aan een node " +"afgeleid van CollisionObject2D. Gebruik het alsjeblieft als een child van " +"Area2D, StaticBody2D, RigidBody2D, KinematicBody2D etc. om ze een vorm te " +"geven." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D werkt het beste wanneer het gebruikt wordt met de " "aangepaste scene root direct als ouder." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11988,9 +11805,10 @@ msgstr "" "van Area, StaticBody, RigidBody, KinematicBody etc. om ze een vorm te geven." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Een vorm moet gegeven worden om CollisionShape te laten werken. Maak " "alsjeblieft een vorm resource voor deze!" @@ -12021,6 +11839,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -12060,8 +11882,8 @@ msgstr "PathFollow2D werkt alleen wanneer het een kind van een Path2D node is." #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -12072,7 +11894,10 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "Pad eigenschap moet verwijzen naar een geldige Spatial node om te werken." @@ -12088,8 +11913,9 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Een SpriteFrames resource moet gemaakt of gegeven worden in de 'Frames' " @@ -12102,7 +11928,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -12142,7 +11970,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Ontkoppel '%s' van '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -12157,7 +11985,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "Animatie boom is ongeldig." #: scene/animation/animation_tree_player.cpp @@ -12169,8 +11997,13 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Raw-modus" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +#, fuzzy +msgid "Raw" +msgstr "Yaw" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -12183,10 +12016,15 @@ msgstr "Huidige kleur als een preset toevoegen" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -12198,23 +12036,24 @@ msgid "Please Confirm..." msgstr "Bevestig Alsjeblieft..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Standaard verbergen pop-ups zich tenzij je popup() aanroept of één van de " "popup*() functies. Ze zichtbaar maken om te bewerken is prima, maar ze " "zullen zich verbergen bij het uitvoeren." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -12264,6 +12103,11 @@ msgid "Input" msgstr "Invoer" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Ongeldige bron voor shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Ongeldige bron voor shader." @@ -12283,6 +12127,40 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "Mislukt om resource te laden." + +#, fuzzy +#~ msgid "Failed to save solution." +#~ msgstr "Mislukt om resource te laden." + +#, fuzzy +#~ msgid "Failed to create C# project." +#~ msgstr "Mislukt om resource te laden." + +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "Subscriptie Maken" + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "Project" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "Bekijk Bestanden" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Zoek Klasses" + +#~ msgid "Update Always" +#~ msgstr "Altijd Updaten" + +#~ msgid "Raw Mode" +#~ msgstr "Raw-modus" + #~ msgid "Path to Node:" #~ msgstr "Pad naar Node:" diff --git a/editor/translations/pl.po b/editor/translations/pl.po index 912df265a7..ff93299b81 100644 --- a/editor/translations/pl.po +++ b/editor/translations/pl.po @@ -34,12 +34,13 @@ # MichaÅ‚ Topa <moonchasered@gmail.com>, 2019. # PrzemysÅ‚aw Pierzga <przemyslawpierzga@gmail.com>, 2019. # Artur MaciÄ…g <arturmaciag@gmail.com>, 2019. +# RafaÅ‚ Wyszomirski <rawyszo@gmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" -"Last-Translator: Tomek <kobewi4e@gmail.com>\n" +"PO-Revision-Date: 2019-07-09 10:47+0000\n" +"Last-Translator: RafaÅ‚ Wyszomirski <rawyszo@gmail.com>\n" "Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/" "godot/pl/>\n" "Language: pl\n" @@ -48,7 +49,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -77,19 +78,19 @@ msgstr "NieprawidÅ‚owe operandy dla operatora %s, %s i %s." #: core/math/expression.cpp msgid "Invalid index of type %s for base type %s" -msgstr "NieprawidÅ‚owy indeks we wÅ‚aÅ›ciwoÅ›ci '%s' wÄ™zÅ‚a %s" +msgstr "NieprawidÅ‚owy indeks we wÅ‚aÅ›ciwoÅ›ci \"%s\" wÄ™zÅ‚a %s" #: core/math/expression.cpp msgid "Invalid named index '%s' for base type %s" -msgstr "Niepoprawny nazwany indeks '%s' dla bazowego typu %s" +msgstr "Niepoprawny nazwany indeks \"%s\" dla bazowego typu %s" #: core/math/expression.cpp msgid "Invalid arguments to construct '%s'" -msgstr "Niepoprawne argumenty do utworzenia '%s'" +msgstr "Niepoprawne argumenty do utworzenia \"%s\"" #: core/math/expression.cpp msgid "On call to '%s':" -msgstr "Przy wywoÅ‚aniu '%s':" +msgstr "Przy wywoÅ‚aniu \"%s\":" #: editor/animation_bezier_editor.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -109,9 +110,8 @@ msgid "Time:" msgstr "Czas:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Wartość" +msgstr "Wartość:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -464,10 +464,28 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Ta animacja należy do importowanej sceny, wiÄ™c zmiany w importowanych " +"Å›cieżkach nie zostanÄ… zapisane.\n" +"\n" +"By umożliwić dodawanie wÅ‚asnych Å›cieżek, przejdź do ustawieÅ„ importu i " +"zmieÅ„\n" +"\"Animation > Storage\" na \"Files\", włącz \"Animation > Keep Custom Tracks" +"\", a potem importuj ponownie.\n" +"Alternatywnie, użyj profilu importu, który importuje animacje do oddzielnych " +"plików." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Ostrzeżenie: Edytowanie importowanej animacji" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Zaznacz wszystko" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "Wybierz wÄ™zeÅ‚" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -643,6 +661,10 @@ msgstr "Idź do lini" msgid "Line Number:" msgstr "Numer linii:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Nie znaleziono" @@ -692,7 +714,7 @@ msgstr "Oddal" msgid "Reset Zoom" msgstr "Wyzeruj przybliżenie" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Ostrzeżenia" @@ -701,38 +723,32 @@ msgid "Line and column numbers." msgstr "Numery linii i kolumn." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Wybierz metodÄ™ w wybranym węźle!" +msgstr "Metoda w węźle docelowym musi zostać podana." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Nie znaleziono wybranej metody! Podaj wÅ‚aÅ›ciwÄ… metodÄ™, lub dołącz skrypt do " +"Docelowa metoda nie znaleziona. Podaj wÅ‚aÅ›ciwÄ… metodÄ™ lub dołącz skrypt do " "wybranego wÄ™zÅ‚a." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "Podłącz do wÄ™zÅ‚a:" +msgstr "Połącz do wÄ™zÅ‚a:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Nie można połączyć do hosta:" +msgstr "Połącz do skryptu:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "SygnaÅ‚y:" +msgstr "Z sygnaÅ‚u:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "WÄ™zeÅ‚ nie zawiera geometrii." +msgstr "Scena nie posiada żadnego skryptu." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -760,9 +776,8 @@ msgid "Extra Call Arguments:" msgstr "Dodatkowe argumenty wywoÅ‚ania:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Opcje zaawansowane" +msgstr "Zaawansowane" #: editor/connections_dialog.cpp msgid "Deferred" @@ -772,6 +787,7 @@ msgstr "Opóźniony" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Opóźnij sygnaÅ‚, kolejkujÄ…c go i uruchamiajÄ…c tylko w czasie bezczynnoÅ›ci." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -779,12 +795,11 @@ msgstr "WywoÅ‚aj raz" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Odłącza sygnaÅ‚ po pierwszej emisji." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Połącz sygnaÅ‚: " +msgstr "Nie można połączyć sygnaÅ‚u" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -805,16 +820,21 @@ msgid "Connect" msgstr "Połącz" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "SygnaÅ‚y:" + +#: 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'" -msgstr "Rozłącz '%s' z '%s'" +msgstr "Rozłącz \"%s\" z \"%s\"" #: editor/connections_dialog.cpp msgid "Disconnect all from signal: '%s'" -msgstr "Rozłącz wszystko z sygnaÅ‚u: '%s'" +msgstr "Rozłącz wszystko z sygnaÅ‚u: \"%s\"" #: editor/connections_dialog.cpp msgid "Connect..." @@ -826,14 +846,12 @@ msgid "Disconnect" msgstr "Rozłącz" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Połącz sygnaÅ‚: " +msgstr "Połącz sygnaÅ‚ do metody" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Edytuj połączenie: " +msgstr "Edytuj połączenie:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -909,21 +927,19 @@ msgid "Dependencies For:" msgstr "ZależnoÅ›ci:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" -"Scena '%s' jest obecnie edytowana.\n" -"Zmiany nie zajdÄ… do czasu przeÅ‚adowania." +"Scena \"%s\" jest obecnie edytowana.\n" +"Zmiany zajdÄ… dopiero po przeÅ‚adowaniu." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" -"Zasób '%s' jest w użyciu.\n" +"Zasób \"%s\" jest w użyciu.\n" "Zmiany zajdÄ… dopiero po jego przeÅ‚adowaniu." #: editor/dependency_editor.cpp @@ -971,7 +987,8 @@ msgid "Owners Of:" msgstr "WÅ‚aÅ›ciciele:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Usunąć wybrane pliki z projektu? (Nie można tego cofnąć)" #: editor/dependency_editor.cpp @@ -1016,9 +1033,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Permanentnie usuÅ„ %d obiekt(ów) (Nie można tego cofnąć)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "ZależnoÅ›ci" +msgstr "Pokaż zależnoÅ›ci" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1281,7 +1297,7 @@ msgstr "Otwórz ukÅ‚ad magistrali audio" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Nie ma pliku \"%s\"." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1338,28 +1354,24 @@ msgid "Valid characters:" msgstr "Dopuszczalne znaki:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"Niepoprawna nazwa. Nie może być taka sama jak istniejÄ…ca klasa silnika." +msgstr "Nie może kolidować z nazwÄ… istniejÄ…cej klasy silnika." #: editor/editor_autoload_settings.cpp -#, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "Niepoprawna nazwa. Nie może być taka sama jak wbudowany typ." +msgid "Must not collide with an existing built-in type name." +msgstr "Nie może kolidować z nazwÄ… istniejÄ…cego wbudowanego typu." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." -msgstr "Niepoprawna nazwa. Nie może być taka sama jak nazwa globalnej staÅ‚ej." +msgstr "Nie może kolidować z nazwÄ… istniejÄ…cej globalnej staÅ‚ej." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "SÅ‚owo kluczowe nie może zostać użyte jako nazwa autoÅ‚adowania." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" -msgstr "AutoLoad '%s' już istnieje!" +msgstr "AutoÅ‚adowanie \"%s\" już istnieje!" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" @@ -1386,9 +1398,8 @@ msgid "Rearrange Autoloads" msgstr "Przestaw Autoloady" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." -msgstr "NiewÅ‚aÅ›ciwa Å›cieżka." +msgstr "Niepoprawna Å›cieżka." #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp msgid "File does not exist." @@ -1441,9 +1452,8 @@ msgid "[unsaved]" msgstr "[niezapisany]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Najpierw wybierz katalog podstawowy" +msgstr "Najpierw wybierz katalog podstawowy." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1488,16 +1498,16 @@ msgid "" "Target platform requires 'ETC' texture compression for GLES2. Enable 'Import " "Etc' in Project Settings." msgstr "" -"Platforma docelowa wymaga dla GLES2 kompresji tekstur 'ETC'. Włącz 'Import " -"Etc' w Ustawieniach Projektu." +"Platforma docelowa wymaga dla GLES2 kompresji tekstur \"ETC\". Włącz " +"\"Import Etc\" w Ustawieniach Projektu." #: editor/editor_export.cpp msgid "" "Target platform requires 'ETC2' texture compression for GLES3. Enable " "'Import Etc 2' in Project Settings." msgstr "" -"Platforma docelowa wymaga dla GLES3 kompresji tekstur 'ETC2'. Włącz 'Import " -"Etc 2' w Ustawieniach Projektu." +"Platforma docelowa wymaga dla GLES3 kompresji tekstur \"ETC2\". Włącz " +"\"Import Etc 2\" w Ustawieniach Projektu." #: editor/editor_export.cpp msgid "" @@ -1506,10 +1516,10 @@ msgid "" "Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback " "Enabled'." msgstr "" -"Platforma docelowa wymaga kompresji tekstur 'ETC', by sterownik awaryjny " +"Platforma docelowa wymaga kompresji tekstur \"ETC\", by sterownik awaryjny " "GLES2 mógÅ‚ zadziaÅ‚ać.\n" -"Włącz 'Import Etc' w Ustawieniach Projektu lub wyłącz 'Driver Fallback " -"Enabled'." +"Włącz \"Import Etc\" w Ustawieniach Projektu lub wyłącz \"Driver Fallback " +"Enabled\"." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -1527,122 +1537,108 @@ msgstr "Nie znaleziono wÅ‚asnego szablonu wydania." msgid "Template file not found:" msgstr "Nie znaleziono pliku szablonu:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Edytor" +msgstr "Edytor 3D" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Otwórz edytor skryptów" +msgstr "Edytor skryptów" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Otwórz bibliotekÄ™ zasobów" +msgstr "Biblioteka zasobów" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Drzewo sceny (wÄ™zÅ‚y):" +msgstr "Edycja drzewa sceny" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Importuj" +msgstr "Dok importowania" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "WÄ™zeÅ‚ przesuniÄ™ty" +msgstr "Dok wÄ™zÅ‚a" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Filesystem Dock" -msgstr "System plików" +msgid "FileSystem and Import Docks" +msgstr "Doki systemu plików i importowania" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "ZastÄ…p wszystkie (nie można cofnąć)" +msgstr "Usunąć profil \"%s\"? (nieodwracalne)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "Nazwa profilu musi być poprawnÄ… nazwÄ… pliku i nie może zawierać \".\"" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Plik lub katalog o tej nazwie już istnieje." +msgstr "Profil o tej nazwie już istnieje." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Edytor wyłączony, WÅ‚aÅ›ciwoÅ›ci wyłączone)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Tylko wÅ‚aÅ›ciwoÅ›ci" +msgstr "(WÅ‚aÅ›ciwoÅ›ci wyłączone)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Wyłącz przycinanie" +msgstr "(Edytor wyłączony)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Opis klasy:" +msgstr "Opcje klasy:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Otwórz nastÄ™pny edytor" +msgstr "Włącz edytor kontekstowy" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "WÅ‚aÅ›ciwoÅ›ci:" +msgstr "Włączone wÅ‚aÅ›ciwoÅ›ci:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "Funkcje" +msgstr "Włączone funkcjonalnoÅ›ci:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Przeszukaj klasy" +msgstr "Włączone klasy:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Format pliku \"%s\" jest nieprawidÅ‚owy, import przerwany." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"Profil \"%s\" już istnieje. UsuÅ„ go przed importowaniem, import przerwany." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Błąd podczas Å‚adowania szablonu '%s'" +msgstr "Błąd zapisywania profilu do Å›cieżki \"%s\"." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Wymaż" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Current Profile" -msgstr "Aktualna wersja:" +msgid "Current Profile:" +msgstr "Bieżący profil:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Bieżący:" +msgstr "Ustaw na bieżący" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1660,44 +1656,32 @@ msgid "Export" msgstr "Eksportuj" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Available Profiles" -msgstr "DostÄ™pne wÄ™zÅ‚y:" - -#: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Przeszukaj klasy" +msgid "Available Profiles:" +msgstr "DostÄ™pne profile:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Opis klasy" +msgstr "Opcje klasy" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Nowa nazwa:" +msgstr "Nazwa nowego profilu:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Usuń obszar" +msgstr "Usuń profil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Zaimportowano projekt" +msgstr "Importuj profil(e)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Wyeksportuj projekt" +msgstr "Eksportuj profil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "ZarzÄ…dzaj szablonami eksportu" +msgstr "ZarzÄ…dzaj profilami funkcjonalnoÅ›ci edytora" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1820,9 +1804,8 @@ msgid "(Un)favorite current folder." msgstr "Dodaj/usuÅ„ aktualny folder z ulubionych." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Przełącz ukryte pliki" +msgstr "Przełącz widoczność ukrytych plików." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1858,7 +1841,7 @@ msgstr "Przeszukaj źródÅ‚a" msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" -msgstr "" +msgstr "Istnieje wiele importerów różnych typów dla pliku %s, import przerwany" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -1989,7 +1972,7 @@ msgstr "" #: editor/editor_help_search.cpp editor/editor_node.cpp #: editor/plugins/script_editor_plugin.cpp msgid "Search Help" -msgstr "Wyszukaj w Pomocy" +msgstr "Wyszukaj w pomocy" #: editor/editor_help_search.cpp msgid "Display All" @@ -2104,23 +2087,23 @@ msgstr "Błąd podczas zapisywania." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Can't open '%s'. The file could have been moved or deleted." -msgstr "Nie można otworzyć '%s'. Plik mógÅ‚ zostać przeniesiony lub usuniÄ™ty." +msgstr "Nie można otworzyć \"%s\". Plik mógÅ‚ zostać przeniesiony lub usuniÄ™ty." #: editor/editor_node.cpp msgid "Error while parsing '%s'." -msgstr "Błąd analizy '%s'." +msgstr "Błąd analizy \"%s\"." #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." -msgstr "Niespodziewane zakoÅ„czenie pliku '%s'." +msgstr "Niespodziewane zakoÅ„czenie pliku \"%s\"." #: editor/editor_node.cpp msgid "Missing '%s' or its dependencies." -msgstr "Brak '%s' lub ich zależnoÅ›ci." +msgstr "Brak \"%s\" lub ich zależnoÅ›ci." #: editor/editor_node.cpp msgid "Error while loading '%s'." -msgstr "Błąd Å‚adowania '%s'." +msgstr "Błąd Å‚adowania \"%s\"." #: editor/editor_node.cpp msgid "Saving Scene" @@ -2202,14 +2185,13 @@ msgstr "" "zrozumieć ten proces." #: editor/editor_node.cpp -#, fuzzy 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 "" "Ten zasób należy do sceny, która zostaÅ‚a zainstancjonowana lub " "odziedziczona.\n" -"Zmiany do niego nie zostanÄ… zachowane w momencie zapisania obecnej sceny." +"Zmiany w nim nie zostanÄ… zachowane w momencie zapisania obecnej sceny." #: editor/editor_node.cpp msgid "" @@ -2220,28 +2202,26 @@ msgstr "" "ustawienia w panelu importów, po czym zaimportuj go ponownie." #: editor/editor_node.cpp -#, fuzzy 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 "" -"Ta scena zostaÅ‚a zaimportowana, wiÄ™c zmiany do niej nie bÄ™dÄ… zachowane.\n" +"Ta scena zostaÅ‚a zaimportowana, wiÄ™c zmiany w niej nie bÄ™dÄ… zachowane.\n" "Instancjacja lub dziedziczenie jest pozwoli na prowadzenie zmian.\n" "ProszÄ™ zapoznać siÄ™ z dokumentacjÄ… dotyczÄ…cÄ… importowania scen, by lepiej " "zrozumieć ten proces." #: editor/editor_node.cpp -#, fuzzy 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 "" -"To jest zdalny obiekt wiÄ™c zmiany nie zostanÄ… zachowane.\n" -"Przeczytaj dokumentacjÄ™ dotyczÄ…cÄ…Â debugowania by lepiej zrozumieć ten sposób " -"pracy." +"To jest zdalny obiekt, wiÄ™c zmiany nie zostanÄ… zachowane.\n" +"Przeczytaj dokumentacjÄ™ dotyczÄ…cÄ…Â debugowania, by lepiej zrozumieć ten " +"proces." #: editor/editor_node.cpp msgid "There is no defined scene to run." @@ -2266,9 +2246,8 @@ msgid "Open Base Scene" msgstr "Otwórz scenÄ™ bazowÄ…" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Szybkie otwieranie sceny..." +msgstr "Szybkie otwieranie..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2284,7 +2263,7 @@ msgstr "Zapisz i zamknij" #: editor/editor_node.cpp msgid "Save changes to '%s' before closing?" -msgstr "Zapisać zmiany w '%s' przed zamkniÄ™ciem?" +msgstr "Zapisać zmiany w \"%s\" przed zamkniÄ™ciem?" #: editor/editor_node.cpp msgid "Saved %s modified resource(s)." @@ -2390,43 +2369,43 @@ msgstr "Wybierz głównÄ… scenÄ™" #: editor/editor_node.cpp msgid "Unable to enable addon plugin at: '%s' parsing of config failed." msgstr "" -"Nie można włączyć dodatku: '%s' - parsowanie konfiguracji nie powiodÅ‚o siÄ™." +"Nie można włączyć dodatku: \"%s\" - parsowanie konfiguracji nie powiodÅ‚o siÄ™." #: editor/editor_node.cpp msgid "Unable to find script field for addon plugin at: 'res://addons/%s'." -msgstr "Nie można odnaleźć pola 'skrypt' w dodatku: 'res://addons/%s'." +msgstr "Nie można odnaleźć pola skryptu w dodatku: \"res://addons/%s\"." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s'." -msgstr "Nie można zaÅ‚adować skryptu dodatku z Å›cieżki: '%s'." +msgstr "Nie można zaÅ‚adować skryptu dodatku z Å›cieżki: \"%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 "" -"Nie można zaÅ‚adować skryptu dodatku ze Å›cieżki: '%s' W kodzie znajduje siÄ™ " +"Nie można zaÅ‚adować skryptu dodatku ze Å›cieżki: \"%s\" W kodzie znajduje siÄ™ " "błąd, sprawdź skÅ‚adniÄ™." #: editor/editor_node.cpp msgid "" "Unable to load addon script from path: '%s' Base type is not EditorPlugin." msgstr "" -"Nie można wczytać skryptu dodatku ze Å›cieżki: '%s' Skrypt nie dziedziczy po " -"klasie EditorPlugin." +"Nie można wczytać skryptu dodatku ze Å›cieżki: \"%s\" Skrypt nie dziedziczy " +"po klasie EditorPlugin." #: editor/editor_node.cpp msgid "Unable to load addon script from path: '%s' Script is not in tool mode." msgstr "" -"Nie można zaÅ‚adować skryptu dodatku z Å›cieżki: '%s' Skrypt nie jest w trybie " -"narzÄ™dzia (tool)." +"Nie można zaÅ‚adować skryptu dodatku z Å›cieżki: \"%s\" Skrypt nie jest w " +"trybie narzÄ™dzia (tool)." #: editor/editor_node.cpp msgid "" "Scene '%s' was automatically imported, so it can't be modified.\n" "To make changes to it, a new inherited scene can be created." msgstr "" -"Scena '%s' zostaÅ‚a automatycznie zaimportowana, wiÄ™c nie może być " +"Scena \"%s\" zostaÅ‚a automatycznie zaimportowana, wiÄ™c nie może być " "zmodyfikowana.\n" "Aby dokonać na niej zmian, można utworzyć nowÄ… odziedziczonÄ… scenÄ™." @@ -2441,7 +2420,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Scene '%s' has broken dependencies:" -msgstr "Scena '%s' ma niespeÅ‚nione zależnoÅ›ci:" +msgstr "Scena \"%s\" ma niespeÅ‚nione zależnoÅ›ci:" #: editor/editor_node.cpp msgid "Clear Recent Scenes" @@ -2462,7 +2441,7 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Wybrana scena '%s' nie istnieje, wybrać poprawnÄ…? \n" +"Wybrana scena \"%s\" nie istnieje, wybrać poprawnÄ…? \n" "Można to później zmienić w \"Ustawienia projektu\" w kategorii \"aplikacja\"." #: editor/editor_node.cpp @@ -2471,7 +2450,7 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" -"Wybrany plik '%s' nie jest scenÄ…, wybrać poprawny?\n" +"Wybrany plik \"%s\" nie jest scenÄ…, wybrać poprawny?\n" "Można to później zmienić w \"Ustawienia projektu\" w kategorii \"aplikacja\"." #: editor/editor_node.cpp @@ -2506,12 +2485,11 @@ msgstr "Zamknij inne karty" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Zamknij karty po prawej" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Zamknij wszystkie" +msgstr "Zamknij wszystkie karty" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2645,7 +2623,7 @@ msgstr "Otwórz folder danych projektu" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Zainstaluj szablon eksportu dla Androida" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2753,10 +2731,30 @@ msgid "Editor Layout" msgstr "UkÅ‚ad edytora" #: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "Zrób zrzut ekranu" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Zrzuty ekranu sÄ… przechowywane w folderze danych/ustawieÅ„ edytora." + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "Automatycznie otwórz zrzuty ekranu" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "Otwórz w zewnÄ™trznym edytorze obrazów." + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "PeÅ‚ny ekran" #: editor/editor_node.cpp +msgid "Toggle System Console" +msgstr "Przełącz systemowÄ… konsolÄ™" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Otwórz folder ustawieÅ„/danych edytora" @@ -2769,9 +2767,8 @@ msgid "Open Editor Settings Folder" msgstr "Otwórz folder ustawieÅ„ edytora" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "ZarzÄ…dzaj szablonami eksportu" +msgstr "ZarzÄ…dzaj funkcjonalnoÅ›ciami edytora" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2796,7 +2793,7 @@ msgstr "Dokumentacja online" #: editor/editor_node.cpp msgid "Q&A" -msgstr "Q&A" +msgstr "Pytania i odpowiedzi" #: editor/editor_node.cpp msgid "Issue Tracker" @@ -2864,16 +2861,16 @@ msgid "Spins when the editor window redraws." msgstr "Obraca siÄ™, gdy okno edytora jest przerysowywane." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Zawsze OdÅ›wieżaj" +msgid "Update Continuously" +msgstr "Aktualizuj ciÄ…gle" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "OdÅ›wież Zmiany" +msgid "Update When Changed" +msgstr "Aktualizuj przy zmianie" #: editor/editor_node.cpp -msgid "Disable Update Spinner" -msgstr "Wyłącz wiatraczek aktualizacji" +msgid "Hide Update Spinner" +msgstr "Ukryj wiatraczek aktualizacji" #: editor/editor_node.cpp msgid "FileSystem" @@ -2901,18 +2898,19 @@ msgstr "Nie zapisuj" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." -msgstr "" +msgstr "Brakuje szablonu budowania Androida, zainstaluj odpowiednie szablony." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "ZarzÄ…dzaj szablonami eksportu" +msgstr "ZarzÄ…dzaj szablonami" #: editor/editor_node.cpp msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"To zainstaluje projekt Androida dla dostosowanych wydaÅ„.\n" +"W celu użycia go, musi zostać dołączony do każdego profilu eksportu." #: editor/editor_node.cpp msgid "" @@ -2920,6 +2918,8 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"Szablon budowania Androida jest już zainstalowany i nie bÄ™dzie nadpisany.\n" +"UsuÅ„ rÄ™cznie folder \"build\" przed spróbowaniem tej operacji ponownie." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3063,7 +3063,7 @@ msgstr "Czas" msgid "Calls" msgstr "WywoÅ‚ania" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Włącz" @@ -3169,6 +3169,11 @@ msgid "Page: " msgstr "Strona: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "UsuÅ„ element" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Nowy klucz:" @@ -3180,11 +3185,6 @@ msgstr "Nowa wartość:" msgid "Add Key/Value Pair" msgstr "Dodaj parÄ™ klucz/wartość" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "UsuÅ„ element" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3208,7 +3208,7 @@ msgstr "Nie udaÅ‚o siÄ™ utworzyć instancji skryptu:" #: editor/editor_run_script.cpp msgid "Did you forget the 'tool' keyword?" -msgstr "ZapomniaÅ‚eÅ› nazwy 'narzÄ™dzia' ?" +msgstr "Zapomniano sÅ‚owa kluczowego \"tool\"?" #: editor/editor_run_script.cpp msgid "Couldn't run script:" @@ -3216,7 +3216,7 @@ msgstr "Nie można uruchomić skryptu:" #: editor/editor_run_script.cpp msgid "Did you forget the '_run' method?" -msgstr "ZapomniaÅ‚eÅ› metody '_run'?" +msgstr "Zapomniano metody \"_run\"?" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" @@ -3339,7 +3339,7 @@ msgid "" "found at '%s'." msgstr "" "Instalacja szablonów siÄ™ nie udaÅ‚a. Problematyczne archiwa szablonów mogÄ… " -"być znalezione w '%s'." +"być znalezione w \"%s\"." #: editor/export_template_manager.cpp msgid "Error requesting url: " @@ -3392,9 +3392,8 @@ msgid "SSL Handshake Error" msgstr "Błąd podczas wymiany (handshake) SSL" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "Dekompresja zasobów" +msgstr "Dekompresja źródeÅ‚ budowania Androida" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3413,7 +3412,6 @@ msgid "Remove Template" msgstr "UsuÅ„ szablon" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" msgstr "Wybierz plik szablonu" @@ -3441,7 +3439,7 @@ msgstr "Ulubione" #: editor/filesystem_dock.cpp msgid "Cannot navigate to '%s' as it has not been found in the file system!" -msgstr "Nie można przejść do '%s' - nie znaleziono w tym systemie plików!" +msgstr "Nie można przejść do \"%s\" - nie znaleziono w tym systemie plików!" #: editor/filesystem_dock.cpp msgid "Status: Import of file failed. Please fix file and reimport manually." @@ -3474,9 +3472,8 @@ msgid "No name provided." msgstr "Nie podano nazwy." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "Podana nazwa zawiera niedozwolone znaki" +msgstr "Podana nazwa zawiera niedozwolone znaki." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3503,26 +3500,22 @@ msgid "Duplicating folder:" msgstr "Duplikowanie Folderu:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Nowa scena dziedziczÄ…ca..." +msgstr "Nowa scena dziedziczÄ…ca" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Otwórz scenÄ™" +msgstr "Otwórz sceny" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Instancja" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" msgstr "Dodaj do ulubionych" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" msgstr "UsuÅ„ z ulubionych" @@ -3572,21 +3565,18 @@ msgid "Rename" msgstr "ZmieÅ„ nazwÄ™" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Poprzedni folder" +msgstr "Poprzedni folder/plik" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "NastÄ™pny folder" +msgstr "NastÄ™pny folder/plik" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "Przeskanuj system plików ponownie" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" msgstr "Przełącz tryb podziaÅ‚u" @@ -3639,6 +3629,8 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Dołącz pliki z podanymi rozszerzeniami. Dodaj lub usuÅ„ je w Ustawieniach " +"Projektu." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3690,6 +3682,7 @@ msgid "Nodes not in Group" msgstr "WÄ™zÅ‚y nie w grupie" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtruj wÄ™zÅ‚y" @@ -3790,11 +3783,11 @@ msgstr "Zapisywanie..." #: editor/import_dock.cpp msgid "Set as Default for '%s'" -msgstr "Ustaw jako domyÅ›lne dla '%s'" +msgstr "Ustaw jako domyÅ›lne dla \"%s\"" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "UsuÅ„ domyÅ›lne dla '%s'" +msgstr "UsuÅ„ domyÅ›lne dla \"%s\"" #: editor/import_dock.cpp msgid " Files" @@ -4079,9 +4072,8 @@ msgid "Open Animation Node" msgstr "Otwórz wÄ™zeÅ‚ animacji" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "TrójkÄ…t już istnieje" +msgstr "TrójkÄ…t już istnieje." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4227,7 +4219,6 @@ msgid "Edit Filtered Tracks:" msgstr "Edytuj filtrowane Å›cieżki:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" msgstr "Włącz filtrowanie" @@ -4307,7 +4298,7 @@ msgstr "Brak animacji do edycji!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" -msgstr "Odtwórz zaznaczonÄ… animacjÄ™ od tyÅ‚u z aktualnej poz. (A)" +msgstr "Odtwórz zaznaczonÄ… animacjÄ™ od tyÅ‚u z aktualnej pozycji. (A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from end. (Shift+A)" @@ -4315,15 +4306,15 @@ msgstr "Odtwarzaj zaznaczonÄ… animacjÄ™ od koÅ„ca. (Shift+A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" -msgstr "Zatrzymaj animacjÄ™ (S)" +msgstr "Zatrzymaj animacjÄ™. (S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "Uruchom animacjÄ™ od poczÄ…tku (Shift+D)" +msgstr "Uruchom animacjÄ™ od poczÄ…tku. (Shift+D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "Uruchom animacjÄ™ od aktualnej pozycji (D)" +msgstr "Uruchom animacjÄ™ od aktualnej pozycji. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." @@ -4340,7 +4331,7 @@ msgstr "NarzÄ™dzia do animacji" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Animation" -msgstr "Animacje" +msgstr "Animacja" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Edit Transitions..." @@ -4360,12 +4351,11 @@ msgstr "Auto odtwarzanie po zaÅ‚adowaniu" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" -msgstr "Włącz Onion skinning" +msgstr "Włącz tryb warstw cebuli (onion skinning)" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "Onion skinning" +msgstr "Opcje trybu warstw cebuli" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4531,7 +4521,7 @@ msgstr "PrzejÅ›cie: " #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "AnimationTree" -msgstr "Drzewo animacji" +msgstr "AnimationTree" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "New name:" @@ -4828,7 +4818,7 @@ msgid "" "Light' flag is on." msgstr "" "Brak siatek do cieniowania. Upewnij siÄ™, że zawierajÄ… kanaÅ‚ UV2 i że flaga " -"'Bake Light' jest ustawiona." +"\"Bake Light\" jest ustawiona." #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "Failed creating lightmap images, make sure path is writable." @@ -4935,6 +4925,8 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Gdy aktywne, poruszanie wÄ™złów typu Control zmienia ich zakotwiczenie, " +"zamiast marginesów." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -4950,41 +4942,35 @@ msgstr "ZmieÅ„ zakotwiczenie" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "NarzÄ™dzie wyboru" +msgstr "Zablokuj wybrane" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "UsuÅ„ zaznaczone" +msgstr "Odblokuj wybrane" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Kopiuj zaznaczenie" +msgstr "Grupuj wybrane" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Kopiuj zaznaczenie" +msgstr "Rozgrupuj wybrane" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" msgstr "Wklej pozÄ™" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" msgstr "Utwórz wÅ‚asne koÅ›ci z wÄ™złów" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "Wyczyść pozÄ™" +msgstr "Wyczyść koÅ›ci" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -5023,8 +5009,8 @@ msgstr "Alt+PrzeciÄ…gnij: PrzesuÅ„" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." msgstr "" -"WciÅ›nij 'v' by Zmienić Pivot, 'Shift+v' by Przesunąć Pivot (podczas " -"poruszania)." +"WciÅ›nij \"v\" by zmienić punkt zaczepienia (pivot), \"Shift+v\" by przesunąć " +"punkt zaczepienia (podczas poruszania)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+RMB: Depth list selection" @@ -5072,7 +5058,6 @@ msgid "Snapping Options" msgstr "Opcje przyciÄ…gania" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" msgstr "PrzyciÄ…gaj do siatki" @@ -5094,37 +5079,30 @@ msgid "Use Pixel Snap" msgstr "Użyj krokowania na poziomie pikseli" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" msgstr "Inteligentne przyciÄ…ganie" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" msgstr "PrzyciÄ…gaj do rodzica" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" -msgstr "PrzyciÄ…gaj do kotwicy wÄ™zÅ‚a" +msgstr "PrzyciÄ…gaj do zakotwiczenia wÄ™zÅ‚a" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" msgstr "PrzyciÄ…gaj do boków wÄ™zÅ‚a" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" msgstr "PrzyciÄ…gaj do Å›rodka wÄ™zÅ‚a" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" msgstr "PrzyciÄ…gaj do innych wÄ™złów" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" msgstr "PrzyciÄ…gaj do prowadnic" @@ -5208,7 +5186,7 @@ msgstr "PowiÄ™ksz do zaznaczenia" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "" +msgstr "Skala płótna podglÄ…du" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -5264,9 +5242,8 @@ msgid "Divide grid step by 2" msgstr "Zmniejsz wielkość siatki dwukrotnie" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Pan View" -msgstr "Widok z tyÅ‚u" +msgstr "PrzesuÅ„ widok" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" @@ -5291,7 +5268,6 @@ msgid "Error instancing scene from %s" msgstr "Błąd instancjacji sceny z %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" msgstr "Zmienić domyÅ›lny typ" @@ -5335,6 +5311,13 @@ msgid "Load Emission Mask" msgstr "Wczytaj maskÄ™ emisji" #: 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 "Uruchom ponownie" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "UsuÅ„ maskÄ™ emisji" @@ -5363,7 +5346,7 @@ msgstr "Przechwytywanie z piksela" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Colors" -msgstr "Kolor emisji" +msgstr "Kolory emisji" #: editor/plugins/cpu_particles_editor_plugin.cpp msgid "CPUParticles" @@ -5380,14 +5363,12 @@ msgid "Create Emission Points From Node" msgstr "Twórz punkty emisji z wÄ™zÅ‚a" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "Flat0" +msgstr "PÅ‚askie 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "Flat1" +msgstr "PÅ‚askie 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -5414,29 +5395,24 @@ msgid "Load Curve Preset" msgstr "Wczytaj predefiniowanÄ… krzywÄ…" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" msgstr "Dodaj punkt" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" msgstr "UsuÅ„ punkt" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" msgstr "Lewe liniowe" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" msgstr "Prawe liniowe" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" -msgstr "Wczytaj ustawienia predefiniowane" +msgstr "Wczytaj profil" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove Curve Point" @@ -5491,16 +5467,14 @@ msgid "This doesn't work on scene root!" msgstr "Nie dziaÅ‚a na głównym węźle sceny!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Utwórz ksztaÅ‚t trójsiatki" +msgstr "Utwórz statyczny ksztaÅ‚t trójsiatki" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "Tworzenie ksztaÅ‚tów nieudane!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" msgstr "Utwórz ksztaÅ‚t wypukÅ‚y" @@ -5558,7 +5532,6 @@ msgid "Create Trimesh Collision Sibling" msgstr "Utwórz sÄ…siadujÄ…cÄ… trójsiatkÄ™ kolizji" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Collision Sibling(s)" msgstr "Utwórz wypukÅ‚ego sÄ…siada kolizji" @@ -5919,7 +5892,6 @@ msgid "Split Segment (in curve)" msgstr "Podziel Segment (na krzywej)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" msgstr "PrzesuÅ„ złącze" @@ -6252,10 +6224,18 @@ msgid "Find Next" msgstr "Znajdź nastÄ™pny" #: editor/plugins/script_editor_plugin.cpp +msgid "Filter scripts" +msgstr "Filtruj skrypty" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "Przełącz alfabetyczne sortowanie listy metod." #: editor/plugins/script_editor_plugin.cpp +msgid "Filter methods" +msgstr "Filtruj metody" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Sortuj" @@ -6366,18 +6346,16 @@ msgid "Debug with External Editor" msgstr "Debugowanie z zewnÄ™trznym edytorem" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Otwórz dokumentacjÄ™ online" +msgstr "Otwórz dokumentacjÄ™ Godota online." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" msgstr "PoproÅ› o dokumentacjÄ™" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "Pomóż polepszyć dokumentacjÄ™ Godota przesyÅ‚ajÄ…c opiniÄ™" +msgstr "Pomóż polepszyć dokumentacjÄ™ Godota przesyÅ‚ajÄ…c opiniÄ™." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6422,29 +6400,27 @@ msgid "Search Results" msgstr "Wyniki wyszukiwania" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "Podłącz do wÄ™zÅ‚a:" +msgstr "Połączenia do metody:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "ŹródÅ‚o:" +msgstr "ŹródÅ‚o" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "SygnaÅ‚y" +msgstr "SygnaÅ‚" #: editor/plugins/script_text_editor.cpp msgid "Target" msgstr "Cel" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "Nic nie podłączono do wejÅ›cia '%s' wÄ™zÅ‚a '%s'." +msgstr "" +"Brakuje połączonej metody \"%s\" dla sygnaÅ‚u \"%s\" z wÄ™zÅ‚a \"%s\" do wÄ™zÅ‚a " +"\"%s\"." #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6476,7 +6452,7 @@ msgstr "Zmień wielkość liter" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Uppercase" -msgstr "Wielkie Litery" +msgstr "Wielkie litery" #: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp msgid "Lowercase" @@ -6491,20 +6467,24 @@ msgid "Syntax Highlighter" msgstr "PodÅ›wietlacz skÅ‚adni" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "ZakÅ‚adki" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Utwórz punkty." #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Wytnij" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Zaznacz wszystko" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "UsuÅ„ wiersz" @@ -6522,24 +6502,20 @@ msgid "Toggle Comment" msgstr "Przełącz komentarz" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "Przełącz swobodny widok" +msgstr "Przełącz zakÅ‚adkÄ™" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "Przejdź do nastÄ™pnego punktu wstrzymania" +msgstr "Przejdź do nastÄ™pnej zakÅ‚adki" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Previous Bookmark" -msgstr "Przejdź do poprzedniego punktu wstrzymania" +msgstr "Przejdź do poprzedniej zakÅ‚adki" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "UsuÅ„ wszystkie elementy" +msgstr "UsuÅ„ wszystkie zakÅ‚adki" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -6615,13 +6591,12 @@ msgid "Contextual Help" msgstr "Pomoc kontekstowa" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"NastÄ™pujÄ…ce pliki sÄ… nowsze na dysku.\n" -"Jakie dziaÅ‚ania należy podjąć?:" +"Ten shader zostaÅ‚ zmieniony na dysku.\n" +"Jakie dziaÅ‚ania podjąć?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -6966,7 +6941,6 @@ msgid "Right View" msgstr "Widok z prawej" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" msgstr "Przełącz widok perspektywiczny/ortogonalny" @@ -7012,7 +6986,6 @@ msgid "Transform" msgstr "PrzeksztaÅ‚canie" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" msgstr "PrzyciÄ…gnij obiekt do podÅ‚ogi" @@ -7203,14 +7176,12 @@ msgid "Settings:" msgstr "Ustawienia:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "PowiÄ™ksz do zaznaczenia" +msgstr "Nie wybrano klatek" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "Dodaj klatkÄ™" +msgstr "Dodaj %d klatek" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" @@ -7261,13 +7232,12 @@ msgid "Animation Frames:" msgstr "Klatki animacji:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Dodaj teksturÄ™/y do TileSetu." +msgstr "Dodaj teksturÄ™ z pliku" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "Dodaj klatki ze Sprite Sheeta" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7286,29 +7256,24 @@ msgid "Move (After)" msgstr "PrzenieÅ› (za)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "Ramki stosu" +msgstr "Zaznacz klatki" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Odbij poziomo" +msgstr "Poziomo:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "WierzchoÅ‚ki" +msgstr "Pionowo:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "Zaznacz wszystko" +msgstr "Wybierz/wyczyść wszystkie klatki" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "Utwórz ze sceny" +msgstr "Utwórz klatki ze Sprite Sheeta" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" @@ -7380,9 +7345,8 @@ msgid "Remove All" msgstr "UsuÅ„ wszystkie" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "Edytuj motyw interfejsu..." +msgstr "Edytuj motyw" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7409,23 +7373,20 @@ msgid "Create From Current Editor Theme" msgstr "Utwórz z aktualnego motywu edytora" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Toggle Button" -msgstr "Przycisk myszy" +msgstr "Przełączany przycisk" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Åšrodkowy guzik" +msgstr "Wyłączony przycisk" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" msgstr "Element" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "Wyłączone" +msgstr "Wyłączony element" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -7445,21 +7406,19 @@ msgstr "Zaznaczony element opcji" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "Nazwany sep." #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Podmenu" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "Element" +msgstr "Element 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "Element" +msgstr "Element 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -7470,9 +7429,8 @@ msgid "Many" msgstr "Wiele" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled LineEdit" -msgstr "Wyłączone" +msgstr "Wyłączony LineEdit" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -7487,13 +7445,12 @@ msgid "Tab 3" msgstr "ZakÅ‚adka 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "Edytowalne dzieci" +msgstr "Edytowalny element" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "Poddrzewo" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7573,14 +7530,12 @@ msgid "Mirror Y" msgstr "Odbij Y" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "Autotiles" +msgstr "Wyłącz autokafelki" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "Edytuj priorytet Kafelka" +msgstr "Włącz priorytety" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7591,33 +7546,30 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift+PPM: Rysuj liniÄ™\n" +"Shift+Ctrl+PPM: Maluj prostokÄ…t" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" msgstr "Wybierz kafelek" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" msgstr "Obróć w lewo" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" msgstr "Obróć w prawo" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Horizontally" msgstr "Odbij poziomo" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Vertically" msgstr "Odbij pionowo" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" msgstr "Wyczyść przeksztaÅ‚cenie" @@ -7654,44 +7606,36 @@ msgid "Select the previous shape, subtile, or Tile." msgstr "Wybierz poprzedni ksztaÅ‚t, podkafelek lub Kafelek." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "Tryb uruchamiania:" +msgstr "Tryb obszaru" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "Sposób interpolacji" +msgstr "Tryb kolizji" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "Edytuj wielokÄ…t okluzji" +msgstr "Tryb okluzji" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "Utwórz siatkÄ™ nawigacyjnÄ… (Navigation Mesh)" +msgstr "Tryb nawigacji" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "Tryb Rotacji" +msgstr "Tryb maski bitowej" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "Tryb eksportu:" +msgstr "Tryb priorytetów" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "Tryb przesuwania" +msgstr "Tryb ikon" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "Tryb przesuwania" +msgstr "Tryb indeksów Z" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7775,7 +7719,6 @@ msgid "Delete polygon." msgstr "UsuÅ„ wielokÄ…t." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "LMB: Set bit on.\n" "RMB: Set bit off.\n" @@ -7784,6 +7727,7 @@ msgid "" msgstr "" "LPM: Włącz bit.\n" "PPM: Wyłącz bit.\n" +"Shift+LPM: Ustaw bit typu wildcard.\n" "Kliknij inny Kafelek, by go edytować." #: editor/plugins/tile_set_editor_plugin.cpp @@ -7897,77 +7841,64 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input +" -msgstr "Dodaj WejÅ›cie" +msgstr "Dodaj wejÅ›cie+" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add output +" -msgstr "Dodaj WejÅ›cie" +msgstr "Dodaj wyjÅ›cie+" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "Skala:" +msgstr "Skalar" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Inspektor" +msgstr "Wektor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Prawda/faÅ‚sz" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "Dodaj WejÅ›cie" +msgstr "Dodaj port wejÅ›ciowy" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Dodaj port wyjÅ›ciowy" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "Zmienić domyÅ›lny typ" +msgstr "ZmieÅ„ typ portu wejÅ›ciowego" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "Zmienić domyÅ›lny typ" +msgstr "ZmieÅ„ typ portu wyjÅ›ciowego" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "ZmieÅ„ nazwÄ™ wejÅ›cia" +msgstr "ZmieÅ„ nazwÄ™ portu wejÅ›ciowego" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "ZmieÅ„ nazwÄ™ wejÅ›cia" +msgstr "ZmieÅ„ nazwÄ™ portu wyjÅ›ciowego" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "UsuÅ„ punkt" +msgstr "UsuÅ„ port wejÅ›ciowy" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "UsuÅ„ punkt" +msgstr "UsuÅ„ port wyjÅ›ciowy" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "ZmieÅ„ wyrażenie" +msgstr "Ustaw wyrażenie" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "Shader wizualny" +msgstr "ZmieÅ„ rozmiar wÄ™zÅ‚a VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" @@ -8006,540 +7937,315 @@ msgid "Light" msgstr "ÅšwiatÅ‚o" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "Utwórz wÄ™zeÅ‚" +msgstr "Utwórz wÄ™zeÅ‚ shadera" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "Przejdź do funkcji" +msgstr "Funkcja koloru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "Operator koloru." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "Utwórz funkcjÄ™" +msgstr "Funkcja odcieni szaroÅ›ci." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "Konwertuje wektor HSV do odpowiednika RGB." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "Konwertuje wektor RGB do odpowiednika HSV." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "ZmieÅ„ nazwÄ™ funkcji" +msgstr "Funkcja sepii." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "Operator wypalenia." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "Operator przyciemnienia." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Difference operator." -msgstr "Tylko różnice" +msgstr "Operator różnicy." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." -msgstr "" +msgstr "Operator uniku." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "HardLight operator" -msgstr "" +msgstr "Operator twardego Å›wiatÅ‚a" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." -msgstr "" +msgstr "Operator rozjaÅ›nienia." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." -msgstr "" +msgstr "Operator pokrycia." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Screen operator." -msgstr "" +msgstr "Operator ekranu." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "SoftLight operator." -msgstr "" +msgstr "Operator miÄ™kkiego Å›wiatÅ‚a." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color constant." -msgstr "StaÅ‚e" +msgstr "StaÅ‚a koloru." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color uniform." -msgstr "Wyczyść przeksztaÅ‚cenie" +msgstr "Uniform koloru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided scalars are equal, greater or " "less." msgstr "" +"Zwraca powiÄ…zany wektor, jeÅ›li podane skalary sÄ… równe, wiÄ™ksze lub mniejsze." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided boolean value is true or false." msgstr "" +"Zwraca powiÄ…zany wektor, jeÅ›li podana wartość boolowska jest prawdziwa albo " +"faÅ‚szywa." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Boolean constant." -msgstr "ZmieÅ„ stałą Vec" +msgstr "StaÅ‚a prawda/faÅ‚sz." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean uniform." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" +msgstr "Uniform prawda/faÅ‚sz." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" +msgid "'%s' input parameter for all shader modes." +msgstr "Parametr wejÅ›ciowy \"%s\" dla wszystkich trybów shadera." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Input parameter." -msgstr "PrzyciÄ…gaj do rodzica" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" +msgstr "Parametr wejÅ›ciowy." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" +"Parametr wejÅ›ciowy \"%s\" dla wierzchoÅ‚kowego i fragmentowego trybu shadera." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "Parametr wejÅ›ciowy \"%s\" dla dla fragmentowego i Å›wiatÅ‚owego shadera." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" +msgid "'%s' input parameter for fragment shader mode." +msgstr "Parametr wejÅ›ciowy \"%s\" dla fragmentowego trybu shadera." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" +msgid "'%s' input parameter for light shader mode." +msgstr "Parametr wejÅ›ciowy \"%s\" dla Å›wiatÅ‚owego trybu shadera." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" +msgid "'%s' input parameter for vertex shader mode." +msgstr "Parametr wejÅ›ciowy \"%s\" dla wierzchoÅ‚kowego trybu shadera." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" +"Parametr wejÅ›ciowy \"%s\" dla wierzchoÅ‚kowego i fragmentowego trybu shadera." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar function." -msgstr "ZamieÅ„ funkcjÄ™ skalarnÄ…" +msgstr "Funkcja skalarna." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar operator." -msgstr "ZmieÅ„ operator skalara" +msgstr "Operator skalarny." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "StaÅ‚a e (2.718282). Reprezentuje podstawÄ™ logarytmu naturalnego." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "StaÅ‚a epsilon (0.00001). Najmniejszy możliwy numer skalarny." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "StaÅ‚a phi (1.618034). ZÅ‚oty podziaÅ‚." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "StaÅ‚a Pi/4 (0.785398) lub 45 stopni." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "StaÅ‚a Pi/2 (1.570796) lub 90 stopni." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "StaÅ‚a Pi (3.141593) lub 180 stopni." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "StaÅ‚a tau (6.283185) lub 360 stopni." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "StaÅ‚a sqrt2 (1.414214). Pierwiastek kwadratowy z 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "Zwraca wartość bezwzglÄ™dnÄ… parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "Zwraca arcus cosinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Tylko GLES3) Zwraca odwrócony cosinus hiperboliczny parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "Zwraca arcus sinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "(Tylko GLES3) Zwraca odwrócony sinus hiperboliczny parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "Zwraca arcus tangens parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "Zwraca arcus tangens parametrów." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Tylko GLES3) Zwraca odwrócony tangens hiperboliczny parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "Znajduje najbliższÄ… liczbÄ™ caÅ‚kowitÄ… wiÄ™kszÄ… lub równÄ… parametrowi." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "Ogranicza wartość, by leżaÅ‚a pomiÄ™dzy dwiema podanymi wartoÅ›ciami." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "Zwraca cosinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Tylko GLES3) Zwraca cosinus hiperboliczny parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "Konwertuje wartość w radianach na stopnie." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "Eksponenta o podstawie e." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "Eksponenta o podstawie 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "Znajduje najbliższÄ… liczbÄ™ caÅ‚kowitÄ… mniejszÄ… lub równÄ… parametrowi." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "Liczy uÅ‚amkowÄ… część argumentu." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "Zwraca odwrotność pierwiastka kwadratowego z parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "Logarytm naturalny." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "Logarytm o podstawie 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "Zwraca wiÄ™kszÄ… z dwóch wartoÅ›ci." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "Zwraca mniejszÄ… z dwóch wartoÅ›ci." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "Interpolacja liniowa miÄ™dzy dwoma skalarami." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "Zwraca przeciwieÅ„stwo parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - skalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." -msgstr "" +msgstr "Zwraca wartość pierwszego parametru podniesionÄ… do potÄ™gi z drugiego." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "Konwertuje wartość ze stopni na radiany." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / skalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(Tylko GLES3) Znajduje najbliższÄ… parametrowi liczbÄ™ caÅ‚kowitÄ…." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." msgstr "" +"(Tylko GLES3) Znajduje najbliższÄ… parametrowi parzystÄ… liczbÄ™ caÅ‚kowitÄ…." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "Ogranicza wartość pomiÄ™dzy 0.0 i 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "WyciÄ…ga znak z parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "Zwraca sinus parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(Tylko GLES3) Zwraca sinus hiperboliczny parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "Zwraca pierwiastek kwadratowy parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8549,6 +8255,12 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"Funkcja gÅ‚adkiego przejÅ›cia( skalar(krawÄ™dź0), skalar(krawÄ™dź1), " +"skalar(x) ).\n" +"\n" +"Zwraca 0.0 jeÅ›li \"x\" jest mniejsze niż \"edge0\" i 1.0 jeÅ›li x jest " +"wiÄ™ksze niż \"edge1\". W innym przypadku, zwraca wartość interpolowanÄ… " +"pomiÄ™dzy 0.0 i 1.0 używajÄ…c wielomianów Hermite'a." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8556,70 +8268,69 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Funkcja przejÅ›cia( skalar(krawÄ™dź), skalar(x) ).\n" +"\n" +"Zwraca 0.0 jeÅ›li \"x\" jest mniejsze niż krawÄ™dź, w innym przypadku 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "Zwraca tangens parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Tylko GLES3) Zwraca tangens hiperboliczny parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." -msgstr "" +msgstr "(Tylko GLES3) Zwraca obciÄ™tÄ… wartość parametru." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "Dodaje skalar do skalara." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "Dzieli skalar przez skalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "Mnoży skalar przez skalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "Zwraca resztÄ™ z dwóch skalarów." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "Odejmuje skalar od skalara." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar constant." -msgstr "ZmieÅ„ wartość staÅ‚ej skalarnej" +msgstr "StaÅ‚a skalarna." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar uniform." -msgstr "Wyczyść przeksztaÅ‚cenie" +msgstr "Uniform skalarny." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "Wykonaj podejrzenie tekstury kubicznej." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the texture lookup." -msgstr "" +msgstr "Wykonaj podejrzenie tekstury." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Cubic texture uniform." -msgstr "" +msgstr "Uniform tekstury kubicznej." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "2D texture uniform." -msgstr "Tekstura 2D" +msgstr "Uniform tekstury 2D." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform function." -msgstr "Okno transformowania..." +msgstr "Funkcja transformacji." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8634,71 +8345,67 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes transform from four vectors." -msgstr "" +msgstr "SkÅ‚ada przeksztaÅ‚cenie z czterech wektorów." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes transform to four vectors." -msgstr "" +msgstr "RozkÅ‚ada przeksztaÅ‚cenie na cztery wektory." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the determinant of a transform." -msgstr "" +msgstr "(Tylko GLES3) Liczy wyznacznik przeksztaÅ‚cenia." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the inverse of a transform." -msgstr "" +msgstr "(Tylko GLES3) Liczy odwrotność przeksztaÅ‚cenia." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the transpose of a transform." -msgstr "" +msgstr "(Tylko GLES3) Liczy transpozycjÄ™ przeksztaÅ‚cenia." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies transform by transform." -msgstr "" +msgstr "Mnoży przeksztaÅ‚cenie przez przeksztaÅ‚cenie." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by transform." -msgstr "" +msgstr "Mnoży wektor przez przeksztaÅ‚cenie." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform constant." -msgstr "Transformacja Zaniechana." +msgstr "StaÅ‚a przeksztaÅ‚cenia." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform uniform." -msgstr "Transformacja Zaniechana." +msgstr "Uniform przeksztaÅ‚cenia." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector function." -msgstr "Przypisanie do funkcji." +msgstr "Funkcja wektorowa." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector operator." -msgstr "ZmieÅ„ operator Vec" +msgstr "Operator wektorowy." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "SkÅ‚ada wektor z trzech skalarów." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "RozkÅ‚ada wektor na trzy skalary." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "Liczy iloczyn wektorowy dwóch wektorów." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "Zwraca dystans pomiÄ™dzy dwoma punktami." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "Liczy iloczyn skalarny dwóch wektorów." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8710,33 +8417,35 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "Liczy dÅ‚ugość wektora." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "Liniowo interpoluje pomiÄ™dzy dwoma wektorami." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." -msgstr "" +msgstr "Liczy znormalizowany wektor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - vector" -msgstr "" +msgstr "1.0 - wektor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / vector" -msgstr "" +msgstr "1.0 / wektor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns a vector that points in the direction of reflection ( a : incident " "vector, b : normal vector )." msgstr "" +"Zwraca wektor zwrócony w kierunku odbicia ( a : wektor padajÄ…cy, b : wektor " +"normalny )." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns a vector that points in the direction of refraction." -msgstr "" +msgstr "Zwraca wektor skierowany w kierunku zaÅ‚amania." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8746,6 +8455,12 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"Funkcja gÅ‚adkiego przejÅ›cia( wektor(krawÄ™dź0), wektor(krawÄ™dź1), " +"wektor(x) ).\n" +"\n" +"Zwraca 0.0 jeÅ›li \"x\" jest mniejsze niż \"edge0\" i 1.0 jeÅ›li x jest " +"wiÄ™ksze niż \"edge1\". W innym przypadku, zwraca wartość interpolowanÄ… " +"pomiÄ™dzy 0.0 i 1.0 używajÄ…c wielomianów Hermite'a." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8755,6 +8470,12 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"Funkcja gÅ‚adkiego przejÅ›cia( skalar(krawÄ™dź0), skalar(krawÄ™dź1), " +"wektor(x) ).\n" +"\n" +"Zwraca 0.0 jeÅ›li \"x\" jest mniejsze niż \"edge0\" i 1.0 jeÅ›li x jest " +"wiÄ™ksze niż \"edge1\". W innym przypadku, zwraca wartość interpolowanÄ… " +"pomiÄ™dzy 0.0 i 1.0 używajÄ…c wielomianów Hermite'a." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8762,6 +8483,9 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Funkcja przejÅ›cia( wektor(krawÄ™dź), wektor(x) ).\n" +"\n" +"Zwraca 0.0 jeÅ›li \"x\" jest mniejsze niż krawÄ™dź, w innym przypadku 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8769,36 +8493,37 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Funkcja przejÅ›cia( skalar(krawÄ™dź), wektor(x) ).\n" +"\n" +"Zwraca 0.0 jeÅ›li \"x\" jest mniejsze niż krawÄ™dź, w innym przypadku 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." -msgstr "" +msgstr "Dodaje wektor do wektora." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "" +msgstr "Dzieli wektor przez wektor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." -msgstr "" +msgstr "Mnoży wektor przez wektor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two vectors." -msgstr "" +msgstr "Zwraca resztÄ™ z dwóch wektorów." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts vector from vector." -msgstr "" +msgstr "Odejmuje wektor od wektora." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector constant." -msgstr "ZmieÅ„ stałą Vec" +msgstr "StaÅ‚a wektorowa." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector uniform." -msgstr "Przypisanie do uniformu." +msgstr "Uniform wektorowy." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8812,50 +8537,66 @@ msgid "" "Returns falloff based on the dot product of surface normal and view " "direction of camera (pass associated inputs to it)." msgstr "" +"Zwraca spadek na podstawie iloczynu skalarnego normalnej powierzchni i " +"kierunku widoku kamery (podaj tu powiÄ…zane wejÅ›cie)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function." msgstr "" +"(Tylko GLES3) (Tylko tryb fragmentów/Å›wiatÅ‚a) Skalarna pochodna funkcji." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function." msgstr "" +"(Tylko GLES3) (Tylko tryb fragmentów/Å›wiatÅ‚a) Wektorowa pochodna funkcji." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using " "local differencing." msgstr "" +"(Tylko GLES3) (Tylko tryb fragmentów/Å›wiatÅ‚a) (Wektor) Pochodna po \"x\" " +"używajÄ…c lokalnej zmiennoÅ›ci." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using " "local differencing." msgstr "" +"(Tylko GLES3) (Tylko tryb fragmentów/Å›wiatÅ‚a) (Skalar) Pochodna po \"x\" " +"używajÄ…c lokalnej zmiennoÅ›ci." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using " "local differencing." msgstr "" +"(Tylko GLES3) (Tylko tryb fragmentów/Å›wiatÅ‚a) (Wektor) Pochodna po \"y\" " +"używajÄ…c lokalnej zmiennoÅ›ci." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using " "local differencing." msgstr "" +"(Tylko GLES3) (Tylko tryb fragmentów/Å›wiatÅ‚a) (Skalar) Pochodna po \"y\" " +"używajÄ…c lokalnej zmiennoÅ›ci." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(Tylko GLES3) (Tylko tryb fragmentów/Å›wiatÅ‚a) (Wektor) Suma bezwzglÄ™dnej " +"pochodnej po \"x\" i \"y\"." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(Tylko GLES3) (Tylko tryb fragmentów/Å›wiatÅ‚a) (Skalar) Suma bezwzglÄ™dnej " +"pochodnej po \"x\" i \"y\"." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "VisualShader" @@ -9190,14 +8931,13 @@ msgstr "Projekt bez nazwy" #: editor/project_manager.cpp msgid "Can't open project at '%s'." -msgstr "Nie można otworzyć projektu w '%s'." +msgstr "Nie można otworzyć projektu w \"%s\"." #: editor/project_manager.cpp msgid "Are you sure to open more than one project?" msgstr "Czy jesteÅ› pewny że chcesz otworzyć wiÄ™cej niż jeden projekt?" #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file does not specify the version of Godot " "through which it was created.\n" @@ -9220,7 +8960,6 @@ msgstr "" "wczeÅ›niejszymi wersjami silnika." #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file was generated by an older engine " "version, and needs to be converted for this version:\n" @@ -9231,8 +8970,8 @@ msgid "" "Warning: You won't be able to open the project with previous versions of the " "engine anymore." msgstr "" -"Podany plik ustawieÅ„ projektu zostaÅ‚ stworzony przez starszÄ… wersjÄ™ silnika " -"i musi zostać przekonwertowany do aktualnej wersji.\n" +"Podany plik ustawieÅ„ projektu zostaÅ‚ wygenerowany przez starszÄ… wersjÄ™ " +"silnika i musi zostać przekonwertowany do aktualnej wersji.\n" "\n" "%s\n" "\n" @@ -9249,14 +8988,14 @@ msgstr "" "kompatybilna z obecnÄ… wersjÄ…." #: editor/project_manager.cpp -#, fuzzy 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 "" -"Nie zdefiniowano głównej sceny, chcesz jakÄ…Å› wybrać?\n" -"Można to później zmienić w \"Ustawienia projektu\" w kategorii \"aplikacja\"." +"Nie można uruchomić projektu: główna scena niezdefiniowana.\n" +"Edytuj projekt i zmieÅ„ głównÄ… scenÄ™ w Ustawieniach Projektu pod kategoriÄ… " +"\"Application\"." #: editor/project_manager.cpp msgid "" @@ -9267,48 +9006,49 @@ msgstr "" "Otwórz projekt w edytorze aby zaimportować zasoby." #: editor/project_manager.cpp -#, fuzzy msgid "Are you sure to run %d projects at once?" -msgstr "Czy jesteÅ› pewny że chcesz uruchomić wiÄ™cej niż jeden projekt?" +msgstr "Czy na pewno chcesz uruchomić %d projektów na raz?" #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove %d projects from the list?\n" "The project folders' contents won't be modified." -msgstr "Usunąć projekt z listy? (Zawartość folderu nie zostanie zmodyfikowana)" +msgstr "" +"Usunąć %d projektów z listy?\n" +"Zawartość folderów projektów nie zostanie zmodyfikowana." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove this project from the list?\n" "The project folder's contents won't be modified." -msgstr "Usunąć projekt z listy? (Zawartość folderu nie zostanie zmodyfikowana)" +msgstr "" +"Usunąć projekt z listy?\n" +"Zawartość folderu projektu nie zostanie zmodyfikowana." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove all missing projects from the list? (Folders contents will not be " "modified)" -msgstr "Usunąć projekt z listy? (Zawartość folderu nie zostanie zmodyfikowana)" +msgstr "" +"Usunąć wszystkie brakujÄ…ce projekty z listy? (Zawartość folderów nie " +"zostanie zmodyfikowana)" #: editor/project_manager.cpp -#, fuzzy msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." msgstr "" "JÄ™zyk zostaÅ‚ zmieniony.\n" -"Interfejs zaktualizuje siÄ™ gdy edytor lub menedżer projektu uruchomi siÄ™." +"Interfejs zaktualizuje siÄ™ po restarcie edytora lub menedżera projektów." #: editor/project_manager.cpp -#, fuzzy msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." msgstr "" -"Masz zamiar przeskanować %s folderów w poszukiwaniu projektów Godot. " -"Potwierdzasz?" +"Czy na pewno chcesz przeskanować %s folderów w poszukiwaniu istniejÄ…cych " +"projektów Godota?\n" +"To może chwilÄ™ zająć." #: editor/project_manager.cpp msgid "Project Manager" @@ -9331,9 +9071,8 @@ msgid "New Project" msgstr "Nowy projekt" #: editor/project_manager.cpp -#, fuzzy msgid "Remove Missing" -msgstr "UsuÅ„ punkt" +msgstr "UsuÅ„ brakujÄ…ce" #: editor/project_manager.cpp msgid "Templates" @@ -9352,13 +9091,12 @@ msgid "Can't run project" msgstr "Nie można uruchomić projektu" #: editor/project_manager.cpp -#, fuzzy msgid "" "You currently don't have any projects.\n" "Would you like to explore official example projects in the Asset Library?" msgstr "" "Nie posiadasz obecnie żadnych projektów.\n" -"Czy chciaÅ‚byÅ› zobaczyć oficjalne przykÅ‚adowe projekty w bibliotece zasobów?" +"Czy chcesz zobaczyć oficjalne przykÅ‚adowe projekty w Bibliotece Zasobów?" #: editor/project_settings_editor.cpp msgid "Key " @@ -9381,13 +9119,12 @@ msgid "" "Invalid action name. it cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'" msgstr "" -"Niepoprawna nazwa akcji. Nie może być pusta ani zawierać '/', ':', '=', '\\' " -"lub '\"'" +"Niepoprawna nazwa akcji. Nie może być pusta ani zawierać \"/\", \":\", \"=" +"\", \"\\\" lub \"" #: editor/project_settings_editor.cpp -#, fuzzy msgid "An action with the name '%s' already exists." -msgstr "Akcja %s już istnieje!" +msgstr "Akcja o nazwie \"%s\" już istnieje." #: editor/project_settings_editor.cpp msgid "Rename Input Action Event" @@ -9523,11 +9260,11 @@ msgstr "Najpierw wybierz ustawienie z listy!" #: editor/project_settings_editor.cpp msgid "No property '%s' exists." -msgstr "WÅ‚aÅ›ciwość '%s' nie istnieje." +msgstr "WÅ‚aÅ›ciwość \"%s\" nie istnieje." #: editor/project_settings_editor.cpp msgid "Setting '%s' is internal, and it can't be deleted." -msgstr "Wbudowana opcja '%s' nie może zostać usuniÄ™ta." +msgstr "Wbudowana opcja \"%s\" nie może zostać usuniÄ™ta." #: editor/project_settings_editor.cpp msgid "Delete Item" @@ -9538,8 +9275,8 @@ msgid "" "Invalid action name. It cannot be empty nor contain '/', ':', '=', '\\' or " "'\"'." msgstr "" -"Niepoprawna nazwa akcji. Nie może być pusta ani zawierać '/', ':', '=', '\\' " -"lub '\"'." +"Niepoprawna nazwa akcji. Nie może być pusta ani zawierać \"/\", \":\", \"=" +"\", \"\\\" lub \"." #: editor/project_settings_editor.cpp msgid "Add Input Action" @@ -9606,9 +9343,8 @@ msgid "Override For..." msgstr "Nadpisz dla..." #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -#, fuzzy msgid "The editor must be restarted for changes to take effect." -msgstr "Edytor musi zostać zrestartowany, by zmiany miaÅ‚y efekt" +msgstr "Edytor musi zostać zrestartowany, by zmiany miaÅ‚y efekt." #: editor/project_settings_editor.cpp msgid "Input Map" @@ -9667,14 +9403,12 @@ msgid "Locales Filter" msgstr "Filtr ustawieÅ„ lokalizacji" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show All Locales" -msgstr "Pokaż wszystkie lokalizacje" +msgstr "Pokaż wszystkie jÄ™zyki" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show Selected Locales Only" -msgstr "Pokaż tylko wybrane lokalizacje" +msgstr "Pokaż tylko wybrane jÄ™zyki" #: editor/project_settings_editor.cpp msgid "Filter mode:" @@ -9762,7 +9496,6 @@ msgid "Suffix" msgstr "Przyrostek" #: editor/rename_dialog.cpp -#, fuzzy msgid "Advanced Options" msgstr "Opcje zaawansowane" @@ -9919,7 +9652,8 @@ msgid "" "Cannot instance the scene '%s' because the current scene exists within one " "of its nodes." msgstr "" -"Nie można utworzyć sceny '%s' ponieważ obecna scena jest jednym z jej wezłów." +"Nie można utworzyć sceny \"%s\" ponieważ obecna scena jest jednym z jej " +"wÄ™złów." #: editor/scene_tree_dock.cpp msgid "Instance Scene(s)" @@ -10024,9 +9758,8 @@ msgid "User Interface" msgstr "Interfejs użytkownika" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Other Node" -msgstr "UsuÅ„ wÄ™zeÅ‚" +msgstr "Inny wÄ™zeÅ‚" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" @@ -10069,7 +9802,6 @@ msgid "Clear Inheritance" msgstr "Wyczyść dziedziczenie" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Open Documentation" msgstr "Otwórz dokumentacjÄ™" @@ -10078,6 +9810,10 @@ msgid "Add Child Node" msgstr "Dodaj wÄ™zeÅ‚" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "RozwiÅ„/zwiÅ„ wszystko" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "ZmieÅ„ typ" @@ -10106,8 +9842,8 @@ msgid "Delete (No Confirm)" msgstr "UsuÅ„ (bez potwierdzenie)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "Dodaj/Utwórz nowy wÄ™zeÅ‚" +msgid "Add/Create a New Node." +msgstr "Dodaj/Utwórz nowy wÄ™zeÅ‚." #: editor/scene_tree_dock.cpp msgid "" @@ -10142,19 +9878,16 @@ msgid "Toggle Visible" msgstr "Przełącz widoczność" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Unlock Node" -msgstr "Wybierz wÄ™zeÅ‚" +msgstr "Odblokuj wÄ™zeÅ‚" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Button Group" -msgstr "Przycisk 7" +msgstr "Grupa przycisków" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "(Connecting From)" -msgstr "Błąd połączenia" +msgstr "(Połączenie z)" #: editor/scene_tree_editor.cpp msgid "Node configuration warning:" @@ -10185,9 +9918,8 @@ msgstr "" "Kliknij, aby wyÅ›wietlić panel grup." #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Open Script:" -msgstr "Otwórz skrypt" +msgstr "Otwórz skrypt:" #: editor/scene_tree_editor.cpp msgid "" @@ -10238,43 +9970,36 @@ msgid "Select a Node" msgstr "Wybierz wÄ™zeÅ‚" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is empty." -msgstr "Åšcieżka jest pusta" +msgstr "Åšcieżka jest pusta." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Filename is empty." -msgstr "Nazwa pliku jest pusta" +msgstr "Nazwa pliku jest pusta." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is not local." -msgstr "Åšcieżka nie jest lokalna" +msgstr "Åšcieżka nie jest lokalna." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid base path." -msgstr "Niepoprawna Å›cieżka bazowa" +msgstr "Niepoprawna Å›cieżka bazowa." #: editor/script_create_dialog.cpp -#, fuzzy msgid "A directory with the same name exists." -msgstr "Katalog o tej nazwie już istnieje" +msgstr "Katalog o tej nazwie już istnieje." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid extension." -msgstr "Niepoprawne rozszerzenie" +msgstr "Niepoprawne rozszerzenie." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Wrong extension chosen." -msgstr "Wybrano błędne rozszeczenie" +msgstr "Wybrano błędne rozszerzenie." #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" -msgstr "Błąd podczas Å‚adowania szablonu '%s'" +msgstr "Błąd podczas Å‚adowania szablonu \"%s\"" #: editor/script_create_dialog.cpp msgid "Error - Could not create script in filesystem." @@ -10289,52 +10014,44 @@ msgid "N/A" msgstr "N/A" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Open Script / Choose Location" -msgstr "Otwórz skrypt/Wybierz lokacjÄ™" +msgstr "Otwórz skrypt / Wybierz lokacjÄ™" #: editor/script_create_dialog.cpp msgid "Open Script" msgstr "Otwórz skrypt" #: editor/script_create_dialog.cpp -#, fuzzy msgid "File exists, it will be reused." -msgstr "Plik istnieje, zostanie nadpisany" +msgstr "Plik istnieje, zostanie użyty ponownie." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid class name." -msgstr "Niepoprawna nazwa klasy" +msgstr "Niepoprawna nazwa klasy." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid inherited parent name or path." -msgstr "NieprawidÅ‚owa nazwa lub Å›cieżka klasy bazowej" +msgstr "NieprawidÅ‚owa nazwa lub Å›cieżka klasy bazowej." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script is valid." -msgstr "Skrypt prawidÅ‚owy" +msgstr "Skrypt jest prawidÅ‚owy." #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9 and _" msgstr "DostÄ™pne znaki: a-z, A-Z, 0-9 i _" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Built-in script (into scene file)." -msgstr "Wbudowany skrypt (w plik sceny)" +msgstr "Wbudowany skrypt (w plik sceny)." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will create a new script file." -msgstr "Utwórz nowy plik skryptu" +msgstr "Utwórz nowy plik skryptu." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will load an existing script file." -msgstr "Wczytaj istniejÄ…cy plik skryptu" +msgstr "Wczytaj istniejÄ…cy plik skryptu." #: editor/script_create_dialog.cpp msgid "Language" @@ -10376,7 +10093,7 @@ msgstr "Åšlad stosu" msgid "Pick one or more items from the list to display the graph." msgstr "Wybierz jeden lub wiÄ™cej elementów z listy by wyÅ›wietlić graf." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Błędy" @@ -10466,7 +10183,7 @@ msgstr "Ustaw z drzewa" #: editor/script_editor_debugger.cpp msgid "Export measures as CSV" -msgstr "" +msgstr "Eksportuj pomiary jako CSV" #: editor/settings_config_dialog.cpp msgid "Erase Shortcut" @@ -10598,12 +10315,11 @@ msgstr "GDNativeLibrary" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Enabled GDNative Singleton" -msgstr "" +msgstr "Włączony singleton GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Disabled GDNative Singleton" -msgstr "Wyłącz wiatraczek aktualizacji" +msgstr "Wyłączony singleton GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Library" @@ -10691,9 +10407,8 @@ msgid "GridMap Fill Selection" msgstr "GridMap WypeÅ‚nij zaznaczenie" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Paste Selection" -msgstr "GridMap UsuÅ„ zaznaczenie" +msgstr "GridMap Wklej zaznaczenie" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Paint" @@ -10779,54 +10494,6 @@ msgstr "Wybierz odlegÅ‚ość:" msgid "Class name can't be a reserved keyword" msgstr "Nazwa klasy nie może być sÅ‚owem zastrzeżonym" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Generowanie solucji..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "Generowanie projektu C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Nie udaÅ‚o siÄ™ stworzyć solucji." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Nie udaÅ‚o siÄ™ zapisać solucji." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Gotowe" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "Nie udaÅ‚o siÄ™ utworzyć projektu jÄ™zyka C#." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "O wsparciu jÄ™zyka C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Utwórz solucjÄ™ C#" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Wydania" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Zbuduj projekt" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Pokaż logi" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Koniec Å›ladu stosu wewnÄ™trznego wyjÄ…tku" @@ -10873,7 +10540,7 @@ msgstr "Tworzenie konturów..." #: modules/recast/navigation_mesh_generator.cpp msgid "Creating polymesh..." -msgstr "Tworzenie polymesh'a..." +msgstr "Tworzenie siatki wielokÄ…tnej..." #: modules/recast/navigation_mesh_generator.cpp msgid "Converting to native navigation mesh..." @@ -11065,7 +10732,7 @@ msgstr "Połącz sekwencjÄ™ wÄ™złów" #: modules/visual_script/visual_script_editor.cpp msgid "Script already has function '%s'" -msgstr "Skrypt posiada już funkcjÄ™ '%s'" +msgstr "Skrypt posiada już funkcjÄ™ \"%s\"" #: modules/visual_script/visual_script_editor.cpp msgid "Change Input Value" @@ -11120,9 +10787,8 @@ msgid "Available Nodes:" msgstr "DostÄ™pne wÄ™zÅ‚y:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Select or create a function to edit its graph." -msgstr "Wybierz lub utwórz funkcjÄ™, aby edytować wykres" +msgstr "Wybierz lub utwórz funkcjÄ™, aby edytować jej graf." #: modules/visual_script/visual_script_editor.cpp msgid "Delete Selected" @@ -11174,7 +10840,7 @@ msgstr "Åšcieżka nie prowadzi do wÄ™zÅ‚a!" #: modules/visual_script/visual_script_func_nodes.cpp msgid "Invalid index property name '%s' in node %s." -msgstr "NieprawidÅ‚owy indeks we wÅ‚aÅ›ciwoÅ›ci '%s' wÄ™zÅ‚a %s." +msgstr "NieprawidÅ‚owy indeks we wÅ‚aÅ›ciwoÅ›ci \"%s\" wÄ™zÅ‚a %s." #: modules/visual_script/visual_script_nodes.cpp msgid ": Invalid argument of type: " @@ -11227,7 +10893,7 @@ msgstr "Segmenty paczki muszÄ… mieć niezerowÄ… dÅ‚ugość." #: platform/android/export/export.cpp msgid "The character '%s' is not allowed in Android application package names." -msgstr "Znak '%s' nie jest dozwolony w nazwach paczek aplikacji Androida." +msgstr "Znak \"%s\" nie jest dozwolony w nazwach paczek aplikacji Androida." #: platform/android/export/export.cpp msgid "A digit cannot be the first character in a package segment." @@ -11235,7 +10901,7 @@ msgstr "Cyfra nie może być pierwszym znakiem w segmencie paczki." #: platform/android/export/export.cpp msgid "The character '%s' cannot be the first character in a package segment." -msgstr "Znak '%s' nie może być pierwszym znakiem w segmencie paczki." +msgstr "Znak \"%s\" nie może być pierwszym znakiem w segmencie paczki." #: platform/android/export/export.cpp msgid "The package must have at least one '.' separator." @@ -11314,7 +10980,7 @@ msgstr "Segmenty identyfikatora muszÄ… mieć niezerowÄ… dÅ‚ugość." #: platform/iphone/export/export.cpp msgid "The character '%s' is not allowed in Identifier." -msgstr "Znak '%s' nie jest dozwolony w identyfikatorze." +msgstr "Znak \"%s\" nie jest dozwolony w identyfikatorze." #: platform/iphone/export/export.cpp msgid "A digit cannot be the first character in a Identifier segment." @@ -11323,7 +10989,7 @@ msgstr "Cyfra nie może być pierwszym znakiem w segmencie identyfikatora." #: platform/iphone/export/export.cpp msgid "" "The character '%s' cannot be the first character in a Identifier segment." -msgstr "Znak '%s' nie może być pierwszym znakiem w segmencie identyfikatora." +msgstr "Znak \"%s\" nie może być pierwszym znakiem w segmencie identyfikatora." #: platform/iphone/export/export.cpp msgid "The Identifier must have at least one '.' separator." @@ -11426,8 +11092,9 @@ msgstr "" "NieprawidÅ‚owe wymiary obrazka ekranu powitalnego (powinno być 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Aby AnimatedSprite pokazywaÅ‚ poszczególne klatki, pole Frames musi zawierać " @@ -11494,8 +11161,9 @@ msgstr "" "\"Particles Animation\"." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Tekstura z ksztaÅ‚tem promieni Å›wiatÅ‚a musi być dodana do pola Tekstura." @@ -11508,7 +11176,8 @@ msgstr "" "zadziaÅ‚aÅ‚." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "Poligon zasÅ‚aniajÄ…cy jest pusty. ProszÄ™ narysować poligon!" #: scene/2d/navigation_polygon.cpp @@ -11595,50 +11264,58 @@ msgstr "" "Tej koÅ›ci brakuje odpowiedniej pozy spoczynkowej. Pójdź do wÄ™zÅ‚a Skeleton2D " "i ustaw jÄ…." +#: 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 sÅ‚uży jedynie do okreÅ›lenia ksztaÅ‚tu kolizji dla jednego z " +"obiektów dziedziczÄ…cych z CollisionObject2D. Używaj go tylko jako dziecko " +"obiektów typu Area2D, StaticBody2D, RigidBody2D, KinematicBody2D itd." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D dziaÅ‚a najlepiej, gdy jest bezpoÅ›rednio pod korzeniem " "aktualnie edytowanej sceny." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera musi dziedziczyć po węźle ARVROrigin" #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRController must have an ARVROrigin node as its parent." -msgstr "ARVRController musi posiadać wÄ™zeÅ‚ ARVROrigin jako nadrzÄ™dny" +msgstr "ARVRController musi posiadać wÄ™zeÅ‚ ARVROrigin jako nadrzÄ™dny." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The controller ID must not be 0 or this controller won't be bound to an " "actual controller." msgstr "" -"Id kontrolera nie może być '0' w innym przypadku kontroler nie zostanie " -"przypisany do żadnego rzeczywistego kontrolera" +"ID kontrolera nie może być 0, w innym przypadku kontroler nie zostanie " +"przypisany do żadnego rzeczywistego kontrolera." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRAnchor must have an ARVROrigin node as its parent." -msgstr "ARVRAnchor musi posiadać wÄ™zeÅ‚ ARVROrigin jako nadrzÄ™dny" +msgstr "ARVRAnchor musi posiadać wÄ™zeÅ‚ ARVROrigin jako nadrzÄ™dny." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The anchor ID must not be 0 or this anchor won't be bound to an actual " "anchor." msgstr "" "ID kotwicy nie może być 0, bo inaczej ta kotwica nie bÄ™dzie przypisana do " -"rzeczywistej kotwicy" +"rzeczywistej kotwicy." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVROrigin requires an ARVRCamera child node." -msgstr "ARVROrigin wymaga dziedziczÄ…cego po nim ARVRCamera" +msgstr "ARVROrigin wymaga wÄ™zÅ‚a potomnego typu ARVRCamera." #: scene/3d/baked_lightmap.cpp msgid "%d%%" @@ -11700,9 +11377,10 @@ msgstr "" "typu Area, StaticBody, RigidBody, KinematicBody itd." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "KsztaÅ‚t musi być okreÅ›lony dla CollisionShape, aby speÅ‚niaÅ‚ swoje zadanie. " "Utwórz zasób typu CollisionShape w odpowiednim polu obiektu!" @@ -11720,13 +11398,12 @@ msgid "Nothing is visible because no mesh has been assigned." msgstr "Nie zostaÅ‚a przypisana żadna siatka, wiÄ™c nic siÄ™ nie pojawi." #: scene/3d/cpu_particles.cpp -#, fuzzy msgid "" "CPUParticles animation requires the usage of a SpatialMaterial whose " "Billboard Mode is set to \"Particle Billboard\"." msgstr "" -"Animacja CPUParticles wymaga użycia SpatialMaterial z włączonym \"Billboard " -"Particles\"." +"Animacja CPUParticles wymaga użycia zasobu SpatialMaterial, którego " +"Billboard Mode jest ustawione na \"Particle Billboard\"." #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" @@ -11740,6 +11417,10 @@ msgstr "" "GIProbes nie sÄ… obsÅ‚ugiwane przez sterownik wideo GLES2.\n" "Zamiast tego użyj BakedLightmap." +#: 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 "" @@ -11771,22 +11452,22 @@ msgstr "" "Nic nie jest widoczne, bo siatki nie zostaÅ‚y przypisane do kolejki rysowania." #: scene/3d/particles.cpp -#, fuzzy msgid "" "Particles animation requires the usage of a SpatialMaterial whose Billboard " "Mode is set to \"Particle Billboard\"." msgstr "" -"Animacja Particles wymaga użycia SpatialMaterial z włączonym \"Billboard " -"Particles\"." +"Animacja Particles wymaga użycia zasobu SpatialMaterial, którego Billboard " +"Mode jest ustawione na \"Particle Billboard\"." #: scene/3d/path.cpp msgid "PathFollow only works when set as a child of a Path node." msgstr "PathFollow dziaÅ‚a tylko, gdy jest wÄ™zÅ‚em podrzÄ™dnym Path." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED wymaga włączonego \"Wektora w górÄ™\" w zasobie " "Curve jego nadrzÄ™dnego wÄ™zÅ‚a Path." @@ -11802,13 +11483,15 @@ msgstr "" "Zamiast tego, zmieÅ„ rozmiary ksztaÅ‚tów kolizji w wÄ™zÅ‚ach podrzÄ™dnych." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "Pole Path musi wskazywać na wÄ™zeÅ‚ Spatial." #: scene/3d/soft_body.cpp -#, fuzzy msgid "This body will be ignored until you set a mesh." -msgstr "To ciaÅ‚o bÄ™dzie ignorowane, dopóki nie ustawisz siatki" +msgstr "To ciaÅ‚o bÄ™dzie ignorowane, dopóki nie ustawisz siatki." #: scene/3d/soft_body.cpp msgid "" @@ -11821,12 +11504,13 @@ msgstr "" "Zamiast tego, zmieÅ„ rozmiary ksztaÅ‚tów kolizji w wÄ™zÅ‚ach podrzÄ™dnych." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" -"Zasób SpriteFrames musi być ustawiony jako wartość wÅ‚aÅ›ciwoÅ›ci 'Frames' żeby " -"AnimatedSprite3D wyÅ›wietlaÅ‚ klatki." +"Zasób SpriteFrames musi być ustawiony jako wartość wÅ‚aÅ›ciwoÅ›ci \"Frames\" " +"żeby AnimatedSprite3D wyÅ›wietlaÅ‚ klatki." #: scene/3d/vehicle_body.cpp msgid "" @@ -11837,8 +11521,10 @@ msgstr "" "dziedziczÄ…cego po VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment wymaga zasobu Environment." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11861,22 +11547,23 @@ msgstr "W węźle BlendTree '%s', animacja nie znaleziona: '%s'" #: scene/animation/animation_blend_tree.cpp msgid "Animation not found: '%s'" -msgstr "Animacja nie znaleziona: '%s'" +msgstr "Animacja nie znaleziona: \"%s\"" #: scene/animation/animation_tree.cpp msgid "In node '%s', invalid animation: '%s'." -msgstr "W węźle '%s', nieprawidÅ‚owa animacja: '%s'." +msgstr "W węźle \"%s\", nieprawidÅ‚owa animacja: \"%s\"." #: scene/animation/animation_tree.cpp msgid "Invalid animation: '%s'." -msgstr "NieprawidÅ‚owa animacja: '%s'." +msgstr "NieprawidÅ‚owa animacja: \"%s\"." #: scene/animation/animation_tree.cpp msgid "Nothing connected to input '%s' of node '%s'." -msgstr "Nic nie podłączono do wejÅ›cia '%s' wÄ™zÅ‚a '%s'." +msgstr "Nic nie podłączono do wejÅ›cia \"%s\" wÄ™zÅ‚a \"%s\"." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "KorzeÅ„ dla grafu AnimationNode nie jest ustawiony." #: scene/animation/animation_tree.cpp @@ -11890,7 +11577,8 @@ msgstr "" "Åšcieżka do wÄ™zÅ‚a AnimationPlayer nie prowadzi do wÄ™zÅ‚a AnimationPlayer." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "KorzeÅ„ AnimationPlayer nie jest poprawnym wÄ™zÅ‚em." #: scene/animation/animation_tree_player.cpp @@ -11902,8 +11590,12 @@ msgid "Pick a color from the screen." msgstr "Pobierz kolor z ekranu." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Trybie RAW" +msgid "HSV" +msgstr "HSV" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "Raw" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11916,16 +11608,23 @@ msgstr "Dodaj bieżący kolor do zapisanych." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" "Kontener sam w sobie nie speÅ‚nia żadnego celu, chyba że jakiÅ› skrypt " "konfiguruje sposób ustawiania jego podrzÄ™dnych wÄ™złów.\n" "JeÅ›li nie zamierzasz dodać skryptu, zamiast tego użyj zwykÅ‚ego wÄ™zÅ‚a " "\"Control\"." +#: 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 "" +"Hint Tooltip nie zostanie pokazany, ponieważ Mouse Filter jest ustawione na " +"\"Ignore\". By to rozwiÄ…zać, ustaw Mouse Filter na \"Stop\" lub \"Pass\"." + #: scene/gui/dialogs.cpp msgid "Alert!" msgstr "Alarm!" @@ -11935,23 +11634,26 @@ msgid "Please Confirm..." msgstr "ProszÄ™ potwierdzić..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "WyskakujÄ…ce okna bÄ™dÄ… domyÅ›lnie ukryte dopóki nie wywoÅ‚asz popup() lub " "dowolnej funkcji popup*(). Ustawienie ich jako widocznych jest przydatne do " "edycji, ale zostanÄ… ukryte po uruchomieniu." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "JeÅ›li exp_edit jest prawdziwe, min_value musi być > 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer jest zaprojektowany do dziaÅ‚ania z jednym dzieckiem klasy " @@ -12004,6 +11706,11 @@ msgid "Input" msgstr "WejÅ›cie" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "NiewÅ‚aÅ›ciwe źródÅ‚o dla shadera." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "NiewÅ‚aÅ›ciwe źródÅ‚o dla shadera." @@ -12021,7 +11728,90 @@ msgstr "Varying może być przypisane tylko w funkcji wierzchoÅ‚ków." #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "StaÅ‚e nie mogÄ… być modyfikowane." + +#~ msgid "Generating solution..." +#~ msgstr "Generowanie solucji..." + +#~ msgid "Generating C# project..." +#~ msgstr "Generowanie projektu C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "Nie udaÅ‚o siÄ™ stworzyć solucji." + +#~ 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#." + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "O wsparciu jÄ™zyka C#" + +#~ msgid "Create C# solution" +#~ msgstr "Utwórz solucjÄ™ C#" + +#~ msgid "Builds" +#~ msgstr "Wydania" + +#~ msgid "Build Project" +#~ msgstr "Zbuduj projekt" + +#~ msgid "View log" +#~ msgstr "Pokaż logi" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment wymaga zasobu Environment." + +#~ msgid "Enabled Classes" +#~ msgstr "Włączone klasy" + +#~ msgid "Update Always" +#~ msgstr "Zawsze OdÅ›wieżaj" + +#~ msgid "'camera' input parameter for all shader modes." +#~ msgstr "Parametr wejÅ›ciowy \"camera\" dla wszystkich trybów shadera." + +#~ msgid "'inv_camera' input parameter for all shader modes." +#~ msgstr "Parametr wejÅ›ciowy \"inv_camera\" dla wszystkich trybów shadera." + +#~ msgid "'inv_projection' input parameter for all shader modes." +#~ msgstr "" +#~ "Parametr wejÅ›ciowy \"inv_projection\" dla wszystkich trybów shadera." + +#~ msgid "'normal' input parameter for all shader modes." +#~ msgstr "Parametr wejÅ›ciowy \"normal\" dla wszystkich trybów shadera." + +#~ msgid "'projection' input parameter for all shader modes." +#~ msgstr "Parametr wejÅ›ciowy \"projection\" dla wszystkich trybów shadera." + +#~ msgid "'time' input parameter for all shader modes." +#~ msgstr "Parametr wejÅ›ciowy \"time\" dla wszystkich trybów shadera." + +#~ msgid "'viewport_size' input parameter for all shader modes." +#~ msgstr "Parametr wejÅ›ciowy \"viewport_size\" dla wszystkich trybów shadera." + +#~ msgid "'world' input parameter for all shader modes." +#~ msgstr "Parametr wejÅ›ciowy \"world\" dla wszystkich trybów shadera." + +#~ msgid "'alpha' input parameter for all shader modes." +#~ msgstr "Parametr wejÅ›ciowy \"alpha\" dla wszystkich trybów shadera." + +#~ msgid "'color' input parameter for all shader modes." +#~ msgstr "Parametr wejÅ›ciowy \"color\" dla wszystkich trybów shadera." + +#~ msgid "'texture_pixel_size' input parameter for all shader modes." +#~ msgstr "" +#~ "Parametr wejÅ›ciowy \"texture_pixel_size\" dla wszystkich trybów shadera." + +#~ msgid "Raw Mode" +#~ msgstr "Trybie RAW" #~ msgid "Path to Node:" #~ msgstr "Åšcieżka do wÄ™zÅ‚a:" @@ -12557,9 +12347,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Przełącz widoczność Spatial" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Przełącz widoczność CanvasItem" - #~ msgid "Condition" #~ msgstr "Warunek" diff --git a/editor/translations/pr.po b/editor/translations/pr.po index 4d976eb687..95c567a176 100644 --- a/editor/translations/pr.po +++ b/editor/translations/pr.po @@ -451,6 +451,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Slit th' Node" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -626,6 +636,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -675,7 +689,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -782,6 +796,11 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Yer signals:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -944,7 +963,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1312,7 +1331,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1489,6 +1508,10 @@ msgstr "Yer fancy release package be nowhere." 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 #, fuzzy msgid "3D Editor" @@ -1517,7 +1540,7 @@ msgid "Node Dock" msgstr "Find ye Node Type" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1573,7 +1596,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1588,7 +1611,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Slit th' Node" #: editor/editor_feature_profile.cpp @@ -1612,14 +1635,10 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "yer Nodes doing nothin':" #: editor/editor_feature_profile.cpp -msgid "Enabled Classes" -msgstr "" - -#: editor/editor_feature_profile.cpp #, fuzzy msgid "Class Options" msgstr "Yar, Blow th' Selected Down!" @@ -2644,10 +2663,31 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Toggle ye Breakpoint" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -2754,15 +2794,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "" +#, fuzzy +msgid "Update When Changed" +msgstr "Change" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2956,7 +2997,7 @@ msgstr "" msgid "Calls" msgstr "Call" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3056,20 +3097,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3574,6 +3615,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp #, fuzzy msgid "Filter nodes" msgstr "Paste yer Node" @@ -5199,6 +5241,13 @@ 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 "" @@ -6120,10 +6169,20 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Paste yer Node" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Paste yer Node" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "" @@ -6357,18 +6416,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Yar, Blow th' Selected Down!" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7968,51 +8031,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8020,203 +8039,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9862,6 +9705,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9891,8 +9738,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Yar, Blow th' Selected Down!" #: editor/scene_tree_dock.cpp msgid "" @@ -10142,7 +9990,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10553,54 +10401,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11213,7 +11013,7 @@ msgstr "Yer splash screen image dimensions aint' 620x300!" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11262,7 +11062,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11272,7 +11072,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11339,14 +11139,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11425,7 +11232,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11454,6 +11261,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11488,8 +11299,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11500,7 +11311,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11516,7 +11329,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11527,7 +11340,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11563,7 +11378,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11575,7 +11390,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11587,7 +11402,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11600,10 +11419,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11617,18 +11441,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11672,6 +11496,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "Yer Calligraphy be wrongly sized." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "Yer Calligraphy be wrongly sized." diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po index d618b0b7d7..c9b8697dd6 100644 --- a/editor/translations/pt_BR.po +++ b/editor/translations/pt_BR.po @@ -62,12 +62,14 @@ # Klaus Dellano <klausdell@hotmail.com>, 2019. # Esdras Tarsis <esdrastarsis@gmail.com>, 2019. # Douglas Fiedler <dognew@gmail.com>, 2019. +# Rarysson Guilherme <r_guilherme12@hotmail.com>, 2019. +# Gustavo da Silva Santos <gustavo94.rb@gmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: 2016-05-30\n" -"PO-Revision-Date: 2019-06-16 19:41+0000\n" -"Last-Translator: Douglas Fiedler <dognew@gmail.com>\n" +"PO-Revision-Date: 2019-07-09 10:46+0000\n" +"Last-Translator: Gustavo da Silva Santos <gustavo94.rb@gmail.com>\n" "Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_BR/>\n" "Language: pt_BR\n" @@ -75,7 +77,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -134,9 +136,8 @@ msgid "Time:" msgstr "Tempo:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Valor" +msgstr "Valor:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -490,10 +491,28 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Esta animação pertence a uma cena importada, dessa forma, mudanças das " +"trilhas importadas não serão salvas.\n" +"\n" +"Para ativar a possibilidade de adicionar trilhas customizadas, navegue até " +"as configurações de importação da cena e defina\n" +"\"Animação > Armazenamento\" para \"Arquivos\", ative \"Animação > Mantenha " +"Trilhas Customizadas\", então reimporte.\n" +"Alternativamente, você pode usar um preset importado que importe animações " +"em arquivos separados." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Aviso: Editando animação importada" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Selecionar Tudo" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "Remover Seleção" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -669,6 +688,10 @@ msgstr "Ir para Linha" msgid "Line Number:" msgstr "Número da Linha:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Sem Correspondências" @@ -718,7 +741,7 @@ msgstr "Reduzir" msgid "Reset Zoom" msgstr "Redefinir Ampliação" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Avisos" @@ -727,38 +750,32 @@ msgid "Line and column numbers." msgstr "Números de linha e coluna." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "O método no Nó alvo precisa ser especificado!" +msgstr "O método no nó alvo precisa ser especificado." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Método alvo não encontrado! Especifique um método válido ou anexe um script " -"ao Nó alvo." +"Método alvo não encontrado. Especifique um método válido ou anexe um script " +"ao nó alvo." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" msgstr "Conectar ao Nó:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Não foi possÃvel conectar ao host:" +msgstr "Conectar ao Script:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Sinais:" +msgstr "Sinal Origem:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "O nó não contém geometria." +msgstr "A cena não contém nenhum script." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -786,18 +803,18 @@ msgid "Extra Call Arguments:" msgstr "Argumentos de Chamada Extras:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Opções avançadas" +msgstr "Avançado" #: editor/connections_dialog.cpp msgid "Deferred" -msgstr "Postergado" +msgstr "Diferido" #: editor/connections_dialog.cpp msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Adia o sinal, guardando em uma fila e o ativando somente em tempo ocioso." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -805,12 +822,11 @@ msgstr "Oneshot" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Desconecta o sinal depois da sua primeira emissão." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Conectar Sinal: " +msgstr "Não foi possÃvel conectar o sinal" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -831,6 +847,11 @@ msgid "Connect" msgstr "Conectar" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Sinais:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Conectar \"%s\" a \"%s\"" @@ -852,14 +873,12 @@ msgid "Disconnect" msgstr "Desconectar" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Conectar Sinal: " +msgstr "Conectar um Sinal a um Método" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Editar Conexão: " +msgstr "Editar Conexão:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -935,22 +954,20 @@ msgid "Dependencies For:" msgstr "Dependências Para:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" -"Cena \"%s\" está sendo editada atualmente.\n" -"Alterações não terão efeito a menos que seja recarregada." +"Cena '%s' está sendo editada atualmente.\n" +"As alterações só serão feitas quando a cena for recarregada." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" -"Recurso \"%s\" está em uso.\n" -"Alterações terão efeito ao recarregar." +"Recurso '%s' está em uso.\n" +"As alterações só serão feitas quando o recurso for recarregado." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -997,7 +1014,8 @@ msgid "Owners Of:" msgstr "Donos De:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Remover arquivos selecionados do projeto? (irreversÃvel)" #: editor/dependency_editor.cpp @@ -1043,9 +1061,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Excluir permanentemente %d item(s)? (IrreversÃvel)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "Dependências" +msgstr "Mostrar Dependências" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1308,7 +1325,7 @@ msgstr "Abrir Layout de Canais de Ãudio" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Não existe o arquivo '%s'." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1365,30 +1382,24 @@ msgid "Valid characters:" msgstr "Caracteres válidos:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "Nome inválido. Não é permitido utilizar nomes de classes da engine." +msgstr "Não é permitido utilizar nomes de classes da engine." #: editor/editor_autoload_settings.cpp -#, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "" -"Nome inválido. Não é permitido utilizar nomes de tipos internos da engine." +msgid "Must not collide with an existing built-in type name." +msgstr "Não deve coincidir com um nome de tipo interno existente." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." -msgstr "" -"Nome inválido. Não é permitido utilizar nomes de constantes globais da " -"engine." +msgstr "Não é permitido utilizar nomes de constantes globais da engine." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "A palavra-chave não pode ser usada como um nome de autoload." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" -msgstr "Autoload \"%s\" já existe!" +msgstr "Autoload '%s' já existe!" #: editor/editor_autoload_settings.cpp msgid "Rename Autoload" @@ -1415,7 +1426,6 @@ msgid "Rearrange Autoloads" msgstr "Reordenar Autoloads" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "Caminho inválido." @@ -1470,9 +1480,8 @@ msgid "[unsaved]" msgstr "[não salvo]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Por favor selecione um diretório base primeiro" +msgstr "Por favor selecione um diretório base primeiro." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1556,30 +1565,29 @@ msgstr "Template customizado de release não encontrado." msgid "Template file not found:" msgstr "Arquivo de modelo não encontrado:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Editor" +msgstr "Editor 3D" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Abrir Editor de Scripts" +msgstr "Editor de Script" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Abrir Biblioteca de Assets" +msgstr "Biblioteca de Assets" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Ãrvore de Cena (Nodes):" +msgstr "Edição da Ãrvore de Cena" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Importar" +msgstr "Importar Dock" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1588,90 +1596,79 @@ msgstr "Nó Movido" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "Arquivos" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Substituir Tudo (sem desfazer)" +msgstr "Apagar perfil '%s'? (sem desfazer)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "O perfil precisa ser um nome de arquivo válido e não pode conter '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Um arquivo ou pasta com esse nome já existe." +msgstr "Um perfil com esse nome já existe." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Editor Desativado, Propriedades Desativadas)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Apenas Propriedades" +msgstr "(Propriedades Desativadas)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Corte Desabilitado" +msgstr "(Editor Desativado)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Descrição da Classe:" +msgstr "Opções da Classe:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Abrir o próximo Editor" +msgstr "Habilitar Editor Contextual" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Propriedades:" +msgstr "Propriedades Ativadas:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "Funcionalidades" +msgstr "Funcionalidades Ativadas:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Pesquisar Classes" +msgstr "Classes Ativadas:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "O formato do arquivo '%s' é inválido, importação abortada." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"Perfil '%s' já existe. Remova-o antes de importar, importação interrompida." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Erro ao carregar modelo '%s'" +msgstr "Erro ao salvar perfil no caminho: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Desmontardo" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Current Profile" -msgstr "Versão Atual:" +msgid "Current Profile:" +msgstr "Perfil Atual:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Atual:" +msgstr "Definir como atual" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1689,44 +1686,32 @@ msgid "Export" msgstr "Exportar" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Available Profiles" -msgstr "Nodes DisponÃveis:" +msgid "Available Profiles:" +msgstr "Perfis DisponÃveis:" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Pesquisar Classes" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Descrição da Classe" +msgstr "Opções da Classe" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Novo nome:" +msgstr "Novo nome de perfil:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Apagar Ãrea" +msgstr "Apagar Perfil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Projeto Importado" +msgstr "Importar Perfil(s)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Exportar Projeto" +msgstr "Exportar Perfil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "Gerenciar Modelos de Exportação" +msgstr "Gerenciar perfis de recurso do editor" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -2232,13 +2217,12 @@ msgstr "" "melhor esse procedimento." #: editor/editor_node.cpp -#, fuzzy msgid "" "This resource belongs to a scene that was instanced or inherited.\n" "Changes to it won't be kept when saving the current scene." msgstr "" "Este recurso pertence a uma cena que foi instanciada ou herdada.\n" -"Alterações nele não serão mantidas ao salvar a cena atual." +"Alterações no recurso não serão mantidas ao salvar a cena atual." #: editor/editor_node.cpp msgid "" @@ -2249,7 +2233,6 @@ msgstr "" "no painel de importação e então re-importe." #: editor/editor_node.cpp -#, fuzzy 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" @@ -2262,7 +2245,6 @@ msgstr "" "melhor esse procedimento." #: editor/editor_node.cpp -#, fuzzy 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 " @@ -2293,9 +2275,8 @@ msgid "Open Base Scene" msgstr "Abrir Cena Base" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Abrir Cena Rapidamente..." +msgstr "Abrir Rapidamente..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2538,12 +2519,11 @@ msgstr "Fechas as outras abas" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Fechar Abas à Direita" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Fechar Tudo" +msgstr "Fechar Todas Abas" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2788,10 +2768,34 @@ msgid "Editor Layout" msgstr "Layout do Editor" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Fazer Raiz de Cena" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Abrir Editor/Configurações de Pasta" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Abrir o próximo Editor" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Alternar Tela-Cheia" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Alternar CanvasItem VisÃvel" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Abrir Editor/Configurações de Pasta" @@ -2831,7 +2835,7 @@ msgstr "Documentação Online" #: editor/editor_node.cpp msgid "Q&A" -msgstr "P&R" +msgstr "Perguntas & Respostas" #: editor/editor_node.cpp msgid "Issue Tracker" @@ -2899,15 +2903,18 @@ msgid "Spins when the editor window redraws." msgstr "Gira quando a janela do editor atualiza." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Atualizar Sempre" +#, fuzzy +msgid "Update Continuously" +msgstr "ContÃnuo" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Atualizar Alterações" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Desabilitar Spinner de Atualização" #: editor/editor_node.cpp @@ -2939,9 +2946,8 @@ msgid "Android build template is missing, please install relevant templates." msgstr "" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Gerenciar Modelos de Exportação" +msgstr "Gerenciar Templates" #: editor/editor_node.cpp msgid "" @@ -3098,7 +3104,7 @@ msgstr "Tempo" msgid "Calls" msgstr "Chamadas" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Ativo" @@ -3205,6 +3211,11 @@ msgid "Page: " msgstr "Página: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Remover Item" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Nova Chave:" @@ -3216,11 +3227,6 @@ msgstr "Novo Valor:" msgid "Add Key/Value Pair" msgstr "Adicionar Par de Chave/Valor" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Remover Item" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3510,9 +3516,8 @@ msgid "No name provided." msgstr "Nenhum nome fornecido." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "O nome fornecido contém caracteres inválidos" +msgstr "O nome fornecido contém caracteres inválidos." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3539,28 +3544,24 @@ msgid "Duplicating folder:" msgstr "Duplicando pasta:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Nova Cena Herdada..." +msgstr "Nova Cena Herdada" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Abrir Cena" +msgstr "Abrir Cenas" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Instância" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" -msgstr "Adicionar aos favoritos" +msgstr "Adicionar aos Favoritos" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "Remover dos favoritos" +msgstr "Remover dos Favoritos" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." @@ -3608,14 +3609,12 @@ msgid "Rename" msgstr "Renomear" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Pasta Anterior" +msgstr "Pasta/Arquivo Anterior" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Próxima Pasta" +msgstr "Próxima Pasta/Arquivo" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" @@ -3675,6 +3674,8 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Inclui os arquivos com as seguintes extensões. Adicione ou remova os " +"arquivos em ProjectSettings." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3726,6 +3727,7 @@ msgid "Nodes not in Group" msgstr "Nós fora do Grupo" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtrar nós" @@ -4114,9 +4116,8 @@ msgid "Open Animation Node" msgstr "Abrir Nó de Animação" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "Triângulo já existe" +msgstr "Triângulo já existe." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4263,9 +4264,8 @@ msgid "Edit Filtered Tracks:" msgstr "Editar trilhas filtradas:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" -msgstr "Habilitar filtragem" +msgstr "Habilitar Filtragem" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" @@ -4987,27 +4987,23 @@ msgstr "Alterar Âncoras" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "Ferramenta Selecionar" +msgstr "Fixar Seleção" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "Excluir Selecionados" +msgstr "Destravar Selecionado" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Copiar Seleção" +msgstr "Agrupar Selecionados" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Copiar Seleção" +msgstr "Desagrupar Selecionados" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" @@ -5329,9 +5325,8 @@ msgid "Error instancing scene from %s" msgstr "Erro ao instanciar cena de %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" -msgstr "Mudar tipo padrão" +msgstr "Mudar Tipo Padrão" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -5373,6 +5368,14 @@ msgid "Load Emission Mask" msgstr "Carregar Máscara de Emissão" #: 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 +#, fuzzy +msgid "Restart" +msgstr "Reiniciar Agora" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Limpar Máscara de Emissão" @@ -5418,14 +5421,12 @@ msgid "Create Emission Points From Node" msgstr "Criar Pontos de Emissão a Partir do Nó" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "Flat0" +msgstr "Plano 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "Flat1" +msgstr "Plano 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -5452,14 +5453,12 @@ msgid "Load Curve Preset" msgstr "Carregar Definição de Curva" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" -msgstr "Adicionar ponto" +msgstr "Adicionar Ponto" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" -msgstr "Remover ponto" +msgstr "Remover Ponto" #: editor/plugins/curve_editor_plugin.cpp #, fuzzy @@ -5535,12 +5534,11 @@ msgstr "Criar Forma Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "Falha ao criar formas!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "Criar Forma Convexa" +msgstr "Criar Forma(s) Convexa(s)" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -6295,10 +6293,20 @@ msgid "Find Next" msgstr "Localizar próximo" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filtrar propriedades" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "Alternar ordenação alfabética da lista de métodos." #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Modo de filtragem:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Ordenar" @@ -6409,18 +6417,16 @@ msgid "Debug with External Editor" msgstr "Depurar com o Editor Externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Abrir a documentação online da Godot" +msgstr "Abrir a documentação online da Godot." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" msgstr "Solicitar documentos" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "Ajude a melhorar a documentação do Godot dando seu feedback" +msgstr "Ajude a melhorar a documentação do Godot dando seu feedback." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6465,29 +6471,25 @@ msgid "Search Results" msgstr "Pesquisar resultados" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "Conectar ao Nó:" +msgstr "Conexões com o método:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Origem:" +msgstr "Origem" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Sinais" +msgstr "Sinal" #: editor/plugins/script_text_editor.cpp msgid "Target" msgstr "Destino" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "Nada está ligado à entrada '%s' do nó '%s'." +msgstr "Falta método conectado '%s' para sinal '%s' do nó '%s' para nó '%s'." #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6534,20 +6536,24 @@ msgid "Syntax Highlighter" msgstr "Realce de sintaxe" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "Marcadores" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Criar pontos." #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Recortar" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Selecionar Tudo" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Excluir Linha" @@ -6565,9 +6571,8 @@ msgid "Toggle Comment" msgstr "Alternar Comentário" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "Alternar Visão Livre" +msgstr "Alternar Marcador" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -7009,9 +7014,8 @@ msgid "Right View" msgstr "Visão Direita" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" -msgstr "Alternar visão Perspectiva/Ortogonal" +msgstr "Alternar Visão Perspectiva/Ortogonal" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" @@ -7055,9 +7059,8 @@ msgid "Transform" msgstr "Transformação" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" -msgstr "Encaixar o objeto no chão" +msgstr "Encaixar Objeto ao Chão" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Dialog..." @@ -7251,9 +7254,8 @@ msgid "No Frames Selected" msgstr "Seleção de Quadros" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "Adicionar Quadro" +msgstr "Adicionar %d Quadro(s)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" @@ -7304,9 +7306,8 @@ msgid "Animation Frames:" msgstr "Quadros da Animação:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Adicionar textura(s) ao TileSet." +msgstr "Adicionar Textura de um Arquivo" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" @@ -7334,14 +7335,12 @@ msgid "Select Frames" msgstr "Pilha de Quadros" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Girar horizontalmente" +msgstr "Horizontal:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "Vértices" +msgstr "Vertical:" #: editor/plugins/sprite_frames_editor_plugin.cpp #, fuzzy @@ -7492,7 +7491,7 @@ msgstr "" #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Submenu" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -7536,7 +7535,7 @@ msgstr "Filhos Editáveis" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "Subárvore" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7634,6 +7633,8 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift+RMB: Desenhar Linha\n" +"Shift+Ctrl+RMB: Pintar Retângulo" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" @@ -7954,13 +7955,12 @@ msgid "Scalar" msgstr "Escala:" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Inspetor" +msgstr "Vetor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Booleano" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -7969,7 +7969,7 @@ msgstr "Adicionar Entrada" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Adicionar porta de saÃda" #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8068,11 +8068,11 @@ msgstr "Fazer Função" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "Converter vetor HSV para um RGB equivalente." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "Converter vetor RGB para um HSV equivalente." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8131,11 +8131,14 @@ msgid "" "Returns an associated vector if the provided scalars are equal, greater or " "less." msgstr "" +"Retorna um vetor associado se o escalar fornecido for igual, maior ou menor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided boolean value is true or false." msgstr "" +"Retorna um vetor associado se o valor lógico fornecido for verdadeiro ou " +"falso." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8147,51 +8150,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8200,203 +8159,27 @@ msgid "Input parameter." msgstr "Encaixar no pai" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8411,72 +8194,73 @@ msgstr "Alterar Operador Escalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "Constante E (2,718282). Representa a base de um logaritmo natural." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "Constante Epsilon (0,00001). O menor número escalar possÃvel." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "Constante Phi (1,618034). Proporção áurea." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "Constante Pi/4 (0,785398) or 45 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "Constante Pi/2 (1,570796) ou 90 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "Constante Pi (3,141593) ou 180 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "Constante Tau (6,283185) ou 360 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "Constante Sqrt2 (1,414214). Raiz quadrada de 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "Retorna o valor absoluto do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "Retorna o arco-cosseno do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Somente em GLES3) Retorna o coseno hiperbólico inverso do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "Retorna o arco-seno do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "(Somente em GLES3) Retorna o seno hiperbólico inverso do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "Retorna o arco-tangente do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "Retorna o arco-tangente dos parâmetros." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." msgstr "" +"(Somente em GLES3) Retorna a tangente hiperbólica inversa do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "Encontra o inteiro mais próximo que é maior ou igual ao parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." @@ -8484,27 +8268,29 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "Retorna o cosseno do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Somente em GLES3) Retorna o coseno hiperbólico do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "Converte uma quantidade em radianos para graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "Exponencial de Base e." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Base-2 Exponential." -msgstr "" +msgstr "Exponencial de Base-2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "Encontra o inteiro mais próximo que é menor ou igual ao parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." @@ -8512,15 +8298,16 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "Retorna o inverso da raiz quadrada do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "Logaritmo natural." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Base-2 logarithm." -msgstr "" +msgstr "Logaritmo de Base-2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." @@ -8532,36 +8319,38 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "Interpolação linear entre dois escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "Retorna o valor oposto do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1,0 - escalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." -msgstr "" +msgstr "Retorna o valor do primeiro parâmetro elevado a potência do segundo." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "Converte uma quantidade em graus para radianos." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1,0 / escalar" #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(Somente em GLES3) Encontra o inteiro mais próximo ao parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(Somente em GLES3) Encontra o inteiro par mais próximo ao parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." @@ -8569,19 +8358,19 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "Extrai o sinal do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "Retorna o seno do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(Somente em GLES3) Retorna o seno hiperbólico do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "Retorna a raiz quadrada do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8601,35 +8390,40 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "Retorna a tangente do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Somente em GLES3) Retorna a tangente hiperbólica do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." -msgstr "" +msgstr "(Somente em GLES3) Encontra o valor truncado do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Adds scalar to scalar." -msgstr "" +msgstr "Adiciona escalar a escalar." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Divides scalar by scalar." -msgstr "" +msgstr "Divide escalar por escalar." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "Multiplica escalar por escalar." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "Retorna o resto das duas escalares." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "Subtrai escalar de escalar." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8684,24 +8478,29 @@ msgid "Decomposes transform to four vectors." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "(GLES3 only) Calculates the determinant of a transform." -msgstr "" +msgstr "(Somente em GLES3) Calcula o determinante da transform." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "(GLES3 only) Calculates the inverse of a transform." -msgstr "" +msgstr "(Somente em GLES3) Calcula a inversa da transform." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "(GLES3 only) Calculates the transpose of a transform." -msgstr "" +msgstr "(Somente em GLES3) Calcula a transposta da transform." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Multiplies transform by transform." -msgstr "" +msgstr "Multiplica transform por transform." #: editor/plugins/visual_shader_editor_plugin.cpp +#, fuzzy msgid "Multiplies vector by transform." -msgstr "" +msgstr "Multiplica vetor por transform." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8725,23 +8524,23 @@ msgstr "Alterar Operador Vet" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "Compõe um vetor de três escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "Decompõe um vetor em três escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "Calcula o produto vetorial de dois vetores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "Retorna a distância entre dois pontos." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "Calcula o produto escalar de dois vetores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8750,36 +8549,43 @@ msgid "" "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 "" +"Retorna um vetor que aponta na mesma direção que um vetor de referência. A " +"função tem três vetores como parâmetros: N, o vetor para orientar, I, o " +"vetor incidente, e Nref, o vetor de referência. Se o produto escalar de I e " +"Nref for menor do que zero o valor de retorno é N. Caso contrário -N é " +"retornado." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "Calcula o comprimento de um vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "Interpolação linear entre dois vetores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." -msgstr "" +msgstr "Calcula o produto normalizado do vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - vector" -msgstr "" +msgstr "1,0 - vetor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / vector" -msgstr "" +msgstr "1,0 / vetor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns a vector that points in the direction of reflection ( a : incident " "vector, b : normal vector )." msgstr "" +"Retorna um vetor que aponta na direção da reflexão ( a: vetor incidente, b: " +"vetor normal )." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns a vector that points in the direction of refraction." -msgstr "" +msgstr "Retorna um vetor que aponta na direção da refração." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8815,23 +8621,23 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." -msgstr "" +msgstr "Adiciona vetor ao vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "" +msgstr "Divide vetor por vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." -msgstr "" +msgstr "Multiplica vetor por vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two vectors." -msgstr "" +msgstr "Retorna o resto dos dois vetores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts vector from vector." -msgstr "" +msgstr "Subtrai vetor de vetor." #: editor/plugins/visual_shader_editor_plugin.cpp #, fuzzy @@ -8929,7 +8735,7 @@ msgid "" "Failed to export the project for platform '%s'.\n" "Export templates seem to be missing or invalid." msgstr "" -"Falha ao exportar o projeto para a plataforma '% s'.\n" +"Falha ao exportar o projeto para a plataforma '%s'.\n" "Os modelos de exportação parecem estar ausentes ou inválidos." #: editor/project_export.cpp @@ -10123,6 +9929,11 @@ msgid "Add Child Node" msgstr "Adicionar Nó Filho" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Recolher Tudo" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Mudar Tipo" @@ -10151,7 +9962,8 @@ msgid "Delete (No Confirm)" msgstr "Excluir (Sem Confirmação)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Adicionar/Criar um Novo Nó" #: editor/scene_tree_dock.cpp @@ -10421,7 +10233,7 @@ msgstr "Rastreamento de pilha" msgid "Pick one or more items from the list to display the graph." msgstr "Escolhe um ou mais itens da lista para mostrar o gráfico." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Erros" @@ -10511,7 +10323,7 @@ msgstr "Definir a partir da árvore" #: editor/script_editor_debugger.cpp msgid "Export measures as CSV" -msgstr "" +msgstr "Exporta medidas como CSV" #: editor/settings_config_dialog.cpp msgid "Erase Shortcut" @@ -10642,8 +10454,9 @@ msgid "GDNativeLibrary" msgstr "GDNativeLibrary" #: modules/gdnative/gdnative_library_singleton_editor.cpp +#, fuzzy msgid "Enabled GDNative Singleton" -msgstr "" +msgstr "Singleton GDBNative ativado" #: modules/gdnative/gdnative_library_singleton_editor.cpp #, fuzzy @@ -10825,54 +10638,6 @@ msgstr "Escolha uma Distância:" msgid "Class name can't be a reserved keyword" msgstr "Nome da classe não pode ser uma palavra reservada" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Gerando solução..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "Gerando projeto C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Falha ao criar solução." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Falha ao salvar solução." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Pronto" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "Falha ao criar projeto C#." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "Sobre o suporte ao C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Criar solução C#" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Compilações" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Compilar Projeto" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Ver registro" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Fim da pilha de rastreamento de exceção interna" @@ -11472,8 +11237,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "Dimensões inválidas da tela de abertura (deve ser 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Um recurso do tipo SpriteFrames deve ser criado ou definido na propriedade " @@ -11540,8 +11306,9 @@ msgstr "" "\"Animação de partÃculas\" ativada." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Uma textura com a forma da luz deve ser fornecida na propriedade \"textura\"." @@ -11554,7 +11321,8 @@ msgstr "" "oclusor tenha efeito." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "O polÃgono para este oclusor está vazio. Por favor desenhe um polÃgono!" @@ -11643,16 +11411,29 @@ msgstr "" "Este osso não possui uma pose REST adequada. Vá para o nó Skeleton2D e " "defina um." +#: 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 apenas serve para fornecer a forma de colisão para um nó " +"derivado de CollisionObject2D. Por favor use-o apenas como filho de Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. para dá-los forma." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D funciona melhor quando usado como filho direto da raiz da " "cena atualmente editada." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera deve ter um nó ARVROrigin como seu pai" #: scene/3d/arvr_nodes.cpp @@ -11748,9 +11529,10 @@ msgstr "" "RigidBody, KinematicBody, etc. para dá-los forma." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Uma forma deve ser fornecida para que o nó CollisionShape funcione. Por " "favor, crie um recurso de forma a ele!" @@ -11788,6 +11570,10 @@ msgstr "" "GIProbes não são suportados pelo driver de vÃdeo GLES2.\n" "Use um BakedLightmap em vez disso." +#: 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 "" @@ -11832,9 +11618,10 @@ msgid "PathFollow only works when set as a child of a Path node." msgstr "PathFollow só funciona quando definido como filho de um nó Path." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED requer \"Up Vector\" habilitado no recurso " "Curva do Caminho pai." @@ -11850,7 +11637,10 @@ msgstr "" "Ao invés disso, altere o tamanho nas formas de colisão filhas." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "A propriedade Caminho deve apontar para um nó Spatial para funcionar." #: scene/3d/soft_body.cpp @@ -11869,8 +11659,9 @@ msgstr "" "Altere o tamanho em formas de colisão de crianças." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Um recurso do tipo SpriteFrames deve ser criado ou definido na propriedade " @@ -11885,8 +11676,10 @@ msgstr "" "favor, use ele como um filho de um VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment precisa de um recurso Environment." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11924,7 +11717,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Nada está ligado à entrada '%s' do nó '%s'." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "Um AnimationNode raiz para o gráfico não está definido." #: scene/animation/animation_tree.cpp @@ -11939,7 +11733,8 @@ msgstr "" "AnimationPlayer." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "AnimationPlayer root não é um nó válido." #: scene/animation/animation_tree_player.cpp @@ -11951,8 +11746,13 @@ msgid "Pick a color from the screen." msgstr "Escolha uma cor da tela." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Modo Bruto" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +#, fuzzy +msgid "Raw" +msgstr "Guinada" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11965,16 +11765,21 @@ msgstr "Adicionar cor atual como uma predefinição." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" "O contêiner por si só não serve para nada, a menos que um script configure " "seu comportamento de posicionamento de filhos.\n" "Se você não pretende adicionar um script, por favor use um nó simples " "'Control'." +#: scene/gui/control.cpp +msgid "" +"The Hint Tooltip won't be displayed as the control's Mouse Filter is set to " +"\"Ignore\". To solve this, set the Mouse Filter to \"Stop\" or \"Pass\"." +msgstr "" + #: scene/gui/dialogs.cpp msgid "Alert!" msgstr "Alerta!" @@ -11984,23 +11789,26 @@ msgid "Please Confirm..." msgstr "Confirme Por Favor..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Popups são ocultos por padrão a menos que você chame alguma das funções " "popup*(). Torná-los visÃveis para editar não causa problema, mas eles serão " "ocultados ao rodar a cena." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Se exp_edit for true, min_value deverá ser> 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "Um ScrollContainer foi feito para trabalhar com um componente filho único.\n" @@ -12052,6 +11860,11 @@ msgid "Input" msgstr "Entrada" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Fonte inválida para o shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Fonte inválida para o shader." @@ -12069,7 +11882,55 @@ msgstr "Variáveis só podem ser atribuÃdas na função de vértice." #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "Constantes não podem serem modificadas." + +#~ msgid "Generating solution..." +#~ msgstr "Gerando solução..." + +#~ msgid "Generating C# project..." +#~ msgstr "Gerando projeto C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "Falha ao criar solução." + +#~ 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#." + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "Sobre o suporte ao C#" + +#~ msgid "Create C# solution" +#~ msgstr "Criar solução C#" + +#~ msgid "Builds" +#~ msgstr "Compilações" + +#~ msgid "Build Project" +#~ msgstr "Compilar Projeto" + +#~ msgid "View log" +#~ msgstr "Ver registro" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment precisa de um recurso Environment." + +#~ msgid "Enabled Classes" +#~ msgstr "Classes Ativadas" + +#~ msgid "Update Always" +#~ msgstr "Atualizar Sempre" + +#~ msgid "Raw Mode" +#~ msgstr "Modo Bruto" #~ msgid "Path to Node:" #~ msgstr "Caminho para o Nó:" @@ -12635,9 +12496,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Alternar Spatial VisÃvel" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Alternar CanvasItem VisÃvel" - #~ msgid "Condition" #~ msgstr "Condição" @@ -13560,9 +13418,6 @@ msgstr "" #~ msgid "Images:" #~ msgstr "Imagens:" -#~ msgid "Select None" -#~ msgstr "Remover Seleção" - #~ msgid "Group" #~ msgstr "Grupo" diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po index d9af00c3c3..4bc53e53db 100644 --- a/editor/translations/pt_PT.po +++ b/editor/translations/pt_PT.po @@ -18,7 +18,7 @@ msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" +"PO-Revision-Date: 2019-07-09 10:47+0000\n" "Last-Translator: João Lopes <linux-man@hotmail.com>\n" "Language-Team: Portuguese (Portugal) <https://hosted.weblate.org/projects/" "godot-engine/godot/pt_PT/>\n" @@ -27,7 +27,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -87,9 +87,8 @@ msgid "Time:" msgstr "Tempo:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Valor" +msgstr "Valor:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -444,10 +443,28 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Esta animação pertence a uma cena importada; alterações não serão " +"guardadas.\n" +"\n" +"Para ativar a capacidade de adicionar faixas personalizadas, vá à " +"configuração de importação da cena e defina\n" +"\"Animação > Armazenamento\" para \"Ficheiros\", ative \"Animação > Manter " +"Faixas Personalizadas\"; depois reimporte.\n" +"Em alternativa, use uma predefinição de importação que importe animações " +"para ficheiros separados." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Aviso: A editar animação importada" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Selecionar tudo" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "Selecionar Nenhum" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -623,6 +640,10 @@ msgstr "Vai para linha" msgid "Line Number:" msgstr "Numero da linha:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Sem combinações" @@ -672,7 +693,7 @@ msgstr "Zoom Out" msgid "Reset Zoom" msgstr "Repor Zoom" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Avisos" @@ -681,38 +702,32 @@ msgid "Line and column numbers." msgstr "Números de Linha e Coluna." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Método no Nó alvo deve ser especificado!" +msgstr "Método no Nó alvo deve ser especificado." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Método alvo não encontrado! Especifique um Método válido ou anexe um Script " +"Método alvo não encontrado. Especifique um método válido ou anexe um script " "ao Nó de destino." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" msgstr "Conectar ao Nó:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "ImpossÃvel ligar ao host:" +msgstr "Conectar ao Script:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Sinais:" +msgstr "Do Sinal:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "O Nó não contêm geometria." +msgstr "A Cena não contém qualquer script." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -740,9 +755,8 @@ msgid "Extra Call Arguments:" msgstr "Argumentos de chamada extra:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Opções Avançadas" +msgstr "Avançado" #: editor/connections_dialog.cpp msgid "Deferred" @@ -752,6 +766,8 @@ msgstr "Deferido" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Retarda o sinal, armazena-o numa fila e só ativando-o em tempo de " +"inatividade." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -759,12 +775,11 @@ msgstr "Oneshot" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Desconecta o sinal após a primeira emissão." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Conectar sinal: " +msgstr "ImpossÃvel conectar sinal" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -785,6 +800,11 @@ msgid "Connect" msgstr "Ligar" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Sinais:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Ligar '%s' a '%s'" @@ -806,14 +826,12 @@ msgid "Disconnect" msgstr "Desligar" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Conectar sinal: " +msgstr "Conectar Sinal a Método" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Editar Conexão: " +msgstr "Editar Conexão:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -889,22 +907,20 @@ msgid "Dependencies For:" msgstr "Dependências para:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" "A Cena '%s' está a ser editada.\n" -"As alterações não terão efeito até recarregar." +"As alterações só terão efeito quando recarregar." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" "Recurso '%s' em uso.\n" -"Alterações terão efeito após reinÃcio." +"As alterações só terão efeito quando recarregar." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -951,7 +967,8 @@ msgid "Owners Of:" msgstr "Proprietários de:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Remover arquivos selecionados do Projeto? (sem desfazer)" #: editor/dependency_editor.cpp @@ -997,9 +1014,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "Apagar permanentemente %d itens? (Sem desfazer!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "Dependências" +msgstr "Mostra Dependências" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1262,7 +1278,7 @@ msgstr "Abrir Modelo de barramento de áudio" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Não existe ficheiro '%s'." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1319,29 +1335,21 @@ msgid "Valid characters:" msgstr "Carateres válidos:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"Nome inválido. Não pode coincidir com um nome de classe do motor já " -"existente." +msgstr "Não pode coincidir com um nome de classe do motor já existente." #: editor/editor_autoload_settings.cpp -#, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "" -"Nome inválido. Não pode coincidir com um nome de um tipo incorporado, já " -"existente." +msgid "Must not collide with an existing built-in type name." +msgstr "Não pode coincidir com um nome de um tipo incorporado já existente." #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing global constant name." -msgstr "" -"Nome inválido. Não pode coincidir com um nome de uma constante global, já " -"existente." +msgstr "Não pode coincidir com um nome de uma constante global já existente." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." msgstr "" +"Palavras-chave não podem ser usadas como nome de carregamento automático." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1372,7 +1380,6 @@ msgid "Rearrange Autoloads" msgstr "Reorganizar Carregamentos Automáticos" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "Caminho inválido." @@ -1427,9 +1434,8 @@ msgid "[unsaved]" msgstr "[não guardado]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Por favor, selecione a diretoria base primeiro" +msgstr "Por favor selecione primeiro a diretoria base." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1513,122 +1519,108 @@ msgstr "Modelo de lançamento personalizado não encontrado." msgid "Template file not found:" msgstr "Ficheiro Modelo não encontrado:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp -#, fuzzy msgid "3D Editor" -msgstr "Editor" +msgstr "Editor 3D" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Abrir Editor de Scripts" +msgstr "Editor de Script" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Abrir Biblioteca de Ativos" +msgstr "Biblioteca de Ativos" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Ãrvore de Cena (Nós):" +msgstr "Edição da Ãrvore de Cena" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Importar" +msgstr "Importar Doca" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "Nó Movido" +msgstr "Nó Doca" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Filesystem Dock" -msgstr "Sistema de Ficheiros" +msgid "FileSystem and Import Docks" +msgstr "Sistema de Ficheiros e Docas de Importação" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Substituir tudo (não há desfazer)" +msgstr "Substituir perfil '%s'? (não há desfazer)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "Perfil tem de ser um ficheiro válido e não pode conter '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Um Ficheiro ou diretoria já existe com este nome." +msgstr "Já existe um Perfil com este nome." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Editor Desativado, Propriedades Desativadas)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Apenas Propriedades" +msgstr "(Propriedades Desativadas)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Recorte desativado" +msgstr "(Editor Desativado)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Descrição da Classe:" +msgstr "Opções da Classe:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Abrir o Editor seguinte" +msgstr "Ativar Editor de Contexto" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Propriedades:" +msgstr "Ativar Propriedades:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "CaracterÃsticas" +msgstr "Ativar CaracterÃsticas:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Procurar Classes" +msgstr "Ativar Classes:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Formato do ficheiro '%s' é inválido, importação interrompida." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"Perfil '%s' já existe. Remova-o antes de importar, importação interrompida." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Erro ao carregar Modelo '%s'" +msgstr "Erro ao guardar perfil no caminho: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Desativar" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Current Profile" -msgstr "Versão Atual:" +msgid "Current Profile:" +msgstr "Perfil atual:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Atual:" +msgstr "Tornar Atual" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1646,44 +1638,32 @@ msgid "Export" msgstr "Exportar" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Available Profiles" -msgstr "Nós DisponÃveis:" +msgid "Available Profiles:" +msgstr "Perfis disponÃveis:" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Procurar Classes" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Descrição da Classe" +msgstr "Opções da Classe" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Novo nome:" +msgstr "Novo nome do perfil:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Apagar Ãrea" +msgstr "Apagar Perfil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Projeto importado" +msgstr "Importar Perfil/Perfis" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Exportar Projeto" +msgstr "Exportar Perfil" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "Gerir Modelos de Exportação" +msgstr "Gerir Editor de Perfis" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1806,9 +1786,8 @@ msgid "(Un)favorite current folder." msgstr "(Não) tornar favorita atual pasta." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Alternar Ficheiros escondidos" +msgstr "Alternar visibilidade de ficheiros escondidos." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1845,6 +1824,8 @@ msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"Existem vários importadores para diferentes tipos que apontam para o " +"ficheiro %s. Importação abortada" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2189,13 +2170,12 @@ msgstr "" "melhor entendimento deste fluxo de trabalho." #: editor/editor_node.cpp -#, fuzzy msgid "" "This resource belongs to a scene that was instanced or inherited.\n" "Changes to it won't be kept when saving the current scene." msgstr "" -"Este recurso pertence a uma Cena que foi instanciada ou herdada.\n" -"As alterações ao mesmo não serão mantidas, ao guardar a Cena atual." +"Este recurso pertence a uma cena que foi instanciada ou herdada.\n" +"As alterações ao mesmo não serão mantidas ao guardar a cena atual." #: editor/editor_node.cpp msgid "" @@ -2206,27 +2186,25 @@ msgstr "" "configurações no painel de importação e então importe de novo." #: editor/editor_node.cpp -#, fuzzy msgid "" "This scene was imported, so changes to it won't be kept.\n" "Instancing it or inheriting will allow making changes to it.\n" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" -"Esta Cena foi importada, portanto, as alterações à mesma não serão " +"Esta cena foi importada, portanto, as alterações à mesma não serão " "mantidas.\n" -"Instanciando-a ou herdando-a vai permitir efetuar alterções à mesma.\n" -"Por favor, leia a documentação relevante sobre importação de Cenas, para um " +"Instanciando-a ou herdando-a vai permitir efetuar alterações à mesma.\n" +"Por favor, leia a documentação relevante sobre importação de cenas, para um " "melhor entendimento do fluxo de trabalho." #: editor/editor_node.cpp -#, fuzzy msgid "" "This is a remote object, so changes to it won't be kept.\n" "Please read the documentation relevant to debugging to better understand " "this workflow." msgstr "" -"Este é um Objeto remoto, portanto, as alterações ao mesmo não serão " +"Este é um objeto remoto, portanto, as alterações ao mesmo não serão " "mantidas.\n" "Por favor, leia a documentação relevante sobre depuração para um melhor " "entendimento deste fluxo de trabalho." @@ -2252,9 +2230,8 @@ msgid "Open Base Scene" msgstr "Abrir Cena Base" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Abrir Cena de forma rápida..." +msgstr "Abertura rápida..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2494,12 +2471,11 @@ msgstr "Fechar outros separadores" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Fechar Separadores à Direita" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Fechar tudo" +msgstr "Fechar Todos os Separadores" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2633,7 +2609,7 @@ msgstr "Abrir Pasta de Dados do Projeto" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Instalar Modelo Android de Compilação" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2743,10 +2719,31 @@ msgid "Editor Layout" msgstr "Apresentação do Editor" #: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "Captura do ecrã" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "" +"Capturas do ecrã são armazenadas na pasta Dados/Configurações do Editor." + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "Abrir Capturas do ecrã automaticamente" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "Abrir num editor de imagem externo." + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Alternar Ecrã completo" #: editor/editor_node.cpp +msgid "Toggle System Console" +msgstr "Alternar Consola do Sistema" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Abrir Pasta do Editor de Dados/Configurações" @@ -2759,9 +2756,8 @@ msgid "Open Editor Settings Folder" msgstr "Abrir Pasta de Configurações do Editor" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "Gerir Modelos de Exportação" +msgstr "Gerir CaracterÃsticas do Editor" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2854,16 +2850,16 @@ msgid "Spins when the editor window redraws." msgstr "Roda quando a janela do editor atualiza." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Atualizar Sempre" +msgid "Update Continuously" +msgstr "Atualização ContÃnua" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "Atualizar Alterações" +msgid "Update When Changed" +msgstr "Atualizar quando há Alterações" #: editor/editor_node.cpp -msgid "Disable Update Spinner" -msgstr "Desativar a roleta de atualização" +msgid "Hide Update Spinner" +msgstr "Esconder Roleta de Atualização" #: editor/editor_node.cpp msgid "FileSystem" @@ -2891,18 +2887,19 @@ msgstr "Não Guardar" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." -msgstr "" +msgstr "Modelo de compilação Android em falta. Instale os modelos necessários." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Gerir Modelos de Exportação" +msgstr "Gerir Modelos" #: editor/editor_node.cpp msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"O projeto Android para compilações personalizadas será instalado.\n" +"Para o utilizar, terá de ser ativado nas predefinições de exportação." #: editor/editor_node.cpp msgid "" @@ -2910,6 +2907,8 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"O modelo de compilação Android está instalado e não será substituÃdo.\n" +"Remova manualmente a diretoria \"build\" antes de repetir esta operação." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -3019,7 +3018,7 @@ msgstr "Medida:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" -msgstr "Tempo de Quadro (seg)" +msgstr "Tempo do Frame (seg)" #: editor/editor_profiler.cpp msgid "Average Time (sec)" @@ -3027,11 +3026,11 @@ msgstr "Tempo Médio (seg)" #: editor/editor_profiler.cpp msgid "Frame %" -msgstr "% Quadro" +msgstr "Frame %" #: editor/editor_profiler.cpp msgid "Physics Frame %" -msgstr "% Quadro de FÃsica" +msgstr "Frame de FÃsica %" #: editor/editor_profiler.cpp msgid "Inclusive" @@ -3043,7 +3042,7 @@ msgstr "Auto" #: editor/editor_profiler.cpp msgid "Frame #:" -msgstr "# quadro:" +msgstr "Frame #:" #: editor/editor_profiler.cpp msgid "Time" @@ -3053,7 +3052,7 @@ msgstr "Tempo" msgid "Calls" msgstr "Chamadas" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "On" @@ -3159,6 +3158,11 @@ msgid "Page: " msgstr "Página: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Remover item" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Nova Chave:" @@ -3170,11 +3174,6 @@ msgstr "Novo Valor:" msgid "Add Key/Value Pair" msgstr "Adicionar Par Chave/Valor" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Remover item" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3381,9 +3380,8 @@ msgid "SSL Handshake Error" msgstr "Erro SSL Handshake" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "A descompactar Ativos" +msgstr "A descompactar Fontes da Compilação Android" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3402,7 +3400,6 @@ msgid "Remove Template" msgstr "Remover Modelo" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" msgstr "Selecionar Ficheiro de Modelo" @@ -3463,9 +3460,8 @@ msgid "No name provided." msgstr "Nome não fornecido." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "O nome contém carateres inválidos" +msgstr "O nome fornecido contém carateres inválidos." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3492,26 +3488,22 @@ msgid "Duplicating folder:" msgstr "A duplicar Diretoria:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Nova Cena Herdada..." +msgstr "Nova Cena Herdada" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Abrir Cena" +msgstr "Abrir Cenas" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "Instância" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" msgstr "Adicionar aos Favoritos" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" msgstr "Remover dos Favoritos" @@ -3561,23 +3553,20 @@ msgid "Rename" msgstr "Renomear" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Pasta Anterior" +msgstr "Pasta/Ficheiro Anterior" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Próxima Pasta" +msgstr "Próxima Pasta/Ficheiro" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "Carregar novamente o Sistema de Ficheiros" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" -msgstr "Alternar modo de divisão" +msgstr "Alternar Modo de Divisão" #: editor/filesystem_dock.cpp msgid "Search files" @@ -3628,6 +3617,8 @@ msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Inclui os ficheiros com as seguintes extensões. Adicione ou remova-os em " +"ProjectSettings." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3679,6 +3670,7 @@ msgid "Nodes not in Group" msgstr "Nós fora do Grupo" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtrar Nós" @@ -4065,9 +4057,8 @@ msgid "Open Animation Node" msgstr "Abrir Nó Animação" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "Já existe triângulo" +msgstr "Já existe triângulo." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4213,9 +4204,8 @@ msgid "Edit Filtered Tracks:" msgstr "Editar Pistas Filtradas:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" -msgstr "Ativar filtragem" +msgstr "Ativar Filtragem" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" @@ -4350,9 +4340,8 @@ msgid "Enable Onion Skinning" msgstr "Ativar Onion Skinning" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "Onion Skinning" +msgstr "Opções de Onion Skinning" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4916,6 +4905,8 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Quando ativo, mover nós Control altera as suas ancoras em vez das sua " +"margens." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -4931,41 +4922,35 @@ msgstr "Mudar âncoras" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "Seleção de ferramenta" +msgstr "Bloquear Seleção" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "Apagar Selecionados" +msgstr "Desbloquear Seleção" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Copiar Seleção" +msgstr "Agrupar Seleção" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Copiar Seleção" +msgstr "Desagrupar Seleção" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" msgstr "Colar Pose" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" -msgstr "Fazer Osso(s) Personalizados a partis de Nó(s)" +msgstr "Criar Osso(s) Personalizado(s) a partis de Nó(s)" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "Limpar pose" +msgstr "Apagar Ossos" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -5052,9 +5037,8 @@ msgid "Snapping Options" msgstr "Opções de Ajuste" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" -msgstr "Ajustar à grelha" +msgstr "Ajustar à Grelha" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" @@ -5074,39 +5058,32 @@ msgid "Use Pixel Snap" msgstr "Usar Ajuste de Pixel" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" -msgstr "Ajuste inteligente" +msgstr "Ajuste Inteligente" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" -msgstr "Ajustar ao parente" +msgstr "Ajustar ao Parente" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" -msgstr "Ajustar ao Nó âncora" +msgstr "Ajustar ao Nó Âncora" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" -msgstr "Ajustar aos lados do Nó" +msgstr "Ajustar aos Lados do Nó" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" -msgstr "Ajustar ao centro do Nó" +msgstr "Ajustar ao Centro do Nó" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" -msgstr "Ajustar a outros Nós" +msgstr "Ajustar a Outros Nós" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" -msgstr "Ajustar à s guias" +msgstr "Ajustar à s Guias" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -5184,11 +5161,11 @@ msgstr "Centrar seleção" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Frame Selection" -msgstr "Emoldurar seleção" +msgstr "Seleção de Frame" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "" +msgstr "Pré-visualizar Escala do Canvas" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -5244,9 +5221,8 @@ msgid "Divide grid step by 2" msgstr "Dividir passo da grelha por 2" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Pan View" -msgstr "Vista de trás" +msgstr "Vista Pan" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" @@ -5271,9 +5247,8 @@ msgid "Error instancing scene from %s" msgstr "Erro a instanciar Cena de %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" -msgstr "Mudar tipo padrão" +msgstr "Mudar Tipo Padrão" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -5315,6 +5290,13 @@ msgid "Load Emission Mask" msgstr "Carregar máscara de emissão" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp +#: editor/plugins/cpu_particles_editor_plugin.cpp +#: editor/plugins/particles_2d_editor_plugin.cpp +#: editor/plugins/particles_editor_plugin.cpp +msgid "Restart" +msgstr "Reiniciar" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Limpar máscara de emissão" @@ -5333,7 +5315,7 @@ msgstr "Contagem de Pontos gerados:" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Mask" -msgstr "Máscara de emissão" +msgstr "Máscara de Emissão" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5343,7 +5325,7 @@ msgstr "Capturar a partir do pixel" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Emission Colors" -msgstr "Cores de emissão" +msgstr "Cores de Emissão" #: editor/plugins/cpu_particles_editor_plugin.cpp msgid "CPUParticles" @@ -5360,14 +5342,12 @@ msgid "Create Emission Points From Node" msgstr "Criar Pontos de emissão a partir do Nó" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "Flat0" +msgstr "Plano 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "Flat1" +msgstr "Plano 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -5394,29 +5374,24 @@ msgid "Load Curve Preset" msgstr "Carregar curva predefinida" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" msgstr "Adicionar Ponto" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" msgstr "Remover Ponto" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" -msgstr "Linear esquerda" +msgstr "Linear Esquerda" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" -msgstr "Linear direita" +msgstr "Linear Direita" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" -msgstr "Carregar predefinição" +msgstr "Carregar Predefinição" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove Curve Point" @@ -5471,18 +5446,16 @@ msgid "This doesn't work on scene root!" msgstr "Não funciona na raiz da Cena!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Criar forma Trimesh" +msgstr "Criar Forma Estática Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "Falha na criação de formas!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "Criar forma convexa" +msgstr "Criar Forma(s) Convexa(s)" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -5538,9 +5511,8 @@ msgid "Create Trimesh Collision Sibling" msgstr "Criar irmão de colisão Trimesh" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Collision Sibling(s)" -msgstr "Criar irmão de colisão convexa" +msgstr "Criar Irmão(s) de Colisão Convexa" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." @@ -5899,7 +5871,6 @@ msgid "Split Segment (in curve)" msgstr "Separar segmento (na curva)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" msgstr "Mover Junta" @@ -6232,10 +6203,18 @@ msgid "Find Next" msgstr "Localizar Seguinte" #: editor/plugins/script_editor_plugin.cpp +msgid "Filter scripts" +msgstr "Scripts de filtro" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "Alternar ordenação alfabética da lista de métodos." #: editor/plugins/script_editor_plugin.cpp +msgid "Filter methods" +msgstr "Métodos de filtro" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Ordenar" @@ -6346,18 +6325,16 @@ msgid "Debug with External Editor" msgstr "Depurar com Editor Externo" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Abrir documentação online do Godot" +msgstr "Abrir documentação online do Godot." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" msgstr "Requisitar Docs" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "Dê a sua opinião para ajudar a melhorar a documentação Godot" +msgstr "Dê a sua opinião para ajudar a melhorar a documentação Godot." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6402,29 +6379,25 @@ msgid "Search Results" msgstr "Resultados da Pesquisa" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "Conectar ao Nó:" +msgstr "Conecções ao método:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Fonte:" +msgstr "Fonte" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Sinais" +msgstr "Sinal" #: editor/plugins/script_text_editor.cpp msgid "Target" -msgstr "" +msgstr "Alvo" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "Nada conectado à entrada '%s' do nó '%s'." +msgstr "Falta método conectado '%s' para sinal '%s' do nó '%s' para nó '%s'." #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6471,20 +6444,24 @@ msgid "Syntax Highlighter" msgstr "Destaque de Sintaxe" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "Marcadores" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Criar pontos." #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Cortar" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Selecionar tudo" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Apagar linha" @@ -6502,24 +6479,20 @@ msgid "Toggle Comment" msgstr "Alternar comentário" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "Alternar Freelook" +msgstr "Alternar Marcador" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "Ir para Próximo Breakpoint" +msgstr "Ir para Próximo Marcador" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Previous Bookmark" -msgstr "Ir para Breakpoint Anterior" +msgstr "Ir para Marcador Anterior" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "Remover todos os itens" +msgstr "Remover todos os Marcadores" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -6595,13 +6568,12 @@ msgid "Contextual Help" msgstr "Ajuda contextual" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"Os seguintes Ficheiros são mais recentes no disco.\n" -"Que ação deve ser tomada?:" +"Este Shader foi modificado no disco.\n" +"Que ação deve ser tomada?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -6946,9 +6918,8 @@ msgid "Right View" msgstr "Vista direita" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" -msgstr "Alternar vista perspetiva/ortogonal" +msgstr "Alternar Vista Perspetiva/Ortogonal" #: editor/plugins/spatial_editor_plugin.cpp msgid "Insert Animation Key" @@ -6992,9 +6963,8 @@ msgid "Transform" msgstr "Transformar" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" -msgstr "Alinhar objetos ao chão" +msgstr "Alinhar Objetos ao Chão" #: editor/plugins/spatial_editor_plugin.cpp msgid "Transform Dialog..." @@ -7182,14 +7152,12 @@ msgid "Settings:" msgstr "Configuração:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "Emoldurar seleção" +msgstr "Não há Frames Selecionados" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "Adicionar Frame" +msgstr "Adicionar %d Frame(s)" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" @@ -7197,7 +7165,7 @@ msgstr "Adicionar Frame" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "ERROR: Couldn't load frame resource!" -msgstr "ERRO: Recurso de Frame não carregado!" +msgstr "ERRO: Recurso de frame não carregado!" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Resource clipboard is empty or not a texture!" @@ -7240,13 +7208,12 @@ msgid "Animation Frames:" msgstr "Frames da Animação:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Adicionar Textura(s) ao TileSet." +msgstr "Adicionar Textura do Ficheiro" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "Adicionar Frames de uma Folha de Sprites" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7265,29 +7232,24 @@ msgid "Move (After)" msgstr "Mover (depois)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "Empilhar Frames" +msgstr "Selecionar Frames" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Inverter horizontalmente" +msgstr "Horizontal:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "Vértices" +msgstr "Vertical:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "Selecionar tudo" +msgstr "Selecionar/Apagar Todos os Frames" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "Criar a partir da Cena" +msgstr "Criar Frames a partir de Folha de Sprites" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" @@ -7359,9 +7321,8 @@ msgid "Remove All" msgstr "Remover tudo" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "Editar tema..." +msgstr "Editar Tema" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7388,23 +7349,20 @@ msgid "Create From Current Editor Theme" msgstr "Criar a partir de tema Editor atual" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Toggle Button" -msgstr "Botão do rato" +msgstr "Alternar Botão" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Botão do meio" +msgstr "Desativar Botão" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" msgstr "Item" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "Desativado" +msgstr "Item Desativado" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -7424,21 +7382,19 @@ msgstr "Item Rádio marcado" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "Sep. Nomeado" #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Sub-menu" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "Item" +msgstr "Item 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "Item" +msgstr "Item 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -7449,9 +7405,8 @@ msgid "Many" msgstr "Muitos" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled LineEdit" -msgstr "Desativado" +msgstr "LineEdit Desativado" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -7466,13 +7421,12 @@ msgid "Tab 3" msgstr "Aba 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "Filhos editáveis" +msgstr "Item Editável" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "Sub-árvore" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7552,14 +7506,12 @@ msgid "Mirror Y" msgstr "Espelho Y" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "Tiles automáticos" +msgstr "Desativar Autotile" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "Editar Prioridade de Tile" +msgstr "Ativar Prioridade" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7570,33 +7522,30 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift+RMB: Desenho de Linha\n" +"Shift+Ctrl+RMB: Pintura de Retângulo" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" msgstr "Escolher Tile" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" -msgstr "Rodar p/ esquerda" +msgstr "Rodar Esquerda" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" -msgstr "Rodar p/ direita" +msgstr "Rodar Direita" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Horizontally" -msgstr "Inverter horizontalmente" +msgstr "Inverter na Horizontal" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Vertically" -msgstr "Inverter verticalmente" +msgstr "Inverter na Vertical" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" msgstr "Limpar Transformação" @@ -7633,44 +7582,36 @@ msgid "Select the previous shape, subtile, or Tile." msgstr "Selecione a forma, subtile ou Tile anterior." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "Modo Execução:" +msgstr "Modo Região" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "Modo de Interpolação" +msgstr "Modo Colisão" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "Editar PolÃgono de Oclusão" +msgstr "Modo Oclusão" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "Criar Malha de Navegação" +msgstr "Modo Navegação" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "Modo rodar" +msgstr "Modo Bitmask" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "Modo exportação:" +msgstr "Modo Prioridade" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "Modo deslocamento" +msgstr "Modo Ãcone" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "Modo deslocamento" +msgstr "Modo Ãndice Z" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7754,7 +7695,6 @@ msgid "Delete polygon." msgstr "Apagar polÃgono." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "LMB: Set bit on.\n" "RMB: Set bit off.\n" @@ -7763,6 +7703,7 @@ msgid "" msgstr "" "LMB: Ligar bit.\n" "RMB: Desligar bit.\n" +"Shift+LMB: Definir bit genérico.\n" "Clique em outro Tile para o editar." #: editor/plugins/tile_set_editor_plugin.cpp @@ -7876,77 +7817,64 @@ msgid "TileSet" msgstr "TileSet" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input +" -msgstr "Adicionar entrada" +msgstr "Adicionar entrada +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add output +" -msgstr "Adicionar entrada" +msgstr "Adicionar saÃda +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "Escala:" +msgstr "Escalar" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "Inspetor" +msgstr "Vetor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Lógico" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "Adicionar entrada" +msgstr "Adicionar porta de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Adicionar porta de saÃda" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "Mudar tipo padrão" +msgstr "Mudar tipo de porta de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "Mudar tipo padrão" +msgstr "Mudar tipo de porta de saÃda" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "Mudar nome de entrada" +msgstr "Mudar nome de porta de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "Mudar nome de entrada" +msgstr "Mudar nome de porta de saÃda" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "Remover Ponto" +msgstr "Remover porta de entrada" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "Remover Ponto" +msgstr "Remover porta de saÃda" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "Mudar Expressão" +msgstr "Definir expressão" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "VIsualShader" +msgstr "Redimensionar nó VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" @@ -7985,540 +7913,312 @@ msgid "Light" msgstr "Luz" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "Criar Nó" +msgstr "Criar Nó Shader" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "Ir para Função" +msgstr "Função Cor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "Operador de Cor." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "Criar Função" +msgstr "Função Cinza." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "Converte vetor HSV para equivalente RGB." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "Converte vetor RGB para equivalente HSV." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "Mudar nome da Função" +msgstr "Função Sépia." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "Operador de Queima." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "Operador Escurecer." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Difference operator." -msgstr "Apenas diferenças" +msgstr "Operador Diferença." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." -msgstr "" +msgstr "Operador Desvio." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "HardLight operator" -msgstr "" +msgstr "Operador HardLight" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." -msgstr "" +msgstr "Operador Clarear." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." -msgstr "" +msgstr "Operador Sobrepor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Screen operator." -msgstr "" +msgstr "Operador Ecrã." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "SoftLight operator." -msgstr "" +msgstr "Operador SoftLight." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color constant." -msgstr "Constante" +msgstr "Constante Cor." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color uniform." -msgstr "Limpar Transformação" +msgstr "Uniforme Cor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided scalars are equal, greater or " "less." msgstr "" +"Devolve um vetor associado se o escalar fornecido for igual, maior ou menor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns an associated vector if the provided boolean value is true or false." msgstr "" +"Devolve um vetor associado se o valor lógico fornecido for verdadeiro ou " +"falso." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Boolean constant." -msgstr "Mudar constante vetorial" +msgstr "Constante Lógica." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean uniform." -msgstr "" +msgstr "Uniforme Lógico." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" +msgid "'%s' input parameter for all shader modes." +msgstr "parâmetro de entrada '%s' para todos os modos shader." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Input parameter." -msgstr "Ajustar ao parente" +msgstr "Parâmetro de Entrada." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "parâmetro de entrada '%s' para os modos shader vertex e fragment." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "parâmetro de entrada '%s' para os modos shader fragment e light." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for fragment shader mode." +msgstr "parâmetro de entrada '%s' para o modo shader fragment." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" +msgid "'%s' input parameter for light shader mode." +msgstr "parâmetro de entrada '%s' para o modo shader light." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" +msgid "'%s' input parameter for vertex shader mode." +msgstr "parâmetro de entrada '%s' para modo shader vertex." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "parâmetro de entrada '%s' para os modos shader vertex e fragment." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar function." -msgstr "Mudar Função escalar" +msgstr "Função Escalar." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar operator." -msgstr "Mudar operador escalar" +msgstr "Operador Escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "Constante E (2.718282). Base dos logaritmos naturais." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "Constante Epsilon (0.00001). O menor número escalar possÃvel." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "Constante Phi (1.618034). Proporção áurea." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "Constante Pi/4 (0.785398) ou 45 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "Constante Pi/2 (1.570796) ou 90 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "Constante Pi (3.141593) ou 180 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "Constante Tau (6.283185) ou 360 graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "Constante Sqrt2 (1.414214). Raiz quadrada de 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "Devolve o valor absoluto do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "Devolve o arco seno do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Apenas GLES3) Devolve o arco cosseno hiperbólico do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "Devolve o arco seno do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "(Apenas GLES3) Devolve o arco seno hiperbólico do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "Devolve o arco tangente do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "Devolve o arco tangente do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Apenas GLES3) Devolve o arco tangente hiperbólico do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Finds the nearest integer that is greater than or equal to the parameter." -msgstr "" +msgstr "Encontra o inteiro mais próximo que seja maior ou igual ao parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Constrains a value to lie between two further values." -msgstr "" +msgstr "Restringe um valor entre dois valores suplementares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "Devolve o cosseno do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Apenas GLES3) Devolve o cosseno hiperbólico do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "Converte um valor em radianos para graus." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "Exponencial base e." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "Exponencial base 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Finds the nearest integer less than or equal to the parameter." -msgstr "" +msgstr "Encontra o inteiro mais próximo que seja menor ou igual ao parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Computes the fractional part of the argument." -msgstr "" +msgstr "Calcula a parte fracionária do argumento." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "Devolve o inverso da raiz quadrada do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "Logaritmo natural." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "Logaritmo base 2." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "Devolve o maior de dois valores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "Devolve o menor de dois valores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "Interpolação linear entre dois escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "Devolve o valor oposto do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 - escalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns the value of the first parameter raised to the power of the second." -msgstr "" +msgstr "Devolve o valor do primeiro parâmetro elevado à potência do segundo." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in degrees to radians." -msgstr "" +msgstr "Converte um valor em graus para radianos." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / escalar" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(Apenas GLES3) Encontra o inteiro mais próximo do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(Apenas GLES3) Encontra o inteiro Ãmpar mais próximo do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "Limita o valor entre 0.0 e 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "Extrai o sinal do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "Devolve o seno do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(Apenas GLES3) Devolve o seno hiperbólico do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "Devolve a raiz quadrada do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8528,6 +8228,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." 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 " +"usando polinomiais Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8535,71 +8240,69 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Função Step( escalar(limite), escalar(x) ).\n" +"\n" +"Devolve 0.0 se 'x' for menor que 'limite' e 1.0 se não for." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "Devolve a tangente do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Apenas GLES3) Devolve a tangente hiperbólica do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." -msgstr "" +msgstr "(Apenas GLES3) Encontra o valor truncado do parâmetro." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "Adiciona escalar a escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "Divide escalar por escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "Multiplica escalar por escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "Devolve o resto dos dois escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "Subtrai escalar a escalar." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar constant." -msgstr "Mudar constante escalar" +msgstr "Constante Escalar." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar uniform." -msgstr "Mudar uniforme escalar" +msgstr "Uniforme Escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "Executa cubic texture lookup." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the texture lookup." -msgstr "" +msgstr "Executa texture lookup." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Cubic texture uniform." -msgstr "Mudar uniforme textura" +msgstr "Uniforme Textura Cúbica." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "2D texture uniform." -msgstr "Mudar uniforme textura" +msgstr "Uniforme Textura 2D." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform function." -msgstr "Diálogo de transformação..." +msgstr "Função Transformação." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8611,74 +8314,77 @@ msgid "" "whose number of rows is the number of components in 'c' and whose number of " "columns is the number of components in 'r'." msgstr "" +"(Apenas GLES3) Calcula o produto tensorial de um par de vetores.\n" +"\n" +"OuterProduct trata o primeiro parâmetro 'c' como um vetor coluna (matriz com " +"uma coluna) e o segundo parâmetro 'r' como um vetor linha (matriz com uma " +"linha) e faz uma multiplicação matricial algébrica linear 'c * r', " +"resultando uma matriz cujo número de linhas é o número de componentes em 'c' " +"e cujo número de colunas é o número de componentes de 'r'." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes transform from four vectors." -msgstr "" +msgstr "Compõe transformação a partir de quatro vetores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes transform to four vectors." -msgstr "" +msgstr "Decompõe transformação em quatro vetores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the determinant of a transform." -msgstr "" +msgstr "(Apenas GLES3) Calcula o determinante de uma transformação." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the inverse of a transform." -msgstr "" +msgstr "(Apenas GLES3) Calcula o inverso de uma transformação." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the transpose of a transform." -msgstr "" +msgstr "(Apenas GLES3) Calcula a transposta de uma transformação." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies transform by transform." -msgstr "" +msgstr "Multiplica transformação por transformação." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by transform." -msgstr "" +msgstr "Multiplica vetor por transformação." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform constant." -msgstr "Transformação abortada." +msgstr "Constante Transformação." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform uniform." -msgstr "Transformação abortada." +msgstr "Uniforme Transformação." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector function." -msgstr "Atribuição a função." +msgstr "Função Vetor." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector operator." -msgstr "Mudar operador vetorial" +msgstr "Operador Vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "Compõe vetor a partir de três escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "Decompõe vetor em três escalares." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "Calcula o produto vetorial de dois vetores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "Devolve a distância entre dois pontos." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "Calcula o produto escalar de dois vetores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8687,36 +8393,42 @@ msgid "" "incident vector, and Nref, the reference vector. If the dot product of I and " "Nref is smaller than zero the return value is N. Otherwise -N is returned." msgstr "" +"Devolve um vetor com a mesma direção de um vetor referência. A função tem " +"três parâmetro: N, o vetor a orientar, I, o vetor incidente, e Nref, o vetor " +"referência. Se o produto escalar de I e Nref for menor que zero o valor de " +"retorno é N, Caso contrário -N será devolvido." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "Calcula o comprimento de um vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "Interpolação linear entre dois vetores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." -msgstr "" +msgstr "Calcula o produto normalizado do vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - vector" -msgstr "" +msgstr "1.0 - vetor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / vector" -msgstr "" +msgstr "1.0 / vetor" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns a vector that points in the direction of reflection ( a : incident " "vector, b : normal vector )." msgstr "" +"Devolve um vetor que aponta na direção da reflexão ( a : vetor incidente, " +"b : vetor normal )." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns a vector that points in the direction of refraction." -msgstr "" +msgstr "Devolve um vetor que aponta na direção da refração." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8726,6 +8438,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." 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 " +"usando polinomiais Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8735,6 +8452,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." 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 " +"usando polinomiais Hermite." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8742,6 +8464,9 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Função Step( vetor(limite), vetor(x) ).\n" +"\n" +"Devolve 0.0 se 'x' for menor que 'limite', senão devolve 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8749,36 +8474,37 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"Função Step( escalar(limite), vetor(x) ).\n" +"\n" +"Devolve 0.0 se 'x' for menor que 'limite', senão devolve 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." -msgstr "" +msgstr "Adiciona vetor a vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "" +msgstr "Divide vetor com vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." -msgstr "" +msgstr "Multiplica vetor com vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two vectors." -msgstr "" +msgstr "Devolve o resto dos dois vetores." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts vector from vector." -msgstr "" +msgstr "Subtrai vetor a vetor." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector constant." -msgstr "Mudar constante vetorial" +msgstr "Constante Vetor." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector uniform." -msgstr "Atribuição a uniforme." +msgstr "Uniforme Vetor." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8786,56 +8512,74 @@ msgid "" "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 "" +"Expressão personalizada da Linguagem Godot Shader, com quantidade variável " +"de portas de entrada e saÃda. Isto é uma injeção direta de código na função " +"vertex/fragment/light, não a use para escrever as declarações internas da " +"função." #: 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 "" +"Devolve queda baseada no produto escalar da normal à superfÃcie e da direção " +"da câmara (passa entradas associadas)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Scalar derivative function." -msgstr "" +msgstr "(Apenas GLES3) (apenas modo Fragment/Light) Função derivada escalar." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function." -msgstr "" +msgstr "(Apenas GLES3) (apenas modo Fragment/Light) Função derivada vetorial." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using " "local differencing." msgstr "" +"(Apenas GLES3) (apenas modo Fragment/Light) Derivação em 'x' usando " +"derivação local." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using " "local differencing." msgstr "" +"(Apenas GLES3) (apenas modo Fragment/Light) (Escalar) Derivação em 'x' " +"usando derivação local." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using " "local differencing." msgstr "" +"(Apenas GLES3) (apenas modo Fragment/Light) (Vetor) Derivação em 'y' usando " +"derivação local." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using " "local differencing." msgstr "" +"(Apenas GLES3) (apenas modo Fragment/Light) (Escalar) Derivação em 'y' " +"usando derivação local." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(Apenas GLES3) (apenas modo Fragment/Light) (Vetor) Soma das derivadas " +"absolutas em 'x' e 'y'." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(Apenas GLES3) (apenas modo Fragment/Light) (Escalar) Soma das derivadas " +"absolutas em 'x' e 'y'." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "VisualShader" @@ -9178,7 +8922,6 @@ msgid "Are you sure to open more than one project?" msgstr "Está seguro que quer abrir mais do que um Projeto?" #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file does not specify the version of Godot " "through which it was created.\n" @@ -9201,7 +8944,6 @@ msgstr "" "motor." #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file was generated by an older engine " "version, and needs to be converted for this version:\n" @@ -9230,15 +8972,14 @@ msgstr "" "cuja configuração não é compatÃvel com esta versão." #: editor/project_manager.cpp -#, fuzzy 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 "" "ImpossÃvel executar o Projeto: Cena principal não definida.\n" -"Edite o Projeto e defina a Cena principal em \"Definições do Projeto\" " -"dentro da categoria \"Aplicação\"." +"Edite o Projeto e defina a Cena principal em Definições do Projeto dentro da " +"categoria \"Aplicação\"." #: editor/project_manager.cpp msgid "" @@ -9249,48 +8990,49 @@ msgstr "" "Edite o Projeto para desencadear a importação inicial." #: editor/project_manager.cpp -#, fuzzy msgid "Are you sure to run %d projects at once?" -msgstr "Está seguro que quer executar mais do que um Projeto?" +msgstr "Está seguro que quer executar %d projetos em simultâneo?" #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove %d projects from the list?\n" "The project folders' contents won't be modified." -msgstr "Remover Projeto da lista? (O conteúdo da pasta não será modificado)" +msgstr "" +"Remover %d projetos da lista?\n" +"O conteúdo das pastas não será modificado." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove this project from the list?\n" "The project folder's contents won't be modified." -msgstr "Remover Projeto da lista? (O conteúdo da pasta não será modificado)" +msgstr "" +"Remover este projeto da lista?\n" +"O conteúdo da pasta não será modificado." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove all missing projects from the list? (Folders contents will not be " "modified)" -msgstr "Remover Projeto da lista? (O conteúdo da pasta não será modificado)" +msgstr "" +"Remover da lista todos os projeto em falta? (O conteúdo da pasta não será " +"modificado)" #: editor/project_manager.cpp -#, fuzzy msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." msgstr "" "Linguagem alterada.\n" -"A interface será atualizada da próxima vez que o Editor ou o Gestor de " -"Projetos arrancar." +"A interface será atualizada após o arranque do editor ou do gestor de " +"projetos." #: editor/project_manager.cpp -#, fuzzy msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." msgstr "" -"Está prestes a analisar %s pastas para Projetos Godot existentes. Confirma?" +"Pretende pesquisar %s pastas por projetos Godot existentes?\n" +"Pode demorar um pouco." #: editor/project_manager.cpp msgid "Project Manager" @@ -9313,9 +9055,8 @@ msgid "New Project" msgstr "Novo Projeto" #: editor/project_manager.cpp -#, fuzzy msgid "Remove Missing" -msgstr "Remover Ponto" +msgstr "Remover Ausente" #: editor/project_manager.cpp msgid "Templates" @@ -9334,13 +9075,12 @@ msgid "Can't run project" msgstr "ImpossÃvel executar o Projeto" #: editor/project_manager.cpp -#, fuzzy msgid "" "You currently don't have any projects.\n" "Would you like to explore official example projects in the Asset Library?" msgstr "" -"Atualmente não tem quaisquer Projetos.\n" -"Gostaria de explorar os Projetos de exemplo oficiais na Biblioteca de Ativos?" +"Atualmente não tem quaisquer projetos.\n" +"Gostaria de explorar os projetos de exemplo oficiais na Biblioteca de Ativos?" #: editor/project_settings_editor.cpp msgid "Key " @@ -9367,9 +9107,8 @@ msgstr "" "'\"'" #: editor/project_settings_editor.cpp -#, fuzzy msgid "An action with the name '%s' already exists." -msgstr "Ação '%s' já existe!" +msgstr "Já existe uma ação com o nome '%s'." #: editor/project_settings_editor.cpp msgid "Rename Input Action Event" @@ -9588,9 +9327,8 @@ msgid "Override For..." msgstr "Sobrepor por..." #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -#, fuzzy msgid "The editor must be restarted for changes to take effect." -msgstr "O editor deve ser reiniciado para que as alterações entrem em vigor" +msgstr "O editor deve ser reiniciado para que as alterações entrem em vigor." #: editor/project_settings_editor.cpp msgid "Input Map" @@ -9649,14 +9387,12 @@ msgid "Locales Filter" msgstr "Filtro de localização" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show All Locales" -msgstr "Mostrar todas as localizações" +msgstr "Mostrar Todos os Idiomas" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show Selected Locales Only" -msgstr "Mostrar apenas localizações selecionadas" +msgstr "Mostrar Apenas Idiomas Selecionados" #: editor/project_settings_editor.cpp msgid "Filter mode:" @@ -9743,7 +9479,6 @@ msgid "Suffix" msgstr "Sufixo" #: editor/rename_dialog.cpp -#, fuzzy msgid "Advanced Options" msgstr "Opções Avançadas" @@ -10004,9 +9739,8 @@ msgid "User Interface" msgstr "Interface do Utilizador" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Other Node" -msgstr "Apagar Nó" +msgstr "Outro Nó" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" @@ -10049,7 +9783,6 @@ msgid "Clear Inheritance" msgstr "Limpar herança" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Open Documentation" msgstr "Abrir documentação" @@ -10058,6 +9791,10 @@ msgid "Add Child Node" msgstr "Adicionar Nó filho" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "Expandir/Colapsar Tudo" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Mudar tipo" @@ -10086,8 +9823,8 @@ msgid "Delete (No Confirm)" msgstr "Apagar (sem confirmação)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "Adicionar/criar novo Nó" +msgid "Add/Create a New Node." +msgstr "Adicionar/Criar Novo Nó." #: editor/scene_tree_dock.cpp msgid "" @@ -10122,19 +9859,16 @@ msgid "Toggle Visible" msgstr "Alternar Visibilidade" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Unlock Node" -msgstr "Selecionar Nó" +msgstr "Desbloquear Nó" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Button Group" -msgstr "Botão 7" +msgstr "Grupo Botão" #: editor/scene_tree_editor.cpp -#, fuzzy msgid "(Connecting From)" -msgstr "Erro de Ligação" +msgstr "(A Ligar de)" #: editor/scene_tree_editor.cpp msgid "Node configuration warning:" @@ -10165,9 +9899,8 @@ msgstr "" "Clique para mostrar doca dos grupos." #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Open Script:" -msgstr "Abrir Script" +msgstr "Abrir Script:" #: editor/scene_tree_editor.cpp msgid "" @@ -10218,39 +9951,32 @@ msgid "Select a Node" msgstr "Selecione um Nó" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is empty." -msgstr "Caminho está vazio" +msgstr "Caminho está vazio." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Filename is empty." -msgstr "Nome do ficheiro vazio" +msgstr "Nome do Ficheiro vazio." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is not local." -msgstr "Caminho não é local" +msgstr "Caminho não é local." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid base path." -msgstr "Caminho base inválido" +msgstr "Caminho base inválido." #: editor/script_create_dialog.cpp -#, fuzzy msgid "A directory with the same name exists." -msgstr "Já existe diretoria com o mesmo nome" +msgstr "Já existe diretoria com o mesmo nome." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid extension." -msgstr "Extensão inválida" +msgstr "Extensão inválida." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Wrong extension chosen." -msgstr "Escolhida uma extensão errada" +msgstr "Escolhida extensão errada." #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" @@ -10269,52 +9995,44 @@ msgid "N/A" msgstr "N/A" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Open Script / Choose Location" -msgstr "Abrir Script/Escolher Localização" +msgstr "Abrir Script/ Escolher Localização" #: editor/script_create_dialog.cpp msgid "Open Script" msgstr "Abrir Script" #: editor/script_create_dialog.cpp -#, fuzzy msgid "File exists, it will be reused." -msgstr "O Ficheiro já existe, será reutilizado" +msgstr "O Ficheiro já existe, será reutilizado." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid class name." -msgstr "Nome de classe inválida" +msgstr "Nome de classe inválido." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid inherited parent name or path." -msgstr "Nome ou Caminho de parente herdado inválido" +msgstr "Nome ou Caminho de parente herdado inválido." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script is valid." -msgstr "Script inválido" +msgstr "Script é válido." #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9 and _" msgstr "Permitido: a-z, A-Z, 0-9 e _" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Built-in script (into scene file)." -msgstr "Script incorporado (no Ficheiro da Cena)" +msgstr "Script incorporado (no ficheiro da cena)." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will create a new script file." -msgstr "Criar novo Ficheiro de Script" +msgstr "Vai criar novo ficheiro de script." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will load an existing script file." -msgstr "Carregar Ficheiro de Script existente" +msgstr "Vai carregar ficheiro de script existente." #: editor/script_create_dialog.cpp msgid "Language" @@ -10356,7 +10074,7 @@ msgstr "Rastreamento de Pilha" msgid "Pick one or more items from the list to display the graph." msgstr "Escolha um ou mais itens da lista para exibir o gráfico." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Erros" @@ -10446,7 +10164,7 @@ msgstr "Definir a partir da árvore" #: editor/script_editor_debugger.cpp msgid "Export measures as CSV" -msgstr "" +msgstr "Exporta medidas como CSV" #: editor/settings_config_dialog.cpp msgid "Erase Shortcut" @@ -10578,12 +10296,11 @@ msgstr "GDNativeLibrary" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Enabled GDNative Singleton" -msgstr "" +msgstr "Ativa Singleton GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Disabled GDNative Singleton" -msgstr "Desativar a roleta de atualização" +msgstr "Instância única GDNative desativada" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Library" @@ -10672,9 +10389,8 @@ msgid "GridMap Fill Selection" msgstr "Seleção de Preenchimento de GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Paste Selection" -msgstr "Apagar seleção GridMap" +msgstr "Colar Seleção GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Paint" @@ -10760,54 +10476,6 @@ msgstr "Distância de escolha:" msgid "Class name can't be a reserved keyword" msgstr "Nome de classe não pode ser uma palavra-chave reservada" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "A gerar soluções..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "A gerar projeto C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Falha ao criar solução." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Falha ao guardar solução." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Feito" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "Falha ao criar projeto C#." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "Sobre o suporte C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Criar solução C#" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Builds" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Construir Projeto" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Ver log" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Fim do stack trace de exceção interna" @@ -11101,9 +10769,8 @@ msgid "Available Nodes:" msgstr "Nós DisponÃveis:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Select or create a function to edit its graph." -msgstr "Selecione ou crie uma Função para editar o grafo" +msgstr "Selecionar ou criar uma função para editar o gráfico." #: modules/visual_script/visual_script_editor.cpp msgid "Delete Selected" @@ -11239,15 +10906,19 @@ msgstr "" #: platform/android/export/export.cpp 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." #: platform/android/export/export.cpp msgid "Invalid Android SDK path for custom build in Editor Settings." -msgstr "" +msgstr "Caminho inválido para Android SDK no Editor de Configurações." #: platform/android/export/export.cpp msgid "" "Android project is not installed for compiling. Install from Editor menu." msgstr "" +"Projeto Android não está instalado para compilação. Instale-o no menu do " +"Editor." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -11262,6 +10933,8 @@ msgid "" "Trying to build from a custom built template, but no version info for it " "exists. Please reinstall from the 'Project' menu." msgstr "" +"A tentar compilar a partir de um modelo personalizado, mas sem informação de " +"versão. Reinstale no menu 'Projeto'." #: platform/android/export/export.cpp msgid "" @@ -11270,20 +10943,27 @@ msgid "" " Godot Version: %s\n" "Please reinstall Android build template from 'Project' menu." msgstr "" +"Incompatibilidade da versão Android:\n" +" Modelo instalado: %s\n" +" Versão Godot: %s\n" +"Reinstale o modelo de compilação Android no menu 'Projeto'." #: platform/android/export/export.cpp msgid "Building Android Project (gradle)" -msgstr "" +msgstr "A compilar Projeto Android (gradle)" #: platform/android/export/export.cpp msgid "" "Building of Android project failed, check output for the error.\n" "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" +"Falhou a compilação do projeto Android, verifique o erro na saÃda.\n" +"Em alternativa visite docs.godotengine.org para a documentação sobre " +"compilação Android." #: platform/android/export/export.cpp msgid "No build apk generated at: " -msgstr "" +msgstr "Nenhum apk gerado em: " #: platform/iphone/export/export.cpp msgid "Identifier is missing." @@ -11410,8 +11090,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "Dimensões inválidas da imagem do ecrã inicial (deve ser 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Um recurso SpriteFrames tem de ser criado ou definido na Propriedade " @@ -11478,8 +11159,9 @@ msgstr "" "\"Particles Animation\" ativada." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "Uma textura com a forma da luz tem de ser disponibilizada na Propriedade " @@ -11493,7 +11175,8 @@ msgstr "" "efeito." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "O PolÃgono oclusor deste Oclusor está vazio. Desenhe um PolÃgono!" #: scene/2d/navigation_polygon.cpp @@ -11579,50 +11262,57 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." msgstr "Falta uma pose DESCANSO a este osso. Vá ao nó Skeleton2D e defina uma." +#: 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 "" +"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." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D funciona melhor quando usado diretamente como parente na " "Cena raiz editada." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera precisa de um Nó ARVROrigin como parente" #: scene/3d/arvr_nodes.cpp -#, fuzzy 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 parente." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The controller ID must not be 0 or this controller won't be bound to an " "actual controller." msgstr "" -"O id do controlador não pode ser 0 senão este controlador não será vinculado " -"a um controlador real" +"O ID do controlador não pode ser 0 senão este controlador não será vinculado " +"a um controlador real." #: scene/3d/arvr_nodes.cpp -#, fuzzy 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 parente." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The anchor ID must not be 0 or this anchor won't be bound to an actual " "anchor." msgstr "" -"O id da âncora não pode ser 0 senão esta âncora não será vinculada a uma " -"âncora real" +"O ID da âncora não pode ser 0 senão esta âncora não será vinculada a uma " +"âncora real." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVROrigin requires an ARVRCamera child node." -msgstr "ARVROrigin exige um Nó filho ARVRCamera" +msgstr "ARVROrigin exige um Nó filho ARVRCamera." #: scene/3d/baked_lightmap.cpp msgid "%d%%" @@ -11684,9 +11374,10 @@ msgstr "" "RigidBody, KinematicBody, etc. para lhes dar uma forma." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Uma forma tem de ser fornecida para CollisionShape funcionar. Crie um " "recurso forma!" @@ -11704,13 +11395,12 @@ msgid "Nothing is visible because no mesh has been assigned." msgstr "Nada é visÃvel porque nenhuma Malha foi atribuÃda." #: scene/3d/cpu_particles.cpp -#, fuzzy msgid "" "CPUParticles animation requires the usage of a SpatialMaterial whose " "Billboard Mode is set to \"Particle Billboard\"." msgstr "" -"Animação CPUParticles requer o uso de um SpatialMaterial com \"Billboard " -"Particles\" ativada." +"Animação CPUParticles requer o uso de um SpatialMaterial com Modo Billboard " +"definido como \"Billboard Particles\"." #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" @@ -11724,6 +11414,10 @@ msgstr "" "Sondas GI não são suportadas pelo driver vÃdeo GLES2.\n" "Em vez disso, use um BakedLightmap." +#: 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 "" @@ -11755,22 +11449,22 @@ msgstr "" "Nada é visÃvel porque não foram atribuÃdas Meshes aos passos de desenho." #: scene/3d/particles.cpp -#, fuzzy msgid "" "Particles animation requires the usage of a SpatialMaterial whose Billboard " "Mode is set to \"Particle Billboard\"." msgstr "" -"Animação Particles requer o uso de um SpatialMaterial com \"Billboard " -"Particles\" ativada." +"Animação Particles requer o uso de um SpatialMaterial com Modo Billboard " +"definido como \"Billboard Particles\"." #: scene/3d/path.cpp msgid "PathFollow only works when set as a child of a Path node." msgstr "PathFollow apenas funciona quando definido como filho de um Nó Path." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED requer \"Up Vector\" habilitado no recurso de " "Curva do Caminho do seu pai." @@ -11786,15 +11480,17 @@ msgstr "" "Mude antes o tamanho das formas de colisão filhas." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "Para funcionar, a Propriedade Caminho tem de apontar para um Nó Spatial " "válido." #: scene/3d/soft_body.cpp -#, fuzzy msgid "This body will be ignored until you set a mesh." -msgstr "Este corpo será ignorado até se definir uma Malha" +msgstr "Este corpo será ignorado até se definir uma malha." #: scene/3d/soft_body.cpp msgid "" @@ -11807,8 +11503,9 @@ msgstr "" "Em vez disso, mude o tamanho das formas de colisão filhas." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Um recurso SpriteFrames tem de ser criado ou definido na Propriedade " @@ -11823,8 +11520,10 @@ msgstr "" "filho de VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment precisa de um recurso Environment." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11862,7 +11561,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Nada conectado à entrada '%s' do nó '%s'." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "Não foi definida um AnimationNode raiz para o gráfico." #: scene/animation/animation_tree.cpp @@ -11876,7 +11576,8 @@ msgstr "" "O caminho definido para AnimationPlayer não conduz a um nó AnimationPlayer." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "A raiz de AnimationPlayer não é um nó válido." #: scene/animation/animation_tree_player.cpp @@ -11888,8 +11589,12 @@ msgid "Pick a color from the screen." msgstr "Escolha uma cor do ecrã." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Modo Raw" +msgid "HSV" +msgstr "HSV" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "Raw" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11902,15 +11607,22 @@ msgstr "Adicionar cor atual como predefinição." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" "Por si só um Contentor não tem utilidade, a não ser que um script configure " -"o comportamento dos seu filhos.\n" -"Se não pretende adicionar um script, será preferÃvel usar um simples nó " -"'Control'." +"a disposição dos seu filhos.\n" +"Se não pretende adicionar um script, use antes um simples Nó 'Control'." + +#: 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 "" +"A Etiqueta de Sugestão não será exibida porque o Filtro de Rato do controle " +"está definido como \"Ignorar\". Em alternativa, defina o Filtro de Rato para " +"\"Parar\" ou \"Passar\"." #: scene/gui/dialogs.cpp msgid "Alert!" @@ -11921,23 +11633,26 @@ msgid "Please Confirm..." msgstr "Confirme por favor..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Popups estão escondidas por defeito a não ser que chame popup() ou qualquer " "das funções popup*(). Torná-las visÃveis para edição é aceitável, mas serão " "escondidas na execução." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Se exp_edit é verdadeiro min_value tem de ser > 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer está destinado a funcionar com um único controlo filho.\n" @@ -11989,6 +11704,11 @@ msgid "Input" msgstr "Entrada" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Fonte inválida para Shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Fonte inválida para Shader." @@ -12006,7 +11726,235 @@ msgstr "Variações só podem ser atribuÃdas na função vértice." #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "Constantes não podem ser modificadas." + +#~ msgid "Generating solution..." +#~ msgstr "A gerar soluções..." + +#~ msgid "Generating C# project..." +#~ msgstr "A gerar projeto C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "Falha ao criar solução." + +#~ 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#." + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "Sobre o suporte C#" + +#~ msgid "Create C# solution" +#~ msgstr "Criar solução C#" + +#~ msgid "Builds" +#~ msgstr "Builds" + +#~ msgid "Build Project" +#~ msgstr "Construir Projeto" + +#~ msgid "View log" +#~ msgstr "Ver log" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment precisa de um recurso Environment." + +#~ msgid "Enabled Classes" +#~ msgstr "Ativar Classes" + +#~ msgid "Update Always" +#~ msgstr "Atualizar Sempre" + +#~ msgid "'camera' input parameter for all shader modes." +#~ msgstr "parâmetro de entrada 'camera' para todos os modos shader." + +#~ msgid "'inv_camera' input parameter for all shader modes." +#~ msgstr "parâmetro de entrada 'inv_camera' para todos os modos shader." + +#~ msgid "'inv_projection' input parameter for all shader modes." +#~ msgstr "parâmetro de entrada 'inv_projection' para todos os modos shader." + +#~ msgid "'normal' input parameter for all shader modes." +#~ msgstr "parâmetro de entrada 'normal' para todos os modos shader." + +#~ msgid "'projection' input parameter for all shader modes." +#~ msgstr "parâmetro de entrada 'projection' para todos os modos shader." + +#~ msgid "'time' input parameter for all shader modes." +#~ msgstr "parâmetro de entrada 'time' para todos os modos shader." + +#~ msgid "'viewport_size' input parameter for all shader modes." +#~ msgstr "parâmetro de entrada 'viewport_size' para todos os modos shader." + +#~ msgid "'world' input parameter for all shader modes." +#~ msgstr "parâmetro de entrada 'world' para todos os modos shader." + +#~ msgid "'alpha' input parameter for all shader modes." +#~ msgstr "parâmetro de entrada 'alpha' para todos os modos shader." + +#~ msgid "'color' input parameter for all shader modes." +#~ msgstr "parâmetro de entrada 'color' para todos os modos shader." + +#~ msgid "'texture_pixel_size' input parameter for all shader modes." +#~ msgstr "" +#~ "parâmetro de entrada 'texture_pixel_size' para todos os modos shader." + +#~ msgid "'alpha' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "parâmetro de entrada 'alpha' para os modos shader vertex e fragment." + +#~ msgid "'binormal' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "parâmetro de entrada 'binormal' para os modos shader vertex e fragment." + +#~ msgid "'color' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "parâmetro de entrada 'color' para os modos shader vertex e fragment." + +#~ msgid "'fragcoord' input parameter for fragment and light shader modes." +#~ msgstr "" +#~ "parâmetro de entrada 'fragcoord' para os modos shader fragment e light." + +#~ msgid "'point_coord' input parameter for fragment shader mode." +#~ msgstr "parâmetro de entrada 'point_coord' para o modo shader fragment." + +#~ msgid "'screen_uv' input parameter for fragment shader mode." +#~ msgstr "parâmetro de entrada 'screen_uv' para o modo shader fragment." + +#~ msgid "'tangent' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "parâmetro de entrada 'tangent' para os modos shader vertex e fragment." + +#~ msgid "'uv2' input parameter for vertex and fragment shader modes." +#~ msgstr "parâmetro de entrada 'uv2' para os modos shader vertex e fragment." + +#~ msgid "'vertex' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "parâmetro de entrada 'vertex' para os modos shader vertex e fragment." + +#~ msgid "'albedo' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'albedo' para o modo shader light." + +#~ msgid "'attenuation' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'attenuation' para o modo shader light." + +#~ msgid "'light' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'light' para o modo shader light." + +#~ msgid "'light_color' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'light_color' para o modo shader light." + +#~ msgid "'roughness' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'roughness' para o modo shader light." + +#~ msgid "'specular' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'specular' para o modo shader light." + +#~ msgid "'transmission' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'transmission' para o modo shader light." + +#~ msgid "'modelview' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'modelview' para o modo shader vertex." + +#~ msgid "'point_size' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'point_size' para o modo shader vertex." + +#~ msgid "'tangent' input parameter for vertex and fragment shader mode." +#~ msgstr "" +#~ "parâmetro de entrada 'tangent' para os modos shader vertex e fragment." + +#~ msgid "'light_pass' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "parâmetro de entrada 'light_pass' para os modos shader vertex e fragment." + +#~ msgid "'point_coord' input parameter for fragment and light shader modes." +#~ msgstr "" +#~ "parâmetro de entrada 'point_coord' para os modos shader fragment e light." + +#~ msgid "'screen_pixel_size' input parameter for fragment shader mode." +#~ msgstr "" +#~ "parâmetro de entrada 'screen_pixel_size' para o modo shader fragment." + +#~ msgid "'screen_uv' input parameter for fragment and light shader modes." +#~ msgstr "" +#~ "parâmetro de entrada 'screen_uv' para modos shader fragment e light." + +#~ msgid "'light_alpha' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'light_alpha' para modo shader light." + +#~ msgid "'light_height' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'light_height' para modo shader light." + +#~ msgid "'light_uv' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'light_uv' para modo shader light." + +#~ msgid "'light_vec' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'light_vec' para modo shader light." + +#~ msgid "'normal' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'normal' para modo shader light." + +#~ msgid "'shadow_color' input parameter for light shader mode." +#~ msgstr "parâmetro de entrada 'shadow_color' para modo shader light." + +#~ msgid "'extra' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'extra' para modo shader vertex." + +#~ msgid "'projection' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'projection' para modo shader vertex." + +#~ msgid "'vertex' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'vertex' para modo shader vertex." + +#~ msgid "'world' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'world' para modo shader vertex." + +#~ msgid "'active' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'active' para modo shader vertex." + +#~ msgid "'alpha' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'alpha' para modo shader vertex." + +#~ msgid "'color' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'color' para modo shader vertex." + +#~ msgid "'custom_alpha' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'custom_alpha' para modo shader vertex." + +#~ msgid "'delta' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'delta' para modo shader vertex." + +#~ msgid "'emission_transform' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'emission_transform' para modo shader vertex." + +#~ msgid "'index' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'index' para modo shader vertex." + +#~ msgid "'lifetime' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'lifetime' para modo shader vertex." + +#~ msgid "'restart' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'restart' para modo shader vertex." + +#~ msgid "'time' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'time' para modo shader vertex." + +#~ msgid "'transform' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'transform' para modo shader vertex." + +#~ msgid "'velocity' input parameter for vertex shader mode." +#~ msgstr "parâmetro de entrada 'velocity' para modo shader vertex." + +#~ msgid "Raw Mode" +#~ msgstr "Modo Raw" #~ msgid "Path to Node:" #~ msgstr "Caminho para Nó:" @@ -12555,9 +12503,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Alternar visibilidade espacial" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Alternar visibilidade do CanvasItem" - #~ msgid "Condition" #~ msgstr "Condição" diff --git a/editor/translations/ro.po b/editor/translations/ro.po index 0cf2c4ef42..b204bf19fd 100644 --- a/editor/translations/ro.po +++ b/editor/translations/ro.po @@ -462,6 +462,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Mod Selectare" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -644,6 +654,10 @@ msgstr "DuceÈ›i-vă la Linie" msgid "Line Number:" msgstr "Linia Numărul:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Nici o Potrivire" @@ -693,7 +707,7 @@ msgstr "Zoom-aÈ›i Afară" msgid "Reset Zoom" msgstr "ResetaÈ›i Zoom-area" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -806,6 +820,11 @@ msgid "Connect" msgstr "ConectaÈ›i" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Semnale:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "ConectaÈ›i '%s' la '%s'" @@ -977,7 +996,8 @@ msgid "Owners Of:" msgstr "Stăpâni La:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "ȘtergeÈ›i fiÈ™ierele selectate din proiect? (fără anulare)" #: editor/dependency_editor.cpp @@ -1356,7 +1376,7 @@ msgstr "" #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" "Nume nevalid. Nu trebuie să se lovească cu un nume de tip deja existent în " "motor tip." @@ -1534,6 +1554,10 @@ msgstr "" msgid "Template file not found:" msgstr "FiÈ™ierul È™ablon nu a fost găsit:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1566,7 +1590,7 @@ msgstr "Mod Mutare" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "Sistemul De FiÈ™iere" #: editor/editor_feature_profile.cpp @@ -1627,7 +1651,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1642,7 +1666,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Versiune Curentă:" #: editor/editor_feature_profile.cpp @@ -1666,13 +1690,9 @@ msgid "Export" msgstr "Exportare" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Căutare Clase" +msgid "Available Profiles:" +msgstr "Proprietăți" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2795,11 +2815,35 @@ msgid "Editor Layout" msgstr "Schema Editorului" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Salvează Scena" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Setări ale Editorului" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Deschide Editorul următor" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Comută în Ecran Complet" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "Modul de Comutare" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "Setări ale Editorului" @@ -2909,15 +2953,18 @@ msgid "Spins when the editor window redraws." msgstr "Se roteÈ™te când ferestra editorului se recolorează!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Actualizează ÃŽntotdeauna" +#, fuzzy +msgid "Update Continuously" +msgstr "Continuu" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Modificări ale Actualizării" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Dezactivează Cercul de Actualizare" #: editor/editor_node.cpp @@ -3112,7 +3159,7 @@ msgstr "Timp" msgid "Calls" msgstr "Apeluri" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3212,6 +3259,11 @@ 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 #, fuzzy msgid "New Key:" msgstr "Nume nou:" @@ -3225,11 +3277,6 @@ msgstr "Nume nou:" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3756,6 +3803,7 @@ msgid "Nodes not in Group" msgstr "Adaugă în Grup" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5448,6 +5496,14 @@ msgid "Load Emission Mask" msgstr "ÃŽncărcare Mască de Emisie" #: 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 +#, fuzzy +msgid "Restart" +msgstr "Restartare (s):" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Curăță Masca de Emisie" @@ -6396,10 +6452,20 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Proprietățile obiectului." + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Proprietățile obiectului." + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "" @@ -6639,18 +6705,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Șterge puncte" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -8278,51 +8348,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8331,203 +8357,27 @@ msgid "Input parameter." msgstr "Snap către părinte" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10203,6 +10053,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Restrânge toate" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10233,8 +10088,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "CreaÈ›i %s Nou" #: editor/scene_tree_dock.cpp msgid "" @@ -10487,7 +10343,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10896,54 +10752,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "Vizualizează fiÈ™iere log" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11531,7 +11339,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11580,7 +11388,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11590,7 +11398,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11657,14 +11465,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11743,7 +11558,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11772,6 +11587,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11806,8 +11625,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11818,7 +11637,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11834,7 +11655,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11845,7 +11666,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11883,7 +11706,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "DeconectaÈ›i '%s' de la '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11897,7 +11720,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "Arborele AnimaÈ›iei este nevalid." #: scene/animation/animation_tree_player.cpp @@ -11909,7 +11732,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11922,10 +11749,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11939,18 +11771,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11994,6 +11826,10 @@ msgid "Input" msgstr "Adaugă Intrare(Input)" #: scene/resources/visual_shader_nodes.cpp +msgid "Invalid source for preview." +msgstr "" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "" @@ -12013,6 +11849,16 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "View log" +#~ msgstr "Vizualizează fiÈ™iere log" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Căutare Clase" + +#~ msgid "Update Always" +#~ msgstr "Actualizează ÃŽntotdeauna" + #~ msgid "Path to Node:" #~ msgstr "Drum la Nod:" diff --git a/editor/translations/ru.po b/editor/translations/ru.po index 90716403f1..a3e64f65b0 100644 --- a/editor/translations/ru.po +++ b/editor/translations/ru.po @@ -49,12 +49,14 @@ # Breadp4ck <iii103@mail.ru>, 2019. # Dark King <damir@t1c.ru>, 2019. # Teashrock <kajitsu22@gmail.com>, 2019. +# Дмитрий Ефимов <daefimov@gmail.com>, 2019. +# Sergey <www.window1@mail.ru>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 02:33+0000\n" -"Last-Translator: Teashrock <kajitsu22@gmail.com>\n" +"PO-Revision-Date: 2019-07-09 10:46+0000\n" +"Last-Translator: Sergey <www.window1@mail.ru>\n" "Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/" "godot/ru/>\n" "Language: ru\n" @@ -63,7 +65,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -123,9 +125,8 @@ msgid "Time:" msgstr "ВремÑ:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "Значение" +msgstr "Значение:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -483,6 +484,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Выбрать вÑе" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "СброÑить выделение" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "Показывать треки только выделенных в дереве узлов." @@ -658,6 +668,10 @@ msgstr "Перейти к Ñтроке" msgid "Line Number:" msgstr "Ðомер Ñтроки:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Ðет Ñовпадений" @@ -707,7 +721,7 @@ msgstr "Отдалить" msgid "Reset Zoom" msgstr "СброÑить приближение" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "ПредупреждениÑ" @@ -716,28 +730,24 @@ msgid "Line and column numbers." msgstr "Ðомера Ñтрок и Ñтолбцов." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Метод должен быть указан в целевом Узле!" +msgstr "Метод должен быть указан в целевом Узле. " #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Целевой метод не найден! Укажите правильный метод или прикрепите Ñкрипт на " +"Целевой метод не найден. Укажите правильный метод или прикрепите Ñкрипт на " "целевой узел." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "ПриÑоединить к узлу:" +msgstr "ПриÑоединить к Узлу:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Ðе удаётÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒÑÑ Ðº хоÑту:" +msgstr "Соединить Ñо Ñкриптом:" #: editor/connections_dialog.cpp #, fuzzy @@ -794,12 +804,11 @@ msgstr "Один раз" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Отключает Ñигнал поÑле его первого вызова." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Подключить Ñигнал: " +msgstr "Ðе удаетÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚ÑŒ Ñигнал" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -820,6 +829,11 @@ msgid "Connect" msgstr "ПриÑоединить" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Сигналы:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "ПриÑоединить '%s' к '%s'" @@ -846,9 +860,8 @@ msgid "Connect a Signal to a Method" msgstr "Подключить Ñигнал: " #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Редактировать Подключение: " +msgstr "Редактировать Подключение:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -924,22 +937,20 @@ msgid "Dependencies For:" msgstr "ЗавиÑимоÑти длÑ:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" "Сцена '%s' в наÑтоÑщее Ð²Ñ€ÐµÐ¼Ñ Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€ÑƒÐµÑ‚ÑÑ.\n" -"Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ вÑтупÑÑ‚ в Ñилу без перезапуÑка." +"Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²ÑтупÑÑ‚ в Ñилу только поÑле перезапуÑка." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" -"РеÑурÑу '% s' иÑпользуетÑÑ.\n" -"Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²ÑтупÑÑ‚ в Ñилу поÑле перезапуÑка." +"РеÑÑƒÑ€Ñ '%s' иÑпользуетÑÑ.\n" +"Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð²ÑтупÑÑ‚ в Ñилу только поÑле перезапуÑка." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -986,7 +997,8 @@ msgid "Owners Of:" msgstr "Владельцы:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Удалить выбранный файл из проекта? (ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ!)" #: editor/dependency_editor.cpp @@ -1031,9 +1043,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "ÐавÑегда удалить %d Ñлемент(ов)? (ÐÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚Ð¼ÐµÐ½Ð¸Ñ‚ÑŒ!)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "ЗавиÑимоÑти" +msgstr "Показать завиÑимоÑти" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1353,25 +1364,16 @@ msgid "Valid characters:" msgstr "ДопуÑтимые Ñимволы:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"ÐедопуÑтимое имÑ. Ðе должно конфликтовать Ñ ÑущеÑтвующим именем клаÑÑа " -"движка." +msgstr "Ðе должно конфликтовать Ñ ÑущеÑтвующим именем клаÑÑа движка." #: editor/editor_autoload_settings.cpp -#, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "" -"ÐедопуÑтимое имÑ. Ðе должно конфликтовать Ñ ÑущеÑтвующим вÑтроенным именем " -"типа." +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 "" -"ÐедопуÑтимое имÑ. Ðе должно конфликтовать Ñ ÑущеÑтвующим глобальным именем " -"конÑтанты." +msgstr "Ðе должно конфликтовать Ñ ÑущеÑтвующим глобальным именем конÑтанты." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." @@ -1406,7 +1408,6 @@ msgid "Rearrange Autoloads" msgstr "ПереÑтановка автозагрузок" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "ÐедопуÑтимый путь." @@ -1546,15 +1547,17 @@ msgstr "ПользовательÑкий релизный шаблон не на 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 -#, fuzzy msgid "3D Editor" -msgstr "Редактор" +msgstr "3D Редактор" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Открыть редактор Ñкриптов" +msgstr "Редактор Ñкриптов" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1578,7 +1581,7 @@ msgstr "Режим перемещениÑ" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "Ð¤Ð°Ð¹Ð»Ð¾Ð²Ð°Ñ ÑиÑтема" #: editor/editor_feature_profile.cpp @@ -1591,23 +1594,23 @@ msgid "Profile must be a valid filename and must not contain '.'" msgstr "" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Файл или папка Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже ÑущеÑтвует." +msgstr "Профиль Ñ Ñ‚Ð°ÐºÐ¸Ð¼ именем уже ÑущеÑтвует." #: editor/editor_feature_profile.cpp +#, fuzzy msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Редактор отключен, СвойÑтва отключены)" #: editor/editor_feature_profile.cpp #, fuzzy msgid "(Properties Disabled)" -msgstr "Только ÑвойÑтва" +msgstr "(СвойÑтва отключены)" #: editor/editor_feature_profile.cpp #, fuzzy msgid "(Editor Disabled)" -msgstr "Отключить обрезку" +msgstr "(Редактор отключен)" #: editor/editor_feature_profile.cpp #, fuzzy @@ -1640,7 +1643,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1655,7 +1658,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð²ÐµÑ€ÑиÑ:" #: editor/editor_feature_profile.cpp @@ -1680,16 +1683,11 @@ msgstr "ÐкÑпорт" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "ДоÑтупные узлы:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "ПоиÑк клаÑÑов" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "ОпиÑание клаÑÑа" @@ -2421,7 +2419,7 @@ msgid "" "Unable to load addon script from path: '%s' There seems to be an error in " "the code, please check the syntax." msgstr "" -"Ðевозможно загрузить Ñкрипт аддона из иÑточника: \"% s\". Ð’ коде еÑть " +"Ðевозможно загрузить Ñкрипт аддона из иÑточника: '%s' Ð’ коде еÑть " "ошибка. ПожалуйÑта, проверьте ÑинтакÑиÑ." #: editor/editor_node.cpp @@ -2774,10 +2772,34 @@ msgid "Editor Layout" msgstr "Макет редактора" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Создать корневой узел Ñцены" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Открыть папку Данные/ÐаÑтройки редактора" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Открыть Ñледующий редактор" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Переключить полноÑкранный режим" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Переключить видимоÑть CanvasItem" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Открыть папку Данные/ÐаÑтройки редактора" @@ -2885,15 +2907,18 @@ msgid "Spins when the editor window redraws." msgstr "ВращаетÑÑ, когда окно редактора перериÑовываетÑÑ." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "ОбновлÑть вÑегда" +#, fuzzy +msgid "Update Continuously" +msgstr "ÐепрерывнаÑ" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "ОбновлÑть при изменениÑÑ…" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Отключить Ñчётчик обновлений" #: editor/editor_node.cpp @@ -3084,7 +3109,7 @@ msgstr "ВремÑ" msgid "Calls" msgstr "Вызовы" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Вкл" @@ -3190,6 +3215,11 @@ 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 "Ðовый ключ:" @@ -3201,11 +3231,6 @@ msgstr "Ðовое значение:" msgid "Add Key/Value Pair" msgstr "Добавить пару: Ключ/Значение" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Удалить Ñлемент" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3710,6 +3735,7 @@ msgid "Nodes not in Group" msgstr "Узлы не в Группе" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Ð¤Ð¸Ð»ÑŒÑ‚Ñ€Ð°Ñ†Ð¸Ñ ÑƒÐ·Ð»Ð¾Ð²" @@ -5356,6 +5382,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "ПерезапуÑтить ÑейчаÑ" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "МаÑка выброÑа очищена" @@ -6275,10 +6309,20 @@ msgid "Find Next" msgstr "Ðайти Ñледующее" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 +#, fuzzy +msgid "Filter methods" +msgstr "Режим фильтра:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Сортировать" @@ -6514,20 +6558,24 @@ msgid "Syntax Highlighter" msgstr "ПодÑветка СинтакÑиÑа" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +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 "Удалить Ñтроку" @@ -8143,51 +8191,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8196,203 +8200,27 @@ msgid "Input parameter." msgstr "ПривÑзка к родителю" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10123,6 +9951,11 @@ msgid "Add Child Node" msgstr "Добавить дочерний узел" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Свернуть вÑе" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Изменить тип" @@ -10151,7 +9984,8 @@ msgid "Delete (No Confirm)" msgstr "Удалить (без подтверждениÑ)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Добавить/Ñоздать новый узел" #: editor/scene_tree_dock.cpp @@ -10422,7 +10256,7 @@ msgid "Pick one or more items from the list to display the graph." msgstr "" "Выбрать один или неÑколько Ñлементов из ÑпиÑка, чтобы отобразить график." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Ошибки" @@ -10825,54 +10659,6 @@ msgstr "РаÑÑтоÑние выбора:" msgid "Class name can't be a reserved keyword" msgstr "Ð˜Ð¼Ñ ÐºÐ»Ð°ÑÑа не может быть зарезервированным ключевым Ñловом" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "Создание C# проекта..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Ðе удалоÑÑŒ Ñоздать решение." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Ðе удалоÑÑŒ Ñохранить решение." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Готово" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "Ðе удалоÑÑŒ Ñоздать C# проект." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Моно" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "О C# поддержке" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Создать C# решение" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "Билды" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Собрать проект" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "ПроÑмотр журнала" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Конец траÑÑировки внутреннего Ñтека иÑключений" @@ -11464,8 +11250,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "Ðеверные размеры заÑтавки (должны быть 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Чтобы AnimatedSprite отображал кадры, пожалуйÑта уÑтановите или Ñоздайте " @@ -11533,8 +11320,9 @@ msgstr "" "включенной функцией \"Particles Animation\"." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" "ТекÑтуры Ñ Ñ„Ð¾Ñ€Ð¼Ð¾Ð¹ Ñвета должны быть предоÑтавлены параметру \"texture\"." @@ -11547,7 +11335,8 @@ msgstr "" "чтобы работать." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "ЗаÑлонÑющий полигон Ð´Ð»Ñ Ñтого окклюдера пуÑÑ‚. ПожалуйÑта, нариÑуйте полигон!" @@ -11638,16 +11427,30 @@ msgstr "" "У Ñтой коÑти отÑутÑтвует Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ REST-позициÑ. Перейдите к узлу " "Skeleton2D и уÑтановите её." +#: 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 и др. чтобы придать " +"им форму." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D работает наилучшим образом при иÑпользовании ÐºÐ¾Ñ€Ð½Ñ " "редактируемой Ñцены, как прÑмого родителÑ." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera должна иметь узел ARVROrigin в качеÑтве предка" #: scene/3d/arvr_nodes.cpp @@ -11743,9 +11546,10 @@ msgstr "" "Area, StaticBody, RigidBody, KinematicBody и др. чтобы придать им форму." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Shape должен быть предуÑмотрен Ð´Ð»Ñ Ñ„ÑƒÐ½ÐºÑ†Ð¸Ð¹ CollisionShape. ПожалуйÑта, " "Ñоздайте shape-реÑÑƒÑ€Ñ Ð´Ð»Ñ Ñтого!" @@ -11783,6 +11587,10 @@ msgstr "" "GIProbes не поддерживаютÑÑ Ð²Ð¸Ð´ÐµÐ¾Ð´Ñ€Ð°Ð¹Ð²ÐµÑ€Ð¾Ð¼ GLES2.\n" "ВмеÑто Ñтого иÑпользуйте BakedLightmap." +#: 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 "" @@ -11825,9 +11633,10 @@ msgid "PathFollow only works when set as a child of a Path node." msgstr "PathFollow работает только при еÑли она дочь узла Path." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED требует Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° \"Up Vector\" в " "родительÑком реÑурÑе Path's Curve." @@ -11843,7 +11652,10 @@ msgstr "" "Измените размер дочерней формы коллизии." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "СвойÑтво Path должно указывать на дейÑтвительный Spatial узел." #: scene/3d/soft_body.cpp @@ -11863,8 +11675,9 @@ msgstr "" "shapes)." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Чтобы AnimatedSprite3D отображал кадры, пожалуйÑта уÑтановите или Ñоздайте " @@ -11879,8 +11692,10 @@ msgstr "" "ребенка VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment необходим Environment реÑурÑ." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11918,7 +11733,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Ðичего не подключено к входу \"%s\" узла \"%s\"." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "Ðе задан корневой AnimationNode Ð´Ð»Ñ Ð³Ñ€Ð°Ñ„Ð°." #: scene/animation/animation_tree.cpp @@ -11930,7 +11746,8 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "Путь, заданный Ð´Ð»Ñ AnimationPlayer, не ведет к узлу AnimationPlayer." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "Корневой Ñлемент AnimationPlayer недейÑтвительный." #: scene/animation/animation_tree_player.cpp @@ -11942,8 +11759,13 @@ msgid "Pick a color from the screen." msgstr "Выбрать цвет Ñ Ñкрана." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "RAW режим" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +#, fuzzy +msgid "Raw" +msgstr "Ð Ñ‹Ñкание" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11957,16 +11779,21 @@ msgstr "Добавить текущий цвет как преÑет" #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" "Контейнер Ñам по Ñебе не имеет ÑмыÑла, пока Ñкрипт не наÑтроит режим " "Ñ€Ð°Ð·Ð¼ÐµÑ‰ÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ детей.\n" "ЕÑли вы не ÑобираетеÑÑŒ добавлÑть Ñкрипт, иÑпользуйте вмеÑто Ñтого проÑтой " "узел 'Control'." +#: 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 "Внимание!" @@ -11976,23 +11803,26 @@ msgid "Please Confirm..." msgstr "Подтверждение..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "ПоÑле запуÑка вÑплывающие окна по умолчанию Ñкрыты, Ð´Ð»Ñ Ð¸Ñ… Ð¾Ñ‚Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ " "иÑпользуйте функцию popup() или любую из popup*(). Делать их видимыми Ð´Ð»Ñ " "Ñ€ÐµÐ´Ð°ÐºÑ‚Ð¸Ñ€Ð¾Ð²Ð°Ð½Ð¸Ñ - нормально, но они будут Ñкрыты при запуÑке." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "ЕÑли exp_edit равен true min_value должно быть > 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer предназначен Ð´Ð»Ñ Ñ€Ð°Ð±Ð¾Ñ‚Ñ‹ Ñ Ð¾Ð´Ð½Ð¸Ð¼ дочерним Ñлементом " @@ -12047,6 +11877,11 @@ msgid "Input" msgstr "Вход" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "ÐедейÑтвительный иÑточник шейдера." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "ÐедейÑтвительный иÑточник шейдера." @@ -12064,7 +11899,56 @@ msgstr "Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð³ÑƒÑ‚ быть назначены только Ð #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "КонÑтанты не могут быть изменены." + +#~ msgid "Generating solution..." +#~ msgstr "Ð“ÐµÐ½ÐµÑ€Ð°Ñ†Ð¸Ñ Ñ€ÐµÑˆÐµÐ½Ð¸Ñ..." + +#~ msgid "Generating C# project..." +#~ msgstr "Создание C# проекта..." + +#~ msgid "Failed to create solution." +#~ msgstr "Ðе удалоÑÑŒ Ñоздать решение." + +#~ msgid "Failed to save solution." +#~ msgstr "Ðе удалоÑÑŒ Ñохранить решение." + +#~ msgid "Done" +#~ msgstr "Готово" + +#~ msgid "Failed to create C# project." +#~ msgstr "Ðе удалоÑÑŒ Ñоздать C# проект." + +#~ msgid "Mono" +#~ msgstr "Моно" + +#~ msgid "About C# support" +#~ msgstr "О C# поддержке" + +#~ msgid "Create C# solution" +#~ msgstr "Создать C# решение" + +#~ msgid "Builds" +#~ msgstr "Билды" + +#~ msgid "Build Project" +#~ msgstr "Собрать проект" + +#~ msgid "View log" +#~ msgstr "ПроÑмотр журнала" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment необходим Environment реÑурÑ." + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "ПоиÑк клаÑÑов" + +#~ msgid "Update Always" +#~ msgstr "ОбновлÑть вÑегда" + +#~ msgid "Raw Mode" +#~ msgstr "RAW режим" #~ msgid "Path to Node:" #~ msgstr "Путь к Узлу:" @@ -12621,9 +12505,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Переключить видимоÑть Spatial" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Переключить видимоÑть CanvasItem" - #~ msgid "Condition" #~ msgstr "УÑловие" @@ -13563,9 +13444,6 @@ msgstr "" #~ msgid "Images:" #~ msgstr "ИзображениÑ:" -#~ msgid "Select None" -#~ msgstr "СброÑить выделение" - #~ msgid "Group" #~ msgstr "Группа" diff --git a/editor/translations/si.po b/editor/translations/si.po index b1f4ea0acd..3f62079f19 100644 --- a/editor/translations/si.po +++ b/editor/translations/si.po @@ -441,6 +441,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -616,6 +625,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -665,7 +678,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -769,6 +782,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -927,7 +944,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1291,7 +1308,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1462,6 +1479,10 @@ msgstr "" 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 "" @@ -1487,7 +1508,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1540,7 +1561,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1553,7 +1574,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1576,11 +1597,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2586,10 +2603,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2696,15 +2733,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "අඛණ්ඩව" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2894,7 +2932,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2992,20 +3030,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3490,6 +3528,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5077,6 +5116,13 @@ 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 "" @@ -5981,10 +6027,18 @@ msgid "Find Next" 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 "" @@ -6213,18 +6267,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7759,51 +7816,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7811,203 +7824,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9638,6 +9475,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9666,7 +9507,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9903,7 +9744,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10303,54 +10144,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10927,7 +10720,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10976,7 +10769,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10986,7 +10779,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11053,14 +10846,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11139,7 +10939,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11168,6 +10968,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11202,8 +11006,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11214,7 +11018,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11230,7 +11036,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11241,7 +11047,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11276,7 +11084,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11288,7 +11096,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11300,7 +11108,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11313,10 +11125,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11330,18 +11147,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11384,6 +11201,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/sk.po b/editor/translations/sk.po index 7a35e8905a..aeef25389e 100644 --- a/editor/translations/sk.po +++ b/editor/translations/sk.po @@ -7,12 +7,13 @@ # Zuzana Palenikova <sousana.is@gmail.com>, 2019. # MineGame159 <petulko08@gmail.com>, 2019. # Michal <alladinsiffon@gmail.com>, 2019. +# Richard <rgarlik@gmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" -"Last-Translator: Michal <alladinsiffon@gmail.com>\n" +"PO-Revision-Date: 2019-07-02 10:51+0000\n" +"Last-Translator: Richard <rgarlik@gmail.com>\n" "Language-Team: Slovak <https://hosted.weblate.org/projects/godot-engine/" "godot/sk/>\n" "Language: sk\n" @@ -20,7 +21,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -77,11 +78,11 @@ msgstr "Zrkadlový" #: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp msgid "Time:" -msgstr "" +msgstr "ÄŒas:" #: editor/animation_bezier_editor.cpp msgid "Value:" -msgstr "" +msgstr "Hodnota:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -96,9 +97,8 @@ msgid "Delete Selected Key(s)" msgstr "ZmazaÅ¥ kľúÄ(e)" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Add Bezier Point" -msgstr "Signály:" +msgstr "PridaÅ¥ Bezierov bod" #: editor/animation_bezier_editor.cpp msgid "Move Bezier Points" @@ -446,6 +446,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "VÅ¡etky vybrané" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -623,6 +633,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -672,7 +686,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -780,6 +794,11 @@ msgid "Connect" msgstr "PripojiÅ¥" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signály:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "PripojiÅ¥ '%s' k '%s'" @@ -946,7 +965,8 @@ msgid "Owners Of:" msgstr "Majitelia:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "OdstrániÅ¥ vybraté súbory z projektu? (nedá sa vrátiÅ¥ späť)" #: editor/dependency_editor.cpp @@ -1317,7 +1337,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1489,6 +1509,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1516,7 +1540,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1572,7 +1596,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1586,7 +1610,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "VytvoriÅ¥ adresár" #: editor/editor_feature_profile.cpp @@ -1609,12 +1633,9 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" -msgstr "" +#, fuzzy +msgid "Available Profiles:" +msgstr "Filter:" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2650,10 +2671,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2761,15 +2802,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "Priebežný" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2964,7 +3006,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3065,20 +3107,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3578,6 +3620,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp #, fuzzy msgid "Filter nodes" msgstr "Filter:" @@ -5203,6 +5246,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "UložiÅ¥ súbor" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6129,10 +6180,20 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filter:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Filter:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "" @@ -6368,18 +6429,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "VÅ¡etky vybrané" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7976,51 +8041,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8028,203 +8049,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9875,6 +9720,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9904,8 +9753,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "VytvoriÅ¥ adresár" #: editor/scene_tree_dock.cpp msgid "" @@ -10156,7 +10006,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10564,55 +10414,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Súbor:" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11205,7 +11006,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11258,8 +11059,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "Textúra s tvarom svetla musà maÅ¥ nastavenú vlastnosÅ¥ \"textúra\"." @@ -11271,7 +11073,7 @@ msgstr "" "prejavil." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11338,14 +11140,25 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 slúži iba na pridelenie kolÃzneho tvaru objektu vydedeného " +"z CollisionObject2D uzlu. ProsÃm, použite ho iba ako dieÅ¥a objektu Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, atÄ. aby ste im dali tvar." + #: scene/2d/visibility_notifier_2d.cpp msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11422,10 +11235,13 @@ 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!" +"shape resource for it." msgstr "" +"MusÃte nastaviÅ¥ tvar objektu CollisionShape2D aby fungoval. ProsÃm, vytvorte " +"preň tvarový objekt!" #: scene/3d/collision_shape.cpp msgid "" @@ -11453,6 +11269,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11487,8 +11307,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11499,7 +11319,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11515,7 +11337,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11526,7 +11348,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11562,7 +11386,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11574,7 +11398,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11586,7 +11410,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11599,10 +11427,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11616,18 +11449,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11671,6 +11504,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "Nesprávna veľkosÅ¥ pÃsma." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "Nesprávna veľkosÅ¥ pÃsma." @@ -11690,6 +11528,10 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "View log" +#~ msgstr "Súbor:" + #~ msgid "Path to Node:" #~ msgstr "Cesta k Node:" diff --git a/editor/translations/sl.po b/editor/translations/sl.po index 1e5ca2be9c..673ed15421 100644 --- a/editor/translations/sl.po +++ b/editor/translations/sl.po @@ -466,6 +466,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Izberi Gradnik" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -648,6 +658,10 @@ msgstr "Pojdi na Vrstico" msgid "Line Number:" msgstr "Å tevilka Vrste:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Ni Zadetkov" @@ -697,7 +711,7 @@ msgstr "Oddalji" msgid "Reset Zoom" msgstr "Ponastavi PoveÄavo/PomanjÅ¡avo" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -809,6 +823,11 @@ msgid "Connect" msgstr "Poveži" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signali:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Poveži '%s' v '%s'" @@ -979,7 +998,8 @@ msgid "Owners Of:" msgstr "Lastniki:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Odstranim izbrane datoteke iz projekta? (brez vrnitve)" #: editor/dependency_editor.cpp @@ -1355,7 +1375,7 @@ msgstr "Neveljavno ime. Ne sme se prekrivati z obstojeÄim imenom razreda." #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" "Neveljavno ime. Ne sme se prekrivati z obstojeÄim vgrajenim imenom tipa." @@ -1532,6 +1552,10 @@ msgstr "" msgid "Template file not found:" msgstr "Predloge ni mogoÄe najti:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1563,7 +1587,7 @@ msgstr "NaÄin Premika" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "DatoteÄniSistem" #: editor/editor_feature_profile.cpp @@ -1624,7 +1648,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1639,7 +1663,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Trenutna RazliÄica:" #: editor/editor_feature_profile.cpp @@ -1664,16 +1688,11 @@ msgstr "Izvozi" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "Na voljo Nodes:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "IÅ¡Äi Razrede" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "Opis" @@ -2781,11 +2800,35 @@ msgid "Editor Layout" msgstr "Postavitev Urejevalnika" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Shrani Prizor" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Nastavitve Urejevalnika" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Odpri naslednji Urejevalnik" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Preklopi na Celozaslonski NaÄin" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "Preklopi NaÄin" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "Nastavitve Urejevalnika" @@ -2896,15 +2939,18 @@ msgid "Spins when the editor window redraws." msgstr "Vrti se ob spremembi okna urejevalnika!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Posodobi Vedno" +#, fuzzy +msgid "Update Continuously" +msgstr "Neprekinjeno" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Posodobi Spremembe" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "OnemogoÄi Posodobitve Kolesca" #: editor/editor_node.cpp @@ -3099,7 +3145,7 @@ msgstr "ÄŒas" msgid "Calls" msgstr "Klici" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3199,6 +3245,11 @@ 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 #, fuzzy msgid "New Key:" msgstr "Novo ime:" @@ -3212,11 +3263,6 @@ msgstr "Novo ime:" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3741,6 +3787,7 @@ msgid "Nodes not in Group" msgstr "Dodaj v Skupino" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5433,6 +5480,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "Znova Zaženi (s):" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6370,10 +6425,20 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Lastnosti objekta." + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Lastnosti objekta." + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "" @@ -6613,18 +6678,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "IzbriÅ¡i toÄke" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -8251,51 +8320,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8304,203 +8329,27 @@ msgid "Input parameter." msgstr "Pripni na Predhodnika" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10171,6 +10020,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "SkrÄi vse" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10201,8 +10055,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Ustvari Nov %s" #: editor/scene_tree_dock.cpp msgid "" @@ -10457,7 +10312,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10867,55 +10722,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Ogled datotek" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11513,8 +11319,9 @@ 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 " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Vir SpriteFrame mora biti ustvarjen ali nastavljen v 'Frames' lastnosti z " @@ -11575,7 +11382,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11585,7 +11392,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11652,14 +11459,26 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 služi le, da zagotavlja collision obliko nodu " +"CollisionObject2D, ki izhaja iz njega. NaproÅ¡amo vas, da ga uporabite le kot " +"otroka od Area2D, StaticBody2D, RigidBody2D, KinematicBody2D, etc. da jim " +"date obliko." + #: scene/2d/visibility_notifier_2d.cpp msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11738,7 +11557,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11767,6 +11586,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11801,8 +11624,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11813,7 +11636,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11828,10 +11653,13 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" +"Vir SpriteFrame mora biti ustvarjen ali nastavljen v 'Frames' lastnosti z " +"namenom, da AnimatedSprite prikaže sliÄice." #: scene/3d/vehicle_body.cpp msgid "" @@ -11840,7 +11668,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11878,7 +11708,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Odklopite '%s' iz '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11893,7 +11723,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "Drevo animacije ni veljavno." #: scene/animation/animation_tree_player.cpp @@ -11905,8 +11735,12 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Neobdelan naÄin" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11919,10 +11753,15 @@ msgstr "Dodaj trenutno barvo kot prednastavljeno" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11934,23 +11773,24 @@ msgid "Please Confirm..." msgstr "Prosimo Potrdite..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Pojavna okna se bodo po privzeti nastavitvi skrila, razen ob klicu popup() " "ali katerih izmed popup*() funkcij. Spreminjanje vidnosti za urejanje je " "sprejemljivo, vendar se bodo ob zagonu skrila." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11994,6 +11834,11 @@ msgid "Input" msgstr "Dodaj Vnos" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Neveljaven vir za shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Neveljaven vir za shader." @@ -12013,6 +11858,20 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "View log" +#~ msgstr "Ogled datotek" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "IÅ¡Äi Razrede" + +#~ msgid "Update Always" +#~ msgstr "Posodobi Vedno" + +#~ msgid "Raw Mode" +#~ msgstr "Neobdelan naÄin" + #~ msgid "Path to Node:" #~ msgstr "Pot do Gradnika:" diff --git a/editor/translations/sq.po b/editor/translations/sq.po index b6db8eed22..f798e780cb 100644 --- a/editor/translations/sq.po +++ b/editor/translations/sq.po @@ -432,6 +432,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Zgjidh" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -606,6 +616,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -655,7 +669,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -763,6 +777,11 @@ msgid "Connect" msgstr "Lidh" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Sinjalet:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Lidh '%s' me '%s'" @@ -929,7 +948,8 @@ msgid "Owners Of:" msgstr "Pronarët e:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Hiq skedarët e zgjedhur nga projekti? (pa kthim pas)" #: editor/dependency_editor.cpp @@ -1305,7 +1325,7 @@ msgstr "" #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "Emër i palejuar. Nuk duhet të përplaset me emrin e një tipi 'buit-in'." #: editor/editor_autoload_settings.cpp @@ -1488,6 +1508,10 @@ msgstr "Shablloni 'Custom release' nuk u gjet." msgid "Template file not found:" msgstr "Skedari shabllon nuk u gjet:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1519,7 +1543,7 @@ msgstr "Nyje" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "FileSystem" #: editor/editor_feature_profile.cpp @@ -1578,7 +1602,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1593,7 +1617,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Versioni Aktual:" #: editor/editor_feature_profile.cpp @@ -1617,12 +1641,9 @@ msgid "Export" msgstr "Eksporto" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" -msgstr "" +#, fuzzy +msgid "Available Profiles:" +msgstr "Vetitë:" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2712,10 +2733,33 @@ msgid "Editor Layout" msgstr "Faqosja e Editorit" #: editor/editor_node.cpp +msgid "Take Screenshot" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Hap Folderin e Editorit për të Dhënat/Opsionet" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Hap Editorin tjetër" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Ndrysho Ekranin e Plotë" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Ndrysho metodën e ndarjes" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Hap Folderin e Editorit për të Dhënat/Opsionet" @@ -2823,15 +2867,18 @@ msgid "Spins when the editor window redraws." msgstr "Rrotullohet kur dritarja e editorit rivizaton." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Përditëso Gjithmonë" +#, fuzzy +msgid "Update Continuously" +msgstr "I Vazhdueshëm" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Përditëso Ndryshimet" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Çaktivizo Rrotulluesin e Përditësimit" #: editor/editor_node.cpp @@ -3023,7 +3070,7 @@ msgstr "Koha" msgid "Calls" msgstr "Thërritjet" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Mbi" @@ -3130,6 +3177,11 @@ msgid "Page: " msgstr "Faqja: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Hiq Artikullin" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Çelës i Ri:" @@ -3141,11 +3193,6 @@ msgstr "Vlerë e Re:" msgid "Add Key/Value Pair" msgstr "Shto Palë Çelës/Vlerë" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Hiq Artikullin" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3653,6 +3700,7 @@ msgid "Nodes not in Group" msgstr "Nyjet që nuk janë në Grup" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Nyjet filtruese" @@ -5244,6 +5292,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "Ruaj & Rifillo" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6149,10 +6205,20 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filtro vetitë." + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Nyjet filtruese" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "" @@ -6383,18 +6449,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Krijo pika." #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7940,51 +8010,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7992,203 +8018,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9824,6 +9674,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Mbyll të Gjitha" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9852,8 +9707,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Krijo një Folder" #: editor/scene_tree_dock.cpp msgid "" @@ -10099,7 +9955,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10501,54 +10357,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11125,7 +10933,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11174,7 +10982,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11184,7 +10992,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11251,14 +11059,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11337,7 +11152,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11366,6 +11181,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11400,8 +11219,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11412,7 +11231,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11428,7 +11249,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11439,7 +11260,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11474,7 +11297,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11486,7 +11309,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11498,7 +11321,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11511,10 +11338,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11528,18 +11360,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11582,6 +11414,10 @@ msgid "Input" 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 "" @@ -11601,6 +11437,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Update Always" +#~ msgstr "Përditëso Gjithmonë" + #~ msgid "Delete selected files?" #~ msgstr "Fshi skedarët e zgjedhur?" diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po index 19e6536f86..024f536ebd 100644 --- a/editor/translations/sr_Cyrl.po +++ b/editor/translations/sr_Cyrl.po @@ -465,6 +465,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Одабери Ñве" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Одабери режим" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -647,6 +657,10 @@ msgstr "Иди на линију" msgid "Line Number:" msgstr "Број линије:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Ðема подудара" @@ -696,7 +710,7 @@ msgstr "Умањи" msgid "Reset Zoom" msgstr "РеÑетуј увеличање" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -809,6 +823,11 @@ msgid "Connect" msgstr "Повежи" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Сигнали:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Повежи '%s' Ñа '%s'" @@ -982,7 +1001,8 @@ msgid "Owners Of:" msgstr "ВлаÑници:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Обриши одабране датотеке из пројекта? (ÐЕМРОПОЗИВÐЊÐ)" #: editor/dependency_editor.cpp @@ -1361,7 +1381,7 @@ msgstr "Ðеважеће име. Име је резервиÑано за поÑÑ #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "Ðеважеће име. Име је резервиÑано за поÑтојећи уграђени тип." #: editor/editor_autoload_settings.cpp @@ -1538,6 +1558,10 @@ msgstr "" msgid "Template file not found:" msgstr "ШаблонÑка датотека није пронађена:\n" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1569,7 +1593,7 @@ msgstr "Режим померања" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "Датотечни ÑиÑтем" #: editor/editor_feature_profile.cpp @@ -1631,7 +1655,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1646,7 +1670,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Тренутна верзија:" #: editor/editor_feature_profile.cpp @@ -1670,13 +1694,9 @@ msgid "Export" msgstr "Извоз" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Потражи клаÑе" +msgid "Available Profiles:" +msgstr "ОÑобине" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2793,11 +2813,35 @@ msgid "Editor Layout" msgstr "РаÑпоред уредника" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Сачувај Ñцену" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "ПоÑтавке уредника" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Отвори Ñледећи уредник" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Укљ./ИÑкљ. режим целог екрана" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "Промени режим" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "ПоÑтавке уредника" @@ -2908,15 +2952,18 @@ msgid "Spins when the editor window redraws." msgstr "Окрене Ñе кад Ñе едиторÑки прозор поново обоји!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Увек ажурирај" +#, fuzzy +msgid "Update Continuously" +msgstr "Трајан" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "Ðжурирај промене" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "ИÑкључи индикатор ажурирања" #: editor/editor_node.cpp @@ -3113,7 +3160,7 @@ msgstr "Време:" msgid "Calls" msgstr "Позиви цртања" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3214,6 +3261,11 @@ 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 #, fuzzy msgid "New Key:" msgstr "Ðово име:" @@ -3227,11 +3279,6 @@ msgstr "Ðово име:" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Обриши Ñтавку" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3767,6 +3814,7 @@ msgid "Nodes not in Group" msgstr "Додај у групу" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5455,6 +5503,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "РеÑтартовање (Ñек.):" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "ОчиÑти маÑку емиÑије" @@ -6409,10 +6465,20 @@ msgid "Find Next" msgstr "Тражи Ñледећи" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 +#, fuzzy +msgid "Filter methods" +msgstr "ПоÑтавке објекта." + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Сортирање" @@ -6659,20 +6725,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +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 "Обриши линију" @@ -8343,51 +8413,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8396,203 +8422,27 @@ msgid "Input parameter." msgstr "Лепи за родитеља" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10285,6 +10135,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Умањи Ñве" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10315,8 +10170,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Ðаправи нов" #: editor/scene_tree_dock.cpp msgid "" @@ -10570,7 +10426,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10984,62 +10840,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Generating solution..." -msgstr "Прављење контура..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "ÐеуÑпех при прављењу ивица!" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to save solution." -msgstr "Грешка при учитавању реÑурÑа." - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Done" -msgstr "Готово!" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create C# project." -msgstr "Грешка при учитавању реÑурÑа." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "Ðаправи ивице" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "Пројекат" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Погледај датотеке" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11633,7 +11433,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11682,7 +11482,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11692,7 +11492,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11759,14 +11559,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11845,7 +11652,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11874,6 +11681,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11908,8 +11719,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11920,7 +11731,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11936,7 +11749,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11947,7 +11760,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11985,7 +11800,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Повежи '%s' Ñа '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11999,7 +11814,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "Ðнимационо дрво није важеће." #: scene/animation/animation_tree_player.cpp @@ -12011,7 +11826,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -12024,10 +11843,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -12041,18 +11865,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -12097,6 +11921,11 @@ msgstr "Додај улаз" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "Ðеважећа величина фонта." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "Ðеважећа величина фонта." @@ -12116,6 +11945,45 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Generating solution..." +#~ msgstr "Прављење контура..." + +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "ÐеуÑпех при прављењу ивица!" + +#, fuzzy +#~ msgid "Failed to save solution." +#~ msgstr "Грешка при учитавању реÑурÑа." + +#, fuzzy +#~ msgid "Done" +#~ msgstr "Готово!" + +#, fuzzy +#~ msgid "Failed to create C# project." +#~ msgstr "Грешка при учитавању реÑурÑа." + +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "Ðаправи ивице" + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "Пројекат" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "Погледај датотеке" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Потражи клаÑе" + +#~ msgid "Update Always" +#~ msgstr "Увек ажурирај" + #~ msgid "Path to Node:" #~ msgstr "Пут ка чвору:" diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po index b4089a1d5a..8478d11a8f 100644 --- a/editor/translations/sr_Latn.po +++ b/editor/translations/sr_Latn.po @@ -447,6 +447,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Uduplaj Selekciju" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -625,6 +635,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -674,7 +688,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -777,6 +791,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -936,7 +954,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1300,7 +1318,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1471,6 +1489,10 @@ msgstr "" 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 "" @@ -1496,7 +1518,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1550,7 +1572,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1563,7 +1585,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1586,11 +1608,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2598,10 +2616,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2708,15 +2746,16 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "Neprekidna" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2906,7 +2945,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3004,20 +3043,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3502,6 +3541,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5100,6 +5140,13 @@ 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 "" @@ -6010,10 +6057,18 @@ msgid "Find Next" 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 "" @@ -6242,18 +6297,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr "Napravi" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7817,51 +7876,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7869,203 +7884,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9702,6 +9541,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9730,8 +9573,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Napravi" #: editor/scene_tree_dock.cpp msgid "" @@ -9968,7 +9812,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10371,54 +10215,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10995,7 +10791,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11044,7 +10840,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11054,7 +10850,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11121,14 +10917,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11207,7 +11010,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11236,6 +11039,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11270,8 +11077,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11282,7 +11089,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11298,7 +11107,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11309,7 +11118,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11344,7 +11155,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11356,7 +11167,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11368,7 +11179,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11381,10 +11196,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11398,18 +11218,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11452,6 +11272,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/sv.po b/editor/translations/sv.po index e746cdadcc..0b7ff433c9 100644 --- a/editor/translations/sv.po +++ b/editor/translations/sv.po @@ -455,6 +455,17 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +#, fuzzy +msgid "Select All" +msgstr "Välj Alla" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Välj Node" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -650,6 +661,10 @@ msgstr "GÃ¥ till Rad" msgid "Line Number:" msgstr "Radnummer:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp #, fuzzy msgid "No Matches" @@ -702,7 +717,7 @@ msgstr "Zooma Ut" msgid "Reset Zoom" msgstr "Ã…terställ Zoom" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp #, fuzzy msgid "Warnings" msgstr "Varning" @@ -818,6 +833,11 @@ msgid "Connect" msgstr "Anslut" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Signaler:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Anslut '%s' till '%s'" @@ -1004,7 +1024,8 @@ msgid "Owners Of:" msgstr "Ägare av:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Ta bort valda filer frÃ¥n projektet? (gÃ¥r inte Ã¥ngra)" #: editor/dependency_editor.cpp @@ -1445,7 +1466,7 @@ msgstr "" #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "Ogiltigt namn. FÃ¥r inte vara samma som ett befintligt inbyggt typnamn." #: editor/editor_autoload_settings.cpp @@ -1638,6 +1659,10 @@ msgstr "" msgid "Template file not found:" msgstr "Mallfil hittades inte:\n" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1669,7 +1694,7 @@ msgid "Node Dock" msgstr "Node Namn:" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1729,7 +1754,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1744,7 +1769,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Nuvarande Version:" #: editor/editor_feature_profile.cpp @@ -1769,16 +1794,11 @@ msgstr "Exportera" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "Tillgängliga Noder:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Sök Klasser" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "Beskrivning" @@ -2964,10 +2984,32 @@ msgid "Editor Layout" msgstr "" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Vettigt!" + +#: editor/editor_node.cpp +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +msgstr "" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Växla Läge" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "" @@ -3080,16 +3122,16 @@ msgstr "" #: editor/editor_node.cpp #, fuzzy -msgid "Update Always" -msgstr "Uppdatera Alltid" +msgid "Update Continuously" +msgstr "Kontinuerlig" #: editor/editor_node.cpp #, fuzzy -msgid "Update Changes" +msgid "Update When Changed" msgstr "Uppdatera Ändringar" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -3289,7 +3331,7 @@ msgstr "Tid:" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp #, fuzzy msgid "On" msgstr "PÃ¥" @@ -3392,6 +3434,11 @@ 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 #, fuzzy msgid "New Key:" msgstr "Nytt namn:" @@ -3405,11 +3452,6 @@ msgstr "Nytt namn:" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3959,6 +4001,7 @@ msgid "Nodes not in Group" msgstr "Lägg till i Grupp" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Filtrera noder" @@ -5657,6 +5700,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "Starta om nu" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6609,11 +6660,21 @@ msgid "Find Next" msgstr "Hitta Nästa" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Filtrera noder" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp #, fuzzy +msgid "Filter methods" +msgstr "Filtrera noder" + +#: editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Sort" msgstr "Sortera" @@ -6867,21 +6928,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp +#: editor/plugins/script_text_editor.cpp #, fuzzy -msgid "Cut" -msgstr "Klipp" +msgid "Breakpoints" +msgstr "Radera punkter" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp #, fuzzy -msgid "Select All" -msgstr "Välj Alla" +msgid "Cut" +msgstr "Klipp" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -8548,51 +8612,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8600,203 +8620,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10529,6 +10373,11 @@ msgstr "Lägg till Barn-Node" #: editor/scene_tree_dock.cpp #, fuzzy +msgid "Expand/Collapse All" +msgstr "Stäng Alla" + +#: editor/scene_tree_dock.cpp +#, fuzzy msgid "Change Type" msgstr "Ändra Typ" @@ -10561,7 +10410,7 @@ msgstr "" #: editor/scene_tree_dock.cpp #, fuzzy -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "Lägga till/Skapa en Ny Node" #: editor/scene_tree_dock.cpp @@ -10827,7 +10676,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp #, fuzzy msgid "Errors" msgstr "Fel" @@ -11255,62 +11104,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Generating solution..." -msgstr "Skapar konturer..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "Misslyckades att ladda resurs." - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to save solution." -msgstr "Misslyckades att ladda resurs." - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Done" -msgstr "Klar!" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create C# project." -msgstr "Misslyckades att ladda resurs." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "Skapa Prenumeration" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "Projekt" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Visa Filer" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11922,7 +11715,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11980,7 +11773,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11990,7 +11783,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -12067,14 +11860,25 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 tjänar bara till att ge en kollisionsform till en " +"CollisionObject2D-härledd nod. Använd endast det som ett barn till Area2D, " +"StaticBody2D, RigidBody2D, KinematicBody2D, etc. för att ge dem en form." + #: scene/2d/visibility_notifier_2d.cpp msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -12163,7 +11967,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -12192,6 +11996,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -12228,8 +12036,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -12240,8 +12048,12 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" +"Sökvägs-egenskapen mÃ¥ste peka pÃ¥ en giltigt Node2D Node för att fungera." #: scene/3d/soft_body.cpp msgid "This body will be ignored until you set a mesh." @@ -12256,7 +12068,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -12267,7 +12079,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -12305,7 +12119,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Anslut '%s' till '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -12318,7 +12132,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -12330,9 +12144,12 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -#, fuzzy -msgid "Raw Mode" -msgstr "Raw-Läge" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -12345,10 +12162,15 @@ msgstr "Lägg till nuvarande färg som en förinställning" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -12364,18 +12186,18 @@ msgstr "Vänligen Bekräfta..." #: 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -12423,6 +12245,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "Ogiltig teckenstorlek." + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "Ogiltig teckenstorlek." @@ -12443,6 +12270,50 @@ msgid "Constants cannot be modified." msgstr "" #, fuzzy +#~ msgid "Generating solution..." +#~ msgstr "Skapar konturer..." + +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "Misslyckades att ladda resurs." + +#, fuzzy +#~ msgid "Failed to save solution." +#~ msgstr "Misslyckades att ladda resurs." + +#, fuzzy +#~ msgid "Done" +#~ msgstr "Klar!" + +#, fuzzy +#~ msgid "Failed to create C# project." +#~ msgstr "Misslyckades att ladda resurs." + +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "Skapa Prenumeration" + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "Projekt" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "Visa Filer" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Sök Klasser" + +#, fuzzy +#~ msgid "Update Always" +#~ msgstr "Uppdatera Alltid" + +#, fuzzy +#~ msgid "Raw Mode" +#~ msgstr "Raw-Läge" + +#, fuzzy #~ msgid "Path to Node:" #~ msgstr "Sökväg till Node:" diff --git a/editor/translations/ta.po b/editor/translations/ta.po index 614ba6f47c..2aad1e09d7 100644 --- a/editor/translations/ta.po +++ b/editor/translations/ta.po @@ -440,6 +440,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "அனைதà¯à®¤à¯ தேரà¯à®µà¯à®•ளà¯" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -616,6 +626,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -665,7 +679,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -768,6 +782,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -927,7 +945,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1291,7 +1309,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1462,6 +1480,10 @@ msgstr "" 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 "" @@ -1487,7 +1509,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1541,7 +1563,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1554,7 +1576,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1577,11 +1599,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2588,10 +2606,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2698,15 +2736,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2896,7 +2934,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2994,20 +3032,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3493,6 +3531,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5084,6 +5123,13 @@ 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 "" @@ -5988,10 +6034,18 @@ msgid "Find Next" 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 "" @@ -6219,18 +6273,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7763,51 +7820,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7815,203 +7828,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9642,6 +9479,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9670,7 +9511,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9908,7 +9749,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10311,54 +10152,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10935,7 +10728,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10984,7 +10777,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10994,7 +10787,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11061,14 +10854,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11147,7 +10947,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11176,6 +10976,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11210,8 +11014,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11222,7 +11026,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11238,7 +11044,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11249,7 +11055,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11284,7 +11092,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11296,7 +11104,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11308,7 +11116,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11321,10 +11133,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11338,18 +11155,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11392,6 +11209,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/te.po b/editor/translations/te.po index 5f79e35f08..8d9b4c87f2 100644 --- a/editor/translations/te.po +++ b/editor/translations/te.po @@ -30,7 +30,7 @@ msgstr "డీకోడింగౠబైటà±à°²à± కోసం తగిన #: core/math/expression.cpp #, fuzzy msgid "Invalid input %i (not passed) in expression" -msgstr "à°µà±à°¯à°•à±à°¤à±€à°•రణలో చెలà±à°²à°¨à°¿ ఇనà±à°ªà±à°Ÿà±% i (ఆమోదించబడలేదà±)" +msgstr "à°µà±à°¯à°•à±à°¤à±€à°•రణలో చెలà±à°²à°¨à°¿ ఇనà±à°ªà±à°Ÿà± %i (ఆమోదించబడలేదà±)" #: core/math/expression.cpp #, fuzzy @@ -427,6 +427,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -601,6 +610,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -650,7 +663,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -753,6 +766,10 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +msgid "Signal:" +msgstr "" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -911,7 +928,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1275,7 +1292,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1446,6 +1463,10 @@ msgstr "" 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 "" @@ -1471,7 +1492,7 @@ msgid "Node Dock" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1524,7 +1545,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1537,7 +1558,7 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" +msgid "Current Profile:" msgstr "" #: editor/editor_feature_profile.cpp @@ -1560,11 +1581,7 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" +msgid "Available Profiles:" msgstr "" #: editor/editor_feature_profile.cpp @@ -2570,10 +2587,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2680,15 +2717,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2878,7 +2915,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -2976,20 +3013,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3474,6 +3511,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5053,6 +5091,13 @@ 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 "" @@ -5953,10 +5998,18 @@ msgid "Find Next" 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 "" @@ -6184,18 +6237,21 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" +#: editor/plugins/script_text_editor.cpp +msgid "Breakpoints" msgstr "" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7715,51 +7771,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7767,203 +7779,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9590,6 +9426,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9618,7 +9458,7 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +msgid "Add/Create a New Node." msgstr "" #: editor/scene_tree_dock.cpp @@ -9855,7 +9695,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10255,54 +10095,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -10879,7 +10671,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -10928,7 +10720,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -10938,7 +10730,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11005,14 +10797,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11091,7 +10890,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11120,6 +10919,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11154,8 +10957,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11166,7 +10969,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11182,7 +10987,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11193,7 +10998,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11228,7 +11035,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11240,7 +11047,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11252,7 +11059,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11265,10 +11076,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11282,18 +11098,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11336,6 +11152,10 @@ msgid "Input" 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 "" diff --git a/editor/translations/th.po b/editor/translations/th.po index 0407a59452..2675f9b850 100644 --- a/editor/translations/th.po +++ b/editor/translations/th.po @@ -471,6 +471,15 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "เลืà¸à¸à¸—ั้งหมด" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "ไม่เลืà¸à¸" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -653,6 +662,10 @@ msgstr "ไปยังบรรทัด" msgid "Line Number:" msgstr "บรรทัดที่:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "ไม่พบ" @@ -702,7 +715,7 @@ msgstr "ย่à¸" msgid "Reset Zoom" msgstr "รีเซ็ตซูม" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "คำเตืà¸à¸™" @@ -813,6 +826,11 @@ msgid "Connect" msgstr "เชื่à¸à¸¡" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "สัà¸à¸à¸²à¸“:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "เชื่à¸à¸¡ '%s' à¸à¸±à¸š '%s'" @@ -984,7 +1002,8 @@ msgid "Owners Of:" msgstr "เจ้าขà¸à¸‡à¸‚à¸à¸‡:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "ลบไฟล์ที่เลืà¸à¸à¸à¸à¸à¸ˆà¸²à¸à¹‚ปรเจà¸à¸•์? (ย้à¸à¸™à¸à¸¥à¸±à¸šà¹„ม่ได้)" #: editor/dependency_editor.cpp @@ -1359,7 +1378,7 @@ msgstr "ชื่à¸à¸œà¸´à¸”พลาด ต้à¸à¸‡à¹„ม่ใช้ชื๠#: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "ชื่à¸à¸œà¸´à¸”พลาด ต้à¸à¸‡à¹„ม่ใช้ชื่à¸à¹€à¸”ียวà¸à¸±à¸šà¸Šà¸™à¸´à¸”ตัวà¹à¸›à¸£" #: editor/editor_autoload_settings.cpp @@ -1538,6 +1557,10 @@ msgstr "ไม่พบà¹à¸žà¸„เà¸à¸ˆà¸ˆà¸³à¸«à¸™à¹ˆà¸²à¸¢à¸—ี่à¸à¸³à¸« 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 #, fuzzy msgid "3D Editor" @@ -1570,7 +1593,7 @@ msgstr "โหมดเคลื่à¸à¸™à¸¢à¹‰à¸²à¸¢" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "ระบบไฟล์" #: editor/editor_feature_profile.cpp @@ -1632,7 +1655,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1647,7 +1670,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "รุ่นปัจจุบัน:" #: editor/editor_feature_profile.cpp @@ -1672,16 +1695,11 @@ msgstr "ส่งà¸à¸à¸" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "โหนดที่มีให้ใช้:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "ค้นหาคลาส" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "รายละเà¸à¸µà¸¢à¸”" @@ -2760,11 +2778,35 @@ msgid "Editor Layout" msgstr "เลย์เà¸à¸²à¸•์โปรà¹à¸à¸£à¸¡" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "เข้าใจ!" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "ตัวเลืà¸à¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "เปิดตัวà¹à¸à¹‰à¹„ขถัดไป" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "สลับเต็มจà¸" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "ซ่à¸à¸™/à¹à¸ªà¸”งโหนด CanvasItem" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "ตัวเลืà¸à¸à¹‚ปรà¹à¸à¸£à¸¡à¸ªà¸£à¹‰à¸²à¸‡à¹€à¸à¸¡" @@ -2875,15 +2917,18 @@ msgid "Spins when the editor window redraws." msgstr "หมุนเมื่à¸à¸¡à¸µà¸à¸²à¸£à¸§à¸²à¸”หน้าต่างโปรà¹à¸à¸£à¸¡à¹ƒà¸«à¸¡à¹ˆ!" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "à¸à¸±à¸žà¹€à¸”ทตลà¸à¸”เวลา" +#, fuzzy +msgid "Update Continuously" +msgstr "ต่à¸à¹€à¸™à¸·à¹ˆà¸à¸‡" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "à¸à¸±à¸žà¹€à¸”ทเมื่à¸à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "ปิดà¸à¸²à¸£à¸à¸±à¸žà¹€à¸”ทตัวหมุน" #: editor/editor_node.cpp @@ -3078,7 +3123,7 @@ msgstr "เวลา" msgid "Calls" msgstr "จำนวนครั้ง" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "เปิด" @@ -3181,6 +3226,11 @@ 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 #, fuzzy msgid "New Key:" msgstr "ชื่à¸à¹ƒà¸«à¸¡à¹ˆ:" @@ -3194,11 +3244,6 @@ msgstr "ชื่à¸à¹ƒà¸«à¸¡à¹ˆ:" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "ลบไà¸à¹€à¸—ม" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3716,6 +3761,7 @@ msgid "Nodes not in Group" msgstr "เพิ่มไปยังà¸à¸¥à¸¸à¹ˆà¸¡" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "ตัวà¸à¸£à¸à¸‡" @@ -5411,6 +5457,14 @@ msgid "Load Emission Mask" msgstr "โหลด Mask à¸à¸²à¸£à¸›à¸°à¸—ุ" #: 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 +#, fuzzy +msgid "Restart" +msgstr "เริ่มใหม่ทันที" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "ลบ Mask à¸à¸²à¸£à¸›à¸¥à¹ˆà¸à¸¢" @@ -6359,10 +6413,20 @@ msgid "Find Next" msgstr "ค้นหาต่à¸à¹„ป" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 +#, fuzzy +msgid "Filter methods" +msgstr "โหมดà¸à¸²à¸£à¸à¸£à¸à¸‡:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "เรียง" @@ -6606,20 +6670,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +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 "ลบบรรทัด" @@ -8286,51 +8354,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8339,203 +8363,27 @@ msgid "Input parameter." msgstr "จำà¸à¸±à¸”ด้วยโหนดà¹à¸¡à¹ˆ" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10239,6 +10087,11 @@ msgid "Add Child Node" msgstr "เพิ่มโหนดลูà¸" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "ยุบโฟลเดà¸à¸£à¹Œ" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "เปลี่ยนประเภท" @@ -10269,7 +10122,8 @@ msgid "Delete (No Confirm)" msgstr "ลบ (ไม่ยืนยัน)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "เพิ่ม/สร้างโหนดใหม่" #: editor/scene_tree_dock.cpp @@ -10541,7 +10395,7 @@ msgstr "สà¹à¸•ค" msgid "Pick one or more items from the list to display the graph." msgstr "เลืà¸à¸à¸‚้à¸à¸¡à¸¹à¸¥à¸ˆà¸²à¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸à¹€à¸žà¸·à¹ˆà¸à¹à¸ªà¸”งà¸à¸£à¸²à¸Ÿ" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "ข้à¸à¸œà¸´à¸”พลาด" @@ -10956,55 +10810,6 @@ msgstr "ระยะà¸à¸²à¸£à¹€à¸¥à¸·à¸à¸:" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ solution..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡à¹‚ปรเจà¸à¸•์ C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "ผิดพลาดในà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡ solution" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "ผิดพลาดในà¸à¸²à¸£à¸šà¸±à¸™à¸—ึภsolution" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "เสร็จสิ้น" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "ผิดพลาดในà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹‚ปรเจà¸à¸•์ C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "โมโน" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "เà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸à¸²à¸£à¸ªà¸™à¸±à¸šà¸ªà¸™à¸¸à¸™ C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "สร้าง C# solution" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "สร้าง" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Build โปรเจà¸à¸•์" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "ดูไฟล์" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "สิ้นสุดสà¹à¸•คข้à¸à¸œà¸´à¸”พลาดภายใน" @@ -11591,8 +11396,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "ขนาดรูปหน้าจà¸à¹€à¸£à¸´à¹ˆà¸¡à¹‚ปรà¹à¸à¸£à¸¡à¸œà¸´à¸”พลาด (ต้à¸à¸‡à¹€à¸›à¹‡à¸™ 620x300)" #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "ต้à¸à¸‡à¸¡à¸µ SpriteFrames ใน 'Frames' เพื่à¸à¹ƒà¸«à¹‰ AnimatedSprite à¹à¸ªà¸”งผลได้" @@ -11651,8 +11457,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "ต้à¸à¸‡à¸¡à¸µà¸£à¸¹à¸›à¸£à¹ˆà¸²à¸‡à¸‚à¸à¸‡à¹à¸ªà¸‡à¸à¸¢à¸¹à¹ˆà¹ƒà¸™ 'texture'" @@ -11662,7 +11469,8 @@ msgid "" msgstr "ต้à¸à¸‡à¸¡à¸µà¸£à¸¹à¸›à¸«à¸¥à¸²à¸¢à¹€à¸«à¸¥à¸µà¹ˆà¸¢à¸¡à¹€à¸žà¸·à¹ˆà¸à¹ƒà¸«à¹‰à¸•ัวบังà¹à¸ªà¸‡à¸™à¸µà¹‰à¸—ำงานได้" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "รูปหลายเหลี่ยมขà¸à¸‡à¸•ัวบังà¹à¸ªà¸‡à¸™à¸µà¹‰à¸§à¹ˆà¸²à¸‡à¹€à¸›à¸¥à¹ˆà¸² à¸à¸£à¸¸à¸“าวาดรูปหลายเหลี่ยม!" #: scene/2d/navigation_polygon.cpp @@ -11734,14 +11542,27 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 ฯลฯ " +"เพื่à¸à¹ƒà¸«à¹‰à¸¡à¸µà¸£à¸¹à¸›à¸—รง" + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "VisibilityEnable2D ควรจะเป็นโหนดลูà¸à¸‚à¸à¸‡à¹‚หนดหลัà¸à¹ƒà¸™à¸‰à¸²à¸à¸™à¸µà¹‰" #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera ต้à¸à¸‡à¸¡à¸µ ARVROrigin เป็นโหนดà¹à¸¡à¹ˆ" #: scene/3d/arvr_nodes.cpp @@ -11830,9 +11651,10 @@ msgstr "" "Area, StaticBody, RigidBody, KinematicBody ฯลฯ เพื่à¸à¹ƒà¸«à¹‰à¸¡à¸µà¸£à¸¹à¸›à¸—รง" #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "ต้à¸à¸‡à¸¡à¸µà¸£à¸¹à¸›à¸—รงเพื่à¸à¹ƒà¸«à¹‰ CollisionShape ทำงานได้ à¸à¸£à¸¸à¸“าสร้างรูปทรง!" #: scene/3d/collision_shape.cpp @@ -11862,6 +11684,10 @@ msgid "" "Use a BakedLightmap instead." 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 "ต้à¸à¸‡à¸¡à¸µ NavigationMesh เพื่à¸à¹ƒà¸«à¹‰à¹‚หนดนี้ทำงานได้" @@ -11899,8 +11725,8 @@ msgstr "PathFollow2D จะทำงานได้ต้à¸à¸‡à¹€à¸›à¹‡à¸™à¹‚ภ#: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11913,7 +11739,10 @@ msgstr "" "à¸à¸£à¸¸à¸“าปรับขนาดขà¸à¸‡ Collision shape à¹à¸—น" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "ต้à¸à¸‡à¹à¸à¹‰à¹„ข Path ให้ชี้ไปยังโหนด Spatial จึงจะทำงานได้" #: scene/3d/soft_body.cpp @@ -11931,8 +11760,9 @@ msgstr "" "à¸à¸£à¸¸à¸“าปรับขนาดขà¸à¸‡ Collision shape à¹à¸—น" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "ต้à¸à¸‡à¸¡à¸µ SpriteFrames ใน 'Frames' เพื่à¸à¹ƒà¸«à¹‰ AnimatedSprite3D à¹à¸ªà¸”งผลได้" @@ -11943,7 +11773,9 @@ msgid "" msgstr "VehicleWheel เป็นระบบล้à¸à¸‚à¸à¸‡ VehicleBody à¸à¸£à¸¸à¸“าใช้เป็นโหนดลูà¸à¸‚à¸à¸‡ VehicleBody" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11981,7 +11813,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "ลบà¸à¸²à¸£à¹€à¸Šà¸·à¹ˆà¸à¸¡à¹‚ยง '%s' à¸à¸±à¸š '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11995,7 +11827,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "ผังà¹à¸à¸™à¸´à¹€à¸¡à¸Šà¸±à¸™à¹„ม่ถูà¸à¸•้à¸à¸‡" #: scene/animation/animation_tree_player.cpp @@ -12007,8 +11839,12 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "โหมด Raw" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -12021,10 +11857,15 @@ msgstr "เพิ่มสีที่เลืà¸à¸à¹ƒà¸™à¸£à¸²à¸¢à¸à¸²à¸£à¹‚ #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -12036,22 +11877,24 @@ msgid "Please Confirm..." msgstr "à¸à¸£à¸¸à¸“ายืนยัน..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "ปà¸à¸•ิป๊à¸à¸›à¸à¸±à¸žà¸ˆà¸°à¸–ูà¸à¸‹à¹ˆà¸à¸™à¸ˆà¸™à¸à¸§à¹ˆà¸²à¸ˆà¸°à¸¡à¸µà¸à¸²à¸£à¹€à¸£à¸µà¸¢à¸à¹ƒà¸Šà¹‰à¸Ÿà¸±à¸‡à¸à¹Œà¸Šà¸±à¸™ popup() หรืภpopup*() " "โดยขณะà¹à¸à¹‰à¹„ขสามารถเปิดให้มà¸à¸‡à¹€à¸«à¹‡à¸™à¹„ด้ à¹à¸•่เมื่à¸à¹€à¸£à¸´à¹ˆà¸¡à¹‚ปรà¹à¸à¸£à¸¡à¸›à¹Šà¸à¸›à¸à¸±à¸žà¸ˆà¸°à¸–ูà¸à¸‹à¹ˆà¸à¸™" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "" #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer ทำงานได้เมื่à¸à¸¡à¸µà¹‚หนดลูà¸à¹€à¸žà¸µà¸¢à¸‡à¸«à¸™à¸¶à¹ˆà¸‡à¹‚หนดเท่านั้น\n" @@ -12104,6 +11947,11 @@ msgstr "เพิ่มà¸à¸´à¸™à¸žà¸¸à¸•" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "ต้นฉบับไม่ถูà¸à¸•้à¸à¸‡!" + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "ต้นฉบับไม่ถูà¸à¸•้à¸à¸‡!" @@ -12123,6 +11971,53 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Generating solution..." +#~ msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ solution..." + +#~ msgid "Generating C# project..." +#~ msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡à¹‚ปรเจà¸à¸•์ C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "ผิดพลาดในà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡ solution" + +#~ msgid "Failed to save solution." +#~ msgstr "ผิดพลาดในà¸à¸²à¸£à¸šà¸±à¸™à¸—ึภsolution" + +#~ msgid "Done" +#~ msgstr "เสร็จสิ้น" + +#~ msgid "Failed to create C# project." +#~ msgstr "ผิดพลาดในà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹‚ปรเจà¸à¸•์ C#" + +#~ msgid "Mono" +#~ msgstr "โมโน" + +#~ msgid "About C# support" +#~ msgstr "เà¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸à¸²à¸£à¸ªà¸™à¸±à¸šà¸ªà¸™à¸¸à¸™ C#" + +#~ msgid "Create C# solution" +#~ msgstr "สร้าง C# solution" + +#~ msgid "Builds" +#~ msgstr "สร้าง" + +#~ msgid "Build Project" +#~ msgstr "Build โปรเจà¸à¸•์" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "ดูไฟล์" + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "ค้นหาคลาส" + +#~ msgid "Update Always" +#~ msgstr "à¸à¸±à¸žà¹€à¸”ทตลà¸à¸”เวลา" + +#~ msgid "Raw Mode" +#~ msgstr "โหมด Raw" + #~ msgid "Path to Node:" #~ msgstr "ตำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่à¸à¸¢à¸¹à¹ˆà¹‚หนด:" @@ -12678,9 +12573,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "ซ่à¸à¸™/à¹à¸ªà¸”งโหนด Spatial" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "ซ่à¸à¸™/à¹à¸ªà¸”งโหนด CanvasItem" - #~ msgid "Condition" #~ msgstr "เงื่à¸à¸™à¹„ข" @@ -13546,9 +13438,6 @@ msgstr "" #~ msgid "Shrink By:" #~ msgstr "ลดไป:" -#~ msgid "Select None" -#~ msgstr "ไม่เลืà¸à¸" - #~ msgid "Samples" #~ msgstr "ไฟล์เสียง" diff --git a/editor/translations/tr.po b/editor/translations/tr.po index 16c42142ec..406b84b591 100644 --- a/editor/translations/tr.po +++ b/editor/translations/tr.po @@ -27,12 +27,13 @@ # Aiden Demir <dnm00110011@hotmail.com>, 2019. # Anton Semchenko <semchenkoanton@protonmail.com>, 2019. # Enes Can Yerlikaya <enescanyerlikaya@gmail.com>, 2019. +# Ömer Akgöz <omerakgoz34@gmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-06-16 19:41+0000\n" -"Last-Translator: Anton Semchenko <semchenkoanton@protonmail.com>\n" +"PO-Revision-Date: 2019-07-02 10:47+0000\n" +"Last-Translator: Ömer Akgöz <omerakgoz34@gmail.com>\n" "Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/" "godot/tr/>\n" "Language: tr\n" @@ -40,7 +41,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -62,9 +63,8 @@ msgid "self can't be used because instance is null (not passed)" msgstr "\"self\" ifadesi kullanılamaz, çünkü nesne \"null\" (tanımlandı)." #: core/math/expression.cpp -#, fuzzy msgid "Invalid operands to operator %s, %s and %s." -msgstr "Geçersiz iÅŸlenen operatörler %s, %s ve %s" +msgstr "%s, %s ve %s operatörleri için geçersiz iÅŸlem." #: core/math/expression.cpp msgid "Invalid index of type %s for base type %s" @@ -84,7 +84,6 @@ msgstr "'%s' çaÄŸrıldığında:" #: editor/animation_bezier_editor.cpp #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Free" msgstr "Ücretsiz" @@ -101,9 +100,8 @@ msgid "Time:" msgstr "Süre:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "DeÄŸer" +msgstr "DeÄŸer:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -163,9 +161,8 @@ msgid "Change Animation Loop" msgstr "Animasyon Döngüsünü DeÄŸiÅŸtir" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Property Track" -msgstr "Özellik:" +msgstr "Özellik Parçası" #: editor/animation_track_editor.cpp msgid "3D Transform Track" @@ -458,10 +455,28 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Bu animasyon içe aktarılmış bir sahneye ait, bu yüzden içe aktarılan " +"parçalara yapılan deÄŸiÅŸiklikler kaydedilmeyecek.\n" +"\n" +"Özel parça ekleme özelliÄŸini aktif etmek için, sahnenin içe aktarma " +"ayarlarına gidin ve \"Animasyon > Depolama\" ayarını \"Dosyalama\" olarak " +"ayarlayın, \"Animasyon > Özel Parçaları Sakla\"ayarını aktif edin ve sonra " +"tekrar içe aktarın.\n" +"Alternatif olarak, animasyonları ayrı dosyalara aktaran bir içe aktarma " +"hazır ayarı kullanabilirsiniz." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "Uyarı: İçe aktarılan animasyonu düzenleme" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Hepsini seç" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "Hiçbir Åžey Seçilmedi" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -637,6 +652,10 @@ msgstr "Satıra git" msgid "Line Number:" msgstr "Satır Numarası:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "EÅŸleÅŸme Yok" @@ -668,7 +687,7 @@ msgstr "Yalnızca Seçim" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Standart" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -686,7 +705,7 @@ msgstr "UzaklaÅŸtır" msgid "Reset Zoom" msgstr "YaklaÅŸmayı Sıfırla" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "Uyarılar" @@ -695,38 +714,32 @@ msgid "Line and column numbers." msgstr "Satır ve sütun numaraları." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Hedef Düğümdeki Metot tanımlanmış olmalı!" +msgstr "Hedef düğümdeki metod tanımlanmalı." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." msgstr "" -"Amaçlanan metot bulunamadı! Geçerli bir metot tanımla ya da amaçlanan düğüme " -"bir betik iliÅŸtirin." +"Hedef metod bulunamadı. Geçerli bir metod tanımlayın ya da hedef düğüme bir " +"komut baÄŸlayın." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" msgstr "Düğüme BaÄŸla:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Ana makineye baÄŸlanılamadı:" +msgstr "Komuta BaÄŸla:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" msgstr "Sinyaller:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "Düğüm uzambilgisi içermiyor." +msgstr "Sahne hiç komut içermiyor." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -754,9 +767,8 @@ msgid "Extra Call Arguments:" msgstr "Ekstra ÇaÄŸrı Argümanları:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Yapışma ayarları" +msgstr "GeliÅŸmiÅŸ" #: editor/connections_dialog.cpp msgid "Deferred" @@ -799,6 +811,11 @@ msgid "Connect" msgstr "BaÄŸla" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Sinyaller:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Bunu '%s' ÅŸuna '%s' baÄŸla" @@ -966,7 +983,8 @@ msgid "Owners Of:" msgstr "Åžunların sahipleri:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "Seçili dosyaları projeden kaldır? (geri alınamaz)" #: editor/dependency_editor.cpp @@ -1339,7 +1357,7 @@ msgstr "Geçersiz isim. Varolan bir motor sınıf ismi ile çakışmamalı." #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "Geçersiz ad. Var olan gömülü türdeki ad ile çakışmamalı." #: editor/editor_autoload_settings.cpp @@ -1521,6 +1539,10 @@ msgstr "Özel yayınlama ÅŸablonu bulunamadı." msgid "Template file not found:" msgstr "Åžablon dosyası bulunamadı:" +#: editor/editor_export.cpp +msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB." +msgstr "" + #: editor/editor_feature_profile.cpp #, fuzzy msgid "3D Editor" @@ -1553,7 +1575,7 @@ msgstr "Biçimi Taşı" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "DosyaSistemi" #: editor/editor_feature_profile.cpp @@ -1615,7 +1637,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1630,7 +1652,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "Åžu Anki Sürüm:" #: editor/editor_feature_profile.cpp @@ -1655,16 +1677,11 @@ msgstr "Dışa Aktar" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" +msgid "Available Profiles:" msgstr "Kullanılabilir Düğümler:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "Sınıfları Ara" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" msgstr "Sınıf Açıklaması" @@ -2422,7 +2439,7 @@ 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 "" -"Sahne '% s' otomatik olarak içe aktarıldı, bu nedenle deÄŸiÅŸtirilemez.\n" +"Sahne '%s' otomatik olarak içe aktarıldı, bu nedenle deÄŸiÅŸtirilemez.\n" "DeÄŸiÅŸiklik yapmak için miras alınmış yeni bir sahne oluÅŸturulabilir." #: editor/editor_node.cpp @@ -2754,10 +2771,34 @@ msgid "Editor Layout" msgstr "Düzenleyici YerleÅŸim Düzeni" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "Anlamlı!" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Düzenleyici Verileri/Ayarları Klasörünü Aç" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "Sonraki Düzenleyiciyi aç" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "Tam Ekran Aç / Kapat" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "CanvasItem'ı Görünür Duruma Getir" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "Düzenleyici Verileri/Ayarları Klasörünü Aç" @@ -2866,15 +2907,18 @@ msgid "Spins when the editor window redraws." msgstr "Düzenleyici penceresi yeniden boyandığında döner." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Sürekli Güncelle" +#, fuzzy +msgid "Update Continuously" +msgstr "Kesintisiz" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "DeÄŸiÅŸiklikleri güncelle" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "Güncelleme Topacını Devre Dışı Bırak" #: editor/editor_node.cpp @@ -3065,7 +3109,7 @@ msgstr "Zaman" msgid "Calls" msgstr "ÇaÄŸrılar" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Açık" @@ -3175,6 +3219,11 @@ msgid "Page: " msgstr "Sayfa: " #: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Öğeyi Kaldır" + +#: editor/editor_properties_array_dict.cpp msgid "New Key:" msgstr "Yeni Anahtar:" @@ -3186,11 +3235,6 @@ msgstr "Yeni DeÄŸer:" msgid "Add Key/Value Pair" msgstr "Anahtar/DeÄŸer İkilisini Ekle" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Öğeyi Kaldır" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3695,6 +3739,7 @@ msgid "Nodes not in Group" msgstr "Düğümler Grupta DeÄŸil" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Düğümleri Süzgeçden Geçir" @@ -5378,6 +5423,14 @@ msgid "Load Emission Mask" msgstr "Yayma Maskesini Yükle" #: 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 +#, fuzzy +msgid "Restart" +msgstr "Åžimdi Yeniden BaÅŸlat" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "Yayma Maskesini Temizle" @@ -6326,10 +6379,20 @@ msgid "Find Next" msgstr "Sonraki Bul" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Özellikleri süz" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Süzgeç kipi:" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "Sırala" @@ -6572,20 +6635,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +msgstr "Noktalar oluÅŸtur." + #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Kes" -#: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Select All" -msgstr "Hepsini seç" - #: editor/plugins/script_text_editor.cpp msgid "Delete Line" msgstr "Satırı Sil" @@ -8250,51 +8317,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8303,203 +8326,27 @@ msgid "Input parameter." msgstr "Ebeveyne yapıştır" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10214,6 +10061,11 @@ msgid "Add Child Node" msgstr "Çocuk Düğüm Ekle" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Hepsini Daralt" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Türü DeÄŸiÅŸtir" @@ -10244,7 +10096,8 @@ msgid "Delete (No Confirm)" msgstr "Sil (DoÄŸrulama Yok)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "Yeni Bir Düğüm Ekle / OluÅŸtur" #: editor/scene_tree_dock.cpp @@ -10518,7 +10371,7 @@ msgstr "Çerçeveleri Yığ" msgid "Pick one or more items from the list to display the graph." msgstr "GrafiÄŸi görüntülemek için listeden bir veya daha fazla öğe seçin." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Hatalar" @@ -10934,55 +10787,6 @@ msgstr "Uzaklık Seç:" msgid "Class name can't be a reserved keyword" msgstr "Sınıf ismi ayrılmış anahtar kelime olamaz" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Çözüm oluÅŸturuluyor..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "C# projesi üretiliyor..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Çözüm oluÅŸturma baÅŸarısız." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Çözüm kaydetme baÅŸarısız." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Oldu" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "C# projesi oluÅŸturma baÅŸarısız." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Tekli" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "C# desteÄŸi hakkında" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "C# Çözümü oluÅŸtur" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "İnÅŸalar" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Projeyi İnÅŸa et" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "Dosyaları Görüntüle" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "İç özel durum yığını izlemesinin sonu" @@ -11580,8 +11384,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "Geçersiz açılış görüntülüğü bediz boyutları (620x300 olmalı)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Bir SpriteFrames kaynağı oluÅŸturulmalı ya da 'Kareler' özelliÄŸine atanmalı " @@ -11648,8 +11453,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "Işık yüzeyli bir doku, 'texture' özelliÄŸine saÄŸlanmalıdır." @@ -11661,7 +11467,8 @@ msgstr "" "(ya da çizilmelidir)." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "Bu engelleyici için engelleyici çokgeni boÅŸ. Lütfen bir çokgen çizin!" #: scene/2d/navigation_polygon.cpp @@ -11742,16 +11549,30 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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 yalnızca CollisionObject2D'den türeyen düğümlere bir ÅŸekil " +"elde etmeye hizmet eder. Lütfen onu yalnızca ÅŸunların çocuÄŸu olarak kullanın " +"ve Area2D, StaticBody2D, RigidBody2D, KinematicBody2D vs.'ye bir ÅŸekil " +"vermek için kullanın." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D düğümü düzenlenmiÅŸ sahne kökü doÄŸrudan ebeveyn olarak " "kullanıldığında çalışır." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera ebeveyni olarak ARVROrigin düğümüne sahip olmalı" #: scene/3d/arvr_nodes.cpp @@ -11847,9 +11668,10 @@ msgstr "" "RigidBody, KinematicBody, v.b. onu sadece bunların çocuÄŸu olarak kullanın." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "CollisionShape'in çalışması için bir ÅŸekil verilmelidir. Lütfen bunun için " "bir ÅŸekil kaynağı oluÅŸturun!" @@ -11882,6 +11704,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11923,8 +11749,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11938,7 +11764,10 @@ msgstr "" "Boyu deÄŸiÅŸikliÄŸini bunun yerine çocuk çarpışma ÅŸekilleri içinden yapın." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "Yol özelliÄŸi, çalışmak için geçerli bir Spatial düğümüne iÅŸaret etmelidir." @@ -11958,8 +11787,9 @@ msgstr "" "Boyu deÄŸiÅŸikliÄŸini bunun yerine çocuk çarpışma ÅŸekilleri içinden yapın." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "AnimatedSprite3D 'nin çerçeveleri görüntülemek için bir SpriteFrames kaynağı " @@ -11974,8 +11804,10 @@ msgstr "" "Lütfen bunu VehicleBody'nin çocuÄŸu olarak kullanın." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment bir Environment kaynağı gerektirir." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -12016,7 +11848,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Åžunun: '%s' ÅŸununla: '%s' baÄŸlantısını kes" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -12032,7 +11864,7 @@ msgstr "" #: scene/animation/animation_tree.cpp #, fuzzy -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "Animasyon aÄŸacı geçersizdir." #: scene/animation/animation_tree_player.cpp @@ -12044,8 +11876,12 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Ham Kip" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -12058,10 +11894,15 @@ msgstr "Åžuanki rengi bir önayar olarak kaydet" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -12073,23 +11914,25 @@ msgid "Please Confirm..." msgstr "Lütfen DoÄŸrulayın..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Açılır pencereler popup() veya popup*() iÅŸlevleri çaÄŸrılmadıkça varsayılan " "olarak gizlenecektir. Onları düzenleme için görünür kılmak da iyidir, ancak " "çalışırken gizlenecekler." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "" #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer tek bir çocuk denetimi ile çalışmak için tasarlanmıştır.\n" @@ -12143,6 +11986,11 @@ msgstr "GiriÅŸ Ekle" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "Geçersiz kaynak!" + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "Geçersiz kaynak!" @@ -12162,6 +12010,56 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Generating solution..." +#~ msgstr "Çözüm oluÅŸturuluyor..." + +#~ msgid "Generating C# project..." +#~ msgstr "C# projesi üretiliyor..." + +#~ msgid "Failed to create solution." +#~ msgstr "Çözüm oluÅŸturma baÅŸarısız." + +#~ 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." + +#~ msgid "Mono" +#~ msgstr "Tekli" + +#~ msgid "About C# support" +#~ msgstr "C# desteÄŸi hakkında" + +#~ msgid "Create C# solution" +#~ msgstr "C# Çözümü oluÅŸtur" + +#~ msgid "Builds" +#~ msgstr "İnÅŸalar" + +#~ msgid "Build Project" +#~ msgstr "Projeyi İnÅŸa et" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "Dosyaları Görüntüle" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment bir Environment kaynağı gerektirir." + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "Sınıfları Ara" + +#~ msgid "Update Always" +#~ msgstr "Sürekli Güncelle" + +#~ msgid "Raw Mode" +#~ msgstr "Ham Kip" + #~ msgid "Path to Node:" #~ msgstr "Düğüm Yolu:" @@ -12722,9 +12620,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Uzaysal Görünürlüğü Aç / Kapat" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "CanvasItem'ı Görünür Duruma Getir" - #~ msgid "Condition" #~ msgstr "KoÅŸul" @@ -13642,9 +13537,6 @@ msgstr "" #~ msgid "Images:" #~ msgstr "Bedizler:" -#~ msgid "Select None" -#~ msgstr "Hiçbir Åžey Seçilmedi" - #~ msgid "Group" #~ msgstr "Öbek" diff --git a/editor/translations/uk.po b/editor/translations/uk.po index 9c033bc4fc..db7f358773 100644 --- a/editor/translations/uk.po +++ b/editor/translations/uk.po @@ -15,7 +15,7 @@ msgid "" msgstr "" "Project-Id-Version: Ukrainian (Godot Engine)\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-05-22 10:19+0000\n" +"PO-Revision-Date: 2019-07-09 10:46+0000\n" "Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n" "Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/" "godot/uk/>\n" @@ -25,7 +25,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -86,9 +86,8 @@ msgid "Time:" msgstr "ЧаÑ:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "ЗначеннÑ" +msgstr "ЗначеннÑ:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -442,10 +441,29 @@ msgid "" "Alternatively, use an import preset that imports animations to separate " "files." msgstr "" +"Ð¦Ñ Ð°Ð½Ñ–Ð¼Ð°Ñ†Ñ–Ñ Ð½Ð°Ð»ÐµÐ¶Ð¸Ñ‚ÑŒ до імпортованої Ñцени, тому зміни у імпортованих " +"доріжках не буде збережено.\n" +"\n" +"Щоб увімкнути можливіÑть Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ð½ÐµÑ‚Ð¸Ð¿Ð¾Ð²Ð¸Ñ… доріжок, перейдіть до " +"параметрів Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ñцени Ñ–\n" +"вÑтановіть Ð´Ð»Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð° «ÐÐ½Ñ–Ð¼Ð°Ñ†Ñ–Ñ > Сховище» Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«Ð¤Ð°Ð¹Ð»Ð¸Â», позначте " +"«ÐÐ½Ñ–Ð¼Ð°Ñ†Ñ–Ñ > Зберегти нетипові доріжки»,\n" +"Ñ– виконайте повторне імпортуваннÑ. Крім того, ви можете ÑкориÑтатиÑÑ Ð½Ð°Ð±Ð¾Ñ€Ð¾Ð¼ " +"параметрів імпортуваннÑ,\n" +"Ñкий надає змогу імпортувати анімації до окремих файлів." #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "ПопередженнÑ: Редагуємо імпортовану анімацію" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "Виділити вÑе" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "СкаÑувати позначеннÑ" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -622,6 +640,10 @@ msgstr "Перейти до Ñ€Ñдка" msgid "Line Number:" msgstr "Ðомер Ñ€Ñдка:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Ðемає збігів" @@ -671,7 +693,7 @@ msgstr "ЗменшеннÑ" msgid "Reset Zoom" msgstr "Скинути маÑштаб" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "ПопередженнÑ" @@ -680,12 +702,10 @@ msgid "Line and column numbers." msgstr "Ðомери Ñ€Ñдків Ñ– позицій." #: editor/connections_dialog.cpp -#, fuzzy msgid "Method in target node must be specified." -msgstr "Метод у цільовому вузлі повинен бути вказаний!" +msgstr "Має бути вказано метод у цільовому вузлі." #: editor/connections_dialog.cpp -#, fuzzy msgid "" "Target method not found. Specify a valid method or attach a script to the " "target node." @@ -694,24 +714,20 @@ msgstr "" "цільового вузла." #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" -msgstr "ПідключитиÑÑ Ð´Ð¾ вузла:" +msgstr "З'єднати з вузлом:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "Ðе вдалоÑÑ Ð¿Ñ–Ð´ÐºÐ»ÑŽÑ‡Ð¸Ñ‚Ð¸ÑÑ Ð´Ð¾ хоÑту:" +msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð·Ñ– Ñкриптом:" #: editor/connections_dialog.cpp -#, fuzzy msgid "From Signal:" -msgstr "Сигнали:" +msgstr "З Ñигналу:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "Вузол не міÑтить геометрії." +msgstr "У Ñцені немає жодного Ñкрипту." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -739,9 +755,8 @@ msgid "Extra Call Arguments:" msgstr "Додаткові аргументи виклику:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Advanced" -msgstr "Додаткові параметри" +msgstr "Додатково" #: editor/connections_dialog.cpp msgid "Deferred" @@ -751,6 +766,8 @@ msgstr "Відкладені" msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." msgstr "" +"Відкладає Ñигнал, зберігаючи його у черзі Ñ– відпуÑкаючи, лише наÑтане Ñтан " +"бездіÑльноÑті." #: editor/connections_dialog.cpp msgid "Oneshot" @@ -758,12 +775,11 @@ msgstr "Один раз" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Від'єднує Ñигнал піÑÐ»Ñ Ð¹Ð¾Ð³Ð¾ першого виданнÑ." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "З'єднати Ñигнал: " +msgstr "Ðе вдалоÑÑ Ð·'єднати Ñигнал" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -784,6 +800,11 @@ msgid "Connect" msgstr "З'єднати" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "Сигнали:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Приєднати '%s' до %s'" @@ -805,14 +826,12 @@ msgid "Disconnect" msgstr "Роз'єднати" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "З'єднати Ñигнал: " +msgstr "З'єднати Ñигнал із методом" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Редагувати з’єднаннÑ: " +msgstr "Редагувати з’єднаннÑ:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -888,22 +907,20 @@ msgid "Dependencies For:" msgstr "ЗалежноÑті длÑ:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." msgstr "" "Сцена \"%s\" зараз редагуєтьÑÑ.\n" -"Зміни не наберуть Ñили, Ñкщо не перезавантажитиÑÑ." +"Зміни не наберуть чинноÑті до перезавантаженнÑ." #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Resource '%s' is in use.\n" "Changes will only take effect when reloaded." msgstr "" "РеÑÑƒÑ€Ñ \"%S \" викориÑтовуєтьÑÑ.\n" -"Зміни набудуть чинноÑті піÑÐ»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ." +"Зміни набудуть чинноÑті лише піÑÐ»Ñ Ð¿ÐµÑ€ÐµÐ·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ." #: editor/dependency_editor.cpp #: modules/gdnative/gdnative_library_editor_plugin.cpp @@ -950,8 +967,9 @@ msgid "Owners Of:" msgstr "ВлаÑники:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" -msgstr "Видалити вибрані файли з проекту? (ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ðµ)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" +msgstr "Видалити вибрані файли з проєкту? (ÑкаÑÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ¼Ð¾Ð¶Ð»Ð¸Ð²Ðµ)" #: editor/dependency_editor.cpp msgid "" @@ -996,9 +1014,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "ОÑтаточно вилучити %d об'єкт(и)? (Ðеможливо ÑкаÑувати)" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "ЗалежноÑті" +msgstr "Показати залежноÑті" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1038,7 +1055,7 @@ msgstr "Ðвтори Ñ€ÑƒÑˆÑ–Ñ Godot" #: editor/editor_about.cpp msgid "Project Founders" -msgstr "ЗаÑновники проекту" +msgstr "ЗаÑновники проєкту" #: editor/editor_about.cpp msgid "Lead Developer" @@ -1261,7 +1278,7 @@ msgstr "Відкрити ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ð°ÑƒÐ´Ñ–Ð¾ шини" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Ðемає файла «%s»." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1318,27 +1335,20 @@ msgid "Valid characters:" msgstr "ПрипуÑтимі Ñимволи:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "" -"ÐеприпуÑтима назва. Ðе повинно конфліктувати з Ñ–Ñнуючим ім'Ñм клаÑу рушіÑ." +msgstr "Ðазва має відрізнÑтиÑÑ Ð²Ñ–Ð´ наÑвної назви клаÑу рушіÑ." #: editor/editor_autoload_settings.cpp -#, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "" -"ÐеприпуÑтима назва. Ðе повинно ÑтикатиÑÑ Ð· Ñ–Ñнуючим вбудованим ім'Ñм типу." +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 "" -"ÐеприпуÑтиме ім'Ñ. Ðе повинно збігатиÑÑŒ з іменем Ñ–Ñнуючої глобальної " -"конÑтанти." +msgstr "Ðазва не повинна збігатиÑÑ Ñ–Ð· назвою наÑвної загальної Ñталої." #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "У назві Ð°Ð²Ñ‚Ð¾Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð½Ðµ можна викориÑтовувати ключові Ñлова." #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1369,7 +1379,6 @@ msgid "Rearrange Autoloads" msgstr "Змінити порÑдок автозавантажень" #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid path." msgstr "Ðеправильний шлÑÑ…." @@ -1401,7 +1410,7 @@ msgstr "Ім'Ñ" #: editor/editor_autoload_settings.cpp msgid "Singleton" -msgstr "Одинак (шаблон проектуваннÑ)" +msgstr "Одинак (шаблон проєктуваннÑ)" #: editor/editor_data.cpp msgid "Updating Scene" @@ -1424,9 +1433,8 @@ msgid "[unsaved]" msgstr "[не збережено]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "Будь лаÑка, виберіть Ñпочатку базовий каталог" +msgstr "Будь лаÑка, виберіть Ñпочатку базовий каталог." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1472,7 +1480,7 @@ msgid "" "Etc' in Project Settings." msgstr "" "Платформа Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±ÑƒÑ” ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚ÐµÐºÑтур «ETC» Ð´Ð»Ñ GLES2. Увімкніть " -"пункт «Імпортувати ETC» у параметрах проекту." +"пункт «Імпортувати ETC» у параметрах проєкту." #: editor/editor_export.cpp msgid "" @@ -1480,7 +1488,7 @@ msgid "" "'Import Etc 2' in Project Settings." msgstr "" "Платформа Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±ÑƒÑ” ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚ÐµÐºÑтур «ETC2» Ð´Ð»Ñ GLES3. Увімкніть " -"пункт «Імпортувати ETC 2» у параметрах проекту." +"пункт «Імпортувати ETC 2» у параметрах проєкту." #: editor/editor_export.cpp msgid "" @@ -1490,7 +1498,7 @@ msgid "" "Enabled'." msgstr "" "Платформа Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±ÑƒÑ” ÑтиÑÐºÐ°Ð½Ð½Ñ Ñ‚ÐµÐºÑтур «ETC» Ð´Ð»Ñ GLES2.\n" -"Увімкніть пункт «Імпортувати ETC» у параметрах проекту або вимкніть пункт " +"Увімкніть пункт «Імпортувати ETC» у параметрах проєкту або вимкніть пункт " "«Увімкнено резервні драйвери»." #: editor/editor_export.cpp platform/android/export/export.cpp @@ -1509,122 +1517,109 @@ msgstr "Ðетипового шаблону випуÑку не знайдено 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 -#, fuzzy msgid "3D Editor" -msgstr "Редактор" +msgstr "3D-редактор" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Відкрити редактор Ñкриптів" +msgstr "Редактор Ñкриптів" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "Відкрити бібліотеку активів" +msgstr "Бібліотека активів" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "Дерево Ñцени (вузли):" +msgstr "Ð ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ñ–Ñ”Ñ€Ð°Ñ€Ñ…Ñ–Ñ— Ñцени" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Імпортувати" +msgstr "Бічна панель імпортуваннÑ" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "ПереÑунуто вузол" +msgstr "Бічна панель вузлів" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Filesystem Dock" -msgstr "Файлова ÑиÑтема" +msgid "FileSystem and Import Docks" +msgstr "Бічна панель файлової ÑиÑтеми та імпортуваннÑ" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Замінити вÑе (без ÑкаÑовуваннÑ)" +msgstr "Витерти профіль «%s»? (не можна ÑкаÑувати)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "Ð”Ð»Ñ Ð¿Ñ€Ð¾Ñ„Ñ–Ð»ÑŽ має бути вказано коректну назву файла, Ñка має міÑтити «.»" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Файл або тека з таким іменем вже Ñ–Ñнує." +msgstr "Профіль із такою назвою вже Ñ–Ñнує." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Редактор вимкнено, влаÑтивоÑті вимкнено)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "Лише влаÑтивоÑті" +msgstr "(ВлаÑтивоÑті вимкнено)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "ÐžÐ±Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð¾" +msgstr "(Редактор вимкнено)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "ÐžÐ¿Ð¸Ñ ÐºÐ»Ð°Ñу:" +msgstr "Параметри клаÑу:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "Відкрити наÑтупний редактор" +msgstr "Увімкнути контекÑтуальний редактор" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "ВлаÑтивоÑті:" +msgstr "Увімкнені влаÑтивоÑті:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "МожливоÑті" +msgstr "Увімкнені можливоÑті:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Пошук клаÑів" +msgstr "Увімкнені клаÑи:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Формат файла «%s» Ñ” некоректним, Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÑ€Ð²Ð°Ð½Ð¾." #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" +"Профіль із назвою «%s» вже Ñ–Ñнує. Перед імпортуваннÑм Ñлід вилучити наÑвний " +"профіль. Ð†Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÑ€Ð²Ð°Ð½Ð¾." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби завантажити шаблон «%s»" +msgstr "Помилка під Ñ‡Ð°Ñ Ñпроби зберегти профіль до каталогу: «%s»." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "Ðе вÑтановлено" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Current Profile" -msgstr "Поточна верÑÑ–Ñ:" +msgid "Current Profile:" +msgstr "Поточний профіль:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Поточний:" +msgstr "Зробити поточним" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1642,44 +1637,32 @@ msgid "Export" msgstr "ЕкÑпортуваннÑ" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Available Profiles" -msgstr "ДоÑтупні вузли:" - -#: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Пошук клаÑів" +msgid "Available Profiles:" +msgstr "ДоÑтупні профілі:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "ÐžÐ¿Ð¸Ñ ÐºÐ»Ð°Ñу" +msgstr "Параметри клаÑу" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Ðова назва:" +msgstr "Ðазва нового профілю:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "Витерти облаÑть" +msgstr "Витерти профіль" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "Імпортований проект" +msgstr "Імпортувати профілі" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "ЕкÑпортувати проект" +msgstr "ЕкÑпорт профілю" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°Ð¼Ð¸ екÑпорту" +msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ„Ñ–Ð»Ñми можливоÑтей редактора" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1763,11 +1746,11 @@ msgstr "Вгору" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Toggle Hidden Files" -msgstr "Переключати приховані файли" +msgstr "Перемкнути приховані файли" #: editor/editor_file_dialog.cpp msgid "Toggle Favorite" -msgstr "Переключити обране" +msgstr "Перемкнути обране" #: editor/editor_file_dialog.cpp msgid "Toggle Mode" @@ -1802,9 +1785,8 @@ msgid "(Un)favorite current folder." msgstr "Перемкнути Ñтан вибраноÑті Ð´Ð»Ñ Ð¿Ð¾Ñ‚Ð¾Ñ‡Ð½Ð¾Ñ— теки." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Переключати приховані файли" +msgstr "Увімкнути або вимкнути видиміÑть прихованих файлів." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1841,6 +1823,8 @@ msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" msgstr "" +"ІÑнує декілька заÑобів Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ñ€Ñ–Ð·Ð½Ð¸Ñ… типів, Ñкі вказують на файл " +"%s, Ñ–Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿ÐµÑ€ÐµÑ€Ð²Ð°Ð½Ð¾" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2045,7 +2029,7 @@ msgstr "ОчиÑтити вивід" #: editor/editor_node.cpp msgid "Project export failed with error code %d." -msgstr "Ðе вдалоÑÑ ÐµÐºÑпортувати проект, код помилки — %d." +msgstr "Ðе вдалоÑÑ ÐµÐºÑпортувати проєкт, код помилки — %d." #: editor/editor_node.cpp msgid "Imported resources can't be saved." @@ -2184,7 +2168,6 @@ msgstr "" "краще зрозуміти цей робочий процеÑ." #: editor/editor_node.cpp -#, fuzzy 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." @@ -2201,7 +2184,6 @@ msgstr "" "Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð½Ð° панелі імпорту, а потім знову імпортуйте." #: editor/editor_node.cpp -#, fuzzy 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" @@ -2214,7 +2196,6 @@ msgstr "" "зрозуміти цей робочий процеÑ." #: editor/editor_node.cpp -#, fuzzy 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 " @@ -2246,9 +2227,8 @@ msgid "Open Base Scene" msgstr "Відкрити оÑновну Ñцену" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Швидке Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñцени..." +msgstr "Швидке відкриттÑ…" #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2340,7 +2320,7 @@ msgstr "Вийти з редактора?" #: editor/editor_node.cpp msgid "Open Project Manager?" -msgstr "Відкрити менеджер проектів?" +msgstr "Відкрити менеджер проєктів?" #: editor/editor_node.cpp msgid "Save & Quit" @@ -2353,7 +2333,7 @@ msgstr "Зберегти зміни в наÑтупній(их) Ñцені(ах) #: editor/editor_node.cpp msgid "Save changes the following scene(s) before opening Project Manager?" msgstr "" -"Зберегти зміни в наÑтупній(их) Ñцені(ах) перед відкриттÑм менеджера проектів?" +"Зберегти зміни в наÑтупній(их) Ñцені(ах) перед відкриттÑм менеджера проєктів?" #: editor/editor_node.cpp msgid "" @@ -2416,9 +2396,9 @@ 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:" @@ -2435,7 +2415,7 @@ msgid "" "category." msgstr "" "ÐÑ–Ñка головна Ñцена ніколи не була визначена, вибрати Ñ—Ñ—?\n" -"Ви можете змінити це пізніше в \"ÐалаштуваннÑÑ… проекту\" в категорії " +"Ви можете змінити це пізніше в \"ÐалаштуваннÑÑ… проєкту\" в категорії " "\"Програма\"." #: editor/editor_node.cpp @@ -2445,7 +2425,7 @@ msgid "" "category." msgstr "" "Вибрана Ñцена '%s' не Ñ–Ñнує, вибрати дійÑну?\n" -"Ви можете змінити це пізніше в \"ÐалаштуваннÑÑ… проекту\" в категорії " +"Ви можете змінити це пізніше в \"ÐалаштуваннÑÑ… проєкту\" в категорії " "\"Програма\"." #: editor/editor_node.cpp @@ -2455,7 +2435,7 @@ msgid "" "category." msgstr "" "Вибрана Ñцена '%s' не Ñ” файлом Ñцени, вибрати дійÑний файл?\n" -"Ви можете змінити це пізніше в \"ÐалаштуваннÑÑ… проекту\" в категорії " +"Ви можете змінити це пізніше в \"ÐалаштуваннÑÑ… проєкту\" в категорії " "\"Програма\"." #: editor/editor_node.cpp @@ -2490,12 +2470,11 @@ msgstr "Закрити інші вкладки" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Закрити вкладки праворуч" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" -msgstr "Закрити вÑе" +msgstr "Закрити уÑÑ– вкладки" #: editor/editor_node.cpp msgid "Switch Scene Tab" @@ -2609,15 +2588,15 @@ msgstr "Повернути Ñцену" #: editor/editor_node.cpp msgid "Miscellaneous project or scene-wide tools." -msgstr "Різні проектні або Ñценографічні інÑтрументи." +msgstr "Різні проєктні або Ñценографічні інÑтрументи." #: editor/editor_node.cpp msgid "Project" -msgstr "Проект" +msgstr "Проєкт" #: editor/editor_node.cpp msgid "Project Settings" -msgstr "Параметри проекту" +msgstr "Параметри проєкту" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" @@ -2625,15 +2604,15 @@ msgstr "ІнÑтрументи" #: editor/editor_node.cpp msgid "Open Project Data Folder" -msgstr "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÐºÐ¸ даних проекту" +msgstr "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÐºÐ¸ даних проєкту" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Ð’Ñтановити шаблон Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Android" #: editor/editor_node.cpp msgid "Quit to Project List" -msgstr "Вийти в ÑпиÑок проектів" +msgstr "Вийти в ÑпиÑок проєктів" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp @@ -2667,7 +2646,7 @@ msgid "" msgstr "" "Якщо цей параметр увімкнено, екÑпорт або Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð´Ð°ÑŽÑ‚ÑŒ мінімальний " "виконуваний файл.\n" -"Файлова ÑиÑтема буде надана редактором у проекті через мережу.\n" +"Файлова ÑиÑтема буде надана редактором у проєкті через мережу.\n" "Ðа Android Ñ€Ð¾Ð·Ð³Ð¾Ñ€Ñ‚Ð°Ð½Ð½Ñ Ð±ÑƒÐ´Ðµ швидше при підключенні через USB.. Цей параметр " "значно приÑкорює теÑÑ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÐµÐ»Ð¸ÐºÐ¸Ñ… ігор." @@ -2740,10 +2719,30 @@ 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 "Знімки зберігаютьÑÑ Ñƒ теці Data/Settings редактора." + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "Ðвтоматично відкривати знімки вікон" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "Ð’Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ Ñ‚ÐµÐºÐ¸ даних/параметрів редактора" @@ -2756,9 +2755,8 @@ msgid "Open Editor Settings Folder" msgstr "Відкрити теку параметрів редактора" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°Ð¼Ð¸ екÑпорту" +msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¼Ð¾Ð¶Ð»Ð¸Ð²Ð¾ÑÑ‚Ñми редактора" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2799,7 +2797,7 @@ msgstr "Про" #: editor/editor_node.cpp msgid "Play the project." -msgstr "ЗапуÑтити проект." +msgstr "ЗапуÑтити проєкт." #: editor/editor_node.cpp msgid "Play" @@ -2851,16 +2849,16 @@ msgid "Spins when the editor window redraws." msgstr "ОбертаєтьÑÑ, коли перемальовуєтьÑÑ Ð²Ñ–ÐºÐ½Ð¾ редактора." #: editor/editor_node.cpp -msgid "Update Always" -msgstr "Завжди оновлювати" +msgid "Update Continuously" +msgstr "Оновлювати неперервно" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "Оновлювати зміни" +msgid "Update When Changed" +msgstr "Оновлювати при зміні" #: editor/editor_node.cpp -msgid "Disable Update Spinner" -msgstr "Вимкнути Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ°" +msgid "Hide Update Spinner" +msgstr "Приховати Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ°" #: editor/editor_node.cpp msgid "FileSystem" @@ -2889,17 +2887,22 @@ msgstr "Ðе зберігати" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." msgstr "" +"Ðе виÑтачає шаблона Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Android. Будь лаÑка, вÑтановіть відповідні " +"шаблони." #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Ð£Ð¿Ñ€Ð°Ð²Ð»Ñ–Ð½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°Ð¼Ð¸ екÑпорту" +msgstr "ÐšÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°Ð¼Ð¸" #: editor/editor_node.cpp msgid "" "This will install the Android project for custom builds.\n" "Note that, in order to use it, it needs to be enabled per export preset." msgstr "" +"У результаті Ð²Ð¸ÐºÐ¾Ð½Ð°Ð½Ð½Ñ Ñ†Ñ–Ñ”Ñ— дії буде вÑтановлено проєкт Android Ð´Ð»Ñ " +"нетипового збираннÑ.\n" +"Зауважте, що Ð´Ð»Ñ Ñ‚Ð¾Ð³Ð¾, щоб ним можна було ÑкориÑтатиÑÑ, його Ñлід увімкнути " +"екÑпортуваннÑм набору правил." #: editor/editor_node.cpp msgid "" @@ -2907,6 +2910,8 @@ msgid "" "Remove the \"build\" directory manually before attempting this operation " "again." msgstr "" +"Шаблон Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð´Ð»Ñ Android вже вÑтановлено. Його не буде перезапиÑано.\n" +"Вилучіть каталог «build» вручну, перш ніж намагатиÑÑ Ð¿Ð¾Ð²Ñ‚Ð¾Ñ€Ð¸Ñ‚Ð¸ цю дію." #: editor/editor_node.cpp msgid "Import Templates From ZIP File" @@ -2914,7 +2919,7 @@ msgstr "Імпортувати шаблони з ZIP-файлу" #: editor/editor_node.cpp editor/project_export.cpp msgid "Export Project" -msgstr "ЕкÑпортувати проект" +msgstr "ЕкÑпортувати проєкт" #: editor/editor_node.cpp msgid "Export Library" @@ -3050,7 +3055,7 @@ msgstr "ЧаÑ" msgid "Calls" msgstr "Виклики" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "Увімкнено" @@ -3157,6 +3162,11 @@ 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 "Ðовий ключ:" @@ -3168,11 +3178,6 @@ msgstr "Ðове значеннÑ:" msgid "Add Key/Value Pair" msgstr "Додати пару ключ-значеннÑ" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "Вилучити елемент" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3379,9 +3384,8 @@ msgid "SSL Handshake Error" msgstr "Помилка SSL РукоÑтиÑканнÑ" #: editor/export_template_manager.cpp -#, fuzzy msgid "Uncompressing Android Build Sources" -msgstr "Ð Ð¾Ð·Ð¿Ð°ÐºÐ¾Ð²ÑƒÐ²Ð°Ð½Ð½Ñ Ð°ÐºÑ‚Ð¸Ð²Ñ–Ð²" +msgstr "Розпаковуємо код Ð´Ð»Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð´Ð»Ñ Android" #: editor/export_template_manager.cpp msgid "Current Version:" @@ -3400,9 +3404,8 @@ msgid "Remove Template" msgstr "Вилучити шаблон" #: editor/export_template_manager.cpp -#, fuzzy msgid "Select Template File" -msgstr "Вибрати файл шаблону" +msgstr "Виберіть файл шаблону" #: editor/export_template_manager.cpp msgid "Export Template Manager" @@ -3462,9 +3465,8 @@ msgid "No name provided." msgstr "Ім'Ñ Ð½Ðµ вказано." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "Ðадане ім'Ñ Ð¼Ñ–Ñтить некоректні Ñимволи" +msgstr "Ðадане ім'Ñ Ð¼Ñ–Ñтить некоректні Ñимволи." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." @@ -3491,28 +3493,24 @@ msgid "Duplicating folder:" msgstr "Ð”ÑƒÐ±Ð»ÑŽÐ²Ð°Ð½Ð½Ñ Ñ‚ÐµÐºÐ¸:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Ðова уÑпадкована Ñцена..." +msgstr "Ðова уÑпадкована Ñцена" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Відкрити Ñцену" +msgstr "Відкрити Ñцени" #: editor/filesystem_dock.cpp msgid "Instance" msgstr "ЕкземплÑÑ€" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" -msgstr "Додати до вибраного" +msgstr "Додати до улюблених" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "Вилучити з вибраного" +msgstr "Вилучити з улюблених" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." @@ -3560,21 +3558,18 @@ msgid "Rename" msgstr "Перейменувати" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ñ‚ÐµÐºÐ°" +msgstr "ÐŸÐ¾Ð¿ÐµÑ€ÐµÐ´Ð½Ñ Ñ‚ÐµÐºÐ° або файл" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "ÐаÑтупна тека" +msgstr "ÐаÑтупна тека або файл" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "ПереÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ð¾Ñ— ÑиÑтеми" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" msgstr "Перемкнути режим поділу" @@ -3627,6 +3622,8 @@ 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 @@ -3678,6 +3675,7 @@ msgid "Nodes not in Group" msgstr "Вузли поза групою" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "Фільтрувати вузли" @@ -4068,9 +4066,8 @@ msgid "Open Animation Node" msgstr "Відкрити вузол анімації" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "Трикутник вже Ñ–Ñнує" +msgstr "Трикутник вже Ñ–Ñнує." #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Add Triangle" @@ -4217,7 +4214,6 @@ msgid "Edit Filtered Tracks:" msgstr "Редагувати фільтровані доріжки:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" msgstr "Увімкнути фільтруваннÑ" @@ -4354,9 +4350,8 @@ msgid "Enable Onion Skinning" msgstr "Увімкнути калькуваннÑ" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Onion Skinning Options" -msgstr "КалькуваннÑ" +msgstr "Параметри калькуваннÑ" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Directions" @@ -4923,6 +4918,8 @@ msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Якщо позначено, переÑÑƒÐ²Ð°Ð½Ð½Ñ Ð²ÑƒÐ·Ð»Ñ–Ð² Control змінюватиме їхню прив'Ñзку, а не " +"їхні полÑ." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" @@ -4938,41 +4935,35 @@ 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 -#, fuzzy msgid "Unlock Selected" -msgstr "Вилучити вибране" +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 "Create Custom Bone(s) from Node(s)" msgstr "Створити нетипові кіÑтки з вузлів" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "ОчиÑтити позу" +msgstr "ОчиÑтити кіÑтки" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -5060,9 +5051,8 @@ msgid "Snapping Options" msgstr "Параметри прив'Ñзки" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Grid" -msgstr "Прив'Ñзати до Ñітки" +msgstr "ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð´Ð¾ Ñітки" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" @@ -5082,37 +5072,30 @@ msgid "Use Pixel Snap" msgstr "ВикориÑтати Ð¿Ñ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð´Ð¾ пікÑелів" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Smart Snapping" msgstr "Інтелектуальне прилипаннÑ" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Parent" msgstr "ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð´Ð¾ предка" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Anchor" msgstr "ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð´Ð¾ прив'Ñзки вузла" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Sides" msgstr "ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð´Ð¾ боків вузла" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Node Center" msgstr "ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð´Ð¾ центру вузла" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Other Nodes" msgstr "ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð´Ð¾ інших вузлів" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Snap to Guides" msgstr "ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð´Ð¾ напрÑмних" @@ -5196,7 +5179,7 @@ msgstr "Кадрувати вибране" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Preview Canvas Scale" -msgstr "" +msgstr "Попередній переглÑд маÑштабованого полотна" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Translation mask for inserting keys." @@ -5252,9 +5235,8 @@ msgid "Divide grid step by 2" msgstr "Розділити крок Ñітки на 2" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Pan View" -msgstr "ВиглÑд ззаду" +msgstr "ÐŸÐ°Ð½Ð¾Ñ€Ð°Ð¼ÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Add %s" @@ -5280,9 +5262,8 @@ msgid "Error instancing scene from %s" msgstr "Помилка Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ñцени з %s" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" -msgstr "Змінити типовий тип" +msgstr "Змінити Ñтандартний тип" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" @@ -5324,6 +5305,13 @@ 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 "ОчиÑтити маÑку випромінюваннÑ" @@ -5369,14 +5357,12 @@ msgid "Create Emission Points From Node" msgstr "Створити випромінювач з вузла" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 0" -msgstr "ПлаÑкий0" +msgstr "ПлаÑкий 0" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Flat 1" -msgstr "ПлаÑкий1" +msgstr "ПлаÑкий 1" #: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp msgid "Ease In" @@ -5403,29 +5389,24 @@ msgid "Load Curve Preset" msgstr "Завантажити заготовку кривої" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" msgstr "Додати точку" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" msgstr "Вилучити точку" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Left Linear" msgstr "Лівий лінійний" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Right Linear" msgstr "Правий лінійний" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Load Preset" -msgstr "Завантажити заготовку" +msgstr "Завантажити шаблон" #: editor/plugins/curve_editor_plugin.cpp msgid "Remove Curve Point" @@ -5433,7 +5414,7 @@ msgstr "Видалити точку кривої" #: editor/plugins/curve_editor_plugin.cpp msgid "Toggle Curve Linear Tangent" -msgstr "Переключити криву лінійного тангенÑу" +msgstr "Перемкнути дотичну до кривої" #: editor/plugins/curve_editor_plugin.cpp msgid "Hold Shift to edit tangents individually" @@ -5480,18 +5461,16 @@ msgid "This doesn't work on scene root!" msgstr "Це не працює на корінь Ñцени!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Trimesh Static Shape" -msgstr "Створити увігнуту форму" +msgstr "Створити триÑіткову Ñтатичну форму" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Failed creating shapes!" -msgstr "" +msgstr "Ðе вдалоÑÑ Ñтворити форми!" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Shape(s)" -msgstr "Створити вигнуту форму" +msgstr "Створити вигнуті форми" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Navigation Mesh" @@ -5547,9 +5526,8 @@ msgid "Create Trimesh Collision Sibling" msgstr "Створити увігнуту облаÑть зіткненнÑ" #: editor/plugins/mesh_instance_editor_plugin.cpp -#, fuzzy msgid "Create Convex Collision Sibling(s)" -msgstr "Створити опуклу облаÑть зіткненнÑ" +msgstr "Створити опуклу облаÑті зіткненнÑ" #: editor/plugins/mesh_instance_editor_plugin.cpp msgid "Create Outline Mesh..." @@ -5909,7 +5887,6 @@ msgid "Split Segment (in curve)" msgstr "Розділити Ñегмент (кривої)" #: editor/plugins/physical_bone_plugin.cpp -#, fuzzy msgid "Move Joint" msgstr "ПереÑунути з'єднаннÑ" @@ -6243,10 +6220,18 @@ msgid "Find Next" 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 "Сортувати" @@ -6357,18 +6342,16 @@ msgid "Debug with External Editor" msgstr "Ð—Ð½ÐµÐ²Ð°Ð´Ð¶ÐµÐ½Ð½Ñ Ð·Ð° допомогою зовнішнього редактора" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Open Godot online documentation." -msgstr "Відкрити онлайнову документацію Godot" +msgstr "Відкрити онлайнову документацію Godot." #: editor/plugins/script_editor_plugin.cpp msgid "Request Docs" msgstr "Запит щодо документації" #: editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Help improve the Godot documentation by giving feedback." -msgstr "Допоможіть у поліпшенні документації до Godot, надіÑлавши Ñвій відгук" +msgstr "Допоможіть у поліпшенні документації Godot наданнÑм відгуків." #: editor/plugins/script_editor_plugin.cpp msgid "Search the reference documentation." @@ -6413,29 +6396,27 @@ msgid "Search Results" msgstr "Результати пошуку" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Connections to method:" -msgstr "ПідключитиÑÑ Ð´Ð¾ вузла:" +msgstr "З'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð· методом:" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Source" -msgstr "Джерело:" +msgstr "Джерело" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Signal" -msgstr "Сигнали" +msgstr "Сигнал" #: editor/plugins/script_text_editor.cpp msgid "Target" -msgstr "" +msgstr "ПризначеннÑ" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "" "Missing connected method '%s' for signal '%s' from node '%s' to node '%s'." -msgstr "Ðічого не з'єднано із входом «%s» вузла «%s»." +msgstr "" +"Ðе Ñтворено з'єднаного методу «%s» Ð´Ð»Ñ Ñигналу «%s» з вузла «%s» до вузла " +"«%s»." #: editor/plugins/script_text_editor.cpp msgid "Line" @@ -6482,20 +6463,24 @@ msgid "Syntax Highlighter" msgstr "ЗаÑіб підÑÐ²Ñ–Ñ‡ÑƒÐ²Ð°Ð½Ð½Ñ ÑинтакÑиÑу" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "Закладки" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +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 "Видалити Ñ€Ñдок" @@ -6513,24 +6498,20 @@ msgid "Toggle Comment" msgstr "Перемкнути коментар" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Toggle Bookmark" -msgstr "ÐŸÐµÑ€ÐµÐ¼Ð¸ÐºÐ°Ð½Ð½Ñ Ð¾Ð³Ð»Ñду" +msgstr "Увімкнути або вимкнути закладку" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Next Bookmark" -msgstr "Перейти до наÑтупної точки зупинки" +msgstr "Перейти до наÑтупної закладки" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Go to Previous Bookmark" -msgstr "Перейти до попередньої точки зупинки" +msgstr "Перейти до попередньої закладки" #: editor/plugins/script_text_editor.cpp -#, fuzzy msgid "Remove All Bookmarks" -msgstr "Вилучити уÑÑ– елементи" +msgstr "Вилучити вÑÑ– закладки" #: editor/plugins/script_text_editor.cpp msgid "Fold/Unfold Line" @@ -6606,13 +6587,12 @@ msgid "Contextual Help" msgstr "КонтекÑтна довідка" #: editor/plugins/shader_editor_plugin.cpp -#, fuzzy msgid "" "This shader has been modified on on disk.\n" "What action should be taken?" msgstr "" -"Такі файли на диÑку новіші.\n" -"Що робити?:" +"До цього шейдера внеÑено зміни на диÑку.\n" +"Що Ñлід зробити?" #: editor/plugins/shader_editor_plugin.cpp msgid "Shader" @@ -6958,7 +6938,6 @@ msgid "Right View" msgstr "ВиглÑд Ñправа" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Switch Perspective/Orthogonal View" msgstr "Перемкнути переглÑд перÑпективи/ортогональний переглÑд" @@ -7004,7 +6983,6 @@ msgid "Transform" msgstr "ПеретвореннÑ" #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Snap Object to Floor" msgstr "Приліпити об'єкт до підлоги" @@ -7196,14 +7174,12 @@ msgid "Settings:" msgstr "Параметри:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "No Frames Selected" -msgstr "Кадрувати вибране" +msgstr "Кадрів не позначено" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add %d Frame(s)" -msgstr "Додати кадр" +msgstr "Додати %d кадри" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frame" @@ -7254,13 +7230,12 @@ msgid "Animation Frames:" msgstr "Кадри анімації:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Add a Texture from File" -msgstr "Додати текÑтури до TileSet." +msgstr "Додати текÑтуру з файла" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Add Frames from a Sprite Sheet" -msgstr "" +msgstr "Додати кадри із аркуша Ñпрайтів" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Insert Empty (Before)" @@ -7279,29 +7254,24 @@ msgid "Move (After)" msgstr "ПереÑунути (піÑлÑ)" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select Frames" -msgstr "СтоÑувати кадри" +msgstr "Вибрати кадри" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Horizontal:" -msgstr "Відзеркалити горизонтально" +msgstr "Горизонтально:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Vertical:" -msgstr "Вершини" +msgstr "Вертикально:" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Select/Clear All Frames" -msgstr "Виділити вÑе" +msgstr "Позначити або Ñпорожнити уÑÑ– кадри" #: editor/plugins/sprite_frames_editor_plugin.cpp -#, fuzzy msgid "Create Frames from Sprite Sheet" -msgstr "Створити зі Ñцени" +msgstr "Створити кадри з аркуша Ñпрайтів" #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "SpriteFrames" @@ -7373,9 +7343,8 @@ msgid "Remove All" msgstr "Вилучити уÑÑ–" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Edit Theme" -msgstr "Редагувати тему..." +msgstr "Редагувати тему" #: editor/plugins/theme_editor_plugin.cpp msgid "Theme editing menu." @@ -7402,23 +7371,20 @@ msgid "Create From Current Editor Theme" msgstr "Створити на оÑнові поточної теми редактора" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Toggle Button" -msgstr "Кнопка миші" +msgstr "Кнопка-перемикач" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Button" -msgstr "Ð¡ÐµÑ€ÐµÐ´Ð½Ñ ÐºÐ½Ð¾Ð¿ÐºÐ°" +msgstr "Вимкнена кнопка" #: editor/plugins/theme_editor_plugin.cpp msgid "Item" msgstr "Елемент" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled Item" -msgstr "Вимкнено" +msgstr "Вимкнений елемент" #: editor/plugins/theme_editor_plugin.cpp msgid "Check Item" @@ -7438,21 +7404,19 @@ msgstr "Позначений пункт варіанта" #: editor/plugins/theme_editor_plugin.cpp msgid "Named Sep." -msgstr "" +msgstr "Імен. розд." #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "Підменю" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 1" -msgstr "Елемент" +msgstr "Елемент 1" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Item 2" -msgstr "Елемент" +msgstr "Елемент 2" #: editor/plugins/theme_editor_plugin.cpp msgid "Has" @@ -7463,9 +7427,8 @@ msgid "Many" msgstr "Багато" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Disabled LineEdit" -msgstr "Вимкнено" +msgstr "Вимкнений LineEdit" #: editor/plugins/theme_editor_plugin.cpp msgid "Tab 1" @@ -7480,13 +7443,12 @@ msgid "Tab 3" msgstr "Вкладка 3" #: editor/plugins/theme_editor_plugin.cpp -#, fuzzy msgid "Editable Item" -msgstr "Редагований дочірній елемент" +msgstr "Редагований елемент" #: editor/plugins/theme_editor_plugin.cpp msgid "Subtree" -msgstr "" +msgstr "Піддерево" #: editor/plugins/theme_editor_plugin.cpp msgid "Has,Many,Options" @@ -7566,14 +7528,12 @@ msgid "Mirror Y" msgstr "Віддзеркалити за Y" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "Ðвтоплитки" +msgstr "Вимкнути автоплитки" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Enable Priority" -msgstr "Редагувати пріоритетніÑть плитки" +msgstr "Увімкнути пріоритетніÑть" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Paint Tile" @@ -7584,33 +7544,30 @@ msgid "" "Shift+RMB: Line Draw\n" "Shift+Ctrl+RMB: Rectangle Paint" msgstr "" +"Shift+права кнопка: малювати лінію\n" +"Shift+Ctrl+права кнопка: малювати прÑмокутник" #: editor/plugins/tile_map_editor_plugin.cpp msgid "Pick Tile" msgstr "Вибрати плитку" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Left" -msgstr "Обертати ліворуч" +msgstr "Обернути ліворуч" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Rotate Right" -msgstr "Обертати праворуч" +msgstr "Обернути праворуч" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Horizontally" -msgstr "Відзеркалити горизонтально" +msgstr "Віддзеркалити горизонтально" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Flip Vertically" msgstr "Віддзеркалити вертикально" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Clear Transform" msgstr "ЗнÑти перетвореннÑ" @@ -7647,44 +7604,36 @@ msgid "Select the previous shape, subtile, or Tile." msgstr "Вибір попередньої форми, підплитки або плитки." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Region Mode" -msgstr "Режим виконаннÑ:" +msgstr "Режим облаÑті" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Collision Mode" -msgstr "Режим інтерполÑції" +msgstr "Режим перешкоди" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Occlusion Mode" -msgstr "Редагувати полігон перешкоди" +msgstr "Режим перешкоди" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Navigation Mode" -msgstr "Створити навігаційну Ñітку" +msgstr "Режим навігації" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Bitmask Mode" -msgstr "Режим повороту" +msgstr "Режим бітової маÑки" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Priority Mode" -msgstr "Режим екÑпортуваннÑ:" +msgstr "Режим пріоритетноÑті" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Icon Mode" -msgstr "Режим панорамуваннÑ" +msgstr "Режим піктограм" #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "Z Index Mode" -msgstr "Режим панорамуваннÑ" +msgstr "Режим Z-покажчика" #: editor/plugins/tile_set_editor_plugin.cpp msgid "Copy bitmask." @@ -7772,7 +7721,6 @@ msgid "Delete polygon." msgstr "Видалити полігон." #: editor/plugins/tile_set_editor_plugin.cpp -#, fuzzy msgid "" "LMB: Set bit on.\n" "RMB: Set bit off.\n" @@ -7781,6 +7729,7 @@ msgid "" msgstr "" "Ліва кнопка: вÑтановити біт.\n" "Права кнопка: знÑти біт.\n" +"Shift+ліва кнопка: вÑтановити біт-замінник.\n" "Клацніть на іншій плитці, щоб редагувати Ñ—Ñ—." #: editor/plugins/tile_set_editor_plugin.cpp @@ -7894,77 +7843,64 @@ msgid "TileSet" msgstr "Ðабір плиток" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input +" -msgstr "Додати вхід" +msgstr "Додати вхід +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add output +" -msgstr "Додати вхід" +msgstr "Додати вихід +" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar" -msgstr "МаÑштаб:" +msgstr "СкалÑÑ€" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "ІнÑпектор" +msgstr "Вектор" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" -msgstr "" +msgstr "Булеве" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Add input port" -msgstr "Додати вхід" +msgstr "Додати вхідний порт" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add output port" -msgstr "" +msgstr "Додати вихідний порт" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port type" -msgstr "Змінити типовий тип" +msgstr "Змінити тип вхідного порту" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port type" -msgstr "Змінити типовий тип" +msgstr "Змінити тип вихідного порту" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change input port name" -msgstr "Змінити назву входу" +msgstr "Змінити назву вхідного порту" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Change output port name" -msgstr "Змінити назву входу" +msgstr "Змінити назву вихідного порту" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove input port" -msgstr "Вилучити точку" +msgstr "Вилучити вхідний порт" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Remove output port" -msgstr "Вилучити точку" +msgstr "Вилучити вихідний порт" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Set expression" -msgstr "Змінити вираз" +msgstr "Ð’Ñтановити вираз" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Resize VisualShader node" -msgstr "VisualShader" +msgstr "Змінити розмір вузла VisualShader" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Set Uniform Name" @@ -8003,540 +7939,318 @@ msgid "Light" msgstr "Світло" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Create Shader Node" -msgstr "Створити вузол" +msgstr "Створити вузол шейдера" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color function." -msgstr "Перейти до функції" +msgstr "Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñƒ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Color operator." -msgstr "" +msgstr "Оператор кольору." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Grayscale function." -msgstr "Створити функцію" +msgstr "Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð²Ñ–Ð´Ñ‚Ñ–Ð½ÐºÑ–Ð² Ñірого." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts HSV vector to RGB equivalent." -msgstr "" +msgstr "Перетворює вектор HSV на еквівалентний колір RGB." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts RGB vector to HSV equivalent." -msgstr "" +msgstr "Перетворює вектор RGB на еквівалентний колір HSV." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Sepia function." -msgstr "Перейменувати функцію" +msgstr "Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ñепії." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Burn operator." -msgstr "" +msgstr "Оператор вигорÑннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Darken operator." -msgstr "" +msgstr "Оператор затемненнÑ." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Difference operator." -msgstr "Тільки відмінноÑті" +msgstr "Оператор різниці." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Dodge operator." -msgstr "" +msgstr "Оператор виÑвітленнÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "HardLight operator" -msgstr "" +msgstr "Оператор ÑÑкравого Ñвітла" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Lighten operator." -msgstr "" +msgstr "Оператор оÑвітленнÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Overlay operator." -msgstr "" +msgstr "Оператор накладаннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Screen operator." -msgstr "" +msgstr "Оператор екрана." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "SoftLight operator." -msgstr "" +msgstr "Оператор розÑÑ–Ñного." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color constant." -msgstr "Сталий" +msgstr "Сталий колір." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Color uniform." -msgstr "ЗнÑти перетвореннÑ" +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 an associated vector if the provided boolean value is true or false." msgstr "" +"Повертає пов'Ñзаний вектор за заданим булевим значеннÑм «true» або «false»." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Boolean constant." -msgstr "Змінити векторну конÑтанту" +msgstr "Булева Ñтала." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean uniform." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" +msgstr "Однорідне булеве." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" +msgid "'%s' input parameter for all shader modes." +msgstr "Вхідний параметр «%s» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Input parameter." -msgstr "ÐŸÑ€Ð¸Ð»Ð¸Ð¿Ð°Ð½Ð½Ñ Ð´Ð¾ предка" +msgstr "Вхідний параметр." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader modes." +msgstr "Вхідний параметр «%s» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин Ñ– фрагментів шейдера." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for fragment and light shader modes." +msgstr "Вхідний параметр «%s» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñ–Ð² фрагментів та Ñвітла шейдера." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" +msgid "'%s' input parameter for fragment shader mode." +msgstr "Вхідний параметр «%s» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñ–Ð² фрагментів шейдера." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" +msgid "'%s' input parameter for light shader mode." +msgstr "Вхідний параметр «%s» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" +msgid "'%s' input parameter for vertex shader mode." +msgstr "Вхідний параметр «%s» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" +msgid "'%s' input parameter for vertex and fragment shader mode." +msgstr "Вхідний параметр «%s» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин Ñ– фрагментів шейдера." #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar function." -msgstr "Змінити ÑкалÑрну функцію" +msgstr "СкалÑрна функціÑ." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar operator." -msgstr "Змінити чиÑловий оператор" +msgstr "СкалÑрний оператор." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "E constant (2.718282). Represents the base of the natural logarithm." -msgstr "" +msgstr "Стала Ойлера (2.718282). Це Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ” оÑновою натурального логарифма." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Epsilon constant (0.00001). Smallest possible scalar number." -msgstr "" +msgstr "Стала ε (0.00001). Ðайменше можливе ÑкалÑрне чиÑло." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Phi constant (1.618034). Golden ratio." -msgstr "" +msgstr "Стала «золотого» перерізу (1.618034)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/4 constant (0.785398) or 45 degrees." -msgstr "" +msgstr "Стала Ï€/4 (0.785398), радіанна міра кута у 45 градуÑів." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi/2 constant (1.570796) or 90 degrees." -msgstr "" +msgstr "Стала Ï€/2 (1.570796), радіанна міра кута у 90 градуÑів." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Pi constant (3.141593) or 180 degrees." -msgstr "" +msgstr "Стала Ï€ (3.141593), радіанна міра кута у 180 градуÑів." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Tau constant (6.283185) or 360 degrees." -msgstr "" +msgstr "Стала Ï„ (6.283185), радіанна міра кута у 360 градуÑів." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Sqrt2 constant (1.414214). Square root of 2." -msgstr "" +msgstr "Квадратний корінь з двох (1.414214)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the absolute value of the parameter." -msgstr "" +msgstr "Повертає модуль параметра." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-cosine of the parameter." -msgstr "" +msgstr "Повертає арккоÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Лише GLES3) Повертає обернений гіперболічний коÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-sine of the parameter." -msgstr "" +msgstr "Повертає аркÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic sine of the parameter." -msgstr "" +msgstr "(Лише GLES3) Повертає обернений гіперболічний ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameter." -msgstr "" +msgstr "Повертає Ð°Ñ€ÐºÑ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the arc-tangent of the parameters." -msgstr "" +msgstr "Повертає Ð°Ñ€ÐºÑ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ñ–Ð²." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the inverse hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Лише GLES3) Повертає обернений гіперболічний Ñ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: 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 "" +msgstr "Обмежує Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð¼Ñ–Ð¶ÐºÐ¾Ð¼ між наÑтупними двома значеннÑми." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the cosine of the parameter." -msgstr "" +msgstr "Повертає коÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic cosine of the parameter." -msgstr "" +msgstr "(Лише GLES3) Повертає гіперболічний коÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Converts a quantity in radians to degrees." -msgstr "" +msgstr "Перетворює Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ радіанах на Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ градуÑах." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-e Exponential." -msgstr "" +msgstr "Показникова Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ Ñ–Ð· оÑновою e (екÑпонента)." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 Exponential." -msgstr "" +msgstr "Показникова Ñ„ÑƒÐ½ÐºÑ†Ñ–Ñ Ñ–Ð· оÑновою 2." #: 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 "" +msgstr "ОбчиÑлює дробову чаÑтину аргументу." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the inverse of the square root of the parameter." -msgstr "" +msgstr "Повертає одиницю поділену на квадратний корінь з параметра." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Natural logarithm." -msgstr "" +msgstr "Ðатуральний логарифм." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Base-2 logarithm." -msgstr "" +msgstr "Двійковий логарифм." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the greater of two values." -msgstr "" +msgstr "Повертає більше із двох значень." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the lesser of two values." -msgstr "" +msgstr "Повертає менше з двох значень." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two scalars." -msgstr "" +msgstr "Лінійна інтерполÑÑ†Ñ–Ñ Ð²Ñ–Ð´ двох ÑкалÑрних значень." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the opposite value of the parameter." -msgstr "" +msgstr "Повертає значеннÑ, Ñке Ñ” протилежним до Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - scalar" -msgstr "" +msgstr "1.0 – ÑкалÑÑ€" #: 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 "" +msgstr "Перетворює Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ градуÑах на Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñƒ радіанах." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / scalar" -msgstr "" +msgstr "1.0 / ÑкалÑÑ€" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest integer to the parameter." -msgstr "" +msgstr "(Лише GLES3) Знаходить найближче ціле Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð¾ параметра." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the nearest even integer to the parameter." -msgstr "" +msgstr "(Лише GLES3) Знаходить найближче парне ціле Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð¾ параметра." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Clamps the value between 0.0 and 1.0." -msgstr "" +msgstr "Обмежує Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ð¼Ñ–Ð¶ÐºÐ¾Ð¼ від 0.0 до 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Extracts the sign of the parameter." -msgstr "" +msgstr "Визначає знак параметра." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the sine of the parameter." -msgstr "" +msgstr "Повертає ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic sine of the parameter." -msgstr "" +msgstr "(Лише GLES3) Повертає гіперболічний ÑÐ¸Ð½ÑƒÑ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the square root of the parameter." -msgstr "" +msgstr "Повертає квадратний корінь з параметра." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8546,6 +8260,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð³Ð»Ð°Ð´ÐºÐ¸Ñ… Ñходинок ( ÑкалÑÑ€(межа0), ÑкалÑÑ€(межа1), ÑкалÑÑ€(x) ).\n" +"\n" +"Повертає 0.0, Ñкщо «x» Ñ” меншим за «межа0», Ñ– 1.0, Ñкщо «x» Ñ” більшим за " +"«межа1». У вÑÑ–Ñ… інших випадках буде повернуто значеннÑ, Ñке Ñ” інтерполÑцією " +"у проміжку від 0.0 до 1.0, Ñку визначено на оÑнові поліномів Ерміта." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8553,71 +8272,69 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"ФункціÑ-Ñходинка ( ÑкалÑÑ€(межа), ÑкалÑÑ€(x) ).\n" +"\n" +"Повертає 0.0, Ñкщо «x» Ñ” меншим за «межа». Якщо це не так, повертає 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the tangent of the parameter." -msgstr "" +msgstr "Повертає Ñ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Returns the hyperbolic tangent of the parameter." -msgstr "" +msgstr "(Лише GLES3) Повертає гіперболічний Ñ‚Ð°Ð½Ð³ÐµÐ½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Finds the truncated value of the parameter." -msgstr "" +msgstr "(Лише GLES3) Визначає обрізане до цілого Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð°Ñ€Ð°Ð¼ÐµÑ‚Ñ€Ð°." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds scalar to scalar." -msgstr "" +msgstr "Додає ÑкалÑÑ€ до ÑкалÑра." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides scalar by scalar." -msgstr "" +msgstr "Ділить ÑкалÑÑ€ на ÑкалÑÑ€." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies scalar by scalar." -msgstr "" +msgstr "Множить ÑкалÑÑ€ на ÑкалÑÑ€." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two scalars." -msgstr "" +msgstr "Повертає лишок за двома ÑкалÑрами." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts scalar from scalar." -msgstr "" +msgstr "Віднімає ÑкалÑÑ€ від ÑкалÑра." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar constant." -msgstr "Змінити чиÑлову Ñталу" +msgstr "СкалÑрна Ñтала." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Scalar uniform." -msgstr "Змінити чиÑлову одиницю" +msgstr "Однорідний ÑкалÑÑ€." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the cubic texture lookup." -msgstr "" +msgstr "Виконує пошук кубічної текÑтури." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Perform the texture lookup." -msgstr "" +msgstr "Виконує пошук текÑтури." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Cubic texture uniform." -msgstr "Змінити одиницю текÑтури" +msgstr "Однорідна кубічна текÑтура." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "2D texture uniform." -msgstr "Змінити одиницю текÑтури" +msgstr "Однорідна плаÑка текÑтура." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform function." -msgstr "Вікно перетвореннÑ..." +msgstr "Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8629,74 +8346,77 @@ msgid "" "whose number of rows is the number of components in 'c' and whose number of " "columns is the number of components in 'r'." msgstr "" +"(Лише GLES3) ОбчиÑлити зовнішній добуток пари векторів.\n" +"\n" +"OuterProduct вважає перший параметр, «c», Ñ” вектором-Ñтовпчиком (матрицею із " +"одного Ñтовпчика) а другий параметр, «r», Ñ” вектором-Ñ€Ñдком (матрицею із " +"одного Ñ€Ñдка). Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð²Ð¸ÐºÐ¾Ð½ÑƒÑ” Ð¼Ð½Ð¾Ð¶ÐµÐ½Ð½Ñ Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†ÑŒ «c * r» так, що утворюєтьÑÑ " +"Ð¼Ð°Ñ‚Ñ€Ð¸Ñ†Ñ Ñ–Ð· кількіÑтю Ñ€Ñдків, Ñка дорівнює кількоÑті компонентів у «c», Ñ– " +"кількіÑтю Ñтовпчиків, Ñка дорівнює кількоÑті компонентів у «r»." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes transform from four vectors." -msgstr "" +msgstr "Створює Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð° оÑнові чотирьох векторів." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes transform to four vectors." -msgstr "" +msgstr "Розкладає Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð° чотири вектори." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the determinant of a transform." -msgstr "" +msgstr "(Лише GLES3) ОбчиÑлює визначник перетвореннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the inverse of a transform." -msgstr "" +msgstr "(Лише GLES3) ОбчиÑлює обернену матрицю перетвореннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) Calculates the transpose of a transform." -msgstr "" +msgstr "(Лише GLES3) ОбчиÑлює транÑпозицію перетвореннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies transform by transform." -msgstr "" +msgstr "Множить Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ð° перетвореннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by transform." -msgstr "" +msgstr "Множить вектор на перетвореннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform constant." -msgstr "ÐŸÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÑ€Ð²Ð°Ð½Ð¾." +msgstr "Стала перетвореннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Transform uniform." -msgstr "ÐŸÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¿ÐµÑ€ÐµÑ€Ð²Ð°Ð½Ð¾." +msgstr "Однорідне перетвореннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector function." -msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ñ„ÑƒÐ½ÐºÑ†Ñ–Ð¹Ð½Ð¾Ð³Ð¾." +msgstr "Векторна функціÑ." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector operator." -msgstr "Змінити векторний оператор" +msgstr "Векторний оператор." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Composes vector from three scalars." -msgstr "" +msgstr "Створює вектор на оÑнові трьох ÑкалÑрних координат." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Decomposes vector to three scalars." -msgstr "" +msgstr "Розкладає вектор на три ÑкалÑрні координати." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the cross product of two vectors." -msgstr "" +msgstr "ОбчиÑлює векторний добуток двох векторів." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the distance between two points." -msgstr "" +msgstr "Повертає відÑтань між точками." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the dot product of two vectors." -msgstr "" +msgstr "ОбчиÑлює ÑкалÑрний добуток двох векторів." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8705,36 +8425,42 @@ msgid "" "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 "" +"Повертає вектор, Ñкий має такий Ñамий напрÑмок Ñк еталонний вектор. Функції " +"передаютьÑÑ Ñ‚Ñ€Ð¸ векторних параметри: N — вектор Ð´Ð»Ñ Ð¾Ñ€Ñ–Ñ”Ð½Ñ‚Ð°Ñ†Ñ–Ñ—, I — вектор " +"падіннÑ, Ñ– Nref — еталонний вектор. Якщо ÑкалÑрний добуток I Ñ– Nref Ñ” " +"від'ємним, буде повернуто N. У іншому випадку буде повернуто вектор -N." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the length of a vector." -msgstr "" +msgstr "ОбчиÑлює довжину вектора." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Linear interpolation between two vectors." -msgstr "" +msgstr "Лінійна інтерполÑÑ†Ñ–Ñ Ð²Ñ–Ð´ двох векторних значень." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Calculates the normalize product of vector." -msgstr "" +msgstr "Повертає нормалізований векторний добуток векторів." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 - vector" -msgstr "" +msgstr "1.0 – вектор" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "1.0 / vector" -msgstr "" +msgstr "1.0 / вектор" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "Returns a vector that points in the direction of reflection ( a : incident " "vector, b : normal vector )." msgstr "" +"Повертає вектор, Ñкий вказує напрÑмок Ð²Ñ–Ð´Ð±Ð¸Ñ‚Ñ‚Ñ ( a — вектор падіннÑ, b — " +"вектор нормалі )." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns a vector that points in the direction of refraction." -msgstr "" +msgstr "Повертає вектор, Ñкий вказує напрÑмок рефракції." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8744,6 +8470,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð³Ð»Ð°Ð´ÐºÐ¸Ñ… Ñходинок ( вектор(межа0), вектор(межа1), вектор(x) ).\n" +"\n" +"Повертає 0.0, Ñкщо «x» Ñ” меншим за «межа0», Ñ– 1.0, Ñкщо «x» Ñ” більшим за " +"«межа1». У вÑÑ–Ñ… інших випадках буде повернуто значеннÑ, Ñке Ñ” інтерполÑцією " +"у проміжку від 0.0 до 1.0, Ñку визначено на оÑнові поліномів Ерміта." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8753,6 +8484,11 @@ msgid "" "'edge1'. Otherwise the return value is interpolated between 0.0 and 1.0 " "using Hermite polynomials." msgstr "" +"Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð³Ð»Ð°Ð´ÐºÐ¸Ñ… Ñходинок ( ÑкалÑÑ€(межа0), ÑкалÑÑ€(межа1), вектор(x) ).\n" +"\n" +"Повертає 0.0, Ñкщо «x» Ñ” меншим за «межа0», Ñ– 1.0, Ñкщо «x» Ñ” більшим за " +"«межа1». У вÑÑ–Ñ… інших випадках буде повернуто значеннÑ, Ñке Ñ” інтерполÑцією " +"у проміжку від 0.0 до 1.0, Ñку визначено на оÑнові поліномів Ерміта." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8760,6 +8496,9 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"ФункціÑ-Ñходинка ( вектор(межа), вектор(x) ).\n" +"\n" +"Повертає 0.0, Ñкщо «x» Ñ” меншим за «межа». Якщо це не так, повертає 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8767,36 +8506,37 @@ msgid "" "\n" "Returns 0.0 if 'x' is smaller then 'edge' and otherwise 1.0." msgstr "" +"ФункціÑ-Ñходинка ( ÑкалÑÑ€(межа), вектор(x) ).\n" +"\n" +"Повертає 0.0, Ñкщо «x» Ñ” меншим за «межа». Якщо це не так, повертає 1.0." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Adds vector to vector." -msgstr "" +msgstr "Додає вектор до вектора." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Divides vector by vector." -msgstr "" +msgstr "Ділить вектор на вектор." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Multiplies vector by vector." -msgstr "" +msgstr "Множить вектор на вектор." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Returns the remainder of the two vectors." -msgstr "" +msgstr "Повертає лишок за двома векторами." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Subtracts vector from vector." -msgstr "" +msgstr "Віднімає вектор від вектора." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector constant." -msgstr "Змінити векторну конÑтанту" +msgstr "Векторна Ñтала." #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector uniform." -msgstr "ÐŸÑ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð¾Ð´Ð½Ð¾Ñ€Ñ–Ð´Ð½Ð¾Ð³Ð¾." +msgstr "Однорідний вектор." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" @@ -8804,56 +8544,78 @@ msgid "" "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 "" +"Ðетиповий вираз мовою шейдерів Godot із нетиповою кількіÑтю вхідних Ñ– " +"вихідних портів. Це безпоÑÐµÑ€ÐµÐ´Ð½Ñ Ð²Ñтавка до коду у функцію вершин, " +"фрагментів або Ñвітла. Ðе викориÑтовуйте це Ð´Ð»Ñ Ð½Ð°Ð¿Ð¸ÑÐ°Ð½Ð½Ñ Ð²Ð±ÑƒÐ´Ð¾Ð²Ð°Ð½Ð¸Ñ… " +"оголошень функцій." #: 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 "(GLES3 only) (Fragment/Light mode only) Scalar derivative function." msgstr "" +"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ ÑкалÑрної " +"похідної." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "(GLES3 only) (Fragment/Light mode only) Vector derivative function." msgstr "" +"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) Ð¤ÑƒÐ½ÐºÑ†Ñ–Ñ Ð²ÐµÐºÑ‚Ð¾Ñ€Ð½Ð¾Ñ— " +"похідної." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'x' using " "local differencing." msgstr "" +"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) (вектор) Похідна у «x» на " +"оÑнові локального диференціюваннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'x' using " "local differencing." msgstr "" +"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) (ÑкалÑÑ€) Похідна у «x» на " +"оÑнові локального диференціюваннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Derivative in 'y' using " "local differencing." msgstr "" +"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) (вектор) Похідна у «y» на " +"оÑнові локального диференціюваннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Derivative in 'y' using " "local differencing." msgstr "" +"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) (ÑкалÑÑ€) Похідна у «y» на " +"оÑнові локального диференціюваннÑ." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Vector) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) (вектор) Сума похідних за " +"модулем у «x» та «y»." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "" "(GLES3 only) (Fragment/Light mode only) (Scalar) Sum of absolute derivative " "in 'x' and 'y'." msgstr "" +"(Лише GLES3) (лише у режимі фрагментів або Ñвітла) Сума похідних за модулем " +"у «x» та «y»." #: editor/plugins/visual_shader_editor_plugin.cpp msgid "VisualShader" @@ -8884,7 +8646,7 @@ msgid "" "Failed to export the project for platform '%s'.\n" "Export templates seem to be missing or invalid." msgstr "" -"Ðе вдалоÑÑ ÐµÐºÑпортувати проект Ð´Ð»Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð¸ «%s».\n" +"Ðе вдалоÑÑ ÐµÐºÑпортувати проєкт Ð´Ð»Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð¸ «%s».\n" "ЗдаєтьÑÑ, шаблони екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ð¿ÑƒÑ‰ÐµÐ½Ð¾ або вони Ñ” некоректними." #: editor/project_export.cpp @@ -8893,7 +8655,7 @@ msgid "" "This might be due to a configuration issue in the export preset or your " "export settings." msgstr "" -"Ðе вдалоÑÑ ÐµÐºÑпортувати проект Ð´Ð»Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð¸ «%s».\n" +"Ðе вдалоÑÑ ÐµÐºÑпортувати проєкт Ð´Ð»Ñ Ð¿Ð»Ð°Ñ‚Ñ„Ð¾Ñ€Ð¼Ð¸ «%s».\n" "Причиною може бути помилка у налаштуваннÑÑ… у наборі налаштувань Ð´Ð»Ñ " "екÑÐ¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð°Ð±Ð¾ параметрах екÑпортуваннÑ." @@ -8932,7 +8694,7 @@ msgstr "РеÑурÑи" #: editor/project_export.cpp msgid "Export all resources in the project" -msgstr "ЕкÑпортувати уÑÑ– реÑурÑи у проекті" +msgstr "ЕкÑпортувати уÑÑ– реÑурÑи у проєкті" #: editor/project_export.cpp msgid "Export selected scenes (and dependencies)" @@ -8961,7 +8723,7 @@ msgstr "" msgid "" "Filters to exclude files from project (comma separated, e.g: *.json, *.txt)" msgstr "" -"Фільтри Ð²Ð¸ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² з проекту (з відокремленнÑм комами, приклад: *." +"Фільтри Ð²Ð¸ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² з проєкту (з відокремленнÑм комами, приклад: *." "json, *.txt)" #: editor/project_export.cpp @@ -9038,7 +8800,7 @@ msgstr "ШлÑху не Ñ–Ñнує." #: editor/project_manager.cpp msgid "Invalid '.zip' project file, does not contain a 'project.godot' file." -msgstr "Ðекоректний файл проекту «.zip»: у ньому немає файла «project.godot»." +msgstr "Ðекоректний файл проєкту «.zip»: у ньому немає файла «project.godot»." #: editor/project_manager.cpp msgid "Please choose an empty folder." @@ -9050,19 +8812,19 @@ msgstr "Будь лаÑка, виберіть файл «project.godot» або #: editor/project_manager.cpp msgid "Directory already contains a Godot project." -msgstr "У каталозі вже міÑтитьÑÑ Ð¿Ñ€Ð¾ÐµÐºÑ‚ Godot." +msgstr "У каталозі вже міÑтитьÑÑ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚ Godot." #: editor/project_manager.cpp msgid "New Game Project" -msgstr "Ðовий проект гри" +msgstr "Ðовий проєкт гри" #: editor/project_manager.cpp msgid "Imported Project" -msgstr "Імпортований проект" +msgstr "Імпортований проєкт" #: editor/project_manager.cpp msgid "Invalid Project Name." -msgstr "Ðекоректна назва проекту." +msgstr "Ðекоректна назва проєкту." #: editor/project_manager.cpp msgid "Couldn't create folder." @@ -9074,27 +8836,27 @@ msgstr "У вказаному каталозі вже міÑтитьÑÑ Ñ‚ÐµÐºÐ #: editor/project_manager.cpp msgid "It would be a good idea to name your project." -msgstr "Вам варто дати назву вашому проекту." +msgstr "Вам варто дати назву вашому проєкту." #: editor/project_manager.cpp msgid "Invalid project path (changed anything?)." -msgstr "Ðекоректний шлÑÑ… до проекту (щоÑÑŒ змінилоÑÑ?)." +msgstr "Ðекоректний шлÑÑ… до проєкту (щоÑÑŒ змінилоÑÑ?)." #: editor/project_manager.cpp msgid "" "Couldn't load project.godot in project path (error %d). It may be missing or " "corrupted." msgstr "" -"Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ project.godot у каталозі проекту (помилка %d). " +"Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ project.godot у каталозі проєкту (помилка %d). " "Можливо, файл вилучено або пошкоджено." #: editor/project_manager.cpp msgid "Couldn't edit project.godot in project path." -msgstr "Ðе вдалоÑÑ Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸ project.godot у каталозі проекту." +msgstr "Ðе вдалоÑÑ Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ñ‚Ð¸ project.godot у каталозі проєкту." #: editor/project_manager.cpp msgid "Couldn't create project.godot in project path." -msgstr "Ðе вдалоÑÑ Ñтворити project.godot у каталозі проекту." +msgstr "Ðе вдалоÑÑ Ñтворити project.godot у каталозі проєкту." #: editor/project_manager.cpp msgid "The following files failed extraction from package:" @@ -9102,11 +8864,11 @@ msgstr "Ðе вдалоÑÑ Ð²Ð¸Ð´Ð¾Ð±ÑƒÑ‚Ð¸ такі файли з пакунк #: editor/project_manager.cpp msgid "Rename Project" -msgstr "Перейменувати проект" +msgstr "Перейменувати проєкт" #: editor/project_manager.cpp msgid "Import Existing Project" -msgstr "Імпортувати наÑвний проект" +msgstr "Імпортувати наÑвний проєкт" #: editor/project_manager.cpp msgid "Import & Edit" @@ -9114,7 +8876,7 @@ msgstr "Імпортувати та редагувати" #: editor/project_manager.cpp msgid "Create New Project" -msgstr "Створити новий проект" +msgstr "Створити новий проєкт" #: editor/project_manager.cpp msgid "Create & Edit" @@ -9122,7 +8884,7 @@ msgstr "Створити та змінити" #: editor/project_manager.cpp msgid "Install Project:" -msgstr "Ð’Ñтановити проект:" +msgstr "Ð’Ñтановити проєкт:" #: editor/project_manager.cpp msgid "Install & Edit" @@ -9130,15 +8892,15 @@ msgstr "Ð’Ñтановити та змінити" #: editor/project_manager.cpp msgid "Project Name:" -msgstr "Ðазва проекту:" +msgstr "Ðазва проєкту:" #: editor/project_manager.cpp msgid "Project Path:" -msgstr "ШлÑÑ… проекту:" +msgstr "ШлÑÑ… проєкту:" #: editor/project_manager.cpp msgid "Project Installation Path:" -msgstr "ШлÑÑ… вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ñƒ:" +msgstr "ШлÑÑ… вÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ:" #: editor/project_manager.cpp msgid "Renderer:" @@ -9184,18 +8946,17 @@ msgstr "" #: editor/project_manager.cpp msgid "Unnamed Project" -msgstr "Проект без назви" +msgstr "Проєкт без назви" #: editor/project_manager.cpp msgid "Can't open project at '%s'." -msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ проект у «%s»." +msgstr "Ðе вдалоÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ проєкт у «%s»." #: editor/project_manager.cpp msgid "Are you sure to open more than one project?" -msgstr "Ви Ñправді хочете відкрити декілька проектів одразу?" +msgstr "Ви Ñправді хочете відкрити декілька проєктів одразу?" #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file does not specify the version of Godot " "through which it was created.\n" @@ -9207,7 +8968,7 @@ msgid "" "Warning: You won't be able to open the project with previous versions of the " "engine anymore." msgstr "" -"У вказаному нижче файлі параметрів проекту не вказано верÑÑ–ÑŽ Godot, за " +"У вказаному нижче файлі параметрів проєкту не вказано верÑÑ–ÑŽ Godot, за " "допомогою Ñкої його було Ñтворено.\n" "\n" "%s\n" @@ -9215,10 +8976,9 @@ msgstr "" "Якщо ви продовжите процедуру його відкриттÑ, дані буде перетворено до " "формату файла налаштувань поточної верÑÑ–Ñ— Godot.\n" "ПопередженнÑ: у результаті Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ð¸ втратите можливіÑть Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ " -"проекту у заÑтарілих верÑÑ–ÑÑ… рушіÑ." +"проєкту у заÑтарілих верÑÑ–ÑÑ… рушіÑ." #: editor/project_manager.cpp -#, fuzzy msgid "" "The following project settings file was generated by an older engine " "version, and needs to be converted for this version:\n" @@ -9229,86 +8989,84 @@ msgid "" "Warning: You won't be able to open the project with previous versions of the " "engine anymore." msgstr "" -"Вказаний нижче файл параметрів проекту було Ñтворено у заÑтарілій верÑÑ–Ñ— " +"Вказаний нижче файл параметрів проєкту було Ñтворено у заÑтарілій верÑÑ–Ñ— " "рушіÑ. Його доведетьÑÑ Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€Ð¸Ñ‚Ð¸ до поточної верÑÑ–Ñ—:\n" "\n" "%s\n" "\n" "Хочете виконати таке перетвореннÑ?\n" "ПопередженнÑ: у результаті Ð¿ÐµÑ€ÐµÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ð¸ втратите можливіÑть Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ñ‚Ñ " -"проекту у заÑтарілих верÑÑ–ÑÑ… рушіÑ." +"проєкту у заÑтарілих верÑÑ–ÑÑ… рушіÑ." #: 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 -#, fuzzy 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 "" -"Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити проект: не визначено головної Ñцени.\n" -"Будь лаÑка, змініть проект, вÑтановивши головну Ñцену у категорії «Програма» " -"Ñторінки «Параметри проекту»." +"Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити проєкт: не визначено головної Ñцени.\n" +"Будь лаÑка, змініть проєкт, вÑтановивши головну Ñцену у категорії «Програма» " +"Ñторінки «Параметри проєкту»." #: editor/project_manager.cpp msgid "" "Can't run project: Assets need to be imported.\n" "Please edit the project to trigger the initial import." msgstr "" -"Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити проект: Ñлід імпортувати вміÑÑ‚.\n" -"Будь лаÑка, змініть проект так, щоб увімкнути початкове імпортуваннÑ." +"Ðе вдалоÑÑ Ð·Ð°Ð¿ÑƒÑтити проєкт: Ñлід імпортувати вміÑÑ‚.\n" +"Будь лаÑка, змініть проєкт так, щоб увімкнути початкове імпортуваннÑ." #: editor/project_manager.cpp -#, fuzzy msgid "Are you sure to run %d projects at once?" -msgstr "Ви Ñправді хочете запуÑтити декілька проектів одночаÑно?" +msgstr "Ви Ñправді хочете запуÑтити %d проєктів одночаÑно?" #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove %d projects from the list?\n" "The project folders' contents won't be modified." -msgstr "Вилучити проект зі ÑпиÑку? (ВміÑÑ‚ теки не буде змінено)" +msgstr "" +"Вилучити %d проєктів зі ÑпиÑку?\n" +"ВміÑÑ‚ тек проєктів змінено не буде." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove this project from the list?\n" "The project folder's contents won't be modified." -msgstr "Вилучити проект зі ÑпиÑку? (ВміÑÑ‚ теки не буде змінено)" +msgstr "" +"Вилучити цей проєкт зі ÑпиÑку?\n" +"ВміÑÑ‚ теки не буде змінено." #: editor/project_manager.cpp -#, fuzzy msgid "" "Remove all missing projects from the list? (Folders contents will not be " "modified)" -msgstr "Вилучити проект зі ÑпиÑку? (ВміÑÑ‚ теки не буде змінено)" +msgstr "" +"Вилучити уÑÑ– проєкти, Ñкі не знайдено, зі ÑпиÑку? (ВміÑÑ‚ тек не буде змінено)" #: editor/project_manager.cpp -#, fuzzy msgid "" "Language changed.\n" "The interface will update after restarting the editor or project manager." msgstr "" "Змінено мову.\n" "Ð†Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð±ÑƒÐ´Ðµ оновлено під Ñ‡Ð°Ñ Ð½Ð°Ñтупного запуÑку редактора або заÑобу " -"ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾ÐµÐºÑ‚Ð°Ð¼Ð¸." +"ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ð°Ð¼Ð¸." #: editor/project_manager.cpp -#, fuzzy msgid "" "Are you sure to scan %s folders for existing Godot projects?\n" "This could take a while." msgstr "" -"Ви наказали розпочати ÑÐºÐ°Ð½ÑƒÐ²Ð°Ð½Ð½Ñ %s тек у пошуках наÑвних проектів Godot. " -"Підтверджуєте ÑкануваннÑ?" +"Ви Ñправді хочете виконати пошук у %s теках наÑвних проєктів Godot?\n" +"Пошук може бути доволі тривалим." #: editor/project_manager.cpp msgid "Project Manager" @@ -9316,7 +9074,7 @@ msgstr "Керівник проекту" #: editor/project_manager.cpp msgid "Project List" -msgstr "СпиÑок проектів" +msgstr "СпиÑок проєктів" #: editor/project_manager.cpp msgid "Scan" @@ -9328,12 +9086,11 @@ msgstr "Виберіть теку Ð´Ð»Ñ ÑкануваннÑ" #: editor/project_manager.cpp msgid "New Project" -msgstr "Ðовий проект" +msgstr "Ðовий проєкт" #: editor/project_manager.cpp -#, fuzzy msgid "Remove Missing" -msgstr "Вилучити точку" +msgstr "Вилучити пропущене" #: editor/project_manager.cpp msgid "Templates" @@ -9349,16 +9106,15 @@ msgstr "Перезавантажити зараз" #: editor/project_manager.cpp msgid "Can't run project" -msgstr "Ðе вдаєтьÑÑ Ð·Ð°Ð¿ÑƒÑтити проект" +msgstr "Ðе вдаєтьÑÑ Ð·Ð°Ð¿ÑƒÑтити проєкт" #: editor/project_manager.cpp -#, fuzzy msgid "" "You currently don't have any projects.\n" "Would you like to explore official example projects in the Asset Library?" msgstr "" -"Зараз проектів немає.\n" -"Хочете вивчити проекти офіційних прикладів з бібліотеки даних?" +"Зараз проєктів немає.\n" +"Хочете вивчити проєкти офіційних прикладів з бібліотеки даних?" #: editor/project_settings_editor.cpp msgid "Key " @@ -9385,9 +9141,8 @@ msgstr "" "Ñимволів «/», «:», «=», «\\» та «\"»" #: editor/project_settings_editor.cpp -#, fuzzy msgid "An action with the name '%s' already exists." -msgstr "Ð—Ð°Ð¿Ð¸Ñ Ð´Ñ–Ñ— «%s» вже Ñ–Ñнує!" +msgstr "Ð”Ñ–Ñ Ñ–Ð· назвою «%s» вже Ñ–Ñнує." #: editor/project_settings_editor.cpp msgid "Rename Input Action Event" @@ -9595,20 +9350,19 @@ msgstr "Змінено режим Ñ„Ñ–Ð»ÑŒÑ‚Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð»Ð¾ÐºÐ°Ð»Ñ–" #: editor/project_settings_editor.cpp msgid "Project Settings (project.godot)" -msgstr "Параметри проекту (project.godot)" +msgstr "Параметри проєкту (project.godot)" #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp msgid "General" -msgstr "\"Загальне\"" +msgstr "Загальне" #: editor/project_settings_editor.cpp msgid "Override For..." msgstr "Перевизначити на..." #: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp -#, fuzzy msgid "The editor must be restarted for changes to take effect." -msgstr "Щоб зміни набули чинноÑті редактор Ñлід перезапуÑтити" +msgstr "Щоб зміни набули чинноÑті, редактор Ñлід перезапуÑтити." #: editor/project_settings_editor.cpp msgid "Input Map" @@ -9667,12 +9421,10 @@ msgid "Locales Filter" msgstr "Фільтр локалізацій" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show All Locales" msgstr "Показати уÑÑ– локалізації" #: editor/project_settings_editor.cpp -#, fuzzy msgid "Show Selected Locales Only" msgstr "Показати лише позначені локалізації" @@ -9762,7 +9514,6 @@ msgid "Suffix" msgstr "СуфікÑ" #: editor/rename_dialog.cpp -#, fuzzy msgid "Advanced Options" msgstr "Додаткові параметри" @@ -10027,9 +9778,8 @@ msgid "User Interface" msgstr "Ð†Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ ÐºÐ¾Ñ€Ð¸Ñтувача" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Other Node" -msgstr "Вилучити вузол" +msgstr "Інший вузол" #: editor/scene_tree_dock.cpp msgid "Can't operate on nodes from a foreign scene!" @@ -10072,7 +9822,6 @@ msgid "Clear Inheritance" msgstr "УÑунути уÑпадкуваннÑ" #: editor/scene_tree_dock.cpp -#, fuzzy msgid "Open Documentation" msgstr "Відкрити документацію" @@ -10081,6 +9830,10 @@ msgid "Add Child Node" msgstr "Додати дочірній вузол" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "Розгорнути/Згорнути вÑе" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "Змінити тип" @@ -10109,8 +9862,8 @@ msgid "Delete (No Confirm)" msgstr "Вилучити (без підтвердженнÑ)" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "Додати або Ñтворити новий вузол" +msgid "Add/Create a New Node." +msgstr "Додати або Ñтворити новий вузол." #: editor/scene_tree_dock.cpp msgid "" @@ -10145,19 +9898,16 @@ 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 -#, fuzzy msgid "(Connecting From)" -msgstr "Помилка з'єднаннÑ" +msgstr "(Джерело з'єднаннÑ)" #: editor/scene_tree_editor.cpp msgid "Node configuration warning:" @@ -10188,9 +9938,8 @@ msgstr "" "Клацніть, щоб переглÑнути панель груп." #: editor/scene_tree_editor.cpp -#, fuzzy msgid "Open Script:" -msgstr "Відкрити Ñкрипт" +msgstr "Відкрити Ñкрипт:" #: editor/scene_tree_editor.cpp msgid "" @@ -10241,39 +9990,32 @@ msgid "Select a Node" msgstr "Виберіть вузол" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is empty." -msgstr "Порожній шлÑÑ…" +msgstr "Порожній шлÑÑ…." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Filename is empty." -msgstr "Ðазва файла Ñ” порожньою" +msgstr "ÐŸÐ¾Ñ€Ð¾Ð¶Ð½Ñ Ð½Ð°Ð·Ð²Ð° файла." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Path is not local." -msgstr "ШлÑÑ… не Ñ” локальним" +msgstr "ШлÑÑ… не Ñ” локальним." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid base path." -msgstr "Ðекоректний базовий шлÑÑ…" +msgstr "Ðекоректний базовий шлÑÑ…." #: editor/script_create_dialog.cpp -#, fuzzy msgid "A directory with the same name exists." -msgstr "Каталог із такою назвою вже Ñ–Ñнує" +msgstr "Каталог із такою назвою вже Ñ–Ñнує." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid extension." -msgstr "Ðекоректний ÑуфікÑ" +msgstr "Ðекоректний ÑуфікÑ." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Wrong extension chosen." -msgstr "Вибрано некоректний ÑуфікÑ" +msgstr "Вибрано некоректний ÑуфікÑ." #: editor/script_create_dialog.cpp msgid "Error loading template '%s'" @@ -10292,7 +10034,6 @@ msgid "N/A" msgstr "Ð/З" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Open Script / Choose Location" msgstr "Відкрити Ñкрипт або вибрати міÑце" @@ -10301,43 +10042,36 @@ msgid "Open Script" msgstr "Відкрити Ñкрипт" #: editor/script_create_dialog.cpp -#, fuzzy msgid "File exists, it will be reused." -msgstr "Файл вже Ñ–Ñнує, його буде викориÑтано повторно" +msgstr "Файл вже Ñ–Ñнує, його буде викориÑтано повторно." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid class name." -msgstr "Ðекоректна назва клаÑу" +msgstr "Ðекоректна назва клаÑу." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Invalid inherited parent name or path." -msgstr "Ðекоректна назва або шлÑÑ… до уÑпадкованого батьківÑького елемента" +msgstr "Ðекоректна назва або шлÑÑ… до уÑпадкованого батьківÑького елемента." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Script is valid." -msgstr "Скрипт Ñ” коректним" +msgstr "Скрипт Ñ” коректним." #: editor/script_create_dialog.cpp msgid "Allowed: a-z, A-Z, 0-9 and _" msgstr "Можна викориÑтовувати: a-z, A-Z, 0-9 Ñ– _" #: editor/script_create_dialog.cpp -#, fuzzy msgid "Built-in script (into scene file)." -msgstr "Вбудований (до файла Ñцени) Ñкрипт" +msgstr "Вбудований (до файла Ñцени) Ñкрипт." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will create a new script file." -msgstr "Створити новий файл Ñкрипту" +msgstr "Створить файл Ñкрипту." #: editor/script_create_dialog.cpp -#, fuzzy msgid "Will load an existing script file." -msgstr "Завантажити наÑвний файл Ñкрипту" +msgstr "Завантажити наÑвний файл Ñкрипту." #: editor/script_create_dialog.cpp msgid "Language" @@ -10379,7 +10113,7 @@ msgstr "ТраÑÑƒÐ²Ð°Ð½Ð½Ñ Ñтека" msgid "Pick one or more items from the list to display the graph." msgstr "Виберіть один або декілька пунктів зі ÑпиÑку Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ³Ð»Ñду графу." -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "Помилки" @@ -10469,7 +10203,7 @@ msgstr "Ð’Ñтановити з дерева" #: editor/script_editor_debugger.cpp msgid "Export measures as CSV" -msgstr "" +msgstr "ЕкÑпортувати виміри Ñк CSV" #: editor/settings_config_dialog.cpp msgid "Erase Shortcut" @@ -10601,12 +10335,11 @@ msgstr "Бібліотека GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Enabled GDNative Singleton" -msgstr "" +msgstr "Увімкнений одинак GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp -#, fuzzy msgid "Disabled GDNative Singleton" -msgstr "Вимкнути Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð»Ñ–Ñ‡Ð¸Ð»ÑŒÐ½Ð¸ÐºÐ°" +msgstr "Вимкнений одинак GDNative" #: modules/gdnative/gdnative_library_singleton_editor.cpp msgid "Library" @@ -10695,9 +10428,8 @@ msgid "GridMap Fill Selection" msgstr "Вибір Ð·Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp -#, fuzzy msgid "GridMap Paste Selection" -msgstr "Ð’Ð¸Ð»ÑƒÑ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾ GridMap" +msgstr "Ð—Ð°Ð¿Ð¾Ð²Ð½ÐµÐ½Ð½Ñ Ð¿Ð¾Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¾Ð³Ð¾ GridMap" #: modules/gridmap/grid_map_editor_plugin.cpp msgid "GridMap Paint" @@ -10783,54 +10515,6 @@ msgstr "ВідÑтань вибору:" msgid "Class name can't be a reserved keyword" msgstr "Ðазвою клаÑу не може бути зарезервоване ключове Ñлово" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð²'Ñзку..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "Створюємо проект C#..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "Ðе вдалоÑÑ Ñтворити розв'Ñзок." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ розв'Ñзок." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "Зроблено" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "Ðе вдалоÑÑ Ñтворити проект C#." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Моно" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "Про підтримку C#" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "Створити розв'Ñзок C#" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "ЗбираннÑ" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "Зібрати проект" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "ПереглÑнути журнал" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "Кінець траÑÑƒÐ²Ð°Ð½Ð½Ñ Ñтека Ð´Ð»Ñ Ð²Ð½ÑƒÑ‚Ñ€Ñ–ÑˆÐ½ÑŒÐ¾Ð³Ð¾ виключеннÑ" @@ -11124,9 +10808,8 @@ msgid "Available Nodes:" msgstr "ДоÑтупні вузли:" #: modules/visual_script/visual_script_editor.cpp -#, fuzzy msgid "Select or create a function to edit its graph." -msgstr "Виберіть або Ñтворіть функцію Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ€Ð°Ñ„Ð°" +msgstr "Виберіть або Ñтворіть функцію Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ Ð³Ñ€Ð°Ñ„Ñƒ." #: modules/visual_script/visual_script_editor.cpp msgid "Delete Selected" @@ -11263,15 +10946,21 @@ msgstr "" #: platform/android/export/export.cpp msgid "Custom build requires a valid Android SDK path in Editor Settings." msgstr "" +"Ðетипове Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¿Ð¾Ñ‚Ñ€ÐµÐ±ÑƒÑ” коректного шлÑху до SDK Ð´Ð»Ñ Android у параметрах " +"редактора." #: platform/android/export/export.cpp msgid "Invalid Android SDK path for custom build in Editor Settings." msgstr "" +"Ðекоректний шлÑÑ… до SDK Ð´Ð»Ñ Android Ð´Ð»Ñ Ð½ÐµÑ‚Ð¸Ð¿Ð¾Ð²Ð¾Ð³Ð¾ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ñƒ параметрах " +"редактора." #: platform/android/export/export.cpp msgid "" "Android project is not installed for compiling. Install from Editor menu." msgstr "" +"Ð”Ð»Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð½Ðµ вÑтановлено проєкт Android. Ð’Ñтановіть його за допомогою " +"меню редактора." #: platform/android/export/export.cpp msgid "Invalid public key for APK expansion." @@ -11286,6 +10975,9 @@ 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 "" @@ -11294,20 +10986,29 @@ msgid "" " Godot Version: %s\n" "Please reinstall Android build template from 'Project' menu." msgstr "" +"ÐевідповідніÑть верÑÑ–Ñ Ð´Ð»Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð´Ð»Ñ Android:\n" +" Ð’Ñтановлений шаблон: %s\n" +" ВерÑÑ–Ñ Godot: %s\n" +"Будь лаÑка, повторно вÑтановіть шаблон Ð´Ð»Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð´Ð»Ñ Android за допомогою " +"меню «Проєкт»." #: platform/android/export/export.cpp msgid "Building Android Project (gradle)" -msgstr "" +msgstr "Ð—Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ Android (gradle)" #: platform/android/export/export.cpp msgid "" "Building of Android project failed, check output for the error.\n" "Alternatively visit docs.godotengine.org for Android build documentation." msgstr "" +"Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð¿Ñ€Ð¾Ñ”ÐºÑ‚Ñƒ Android. ОзнайомтеÑÑ Ñ–Ð· виведеними " +"даними, щоб визначити причину помилки.\n" +"Крім того, можете відвідати docs.godotengine.org Ñ– ознайомитиÑÑ Ñ–Ð· " +"документацією щодо Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ð´Ð»Ñ Android." #: platform/android/export/export.cpp msgid "No build apk generated at: " -msgstr "" +msgstr "Ðемає apk Ð´Ð»Ñ Ð·Ð±Ð¸Ñ€Ð°Ð½Ð½Ñ Ñƒ: " #: platform/iphone/export/export.cpp msgid "Identifier is missing." @@ -11340,7 +11041,7 @@ msgstr "У ідентифікаторі має бути принаймні одР#: platform/iphone/export/export.cpp msgid "App Store Team ID not specified - cannot configure the project." msgstr "" -"Ðе вказано ідентифікатор команди App Store — проект неможливо налаштувати." +"Ðе вказано ідентифікатор команди App Store — проєкт неможливо налаштувати." #: platform/iphone/export/export.cpp msgid "Invalid Identifier:" @@ -11437,8 +11138,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "Ðекоректні розмірноÑті Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ Ð²Ñ–ÐºÐ½Ð° Ð²Ñ–Ñ‚Ð°Ð½Ð½Ñ (мають бути 620x300)." #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "Щоб AnimatedSprite могла показувати кадри, має бути Ñтворено або вÑтановлено " @@ -11504,8 +11206,9 @@ msgstr "" "увімкненим параметром «ÐÐ½Ñ–Ð¼Ð°Ñ†Ñ–Ñ Ñ‡Ð°Ñток»." #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "Ð”Ð»Ñ Ð²Ð»Ð°ÑтивоÑті «texture» Ñлід надати текÑтуру із формою оÑвітленнÑ." @@ -11517,7 +11220,8 @@ msgstr "" "багатокутник затулÑннÑ." #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" "Ð”Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ затулÑÐ½Ð½Ñ Ð±Ð°Ð³Ð°Ñ‚Ð¾ÐºÑƒÑ‚Ð½Ð¸Ðº Ñ” порожнім. Будь лаÑка, намалюйте " "багатокутник!" @@ -11608,50 +11312,58 @@ msgstr "" "Цій кіÑтці бракує належної пози REST. Перейдіть до вузла Skeleton2D Ñ– " "вÑтановіть Ñ—Ñ—." +#: 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 "" +"TileMap із увімкненим Use Parent on потребує Ð½Ð°Ð´Ð°Ð½Ð½Ñ Ñ„Ð¾Ñ€Ð¼ до батьківÑького " +"CollisionShape2D. Будь лаÑка, викориÑтовуйте його Ñк дочірній елемент " +"Area2D, StaticBody2D, RigidBody2D, KinematicBody2D тощо, щоб надати йому " +"форми." + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "" "VisibilityEnable2D найкраще працюватиме, Ñкщо його викориÑтано із " "безпоÑереднім батьківÑьким елементом — редагованим коренем Ñцени." #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera повинен мати батьківÑьким вузлом вузол ARVROrigin" #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRController must have an ARVROrigin node as its parent." -msgstr "ARVRController повинен мати батьківÑьким вузлом вузол ARVROrigin" +msgstr "ARVRController повинен мати батьківÑьким вузлом вузол ARVROrigin." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The controller ID must not be 0 or this controller won't be bound to an " "actual controller." msgstr "" "Ідентифікатором контролера має бути значеннÑ, Ñке Ñ” відмінним від 0, інакше " -"цей контролер не буде пов'Ñзано із Ñправжнім елементом керуваннÑ" +"цей контролер не буде пов'Ñзано із Ñправжнім елементом керуваннÑ." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVRAnchor must have an ARVROrigin node as its parent." -msgstr "ARVRAnchor повинен мати батьківÑьким вузлом вузол ARVROrigin" +msgstr "ARVRAnchor повинен мати батьківÑьким вузлом вузол ARVROrigin." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "" "The anchor ID must not be 0 or this anchor won't be bound to an actual " "anchor." msgstr "" "Ідентифікатором прив'Ñзки має бути значеннÑ, Ñке Ñ” відмінним від 0, інакше " -"цю прив'Ñзку не буде пов'Ñзано із Ñправжньою прив'Ñзкою" +"цю прив'Ñзку не буде пов'Ñзано із Ñправжньою прив'Ñзкою." #: scene/3d/arvr_nodes.cpp -#, fuzzy msgid "ARVROrigin requires an ARVRCamera child node." -msgstr "ARVROrigin повинен мати дочірній вузол ARVRCamera" +msgstr "ARVROrigin повинен мати дочірній вузол ARVRCamera." #: scene/3d/baked_lightmap.cpp msgid "%d%%" @@ -11713,9 +11425,10 @@ msgstr "" "Area, StaticBody, RigidBody, KinematicBody тощо, щоб надати їм форми." #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "Ð”Ð»Ñ Ð·Ð°Ð±ÐµÐ·Ð¿ÐµÑ‡ÐµÐ½Ð½Ñ Ð¿Ñ€Ð°Ñ†ÐµÐ·Ð´Ð°Ñ‚Ð½Ð¾Ñті CollisionShape Ñлід надати форму. Будь " "лаÑка, Ñтворіть реÑÑƒÑ€Ñ Ñ„Ð¾Ñ€Ð¼Ð¸ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ елемента!" @@ -11733,13 +11446,12 @@ msgid "Nothing is visible because no mesh has been assigned." msgstr "Ðічого не видно, оÑкільки не призначено Ñітки." #: scene/3d/cpu_particles.cpp -#, fuzzy msgid "" "CPUParticles animation requires the usage of a SpatialMaterial whose " "Billboard Mode is set to \"Particle Billboard\"." msgstr "" -"ÐÐ½Ñ–Ð¼Ð°Ñ†Ñ–Ñ CPUParticles потребує викориÑÑ‚Ð°Ð½Ð½Ñ SpatialMaterial із увімкненим " -"параметром «ЧаÑтки дошки»." +"Ð”Ð»Ñ Ð°Ð½Ñ–Ð¼Ð°Ñ†Ñ–Ñ— CPUParticles Ñлід викориÑтовувати SpatialMaterial, режим " +"Billboard Ñкого Ñлід вÑтановити у Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«Particle Billboard»." #: scene/3d/gi_probe.cpp msgid "Plotting Meshes" @@ -11753,6 +11465,10 @@ msgstr "" "У драйвері GLES2 не передбачено підтримки GIProbes.\n" "СкориÑтайтеÑÑ Ð·Ð°Ð¼Ñ–Ñть них BakedLightmap." +#: 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 "" @@ -11785,22 +11501,22 @@ msgstr "" "Ðічого не видно, оÑкільки Ñітки не було пов'Ñзано із проходами малюваннÑ." #: scene/3d/particles.cpp -#, fuzzy msgid "" "Particles animation requires the usage of a SpatialMaterial whose Billboard " "Mode is set to \"Particle Billboard\"." msgstr "" -"ÐÐ½Ñ–Ð¼Ð°Ñ†Ñ–Ñ Ñ‡Ð°Ñток потребує викориÑÑ‚Ð°Ð½Ð½Ñ SpatialMaterial із увімкненим " -"параметром «ЧаÑтки дошки»." +"Ð”Ð»Ñ Ð°Ð½Ñ–Ð¼Ð°Ñ†Ñ–Ñ— чаÑток Ñлід викориÑтовувати SpatialMaterial, режим Billboard " +"Ñкого Ñлід вÑтановити у Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«Particle Billboard»." #: scene/3d/path.cpp msgid "PathFollow only works when set as a child of a Path node." msgstr "PathFollow працюватиме лише Ñк дочірній елемент вузла Path." #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED потребує Ð²Ð¼Ð¸ÐºÐ°Ð½Ð½Ñ Â«Up Vector» у його " "батьківÑькому реÑурÑÑ– Curve у Path." @@ -11816,15 +11532,17 @@ msgstr "" "ЗаміÑть цієї зміни, вам варто змінити розміри дочірніх форм зіткненнÑ." #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" "Щоб уÑе працювало Ñк Ñлід, влаÑтивіÑть шлÑху (path) має вказувати на " "коректний вузол Spatial." #: scene/3d/soft_body.cpp -#, fuzzy msgid "This body will be ignored until you set a mesh." -msgstr "Це тіло буде проігноровано, аж доки ви не вÑтановите Ñітку" +msgstr "Це тіло буде проігноровано, аж доки ви не вÑтановите Ñітку." #: scene/3d/soft_body.cpp msgid "" @@ -11836,8 +11554,9 @@ msgstr "" "ЗаміÑть цієї зміни, вам варто змінити розміри дочірніх форм зіткненнÑ." #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "Щоб AnimatedSprite могла показувати кадри, має бути Ñтворено або вÑтановлено " @@ -11852,8 +11571,10 @@ msgstr "" "Будь лаÑка, викориÑтовуйте цей елемент Ñк дочірній елемент вузла VehicleBody." #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment потребує реÑурÑу Environment." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11892,7 +11613,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Ðічого не з'єднано із входом «%s» вузла «%s»." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "Кореневий елемент AnimationNode Ð´Ð»Ñ Ð³Ñ€Ð°Ñ„Ñƒ не вÑтановлено." #: scene/animation/animation_tree.cpp @@ -11905,7 +11627,8 @@ msgstr "" "ШлÑÑ…, вÑтановлений Ð´Ð»Ñ AnimationPlayer, не веде до вузла AnimationPlayer." #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "Кореневий елемент AnimationPlayer не Ñ” коректним вузлом." #: scene/animation/animation_tree_player.cpp @@ -11918,8 +11641,12 @@ msgid "Pick a color from the screen." msgstr "Вибрати колір з екрана." #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Raw (Ñирий) режим" +msgid "HSV" +msgstr "HSV" + +#: scene/gui/color_picker.cpp +msgid "Raw" +msgstr "Без обробки" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11932,16 +11659,24 @@ msgstr "Додати поточний колір Ñк шаблон." #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" "Сам контейнер не має призначеннÑ, Ñкщо Ñкрипт не налаштовує поведінку щодо " "Ñ€Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ð¹Ð¾Ð³Ð¾ дочірніх об'єктів.\n" "Якщо ви не маєте наміру додавати Ñкрипт, будь лаÑка, ÑкориÑтайтеÑÑ Ð·Ð°Ð¼Ñ–Ñть " "контейнера звичайним вузлом «Control»." +#: 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 "" +"Панель підказки не буде показано, оÑкільки Mouse Filter Ð´Ð»Ñ Ð·Ð°Ñобу ÐºÐµÑ€ÑƒÐ²Ð°Ð½Ð½Ñ " +"вÑтановлено у Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«Ignore». Щоб вирішити проблему, вÑтановіть Ð´Ð»Ñ Mouse " +"Filter Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Â«Stop» або «Pass»." + #: scene/gui/dialogs.cpp msgid "Alert!" msgstr "Увага!" @@ -11951,23 +11686,26 @@ msgid "Please Confirm..." msgstr "Будь лаÑка, підтвердьте..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "КонтекÑтні підказки типово буде приховано, Ñкщо ви не викличете popup() або " "ÑкуÑÑŒ із функцій popup*(). Втім, робити Ñ—Ñ… видимими Ð´Ð»Ñ Ñ€ÐµÐ´Ð°Ð³ÑƒÐ²Ð°Ð½Ð½Ñ â€” звична " "практика. Втім, Ñлід пам'Ñтати, що під Ñ‡Ð°Ñ Ð·Ð°Ð¿ÑƒÑку Ñ—Ñ… буде приховано." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "Якщо exp_edit має Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ true, min_value має бути > 0." #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer призначено Ð´Ð»Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ із одинарним дочірнім заÑобом " @@ -11985,7 +11723,7 @@ msgid "" "Environment -> Default Environment) could not be loaded." msgstr "" "Ðе вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ типове Ñередовище, Ñк його визначено у параметрах " -"проекту (Обробка -> Середовище -> Типове Ñередовище)." +"проєкту (Обробка -> Середовище -> Типове Ñередовище)." #: scene/main/viewport.cpp msgid "" @@ -12020,6 +11758,11 @@ msgid "Input" msgstr "Вхідні дані" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "Ðекоректне джерело програми побудови тіней." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "Ðекоректне джерело програми побудови тіней." @@ -12037,7 +11780,227 @@ msgstr "Змінні величини можна пов'Ñзувати лише #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "Сталі не можна змінювати." + +#~ msgid "Generating solution..." +#~ msgstr "Ð¡Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ€Ð¾Ð·Ð²'Ñзку..." + +#~ msgid "Generating C# project..." +#~ msgstr "Створюємо проєкт C#..." + +#~ msgid "Failed to create solution." +#~ msgstr "Ðе вдалоÑÑ Ñтворити розв'Ñзок." + +#~ msgid "Failed to save solution." +#~ msgstr "Ðе вдалоÑÑ Ð·Ð±ÐµÑ€ÐµÐ³Ñ‚Ð¸ розв'Ñзок." + +#~ msgid "Done" +#~ msgstr "Зроблено" + +#~ msgid "Failed to create C# project." +#~ msgstr "Ðе вдалоÑÑ Ñтворити проєкт C#." + +#~ msgid "Mono" +#~ msgstr "Моно" + +#~ msgid "About C# support" +#~ msgstr "Про підтримку C#" + +#~ msgid "Create C# solution" +#~ msgstr "Створити розв'Ñзок C#" + +#~ msgid "Builds" +#~ msgstr "ЗбираннÑ" + +#~ msgid "Build Project" +#~ msgstr "Зібрати проєкт" + +#~ msgid "View log" +#~ msgstr "ПереглÑнути журнал" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment потребує реÑурÑу Environment." + +#~ msgid "Enabled Classes" +#~ msgstr "Увімкнені клаÑи" + +#~ msgid "Update Always" +#~ msgstr "Завжди оновлювати" + +#~ msgid "'camera' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «camera» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'inv_camera' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «inv_camera» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'inv_projection' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «inv_projection» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'normal' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «normal» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'projection' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «projection» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'time' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «time» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'viewport_size' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «viewport_size» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'world' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «world» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'alpha' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «alpha» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'color' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «color» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'texture_pixel_size' input parameter for all shader modes." +#~ msgstr "Вхідний параметр «texture_pixel_size» Ð´Ð»Ñ ÑƒÑÑ–Ñ… режимів шейдера." + +#~ msgid "'alpha' input parameter for vertex and fragment shader modes." +#~ msgstr "Вхідний параметр «alpha» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин Ñ– фрагментів шейдера." + +#~ msgid "'binormal' input parameter for vertex and fragment shader modes." +#~ msgstr "Вхідний параметр «binormal» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин Ñ– фрагментів шейдера." + +#~ msgid "'color' input parameter for vertex and fragment shader modes." +#~ msgstr "Вхідний параметр «color» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин Ñ– фрагментів шейдера." + +#~ msgid "'fragcoord' input parameter for fragment and light shader modes." +#~ msgstr "" +#~ "Вхідний параметр «fragcoord» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñ–Ð² фрагментів та Ñвітла шейдера." + +#~ msgid "'point_coord' input parameter for fragment shader mode." +#~ msgstr "Вхідний параметр «point_coord» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ фрагментів шейдера." + +#~ msgid "'screen_uv' input parameter for fragment shader mode." +#~ msgstr "Вхідний параметр «screen_uv» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñ–Ð² фрагментів шейдера." + +#~ msgid "'tangent' input parameter for vertex and fragment shader modes." +#~ msgstr "Вхідний параметр «tangent» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин Ñ– фрагментів шейдера." + +#~ msgid "'uv2' input parameter for vertex and fragment shader modes." +#~ msgstr "Вхідний параметр «uv2» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин Ñ– фрагментів шейдера." + +#~ msgid "'vertex' input parameter for vertex and fragment shader modes." +#~ msgstr "Вхідний параметр «vertex» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин Ñ– фрагментів шейдера." + +#~ msgid "'albedo' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «albedo» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'attenuation' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «attenuation» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'light' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «light» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'light_color' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «light_color» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'roughness' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «roughness» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'specular' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «specular» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'transmission' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «transmission» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'modelview' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «modelview» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'point_size' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «point_size» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'tangent' input parameter for vertex and fragment shader mode." +#~ msgstr "Вхідний параметр «tangent» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин Ñ– фрагментів шейдера." + +#~ msgid "'light_pass' input parameter for vertex and fragment shader modes." +#~ msgstr "" +#~ "Вхідний параметр «light_pass» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин Ñ– фрагментів шейдера." + +#~ msgid "'point_coord' input parameter for fragment and light shader modes." +#~ msgstr "" +#~ "Вхідний параметр «point_coord» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñ–Ð² фрагментів та Ñвітла шейдера." + +#~ msgid "'screen_pixel_size' input parameter for fragment shader mode." +#~ msgstr "Вхідний параметр «screen_pixel_size» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ фрагментів шейдера." + +#~ msgid "'screen_uv' input parameter for fragment and light shader modes." +#~ msgstr "" +#~ "Вхідний параметр «screen_uv» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñ–Ð² фрагментів та Ñвітла шейдера." + +#~ msgid "'light_alpha' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «light_alpha» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'light_height' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «light_height» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'light_uv' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «light_uv» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'light_vec' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «light_vec» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'normal' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «normal» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'shadow_color' input parameter for light shader mode." +#~ msgstr "Вхідний параметр «shadow_color» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ Ñвітла шейдера." + +#~ msgid "'extra' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «extra» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'projection' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «projection» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'vertex' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «vertex» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'world' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «world» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'active' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «active» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'alpha' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «alpha» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'color' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «color» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'custom_alpha' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «custom_alph» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'delta' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «delta» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'emission_transform' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «emission_transform» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'index' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «index» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'lifetime' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «lifetime» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'restart' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «restart» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'time' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «time» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'transform' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «transform» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "'velocity' input parameter for vertex shader mode." +#~ msgstr "Вхідний параметр «velocity» Ð´Ð»Ñ Ñ€ÐµÐ¶Ð¸Ð¼Ñƒ вершин шейдера." + +#~ msgid "Raw Mode" +#~ msgstr "Raw (Ñирий) режим" #~ msgid "Path to Node:" #~ msgstr "ШлÑÑ… до вузла:" @@ -12583,9 +12546,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "Перемкнути проÑторову видиміÑть" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "Перемкнути видиміÑть CanvasItem" - #~ msgid "Condition" #~ msgstr "Умова" diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po index fdf5b30709..cccbdbf067 100644 --- a/editor/translations/ur_PK.po +++ b/editor/translations/ur_PK.po @@ -435,6 +435,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr ".تمام کا انتخاب" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -610,6 +620,10 @@ msgstr "" msgid "Line Number:" msgstr "" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "" @@ -659,7 +673,7 @@ msgstr "" msgid "Reset Zoom" msgstr "" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -766,6 +780,11 @@ msgid "Connect" msgstr "" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr ".تمام کا انتخاب" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "" @@ -927,7 +946,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -1295,7 +1314,7 @@ msgid "Must not collide with an existing engine class name." msgstr "" #: editor/editor_autoload_settings.cpp -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1467,6 +1486,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1495,7 +1518,7 @@ msgid "Node Dock" msgstr "ایکشن منتقل کریں" #: editor/editor_feature_profile.cpp -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "" #: editor/editor_feature_profile.cpp @@ -1550,7 +1573,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1563,8 +1586,9 @@ msgid "Unset" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Current Profile" -msgstr "" +#, fuzzy +msgid "Current Profile:" +msgstr ".تمام کا انتخاب" #: editor/editor_feature_profile.cpp msgid "Make Current" @@ -1586,12 +1610,9 @@ msgid "Export" msgstr "" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" -msgstr "" +#, fuzzy +msgid "Available Profiles:" +msgstr ".تمام کا انتخاب" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2613,10 +2634,30 @@ 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 "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "" @@ -2723,15 +2764,15 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" +msgid "Update Continuously" msgstr "" #: editor/editor_node.cpp -msgid "Update Changes" +msgid "Update When Changed" msgstr "" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2923,7 +2964,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3023,20 +3064,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3530,6 +3571,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "" @@ -5144,6 +5186,13 @@ 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 "" @@ -6062,10 +6111,19 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 "" @@ -6297,18 +6355,22 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 scene/gui/line_edit.cpp -#: scene/gui/text_edit.cpp -msgid "Cut" -msgstr "" +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +msgstr ".تمام کا انتخاب" #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp -msgid "Select All" +msgid "Cut" msgstr "" #: editor/plugins/script_text_editor.cpp @@ -7880,51 +7942,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -7932,203 +7950,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9771,6 +9613,10 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +msgid "Expand/Collapse All" +msgstr "" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9800,8 +9646,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "سب سکریپشن بنائیں" #: editor/scene_tree_dock.cpp msgid "" @@ -10047,7 +9894,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10457,55 +10304,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "سب سکریپشن بنائیں" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11088,7 +10886,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11137,7 +10935,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11147,7 +10945,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11214,14 +11012,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11300,7 +11105,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11329,6 +11134,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11363,8 +11172,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11375,7 +11184,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11391,7 +11202,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11402,7 +11213,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11437,7 +11250,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11449,7 +11262,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11461,7 +11274,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11474,10 +11291,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11491,18 +11313,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11545,6 +11367,10 @@ msgid "Input" 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 "" @@ -11565,6 +11391,10 @@ msgid "Constants cannot be modified." msgstr "" #, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "سب سکریپشن بنائیں" + +#, fuzzy #~ msgid "Ease in" #~ msgstr ".تمام کا انتخاب" diff --git a/editor/translations/vi.po b/editor/translations/vi.po index 54ea3e786e..e30b7b02b6 100644 --- a/editor/translations/vi.po +++ b/editor/translations/vi.po @@ -9,12 +9,13 @@ # Tung Le <tungkradle@gmail.com>, 2017. # 38569459 <xxx38569459@gmail.com>, 2018. # TyTYct Hihi <tytyct@gmail.com>, 2019. +# Steve Dang <itsnguu@outlook.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Godot Engine editor\n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2019-03-01 11:59+0000\n" -"Last-Translator: TyTYct Hihi <tytyct@gmail.com>\n" +"PO-Revision-Date: 2019-07-02 10:49+0000\n" +"Last-Translator: Steve Dang <itsnguu@outlook.com>\n" "Language-Team: Vietnamese <https://hosted.weblate.org/projects/godot-engine/" "godot/vi/>\n" "Language: vi\n" @@ -22,7 +23,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 3.5-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -66,7 +67,7 @@ msgstr "" #: editor/animation_bezier_editor.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Free" -msgstr "" +msgstr "Miá»…n phÃ" #: editor/animation_bezier_editor.cpp msgid "Balanced" @@ -78,11 +79,11 @@ msgstr "" #: editor/animation_bezier_editor.cpp editor/editor_profiler.cpp msgid "Time:" -msgstr "" +msgstr "Thá»i gian:" #: editor/animation_bezier_editor.cpp msgid "Value:" -msgstr "" +msgstr "Giá trị:" #: editor/animation_bezier_editor.cpp #, fuzzy @@ -193,11 +194,11 @@ msgstr "Phóng Animation." #: editor/animation_track_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Functions:" -msgstr "" +msgstr "Hà m:" #: editor/animation_track_editor.cpp msgid "Audio Clips:" -msgstr "" +msgstr "Âm thanh:" #: editor/animation_track_editor.cpp msgid "Anim Clips:" @@ -264,9 +265,8 @@ msgid "Linear" msgstr "Tịnh tuyến" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Cubic" -msgstr "Báºc ba" +msgstr "Khối" #: editor/animation_track_editor.cpp msgid "Clamp Loop Interp" @@ -279,32 +279,27 @@ msgstr "" #: editor/animation_track_editor.cpp #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Insert Key" -msgstr "Chèn Key" +msgstr "Chèn khoá" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Duplicate Key(s)" -msgstr "Nhân đôi Các Key cá»§a Animation" +msgstr "Nhân bản các khoá hoạt ảnh" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Delete Key(s)" -msgstr "Xóa phÃm Anim" +msgstr "Xoá khoá hoạt ảnh" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Update Mode" -msgstr "Äổi độ dà i Anim" +msgstr "Äổi chế độ cáºp nháºt hoạt ảnh" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Interpolation Mode" -msgstr "Äổi độ dà i Anim" +msgstr "Äổi chế độ ná»™i suy hoạt ảnh" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Loop Mode" -msgstr "Äổi vòng lặp Anim" +msgstr "Äổi chế độ vòng lặp hoạt ảnh" #: editor/animation_track_editor.cpp msgid "Remove Anim Track" @@ -335,11 +330,11 @@ msgstr "Chèn Anim" #: editor/animation_track_editor.cpp msgid "AnimationPlayer can't animate itself, only other players." -msgstr "" +msgstr "AnimationPlayer không thể tá»± tạo hoạt ảnh, chỉ các player khác." #: editor/animation_track_editor.cpp msgid "Anim Create & Insert" -msgstr "Tạo & Chèn Anim" +msgstr "Tạo & Chèn Hoạt ảnh" #: editor/animation_track_editor.cpp msgid "Anim Insert Track & Key" @@ -350,14 +345,12 @@ msgid "Anim Insert Key" msgstr "Chèn Key Anim" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Change Animation Step" -msgstr "Äổi vòng lặp Anim" +msgstr "Äổi các bước hoạt ảnh" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Rearrange Tracks" -msgstr "Sắp xếp lại Autoloads" +msgstr "Sắp xếp lại Tracks" #: editor/animation_track_editor.cpp msgid "Transform tracks only apply to Spatial-based nodes." @@ -421,15 +414,15 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Anim Move Keys" -msgstr "Di chuyển các Key Anim" +msgstr "Di chuyển các khoá hoạt cảnh" #: editor/animation_track_editor.cpp msgid "Clipboard is empty" -msgstr "" +msgstr "Clipboard rá»—ng" #: editor/animation_track_editor.cpp msgid "Paste Tracks" -msgstr "" +msgstr "Dán Tracks" #: editor/animation_track_editor.cpp #, fuzzy @@ -456,9 +449,19 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" +msgstr "Cảnh bảo: Chỉnh sá»a hoạt ảnh đã nháºp" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" msgstr "" #: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "Chế độ chá»n" + +#: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -478,7 +481,7 @@ msgstr "Phóng Animation." #: editor/animation_track_editor.cpp msgid "Seconds" -msgstr "" +msgstr "Giây" #: editor/animation_track_editor.cpp msgid "FPS" @@ -491,12 +494,11 @@ msgstr "" #: editor/project_manager.cpp editor/project_settings_editor.cpp #: editor/property_editor.cpp modules/visual_script/visual_script_editor.cpp msgid "Edit" -msgstr "" +msgstr "Chỉnh sá»a" #: editor/animation_track_editor.cpp -#, fuzzy msgid "Animation properties." -msgstr "Phóng Animation." +msgstr "Thuá»™c tÃnh hoạt cảnh." #: editor/animation_track_editor.cpp msgid "Copy Tracks" @@ -605,7 +607,7 @@ msgstr "" #: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Copy" -msgstr "Copy" +msgstr "Sao chép" #: editor/animation_track_editor_plugins.cpp #, fuzzy @@ -640,6 +642,10 @@ msgstr "Äến Dòng" msgid "Line Number:" msgstr "Dòng số:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "Không tìm thấy" @@ -672,7 +678,7 @@ msgstr "Chỉ lá»±a chá»n" #: editor/code_editor.cpp editor/plugins/script_text_editor.cpp #: editor/plugins/text_editor.cpp msgid "Standard" -msgstr "" +msgstr "Chuẩn" #: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp @@ -690,13 +696,13 @@ msgstr "Thu nhá»" msgid "Reset Zoom" msgstr "Äặt lại phóng" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" -msgstr "" +msgstr "Cảnh báo" #: editor/code_editor.cpp msgid "Line and column numbers." -msgstr "" +msgstr "Số dòng và cá»™t." #: editor/connections_dialog.cpp #, fuzzy @@ -729,7 +735,7 @@ msgstr "Äang kết nối Signal:" #: editor/connections_dialog.cpp msgid "Scene does not contain any script." -msgstr "" +msgstr "Cảnh không chứa mã lệnh." #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -759,7 +765,7 @@ msgstr "" #: editor/connections_dialog.cpp msgid "Advanced" -msgstr "" +msgstr "Nâng cao" #: editor/connections_dialog.cpp #, fuzzy @@ -773,16 +779,15 @@ msgstr "" #: editor/connections_dialog.cpp msgid "Oneshot" -msgstr "" +msgstr "Má»™t lần" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "Ngắt kết nối tÃn hiệu sau lần phát xạ đầu tiên." #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "Äang kết nối Signal:" +msgstr "Không thể kết nối tÃn hiệu" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -803,6 +808,11 @@ msgid "Connect" msgstr "Kết nối" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "TÃn hiệu:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "Kết nối '%s' đến '%s'" @@ -825,19 +835,16 @@ msgid "Disconnect" msgstr "Há»§y kết nối" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "Äang kết nối Signal:" +msgstr "Kết nối tÃn hiệu và o hà m" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "Sá»a Curve đã chá»n" +msgstr "Chỉnh sá»a kết nối:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Are you sure you want to remove all connections from the \"%s\" signal?" -msgstr "Bạn có chắc muốn xóa bá» tất cả kết nối từ tÃn hiệu nà y?" +msgstr "Bạn muốn xoá tất cả kết nối từ tÃn hiệu \"%s\"?" #: editor/connections_dialog.cpp editor/editor_help.cpp editor/node_dock.cpp msgid "Signals" @@ -848,9 +855,8 @@ msgid "Are you sure you want to remove all connections from this signal?" msgstr "Bạn có chắc muốn xóa bá» tất cả kết nối từ tÃn hiệu nà y?" #: editor/connections_dialog.cpp -#, fuzzy msgid "Disconnect All" -msgstr "Há»§y kết nối" +msgstr "Há»§y kết nối tất cả" #: editor/connections_dialog.cpp msgid "Edit..." @@ -967,7 +973,7 @@ msgid "Owners Of:" msgstr "" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "" #: editor/dependency_editor.cpp @@ -979,11 +985,11 @@ msgstr "" #: editor/dependency_editor.cpp editor/export_template_manager.cpp msgid "Cannot remove:" -msgstr "" +msgstr "Không thể gỡ bá»:" #: editor/dependency_editor.cpp msgid "Error loading:" -msgstr "" +msgstr "Lá»—i tải nạp:" #: editor/dependency_editor.cpp msgid "Load failed due to missing dependencies:" @@ -1003,11 +1009,11 @@ msgstr "" #: editor/dependency_editor.cpp msgid "Errors loading!" -msgstr "" +msgstr "Lá»—i tải nạp!" #: editor/dependency_editor.cpp msgid "Permanently delete %d item(s)? (No undo!)" -msgstr "" +msgstr "Xoá vÄ©nh viá»…n các đối tượng %d? (Không thể hoà n lại!)" #: editor/dependency_editor.cpp #, fuzzy @@ -1036,27 +1042,27 @@ msgstr "" #: editor/dictionary_property_edit.cpp msgid "Change Dictionary Key" -msgstr "" +msgstr "Äổi khoá từ Ä‘iển" #: editor/dictionary_property_edit.cpp msgid "Change Dictionary Value" -msgstr "" +msgstr "Äổi giá trị từ Ä‘iển" #: editor/editor_about.cpp msgid "Thanks from the Godot community!" -msgstr "" +msgstr "Cảm Æ¡n từ cá»™ng đồng Godot!" #: editor/editor_about.cpp msgid "Godot Engine contributors" -msgstr "" +msgstr "Äóng góp và o Godot Engine" #: editor/editor_about.cpp msgid "Project Founders" -msgstr "" +msgstr "Sáng láºp dá»± án" #: editor/editor_about.cpp msgid "Lead Developer" -msgstr "" +msgstr "Phát triển chÃnh" #: editor/editor_about.cpp msgid "Project Manager " @@ -1116,19 +1122,19 @@ msgstr "" #: editor/editor_about.cpp msgid "All Components" -msgstr "" +msgstr "Tất cả thà nh phần" #: editor/editor_about.cpp msgid "Components" -msgstr "" +msgstr "Thà nh phần" #: editor/editor_about.cpp msgid "Licenses" -msgstr "" +msgstr "Các giấy phép" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Error opening package file, not in zip format." -msgstr "" +msgstr "Lá»—i không thể mở gói, không phải dạng nén." #: editor/editor_asset_installer.cpp msgid "Uncompressing Assets" @@ -1136,21 +1142,21 @@ msgstr "" #: editor/editor_asset_installer.cpp editor/project_manager.cpp msgid "Package installed successfully!" -msgstr "" +msgstr "Cà i đặt gói thà nh công!" #: editor/editor_asset_installer.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Success!" -msgstr "" +msgstr "Thà nh công!" #: editor/editor_asset_installer.cpp editor/editor_node.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Install" -msgstr "" +msgstr "Cà i đặt" #: editor/editor_asset_installer.cpp msgid "Package Installer" -msgstr "" +msgstr "Gói cà i đặt" #: editor/editor_audio_buses.cpp msgid "Speakers" @@ -1158,7 +1164,7 @@ msgstr "" #: editor/editor_audio_buses.cpp msgid "Add Effect" -msgstr "" +msgstr "Thêm hiệu ứng" #: editor/editor_audio_buses.cpp msgid "Rename Audio Bus" @@ -1206,7 +1212,7 @@ msgstr "" #: editor/editor_audio_buses.cpp msgid "Mute" -msgstr "" +msgstr "Tắt tiếng" #: editor/editor_audio_buses.cpp msgid "Bypass" @@ -1219,19 +1225,19 @@ 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 "" +msgstr "Nhân bản" #: editor/editor_audio_buses.cpp msgid "Reset Volume" -msgstr "" +msgstr "Äặt lại âm lượng" #: editor/editor_audio_buses.cpp msgid "Delete Effect" -msgstr "" +msgstr "Xoá hiệu ứng" #: editor/editor_audio_buses.cpp msgid "Audio" -msgstr "" +msgstr "Âm thanh" #: editor/editor_audio_buses.cpp msgid "Add Audio Bus" @@ -1271,11 +1277,11 @@ msgstr "" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "Không có tệp tin '%s'." #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" -msgstr "" +msgstr "Bố trÃ" #: editor/editor_audio_buses.cpp msgid "Invalid file, not an audio bus layout." @@ -1293,7 +1299,7 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp #: editor/script_create_dialog.cpp msgid "Load" -msgstr "" +msgstr "Nạp" #: editor/editor_audio_buses.cpp msgid "Load an existing Bus Layout." @@ -1301,7 +1307,7 @@ msgstr "" #: editor/editor_audio_buses.cpp msgid "Save As" -msgstr "" +msgstr "Lưu thà nh" #: editor/editor_audio_buses.cpp msgid "Save this Bus Layout to a file." @@ -1309,7 +1315,7 @@ msgstr "" #: editor/editor_audio_buses.cpp editor/import_dock.cpp msgid "Load Default" -msgstr "" +msgstr "Nạp mặc định" #: editor/editor_audio_buses.cpp msgid "Load the default Bus Layout." @@ -1321,18 +1327,18 @@ msgstr "" #: editor/editor_autoload_settings.cpp msgid "Invalid name." -msgstr "" +msgstr "Tên không hợp lệ." #: editor/editor_autoload_settings.cpp msgid "Valid characters:" -msgstr "" +msgstr "Ký tá»± hợp lệ:" #: 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 buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "" #: editor/editor_autoload_settings.cpp @@ -1378,7 +1384,7 @@ msgstr "ÄÆ°á»ng dẫn sai." #: editor/editor_autoload_settings.cpp editor/script_create_dialog.cpp msgid "File does not exist." -msgstr "File không tồn tại." +msgstr "Tệp không tồn tại." #: editor/editor_autoload_settings.cpp msgid "Not in resource path." @@ -1408,15 +1414,15 @@ msgstr "Singleton" #: editor/editor_data.cpp msgid "Updating Scene" -msgstr "Cáºp nháºt Scene" +msgstr "Cáºp nháºt Cảnh" #: editor/editor_data.cpp msgid "Storing local changes..." -msgstr "" +msgstr "Lưu các thay đổi cục bá»™ ..." #: editor/editor_data.cpp msgid "Updating scene..." -msgstr "Äang cáºp nháºt scene..." +msgstr "Äang cáºp nháºt cảnh ..." #: editor/editor_data.cpp editor/editor_properties.cpp msgid "[empty]" @@ -1428,17 +1434,17 @@ msgstr "[chưa save]" #: editor/editor_dir_dialog.cpp msgid "Please select a base directory first." -msgstr "" +msgstr "Chá»n thư mục cÆ¡ sở đầu tiên." #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" -msgstr "" +msgstr "Chá»n má»™t Thư mục" #: 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 "Tạo Folder" +msgstr "Tạo thư mục" #: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp #: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp @@ -1458,7 +1464,7 @@ msgstr "Chá»n" #: editor/editor_export.cpp msgid "Storing File:" -msgstr "" +msgstr "Lưu trữ tệp tin:" #: editor/editor_export.cpp msgid "No export template found at the expected path:" @@ -1466,7 +1472,7 @@ msgstr "" #: editor/editor_export.cpp msgid "Packing" -msgstr "" +msgstr "Äóng gói" #: editor/editor_export.cpp msgid "" @@ -1492,7 +1498,7 @@ msgstr "" #: 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 "" +msgstr "Không tìm thấy mẫu gỡ lá»—i tuỳ chỉnh." #: editor/editor_export.cpp platform/android/export/export.cpp #: platform/iphone/export/export.cpp platform/javascript/export/export.cpp @@ -1502,202 +1508,185 @@ msgstr "" #: editor/editor_export.cpp platform/javascript/export/export.cpp msgid "Template file not found:" +msgstr "Không tìm thấy tệp tin mẫu:" + +#: 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 "" +msgstr "Trình chỉnh sá»a 3D" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "Tạo Script" +msgstr "Trình viết mã lệnh" #: editor/editor_feature_profile.cpp msgid "Asset Library" -msgstr "" +msgstr "Thư viện tà i nguyên" #: editor/editor_feature_profile.cpp msgid "Scene Tree Editing" -msgstr "" +msgstr "Chỉnh sá»a cảnh" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "Nháºp từ bên ngoà i" +msgstr "Nháºp và o" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "Äổi tên" +msgstr "Nút" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" -msgstr "Quét lại hệ thống táºp tin" +msgid "FileSystem and Import Docks" +msgstr "Hệ thống táºp tin" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "Thay thế tất cả" +msgstr "Xoá hồ sÆ¡ '%s'? (không hoà n tác)" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "Hồ sÆ¡ có tên hợp lệ và không chứa ký tá»± '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "Äã có má»™t file hoặc folder trùng tên." +msgstr "Hồ sÆ¡ tên nà y đã tồn tại." #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(Äã tắt trình chỉnh sá»a, thuá»™c tÃnh)" #: editor/editor_feature_profile.cpp msgid "(Properties Disabled)" -msgstr "" +msgstr "(Äã tắt thuá»™c tÃnh)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "Chỉnh sá»a Variable:" +msgstr "(Äã tắt trình chỉnh sá»a)" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "Mô tả:" +msgstr "Tuỳ chá»n lá»›p:" #: editor/editor_feature_profile.cpp msgid "Enable Contextual Editor" -msgstr "" +msgstr "Báºt trình chỉnh sá»a ngữ cảnh" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "Thu gá»n tất cả" +msgstr "Thuá»™c tÃnh đã báºt:" #: editor/editor_feature_profile.cpp msgid "Enabled Features:" -msgstr "" +msgstr "TÃnh năng đã báºt:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "Tìm Class" +msgstr "Lá»›p đã báºt:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "Tệp '%s' định dạng không hợp lệ, huá»· nháºp và o." #: editor/editor_feature_profile.cpp +#, fuzzy msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." -msgstr "" +msgstr "Hồ sÆ¡ '%s' đã tồn tại. Di chuyển hồ sÆ¡ trước khi nháºp, huá»· nháºp." #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "Lá»—i tải font." +msgstr "Lá»—i khi lưu hồ sÆ¡ đến đưá»ng dẫn: '%s'." #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "BỠđặt" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" -msgstr "Phiên bản hiện tại:" +msgid "Current Profile:" +msgstr "Hồ sÆ¡ hiện tại" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "Hiện tại:" +msgstr "Äặt là m hiện tại" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp msgid "New" -msgstr "" +msgstr "Má»›i" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp msgid "Import" -msgstr "Nháºp từ bên ngoà i" +msgstr "Nháºp và o" #: editor/editor_feature_profile.cpp editor/editor_node.cpp #: editor/project_export.cpp msgid "Export" -msgstr "" +msgstr "Xuất ra" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" -msgstr "Nodes khả dụng:" +msgid "Available Profiles:" +msgstr "Hồ sÆ¡ khả dụng" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "Tìm Class" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "Mô tả:" +msgstr "Tuỳ chỉnh lá»›p" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "Tên má»›i:" +msgstr "Tên má»›i hồ sÆ¡:" #: editor/editor_feature_profile.cpp msgid "Erase Profile" -msgstr "" +msgstr "Xoá hồ sÆ¡" #: editor/editor_feature_profile.cpp msgid "Import Profile(s)" -msgstr "" +msgstr "Nháºp và o hồ sÆ¡" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "Nháºp từ Node:" +msgstr "Xuất hồ sÆ¡" #: editor/editor_feature_profile.cpp msgid "Manage Editor Feature Profiles" -msgstr "" +msgstr "Quản lý trình tÃnh năng" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" -msgstr "Chá»n Folder hiện tại" +msgstr "Chá»n thư mục hiện tại" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File Exists, Overwrite?" -msgstr "File đã tồn tại, Viết đè?" +msgstr "Tệp tin tồn tại, ghi đè?" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Select This Folder" -msgstr "Chá»n folder nà y" +msgstr "Chá»n thư mục nà y" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "Copy Path" -msgstr "Copy ÄÆ°á»ng dẫn" +msgstr "Sao chép đưá»ng dẫn" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp -#, fuzzy msgid "Open in File Manager" -msgstr "Mở trong Trình quản là file" +msgstr "Mở trong trình quản lý tệp tin" #: editor/editor_file_dialog.cpp editor/editor_node.cpp #: editor/filesystem_dock.cpp editor/project_manager.cpp -#, fuzzy msgid "Show in File Manager" -msgstr "Hiển thị trong Trình quản là file" +msgstr "Xem trong trình quản lý tệp" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "New Folder..." -msgstr "Folder Má»›i..." +msgstr "Thư mục má»›i ..." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Refresh" @@ -1709,25 +1698,23 @@ msgstr "" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "All Files (*)" -msgstr "Tất cả Files (*)" +msgstr "Tất cả tệp tin (*)" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open a File" -msgstr "Mở má»™t File" +msgstr "Mở má»™t Tệp tin" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Open File(s)" -msgstr "Mở File(s)" +msgstr "Mở Tệp tin" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Open a Directory" -msgstr "Mở má»™t Äịa chỉ" +msgstr "Mở má»™t thư mục" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Open a File or Directory" -msgstr "Mở má»™t File hoặc Äịa chỉ" +msgstr "Mở má»™t tệp tin hoặc thư mục" #: editor/editor_file_dialog.cpp editor/editor_node.cpp #: editor/editor_properties.cpp editor/inspector_dock.cpp @@ -1738,7 +1725,7 @@ msgstr "Lưu" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Save a File" -msgstr "Lưu thà nh File" +msgstr "Lưu thà nh tệp tin" #: editor/editor_file_dialog.cpp msgid "Go Back" @@ -1777,41 +1764,36 @@ msgid "Move Favorite Down" msgstr "Di chuyển Ưa thÃch xuống" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Previous Folder" msgstr "Thư mục trước" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Next Folder" -msgstr "Tạo Folder" +msgstr "Thư mục sau" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Go to parent folder." -msgstr "Äến folder parent" +msgstr "Äến thư mục cha" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "(Un)favorite current folder." -msgstr "Không thể tạo folder." +msgstr "Bá» yêu thÃch thư mục hiện tại." #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "Báºt tắt File ẩn" +msgstr "Báºt tắt hiện các tệp tin ẩn." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." -msgstr "" +msgstr "Xem các mục dạng lưới các hình thu nhá»." #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a list." -msgstr "" +msgstr "Xem mục dạng danh sách." #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Directories & Files:" -msgstr "Những địa chỉ & File:" +msgstr "Các Thư mục và Tệp tin:" #: editor/editor_file_dialog.cpp editor/plugins/sprite_editor_plugin.cpp #: editor/plugins/style_box_editor_plugin.cpp @@ -1821,16 +1803,15 @@ msgstr "Xem thá»:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "File:" -msgstr "File" +msgstr "Tệp tin:" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp -#, fuzzy msgid "Must use a valid extension." -msgstr "Phải sá» dụng extension có hiệu lá»±c" +msgstr "Sá» dụng phần mở rá»™ng hợp lệ." #: editor/editor_file_system.cpp msgid "ScanSources" -msgstr "" +msgstr "Quét nguồn" #: editor/editor_file_system.cpp msgid "" @@ -1848,7 +1829,7 @@ msgstr "Trên đầu" #: editor/editor_help.cpp msgid "Class:" -msgstr "Class:" +msgstr "Lá»›p:" #: editor/editor_help.cpp editor/scene_tree_editor.cpp msgid "Inherits:" @@ -1864,20 +1845,19 @@ msgstr "Mô tả ngắn gá»n:" #: editor/editor_help.cpp msgid "Properties" -msgstr "" +msgstr "Thuá»™c tÃnh" #: editor/editor_help.cpp msgid "Properties:" -msgstr "" +msgstr "Thuá»™c tÃnh:" #: editor/editor_help.cpp msgid "Methods" -msgstr "" +msgstr "Hà m" #: editor/editor_help.cpp -#, fuzzy msgid "Methods:" -msgstr "Äến Method" +msgstr "Hà m:" #: editor/editor_help.cpp msgid "Theme Properties" @@ -1889,7 +1869,7 @@ msgstr "" #: editor/editor_help.cpp modules/visual_script/visual_script_editor.cpp msgid "Signals:" -msgstr "" +msgstr "TÃn hiệu:" #: editor/editor_help.cpp msgid "Enumerations" @@ -1912,9 +1892,8 @@ msgid "Constants:" msgstr "" #: editor/editor_help.cpp -#, fuzzy msgid "Class Description" -msgstr "Mô tả:" +msgstr "Mô tả lá»›p:" #: editor/editor_help.cpp #, fuzzy @@ -1923,7 +1902,7 @@ msgstr "Mô tả:" #: editor/editor_help.cpp msgid "Online Tutorials:" -msgstr "" +msgstr "Hướng dẫn trá»±c tuyến:" #: editor/editor_help.cpp msgid "" @@ -1949,14 +1928,12 @@ msgid "" msgstr "" #: editor/editor_help.cpp -#, fuzzy msgid "Method Descriptions" -msgstr "Mô tả:" +msgstr "Mô tả hà m" #: editor/editor_help.cpp -#, fuzzy msgid "Method Descriptions:" -msgstr "Mô tả:" +msgstr "Mô tả hà m:" #: editor/editor_help.cpp msgid "" @@ -1970,67 +1947,60 @@ msgid "Search Help" msgstr "Tìm sá»± giúp đỡ" #: editor/editor_help_search.cpp -#, fuzzy msgid "Display All" -msgstr "Thay thế tất cả" +msgstr "Hiển thị tất cả" #: editor/editor_help_search.cpp msgid "Classes Only" -msgstr "" +msgstr "Chỉ các Lá»›p" #: editor/editor_help_search.cpp -#, fuzzy msgid "Methods Only" -msgstr "Chỉ lá»±a chá»n" +msgstr "Chỉ các Hà m" #: editor/editor_help_search.cpp -#, fuzzy msgid "Signals Only" -msgstr "TÃn hiệu" +msgstr "Chỉ các TÃn hiệu" #: editor/editor_help_search.cpp -#, fuzzy msgid "Constants Only" -msgstr "Cố định" +msgstr "Chỉ các Äịnh nghÄ©a" #: editor/editor_help_search.cpp msgid "Properties Only" -msgstr "" +msgstr "Chỉ các Thuá»™c tÃnh" #: editor/editor_help_search.cpp msgid "Theme Properties Only" msgstr "" #: editor/editor_help_search.cpp -#, fuzzy msgid "Member Type" -msgstr "Những Thà nh viên" +msgstr "Loại" #: editor/editor_help_search.cpp -#, fuzzy msgid "Class" -msgstr "Class:" +msgstr "Lá»›p" #: editor/editor_inspector.cpp editor/project_settings_editor.cpp msgid "Property:" -msgstr "" +msgstr "Thuá»™c tÃnh:" #: editor/editor_inspector.cpp msgid "Set" -msgstr "" +msgstr "Gán" #: editor/editor_inspector.cpp msgid "Set Multiple:" -msgstr "" +msgstr "Gán nhiá»u:" #: editor/editor_log.cpp msgid "Output:" -msgstr "" +msgstr "Äầu ra:" #: editor/editor_log.cpp editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Copy Selection" -msgstr "Di chuyển Lá»±a chá»n" +msgstr "Sao chép lá»±a chá»n" #: editor/editor_log.cpp editor/editor_profiler.cpp #: editor/editor_properties.cpp @@ -2040,19 +2010,19 @@ msgstr "Di chuyển Lá»±a chá»n" #: modules/gdnative/gdnative_library_editor_plugin.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Clear" -msgstr "" +msgstr "Xoá" #: editor/editor_log.cpp msgid "Clear Output" -msgstr "" +msgstr "Xoá đầu ra" #: editor/editor_node.cpp msgid "Project export failed with error code %d." -msgstr "" +msgstr "Xuất dá»± án thất bại vá»›i mã lá»—i %d." #: editor/editor_node.cpp msgid "Imported resources can't be saved." -msgstr "" +msgstr "Tà i nguyên đã nháºp không thể lưu." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: scene/gui/dialogs.cpp @@ -2068,30 +2038,32 @@ msgid "" "This resource can't be saved because it does not belong to the edited scene. " "Make it unique first." msgstr "" +"Tà i nguyên nà y không thể lưu vì nó không thuá»™c cảnh đã chỉnh sá»a. Tạo nó là " +"duy nhất." #: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp msgid "Save Resource As..." -msgstr "" +msgstr "Lưu tà i nguyên thà nh ..." #: editor/editor_node.cpp msgid "Can't open file for writing:" -msgstr "" +msgstr "Không thể mở tệp để ghi:" #: editor/editor_node.cpp msgid "Requested file format unknown:" -msgstr "" +msgstr "Tệp yêu cầu có định dạng không xác định:" #: editor/editor_node.cpp msgid "Error while saving." -msgstr "" +msgstr "Lá»—i khi lưu." #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Can't open '%s'. The file could have been moved or deleted." -msgstr "" +msgstr "Không thể mở '%s'. Tệp đã được di chuyển hoặc xoá." #: editor/editor_node.cpp msgid "Error while parsing '%s'." -msgstr "" +msgstr "Lá»—i khi Ä‘ang phân tÃch '%s'." #: editor/editor_node.cpp msgid "Unexpected end of file '%s'." @@ -2103,39 +2075,43 @@ msgstr "" #: editor/editor_node.cpp msgid "Error while loading '%s'." -msgstr "" +msgstr "Lá»—i khi Ä‘ang nạp '%s'." #: editor/editor_node.cpp msgid "Saving Scene" -msgstr "" +msgstr "Lưu cảnh" #: editor/editor_node.cpp msgid "Analyzing" -msgstr "" +msgstr "Phân tÃch" #: editor/editor_node.cpp msgid "Creating Thumbnail" -msgstr "" +msgstr "Tạo hình thu nhá»" #: editor/editor_node.cpp msgid "This operation can't be done without a tree root." -msgstr "" +msgstr "Hoạt động không thể hoà n tất khi không có nút gốc." #: 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 "" +"Cảnh nà y không thể lưu vì đây bao má»™t trưá»ng hợp theo chu kỳ.\n" +"Giải quyết nó và cố gắng lưu lại." #: editor/editor_node.cpp msgid "" "Couldn't save scene. Likely dependencies (instances or inheritance) couldn't " "be satisfied." msgstr "" +"Không thể lưu cảnh. Các phần phụ thuá»™c (trưá»ng hợp hoặc kế thừa) không thoả " +"mãn." #: editor/editor_node.cpp editor/scene_tree_dock.cpp msgid "Can't overwrite scene that is still open!" -msgstr "" +msgstr "Không thể ghi đè cảnh vẫn Ä‘ang mở!" #: editor/editor_node.cpp msgid "Can't load MeshLibrary for merging!" @@ -2151,23 +2127,23 @@ msgstr "" #: editor/editor_node.cpp msgid "Error saving TileSet!" -msgstr "" +msgstr "Lá»—i khi lưu các TileSet!" #: editor/editor_node.cpp msgid "Error trying to save layout!" -msgstr "" +msgstr "Lá»—i khi cố gắng lưu bố cục!" #: editor/editor_node.cpp msgid "Default editor layout overridden." -msgstr "" +msgstr "Bố cục trình biên táºp mặc định bị ghi đè." #: editor/editor_node.cpp msgid "Layout name not found!" -msgstr "" +msgstr "Tên bố cục không tìm thấy!" #: editor/editor_node.cpp msgid "Restored default layout to base settings." -msgstr "" +msgstr "Äã khôi phục bố cục mặc định cho các thiết láºp." #: editor/editor_node.cpp msgid "" @@ -2175,18 +2151,24 @@ msgid "" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" +"Tà i nguyên thuá»™c vá» cảnh đã nháºp, nó không thể chỉnh sá»a.\n" +"Äá»c tà i liệu liên quan để cách nháºp Cảnh để hiểu rõ quy trình việc nà y." #: 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 "" +"Tà i nguyên thuá»™c vá» Cảnh đã Ä‘iá»u chỉnh hoặc kế thừa.\n" +"Thay đổi vá»›i nó sẽ không được giữ khi lưu cảnh hiện tại." #: 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 "" +"Tà i nguyên đã được nháºp và o, không thể chỉnh sá»a. Thay đổi cà i đặt cá»§a nó " +"trong bảng Nháºp và o, sau đó nháºp và o lại." #: editor/editor_node.cpp msgid "" @@ -2195,6 +2177,10 @@ msgid "" "Please read the documentation relevant to importing scenes to better " "understand this workflow." msgstr "" +"Cảnh nà y đã được nháºp và o, những thay đổi sẽ không được giữ lại.\n" +"Tạo thá»±c thể nó hoặc kế thừa sẽ cho phép thá»±c hiện các thay đổi.\n" +"Äá»c tà i liệu tà i liệu liên quan đến nháºp Cảnh để hiểu rõ vá» quy trình việc " +"nà y." #: editor/editor_node.cpp msgid "" @@ -2202,18 +2188,20 @@ msgid "" "Please read the documentation relevant to debugging to better understand " "this workflow." msgstr "" +"Äây là đối được Ä‘iá»u khiển từ xa, những thay đổi sẽ không được giữ lại.\n" +"Äá»c tà i liệu liên quan đến gỡ lá»—i để hiểu rõ quy trình việc nà y." #: editor/editor_node.cpp msgid "There is no defined scene to run." -msgstr "" +msgstr "Không có cảnh được xác định để chạy." #: editor/editor_node.cpp msgid "Current scene was never saved, please save it prior to running." -msgstr "Scene hiện tại chưa được lưu, hãy lưu nó trước khi chạy." +msgstr "Cảnh hiện tại chưa được lưu, hãy lưu nó trước khi chạy." #: editor/editor_node.cpp msgid "Could not start subprocess!" -msgstr "" +msgstr "Không thể bắt đầu quá trình nhá»!" #: editor/editor_node.cpp editor/filesystem_dock.cpp msgid "Open Scene" @@ -2224,9 +2212,8 @@ msgid "Open Base Scene" msgstr "Mở Scene Mẫu" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "Mở Scene nhanh..." +msgstr "Mở nhanh ..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2245,13 +2232,12 @@ msgid "Save changes to '%s' before closing?" msgstr "Lưu thay đổi và o '%s' trước khi đóng?" #: editor/editor_node.cpp -#, fuzzy msgid "Saved %s modified resource(s)." -msgstr "Lưu animation nà y" +msgstr "Äã lưu tà i nguyên được sá»a đổi." #: editor/editor_node.cpp msgid "A root node is required to save the scene." -msgstr "" +msgstr "Yêu cầu má»™t nút gốc khi lưu cảnh." #: editor/editor_node.cpp msgid "Save Scene As..." @@ -2295,7 +2281,7 @@ msgstr "Scene hiện tại chưa save. Kệ mở luôn?" #: editor/editor_node.cpp msgid "Can't reload a scene that was never saved." -msgstr "Không thể reload má»™t scene mà chưa save bao giá»." +msgstr "Không thể nạp má»™t cảnh mà chưa lưu bao giá»." #: editor/editor_node.cpp #, fuzzy @@ -2303,9 +2289,8 @@ msgid "Revert" msgstr "Trở lại" #: editor/editor_node.cpp -#, fuzzy msgid "This action cannot be undone. Revert anyway?" -msgstr "Hà nh động nà y không thể hoà n tác. Kệ trở lại luôn?" +msgstr "Hà nh động nà y không thể hoà n tác. Trở lại luôn?" #: editor/editor_node.cpp msgid "Quick Run Scene..." @@ -2317,11 +2302,11 @@ msgstr "Thoát" #: editor/editor_node.cpp msgid "Exit the editor?" -msgstr "Thoát editor?" +msgstr "Thoát trình biên táºp?" #: editor/editor_node.cpp msgid "Open Project Manager?" -msgstr "Mở Project Manager?" +msgstr "Mở Quản lý dá»± án?" #: editor/editor_node.cpp msgid "Save & Quit" @@ -2340,8 +2325,8 @@ msgid "" "This option is deprecated. Situations where refresh must be forced are now " "considered a bug. Please report." msgstr "" -"Tùy chỉnh nà y đã quá date. Những tùy huống mà phải bị bắt phải refresh bây " -"giỠđược xem là lá»—i. Xin hãy báo lại." +"Tùy chỉnh không chấp nháºn. Những tình huống mà bắt phải là m má»›i bây giỠđược " +"xem là lá»—i. Xin hãy báo lại." #: editor/editor_node.cpp msgid "Pick a Main Scene" @@ -2379,22 +2364,24 @@ 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 "" -"Scene '%s' được load tá»± động, vì váºy không thể chỉnh sá»a.\n" -"Tạo má»™t scene con để chỉnh sá»a." +"Scene '%s' được nháºp tá»± động, không thể chỉnh sá»a.\n" +"Tạo má»™t cảnh kế thừa để chỉnh sá»a." #: 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 "" +"Lá»—i nạp cảnh, nó phải trong đưá»ng dẫn dá»± án. Sá» dụng 'Nháºp và o' để mở cảnh, " +"sau đó lưu lại trong đưá»ng dẫn dá»± án." #: editor/editor_node.cpp msgid "Scene '%s' has broken dependencies:" -msgstr "" +msgstr "Cảnh '%s' bị há»ng các phụ thuá»™c:" #: editor/editor_node.cpp msgid "Clear Recent Scenes" -msgstr "" +msgstr "Dá»n các cảnh gần đây" #: editor/editor_node.cpp msgid "" @@ -2402,6 +2389,8 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"Không có cảnh chÃnh được xác định, chá»n má»™t cảnh?\n" +"Bạn có thể thay đổi nó sau trong \"Cà i đặt dá»± án\", nằm trong mục 'ứng dụng'." #: editor/editor_node.cpp msgid "" @@ -2409,6 +2398,8 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"Cảnh đã chá»n '%s' không tồn tại, chá»n má»™t cảnh hợp lệ?\n" +"Bạn có thể thay đổi nó sau trong \"Cà i đặt dá»± án\", nằm trong mục 'ứng dụng'." #: editor/editor_node.cpp msgid "" @@ -2416,67 +2407,66 @@ msgid "" "You can change it later in \"Project Settings\" under the 'application' " "category." msgstr "" +"Chá»n '%s' không phải má»™t tệp cảnh, chá»n tệp cảnh hợp lệ?\n" +"Bạn có thể thay đổi nó sau trong \"Cà i đặt dá»± án\", nằm trong mục 'ứng dụng'." #: editor/editor_node.cpp msgid "Save Layout" -msgstr "" +msgstr "Lưu bố cục" #: editor/editor_node.cpp msgid "Delete Layout" -msgstr "" +msgstr "Xoá bố cục" #: editor/editor_node.cpp editor/import_dock.cpp #: editor/script_create_dialog.cpp msgid "Default" -msgstr "" +msgstr "Mặc định" #: editor/editor_node.cpp editor/editor_properties.cpp #: editor/plugins/script_editor_plugin.cpp editor/property_editor.cpp -#, fuzzy msgid "Show in FileSystem" -msgstr "Quét lại hệ thống táºp tin" +msgstr "Hiện trong Hệ thống tệp tin" #: editor/editor_node.cpp msgid "Play This Scene" -msgstr "" +msgstr "Chạy cảnh nà y" #: editor/editor_node.cpp -#, fuzzy msgid "Close Tab" -msgstr "Äóng tất cả Tab" +msgstr "Äóng Tab" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Close Other Tabs" -msgstr "Äóng tất cả Tab" +msgstr "Äóng tất cả Tab khác" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "Äóng các Tab bên phải" #: editor/editor_node.cpp -#, fuzzy msgid "Close All Tabs" msgstr "Äóng tất cả" #: editor/editor_node.cpp msgid "Switch Scene Tab" -msgstr "" +msgstr "Chuyển Tab cảnh" #: editor/editor_node.cpp msgid "%d more files or folders" -msgstr "" +msgstr "%d thêm các tệp hoặc thư mục." #: editor/editor_node.cpp msgid "%d more folders" -msgstr "" +msgstr "%d thêm các thư mục" #: editor/editor_node.cpp msgid "%d more files" -msgstr "" +msgstr "%d thêm các tệp tin" #: editor/editor_node.cpp msgid "Dock Position" -msgstr "" +msgstr "Vị trà Dock" #: editor/editor_node.cpp msgid "Distraction Free Mode" @@ -2488,64 +2478,63 @@ msgstr "" #: editor/editor_node.cpp msgid "Add a new scene." -msgstr "Thêm má»™t scene má»›i." +msgstr "Thêm má»™t cảnh má»›i." #: editor/editor_node.cpp msgid "Scene" -msgstr "" +msgstr "Phân cảnh" #: editor/editor_node.cpp msgid "Go to previously opened scene." -msgstr "" +msgstr "Trở vá» cảnh đã mở trước đó." #: editor/editor_node.cpp msgid "Next tab" -msgstr "" +msgstr "Tab tiếp theo" #: editor/editor_node.cpp msgid "Previous tab" -msgstr "" +msgstr "Tab trước" #: editor/editor_node.cpp msgid "Filter Files..." -msgstr "" +msgstr "Lá»c tệp tin ..." #: editor/editor_node.cpp msgid "Operations with scene files." -msgstr "" +msgstr "Hoạt động vá»›i các tệp cảnh." #: editor/editor_node.cpp msgid "New Scene" -msgstr "Tạo Scene Má»›i" +msgstr "Tạo Cảnh Má»›i" #: editor/editor_node.cpp msgid "New Inherited Scene..." -msgstr "Tạo Scene Con..." +msgstr "Tạo Cảnh Kế thừa..." #: editor/editor_node.cpp msgid "Open Scene..." -msgstr "" +msgstr "Mở Cảnh ..." #: editor/editor_node.cpp msgid "Save Scene" -msgstr "" +msgstr "Lưu Cảnh" #: editor/editor_node.cpp -#, fuzzy msgid "Save All Scenes" -msgstr "Lưu Scene vá»›i tên..." +msgstr "Lưu tất cả Cảnh" #: editor/editor_node.cpp msgid "Close Scene" -msgstr "" +msgstr "Äóng Cảnh" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Open Recent" -msgstr "" +msgstr "Mở gần đây" #: editor/editor_node.cpp msgid "Convert To..." -msgstr "" +msgstr "Chuyển đổi ..." #: editor/editor_node.cpp msgid "MeshLibrary..." @@ -2558,12 +2547,12 @@ msgstr "" #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Undo" -msgstr "" +msgstr "Hoà n tác" #: editor/editor_node.cpp editor/plugins/script_text_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Redo" -msgstr "" +msgstr "Là m lại" #: editor/editor_node.cpp msgid "Revert Scene" @@ -2575,7 +2564,7 @@ msgstr "" #: editor/editor_node.cpp msgid "Project" -msgstr "" +msgstr "Dá»± án" #: editor/editor_node.cpp msgid "Project Settings" @@ -2583,35 +2572,36 @@ msgstr "" #: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp msgid "Tools" -msgstr "" +msgstr "Công cụ" #: editor/editor_node.cpp -#, fuzzy msgid "Open Project Data Folder" -msgstr "Chá»n folder nà y" +msgstr "Mở thư mục dữ liệu dá»± án" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "Cà i đặt mẫu xây dá»±ng Android" #: editor/editor_node.cpp msgid "Quit to Project List" -msgstr "" +msgstr "Thoát danh sách dá»± án" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp #: editor/project_export.cpp msgid "Debug" -msgstr "" +msgstr "Gỡ lá»—i" #: editor/editor_node.cpp msgid "Deploy with Remote Debug" -msgstr "" +msgstr "Triển khai gỡ lá»—i từ xa" #: editor/editor_node.cpp msgid "" "When exporting or deploying, the resulting executable will attempt to " "connect to the IP of this computer in order to be debugged." msgstr "" +"Khi xuất ra hoặc triển khai, kết quả thá»±c thi sẽ kết nối đến IP máy tÃnh nà y " +"để được gỡ lá»—i." #: editor/editor_node.cpp msgid "Small Deploy with Network FS" @@ -2673,25 +2663,47 @@ msgstr "" #: editor/editor_node.cpp msgid "Editor" -msgstr "" +msgstr "Trình biên táºp" #: editor/editor_node.cpp editor/settings_config_dialog.cpp msgid "Editor Settings" -msgstr "" +msgstr "Cà i đặt Trình biên táºp" #: editor/editor_node.cpp msgid "Editor Layout" +msgstr "Cà i đặt Bố cục" + +#: editor/editor_node.cpp +msgid "Take Screenshot" msgstr "" #: editor/editor_node.cpp -msgid "Toggle Fullscreen" +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "Mở thư mục dữ liệu Trình biên táºp" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" msgstr "" #: editor/editor_node.cpp -msgid "Open Editor Data/Settings Folder" +msgid "Open in an external image editor." msgstr "" #: editor/editor_node.cpp +msgid "Toggle Fullscreen" +msgstr "Chế độ Toà n mà n hình" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "Chế độ Phân chia" + +#: editor/editor_node.cpp +msgid "Open Editor Data/Settings Folder" +msgstr "Mở thư mục dữ liệu Trình biên táºp" + +#: editor/editor_node.cpp msgid "Open Editor Data Folder" msgstr "" @@ -2701,15 +2713,15 @@ msgstr "" #: editor/editor_node.cpp msgid "Manage Editor Features" -msgstr "" +msgstr "Quản lý tÃnh năng Trình biên táºp" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" -msgstr "" +msgstr "Quản lý mẫu Xuất ra" #: editor/editor_node.cpp msgid "Help" -msgstr "" +msgstr "Trợ giúp" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp @@ -2718,19 +2730,19 @@ msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp #: editor/project_settings_editor.cpp editor/rename_dialog.cpp msgid "Search" -msgstr "" +msgstr "Tìm kiếm" #: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp msgid "Online Docs" -msgstr "" +msgstr "Tà i liệu trá»±c tuyến" #: editor/editor_node.cpp msgid "Q&A" -msgstr "" +msgstr "Há»i và Äáp" #: editor/editor_node.cpp msgid "Issue Tracker" -msgstr "" +msgstr "Theo dõi vấn Ä‘á»" #: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp msgid "Community" @@ -2738,71 +2750,73 @@ msgstr "Cá»™ng đồng" #: editor/editor_node.cpp msgid "About" -msgstr "Thông tin" +msgstr "Thông tin chúng tôi" #: editor/editor_node.cpp msgid "Play the project." -msgstr "" +msgstr "Chạy dá»± án." #: editor/editor_node.cpp msgid "Play" -msgstr "" +msgstr "Chạy" #: editor/editor_node.cpp msgid "Pause the scene" -msgstr "" +msgstr "Tạm dừng cảnh" #: editor/editor_node.cpp msgid "Pause Scene" -msgstr "" +msgstr "Tạm dừng Cảnh" #: editor/editor_node.cpp msgid "Stop the scene." -msgstr "" +msgstr "Dừng cảnh." #: editor/editor_node.cpp editor/editor_profiler.cpp msgid "Stop" -msgstr "" +msgstr "Dừng" #: editor/editor_node.cpp msgid "Play the edited scene." -msgstr "" +msgstr "Chạy cảnh đã chỉnh sá»a." #: editor/editor_node.cpp msgid "Play Scene" -msgstr "" +msgstr "Chạy Cảnh" #: editor/editor_node.cpp msgid "Play custom scene" -msgstr "" +msgstr "Chạy cảnh tuỳ chá»n" #: editor/editor_node.cpp msgid "Play Custom Scene" -msgstr "" +msgstr "Chạy Cảnh Tuỳ Chá»n" #: editor/editor_node.cpp msgid "Changing the video driver requires restarting the editor." -msgstr "" +msgstr "Thay đổi trình Ä‘iá»u kiển Video, yêu cầu khởi động lại Trình biên táºp." #: editor/editor_node.cpp editor/project_settings_editor.cpp #: editor/settings_config_dialog.cpp msgid "Save & Restart" -msgstr "" +msgstr "Lưu & Khởi động lại" #: editor/editor_node.cpp msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "" +#, fuzzy +msgid "Update Continuously" +msgstr "Liên tục" #: editor/editor_node.cpp -msgid "Update Changes" -msgstr "" +#, fuzzy +msgid "Update When Changed" +msgstr "Äối số đã thay đổi" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -2811,33 +2825,31 @@ msgstr "" #: editor/editor_node.cpp msgid "Inspector" -msgstr "" +msgstr "Quản lý đối tượng" #: editor/editor_node.cpp msgid "Node" -msgstr "" +msgstr "Nút" #: editor/editor_node.cpp -#, fuzzy msgid "Expand Bottom Panel" -msgstr "Mở rá»™ng tất cả" +msgstr "Mở rá»™ng bảng Ä‘iá»u khiển phÃa dưới" #: editor/editor_node.cpp scene/resources/visual_shader.cpp msgid "Output" -msgstr "" +msgstr "Äầu ra" #: editor/editor_node.cpp msgid "Don't Save" -msgstr "" +msgstr "Không Lưu" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." msgstr "" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Templates" -msgstr "Khung project" +msgstr "Quản lý Mẫu" #: editor/editor_node.cpp msgid "" @@ -2854,15 +2866,15 @@ msgstr "" #: editor/editor_node.cpp msgid "Import Templates From ZIP File" -msgstr "Nháºp Template từ file ZIP" +msgstr "Nháºp mẫu và o từ tệp nén ZIP" #: editor/editor_node.cpp editor/project_export.cpp msgid "Export Project" -msgstr "" +msgstr "Xuất dá»± án ra" #: editor/editor_node.cpp msgid "Export Library" -msgstr "" +msgstr "Xuất thư viện ra" #: editor/editor_node.cpp msgid "Merge With Existing" @@ -2870,39 +2882,39 @@ msgstr "" #: editor/editor_node.cpp msgid "Password:" -msgstr "" +msgstr "Máºt khẩu:" #: editor/editor_node.cpp msgid "Open & Run a Script" -msgstr "" +msgstr "Mở & Chạy mã lệnh" #: editor/editor_node.cpp msgid "New Inherited" -msgstr "" +msgstr "Kế thừa má»›i" #: editor/editor_node.cpp msgid "Load Errors" -msgstr "" +msgstr "Nạp Lá»—i" #: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp msgid "Select" -msgstr "" +msgstr "Chá»n" #: editor/editor_node.cpp msgid "Open 2D Editor" -msgstr "" +msgstr "Mở Trình biên táºp 2D" #: editor/editor_node.cpp msgid "Open 3D Editor" -msgstr "" +msgstr "Mở Trình biên táºp 3D" #: editor/editor_node.cpp msgid "Open Script Editor" -msgstr "" +msgstr "Mở Trình biên táºp Mã lệnh" #: editor/editor_node.cpp editor/project_manager.cpp msgid "Open Asset Library" -msgstr "" +msgstr "Mở Thư viện Nguyên liệu" #: editor/editor_node.cpp msgid "Open the next Editor" @@ -2930,33 +2942,33 @@ msgstr "" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp msgid "Update" -msgstr "" +msgstr "Cáºp nháºt" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Version:" -msgstr "" +msgstr "Phiên bản:" #: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp msgid "Author:" -msgstr "" +msgstr "Tác giả:" #: editor/editor_plugin_settings.cpp msgid "Status:" -msgstr "" +msgstr "Trạng thái:" #: editor/editor_plugin_settings.cpp msgid "Edit:" -msgstr "" +msgstr "Sá»a:" #: editor/editor_profiler.cpp editor/plugins/animation_state_machine_editor.cpp #: editor/rename_dialog.cpp msgid "Start" -msgstr "" +msgstr "Bắt đầu" #: editor/editor_profiler.cpp msgid "Measure:" -msgstr "" +msgstr "Äo đạc:" #: editor/editor_profiler.cpp msgid "Frame Time (sec)" @@ -2994,7 +3006,7 @@ msgstr "" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3008,7 +3020,7 @@ msgstr "" #: editor/editor_properties.cpp msgid "[Empty]" -msgstr "" +msgstr "[Rá»—ng]" #: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp msgid "Assign..." @@ -3045,15 +3057,15 @@ msgstr "" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New Script" -msgstr "" +msgstr "Mã lệnh má»›i" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "New %s" -msgstr "" +msgstr "Má»›i %s" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Make Unique" -msgstr "" +msgstr "Duy nhất" #: editor/editor_properties.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp @@ -3067,7 +3079,7 @@ msgstr "" #: editor/plugins/tile_map_editor_plugin.cpp editor/property_editor.cpp #: scene/gui/line_edit.cpp scene/gui/text_edit.cpp msgid "Paste" -msgstr "" +msgstr "Dán" #: editor/editor_properties.cpp editor/property_editor.cpp msgid "Convert To %s" @@ -3086,28 +3098,28 @@ msgstr "" #: editor/editor_properties_array_dict.cpp msgid "Size: " -msgstr "" +msgstr "KÃch thước: " #: editor/editor_properties_array_dict.cpp msgid "Page: " -msgstr "" +msgstr "Trang: " + +#: editor/editor_properties_array_dict.cpp +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" +msgstr "Gõ bá» Mục" #: editor/editor_properties_array_dict.cpp msgid "New Key:" -msgstr "" +msgstr "Khoá má»›i:" #: editor/editor_properties_array_dict.cpp msgid "New Value:" -msgstr "" +msgstr "Giá trị má»›i:" #: editor/editor_properties_array_dict.cpp msgid "Add Key/Value Pair" -msgstr "" - -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "" +msgstr "Thêm cặp Khoá/Giá trị" #: editor/editor_run_native.cpp msgid "" @@ -3117,7 +3129,7 @@ msgstr "" #: editor/editor_run_script.cpp msgid "Write your logic in the _run() method." -msgstr "" +msgstr "Ghi logic cá»§a bạn trong hà m _run()." #: editor/editor_run_script.cpp msgid "There is an edited scene already." @@ -3141,19 +3153,19 @@ msgstr "" #: editor/editor_sub_scene.cpp msgid "Select Node(s) to Import" -msgstr "Chá»n Node để Nháºp" +msgstr "Chá»n Nút để Nháºp" #: editor/editor_sub_scene.cpp editor/project_manager.cpp msgid "Browse" -msgstr "" +msgstr "Duyệt" #: editor/editor_sub_scene.cpp msgid "Scene Path:" -msgstr "" +msgstr "ÄÆ°á»ng dẫn Cảnh:" #: editor/editor_sub_scene.cpp msgid "Import From Node:" -msgstr "Nháºp từ Node:" +msgstr "Nháºp từ Nút:" #: editor/export_template_manager.cpp msgid "Re-Download" @@ -3161,7 +3173,7 @@ msgstr "Tải lại" #: editor/export_template_manager.cpp msgid "Uninstall" -msgstr "" +msgstr "Gỡ cà i đặt" #: editor/export_template_manager.cpp msgid "(Installed)" @@ -3221,7 +3233,7 @@ msgstr "" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't resolve." -msgstr "" +msgstr "Không thể giải quyết." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -3241,16 +3253,16 @@ msgstr "Yêu cầu thất bại." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Redirect Loop." -msgstr "" +msgstr "Chuyển hướng vòng lặp." #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp msgid "Failed:" -msgstr "Thất bại." +msgstr "Thất bại:" #: editor/export_template_manager.cpp msgid "Download Complete." -msgstr "Tải xong." +msgstr "Tải xuống xong." #: editor/export_template_manager.cpp msgid "" @@ -3260,7 +3272,7 @@ msgstr "" #: editor/export_template_manager.cpp msgid "Error requesting url: " -msgstr "" +msgstr "Lá»—i khi yêu cầu đưá»ng dẫn: " #: editor/export_template_manager.cpp msgid "Connecting to Mirror..." @@ -3272,11 +3284,11 @@ msgstr "Äứt kết nối" #: editor/export_template_manager.cpp msgid "Resolving" -msgstr "" +msgstr "Äang giải quyết" #: editor/export_template_manager.cpp msgid "Can't Resolve" -msgstr "" +msgstr "Không thể giải quyết" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -3285,11 +3297,11 @@ msgstr "Äang kết nối..." #: editor/export_template_manager.cpp msgid "Can't Connect" -msgstr "" +msgstr "Không thể Kết nối" #: editor/export_template_manager.cpp msgid "Connected" -msgstr "" +msgstr "Äã kết nối" #: editor/export_template_manager.cpp #: editor/plugins/asset_library_editor_plugin.cpp @@ -3339,7 +3351,7 @@ msgstr "" #: editor/export_template_manager.cpp msgid "Download Templates" -msgstr "Tải Templates" +msgstr "Tải các Mẫu" #: editor/export_template_manager.cpp msgid "Select mirror from list: (Shift+Click: Open in Browser)" @@ -3364,11 +3376,11 @@ msgstr "" #: editor/filesystem_dock.cpp msgid "Cannot move/rename resources root." -msgstr "" +msgstr "Không thể di chuyển/đổi tên tà i nguyên gốc." #: editor/filesystem_dock.cpp msgid "Cannot move a folder into itself." -msgstr "" +msgstr "Không thể di chuyển thư mục và o chÃnh nó." #: editor/filesystem_dock.cpp msgid "Error moving:" @@ -3376,72 +3388,67 @@ msgstr "Lá»—i di chuyển:" #: editor/filesystem_dock.cpp msgid "Error duplicating:" -msgstr "" +msgstr "Lá»—i nhân bản:" #: editor/filesystem_dock.cpp msgid "Unable to update dependencies:" -msgstr "" +msgstr "Không thể cáºp nháºt các phần phụ thuá»™c:" #: editor/filesystem_dock.cpp editor/scene_tree_editor.cpp msgid "No name provided." -msgstr "" +msgstr "Không có tên được cung cấp." #: editor/filesystem_dock.cpp -#, fuzzy msgid "Provided name contains invalid characters." -msgstr "Tên có kà tá»± không hợp lệ." +msgstr "Tên có chứa ký tá»± không hợp lệ." #: editor/filesystem_dock.cpp msgid "Name contains invalid characters." -msgstr "Tên có kà tá»± không hợp lệ." +msgstr "Tên có chứa kà tá»± không hợp lệ." #: editor/filesystem_dock.cpp msgid "A file or folder with this name already exists." -msgstr "Äã có má»™t file hoặc folder trùng tên." +msgstr "Äã có má»™t têp tin hoặc thư mục trùng tên." #: editor/filesystem_dock.cpp msgid "Renaming file:" -msgstr "Äổi tên file:" +msgstr "Äổi tên tệp tin:" #: editor/filesystem_dock.cpp msgid "Renaming folder:" -msgstr "Äổi tên folder:" +msgstr "Äổi tên thư mục:" #: editor/filesystem_dock.cpp msgid "Duplicating file:" -msgstr "Tạo bản sao file:" +msgstr "Tạo bản sao tệp tin:" #: editor/filesystem_dock.cpp msgid "Duplicating folder:" -msgstr "Tạo bản sao folder:" +msgstr "Tạo bản sao thư mục:" #: editor/filesystem_dock.cpp -#, fuzzy msgid "New Inherited Scene" -msgstr "Tạo Scene Con..." +msgstr "Tạo Cảnh kế thừa má»›i" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Open Scenes" -msgstr "Mở Scene" +msgstr "Mở cảnh" #: editor/filesystem_dock.cpp msgid "Instance" -msgstr "Thêm và o scene" +msgstr "Thêm và o Cảnh" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Add to Favorites" -msgstr "Ưa thÃch:" +msgstr "Thêm và o Ưa thÃch" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Remove from Favorites" -msgstr "Xóa khá»i Nhóm" +msgstr "Xóa Ưa thÃch" #: editor/filesystem_dock.cpp msgid "Edit Dependencies..." -msgstr "Chỉnh sá»a các File phụ thuá»™c..." +msgstr "Chỉnh sá»a các phần phụ thuá»™c..." #: editor/filesystem_dock.cpp msgid "View Owners..." @@ -3460,25 +3467,22 @@ msgid "Move To..." msgstr "Di chuyển đến..." #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "New Script..." -msgstr "Tạo Script" +msgstr "Tạo Mã lệnh ..." #: editor/filesystem_dock.cpp msgid "New Resource..." -msgstr "" +msgstr "Tà i nguyên má»›i ..." #: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Expand All" -msgstr "Mở rá»™ng tất cả" +msgstr "Mở rá»™ng Tất cả" #: editor/filesystem_dock.cpp editor/plugins/visual_shader_editor_plugin.cpp #: editor/script_editor_debugger.cpp -#, fuzzy msgid "Collapse All" -msgstr "Thu gá»n tất cả" +msgstr "Thu gá»n Tất cả" #: editor/filesystem_dock.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp @@ -3488,79 +3492,72 @@ msgid "Rename" msgstr "Äổi tên" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Previous Folder/File" -msgstr "Thư mục trước" +msgstr "Thư mục/Tệp tin trước" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Next Folder/File" -msgstr "Tạo Folder" +msgstr "Thư mục/Tệp tin tiếp" #: editor/filesystem_dock.cpp msgid "Re-Scan Filesystem" msgstr "Quét lại hệ thống táºp tin" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Toggle Split Mode" -msgstr "Báºt tắt Chức năng" +msgstr "Chế độ Phân chia" #: editor/filesystem_dock.cpp -#, fuzzy msgid "Search files" -msgstr "Tìm kiếm:" +msgstr "Tìm kiếm tệp tin" #: editor/filesystem_dock.cpp msgid "" "Scanning Files,\n" "Please Wait..." msgstr "" -"Äang quét file,\n" -"Chá» môt chút..." +"Äang quét các tệp tin,\n" +"Chá» má»™t chút ..." #: editor/filesystem_dock.cpp msgid "Move" msgstr "Di chuyển" #: editor/filesystem_dock.cpp -#, fuzzy msgid "There is already file or folder with the same name in this location." -msgstr "Äã có má»™t file hoặc folder trùng tên." +msgstr "Äã có tệp tin hoặc thư mục cùng tên tại vị trà nà y." #: editor/filesystem_dock.cpp msgid "Overwrite" -msgstr "" +msgstr "Ghi đè" #: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp msgid "Create Script" -msgstr "Tạo Script" +msgstr "Tạo Mã lệnh" #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp -#, fuzzy msgid "Find in Files" -msgstr "Tìm..." +msgstr "Tìm trong các Tệp tin" #: editor/find_in_files.cpp -#, fuzzy msgid "Find:" -msgstr "Tìm tiếp theo" +msgstr "Tìm:" #: editor/find_in_files.cpp -#, fuzzy msgid "Folder:" -msgstr "Tạo Folder" +msgstr "Thư mục:" #: editor/find_in_files.cpp -#, fuzzy msgid "Filters:" -msgstr "Lá»c..." +msgstr "Lá»c:" #: editor/find_in_files.cpp msgid "" "Include the files with the following extensions. Add or remove them in " "ProjectSettings." msgstr "" +"Bao gồm các tệp tin vá»›i các phần mở rá»™ng sau. Thêm hoặc loại bá» chúng trong " +"Cà i đặt Dá»± án." #: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp #: editor/plugins/script_text_editor.cpp @@ -3569,63 +3566,56 @@ msgstr "Tìm..." #: editor/find_in_files.cpp editor/plugins/script_text_editor.cpp msgid "Replace..." -msgstr "" +msgstr "Thay thế ..." #: editor/find_in_files.cpp editor/progress_dialog.cpp scene/gui/dialogs.cpp msgid "Cancel" -msgstr "" +msgstr "Huá»· bá»" #: editor/find_in_files.cpp -#, fuzzy msgid "Find: " -msgstr "Tìm tiếp theo" +msgstr "Tìm: " #: editor/find_in_files.cpp -#, fuzzy msgid "Replace: " -msgstr "Thay thế" +msgstr "Thay thế: " #: editor/find_in_files.cpp -#, fuzzy msgid "Replace all (no undo)" -msgstr "Thay thế tất cả" +msgstr "Thay thế tất cả (không hoà n tác)" #: editor/find_in_files.cpp -#, fuzzy msgid "Searching..." -msgstr "Tìm kiếm:" +msgstr "Äang tìm kiếm ..." #: editor/find_in_files.cpp msgid "Search complete" -msgstr "" +msgstr "Tìm kiếm hoà n tất" #: editor/groups_editor.cpp -#, fuzzy msgid "Group name already exists." -msgstr "Lá»–I: Tên animation trùng lặp!" +msgstr "Tên nhóm đã tồn tại." #: editor/groups_editor.cpp -#, fuzzy msgid "Invalid group name." -msgstr "KÃch thước font không hợp lệ." +msgstr "Tên nhóm không hợp lệ." #: editor/groups_editor.cpp editor/node_dock.cpp msgid "Groups" -msgstr "" +msgstr "Nhóm" #: editor/groups_editor.cpp -#, fuzzy msgid "Nodes not in Group" -msgstr "Thêm và o Nhóm" +msgstr "Nút không trong Nhóm" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" -msgstr "" +msgstr "Lá»c các nút" #: editor/groups_editor.cpp -#, fuzzy msgid "Nodes in Group" -msgstr "Thêm và o Nhóm" +msgstr "Các nút trong Nhóm" #: editor/groups_editor.cpp msgid "Add to Group" @@ -3637,43 +3627,43 @@ msgstr "Xóa khá»i Nhóm" #: editor/groups_editor.cpp msgid "Manage Groups" -msgstr "" +msgstr "Quản lý Nhóm" #: editor/import/resource_importer_scene.cpp msgid "Import as Single Scene" -msgstr "" +msgstr "Nháºp và o Cảnh đơn" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Animations" -msgstr "Load vá»›i các Animation riêng biệt" +msgstr "Nháºp và o vá»›i các Hoạt ảnh riêng biệt" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials" -msgstr "Load vá»›i các Material riêng biệt" +msgstr "Nháºp và o vá»›i các Material riêng biệt" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects" -msgstr "Load vá»›i các Object riêng biệt" +msgstr "Nháºp và o vá»›i các Äối tượng riêng biệt" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials" -msgstr "Load vá»›i các Object+Material riêng biệt" +msgstr "Nháºp và o vá»›i các Object+Material riêng biệt" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Animations" -msgstr "Load vá»›i các Object+Animation riêng biệt" +msgstr "Nháºp và o vá»›i các Object+Animation riêng biệt" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Materials+Animations" -msgstr "Load vá»›i Material+Animation riêng biệt" +msgstr "Nháºp và o vá»›i Material+Animation riêng biệt" #: editor/import/resource_importer_scene.cpp msgid "Import with Separate Objects+Materials+Animations" -msgstr "Load vá»›i các Object+Material+Animation riêng biệt" +msgstr "Nháºp và o vá»›i các Object+Material+Animation riêng biệt" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes" -msgstr "" +msgstr "Nháºp và o Nhiá»u cảnh" #: editor/import/resource_importer_scene.cpp msgid "Import as Multiple Scenes+Materials" @@ -3714,35 +3704,35 @@ msgstr "" #: editor/import/resource_importer_scene.cpp msgid "Saving..." -msgstr "" +msgstr "Äang lưu ..." #: editor/import_dock.cpp msgid "Set as Default for '%s'" -msgstr "" +msgstr "Gán Mặc định cho '%s'" #: editor/import_dock.cpp msgid "Clear Default for '%s'" -msgstr "" +msgstr "Dá»n Mặc định cho '%s'" #: editor/import_dock.cpp msgid " Files" -msgstr "" +msgstr " Tệp tin" #: editor/import_dock.cpp msgid "Import As:" -msgstr "" +msgstr "Nháºp và o vá»›i:" #: editor/import_dock.cpp editor/property_editor.cpp msgid "Preset..." -msgstr "" +msgstr "Cà i sẵn ..." #: editor/import_dock.cpp msgid "Reimport" -msgstr "" +msgstr "Nháºp và o lại" #: editor/import_dock.cpp msgid "Save scenes, re-import and restart" -msgstr "" +msgstr "Lưu các cảnh, nháºp và o lại và khởi động lại" #: editor/import_dock.cpp msgid "Changing the type of an imported file requires editor restart." @@ -3759,34 +3749,32 @@ msgstr "" #: editor/inspector_dock.cpp msgid "Expand All Properties" -msgstr "" +msgstr "Mở rá»™ng tất cả" #: editor/inspector_dock.cpp -#, fuzzy msgid "Collapse All Properties" msgstr "Thu gá»n tất cả" #: editor/inspector_dock.cpp editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/script_editor_plugin.cpp msgid "Save As..." -msgstr "" +msgstr "Lưu thà nh ..." #: editor/inspector_dock.cpp msgid "Copy Params" -msgstr "" +msgstr "Sao chép các đối số" #: editor/inspector_dock.cpp msgid "Paste Params" -msgstr "" +msgstr "Dán các đối số" #: editor/inspector_dock.cpp -#, fuzzy msgid "Edit Resource Clipboard" -msgstr "Lá»–I: Không có animation trên clipboard!" +msgstr "Chỉnh sá»a Tà i nguyên trên Clipboard" #: editor/inspector_dock.cpp msgid "Copy Resource" -msgstr "" +msgstr "Sao chép Tà i nguyên" #: editor/inspector_dock.cpp msgid "Make Built-In" @@ -3798,7 +3786,7 @@ msgstr "" #: editor/inspector_dock.cpp msgid "Open in Help" -msgstr "" +msgstr "Mở trong Trợ giúp" #: editor/inspector_dock.cpp msgid "Create a new resource in memory and edit it." @@ -3809,9 +3797,8 @@ msgid "Load an existing resource from disk and edit it." msgstr "" #: editor/inspector_dock.cpp -#, fuzzy msgid "Save the currently edited resource." -msgstr "Lưu animation nà y" +msgstr "Lưu tà i nguyên đã chỉnh sá»a hiện tại." #: editor/inspector_dock.cpp msgid "Go to the previous edited object in history." @@ -3827,15 +3814,15 @@ msgstr "" #: editor/inspector_dock.cpp msgid "Object properties." -msgstr "" +msgstr "Thuá»™c tÃnh đối tượng." #: editor/inspector_dock.cpp msgid "Filter properties" -msgstr "" +msgstr "Lá»c các thuá»™c tÃnh" #: editor/inspector_dock.cpp msgid "Changes may be lost!" -msgstr "" +msgstr "Các thay đổi có thể mất!" #: editor/multi_node_edit.cpp msgid "MultiNode Set" @@ -3860,32 +3847,30 @@ msgstr "" #: editor/plugin_config_dialog.cpp msgid "Subfolder:" -msgstr "" +msgstr "Thư mục phụ:" #: editor/plugin_config_dialog.cpp msgid "Language:" -msgstr "" +msgstr "Ngôn ngữ:" #: editor/plugin_config_dialog.cpp msgid "Script Name:" -msgstr "" +msgstr "Tên Mã lệnh:" #: editor/plugin_config_dialog.cpp msgid "Activate now?" -msgstr "" +msgstr "KÃch hoạt bây giá»?" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp -#, fuzzy msgid "Create Polygon" -msgstr "Tạo" +msgstr "Tạo Polygon" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Create points." -msgstr "Tạo Script" +msgstr "Tạo các Ä‘iểm." #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "" @@ -3893,24 +3878,26 @@ msgid "" "LMB: Move Point\n" "RMB: Erase Point" msgstr "" +"Chỉnh sá»a Ä‘iểm.\n" +"LMB: Di chuyển Ä‘iểm\n" +"RMB: Xoá Ä‘iểm" #: editor/plugins/abstract_polygon_2d_editor.cpp #: editor/plugins/animation_blend_space_1d_editor.cpp msgid "Erase points." -msgstr "" +msgstr "Xoá các Ä‘iểm." #: editor/plugins/abstract_polygon_2d_editor.cpp -#, fuzzy msgid "Edit Polygon" -msgstr "Tạo" +msgstr "Chỉnh sá»a Polygon" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Insert Point" -msgstr "" +msgstr "Chén Ä‘iểm" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Edit Polygon (Remove Point)" -msgstr "" +msgstr "Sá»a Polygon (Gỡ Ä‘iểm)" #: editor/plugins/abstract_polygon_2d_editor.cpp msgid "Remove Polygon And Point" @@ -3929,13 +3916,12 @@ msgstr "Thêm Animation" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp msgid "Load..." -msgstr "" +msgstr "Nạp ..." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Move Node Point" -msgstr "Di chuyển đến..." +msgstr "Di chuyển Ä‘iểm Nút" #: editor/plugins/animation_blend_space_1d_editor.cpp #, fuzzy @@ -3955,15 +3941,13 @@ msgstr "" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Add Node Point" -msgstr "Di chuyển đến..." +msgstr "Thêm Ä‘iểm Nút" #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Add Animation Point" -msgstr "Thêm Animation" +msgstr "Thêm Ä‘iểm Hoạt ảnh" #: editor/plugins/animation_blend_space_1d_editor.cpp msgid "Remove BlendSpace1D Point" @@ -3995,30 +3979,27 @@ 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 "KÃch hoạt Snap và hiện Grid." #: editor/plugins/animation_blend_space_1d_editor.cpp #: editor/plugins/animation_blend_space_2d_editor.cpp msgid "Point" -msgstr "" +msgstr "Äiểm" #: 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 -#, fuzzy msgid "Open Animation Node" -msgstr "Tối ưu Animation" +msgstr "Mở nút Hoạt ảnh" #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Triangle already exists." -msgstr "Lá»–I: Tên animation trùng lặp!" +msgstr "Tam giác đã tồn tại." #: editor/plugins/animation_blend_space_2d_editor.cpp -#, fuzzy msgid "Add Triangle" -msgstr "Thêm Biến" +msgstr "Thêm Tam giác" #: editor/plugins/animation_blend_space_2d_editor.cpp #, fuzzy @@ -4067,16 +4048,16 @@ msgstr "" #: editor/plugins/animation_blend_space_2d_editor.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Blend:" -msgstr "" +msgstr "Trá»™n:" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Parameter Changed" -msgstr "" +msgstr "Äối số đã thay đổi" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Edit Filters" -msgstr "" +msgstr "Chỉnh sá»a Lá»c" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Output node can't be added to the blend tree." @@ -4088,51 +4069,45 @@ msgstr "" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Node Moved" -msgstr "Äổi tên" +msgstr "Äã di chuyển Nút" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "Unable to connect, port may be in use or connection may be invalid." msgstr "" +"Không thể kết nối, cổng có thể Ä‘ang được sá» dụng hoặc kết nối không hợp lệ." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Nodes Connected" -msgstr "Äứt kết nối" +msgstr "Các Nút đã Kết nối" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Nodes Disconnected" -msgstr "Äứt kết nối" +msgstr "Các Nút đã ngắt Kết nối" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Set Animation" -msgstr "Tạo Animation má»›i" +msgstr "Gán Hoạt ảnh" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Delete Node" -msgstr "Xóa Node(s)" +msgstr "Xoá Nút" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/scene_tree_dock.cpp msgid "Delete Node(s)" -msgstr "Xóa Node(s)" +msgstr "Xoá các Nút" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Toggle Filter On/Off" -msgstr "Báºt tắt Ưa thÃch" +msgstr "Bá»™ lá»c Báºt/Tắt" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Change Filter" -msgstr "Äổi" +msgstr "Äổi bá»™ lá»c" #: editor/plugins/animation_blend_tree_editor_plugin.cpp msgid "No animation player set, so unable to retrieve track names." @@ -4151,14 +4126,13 @@ msgstr "" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Node Renamed" -msgstr "Äổi tên" +msgstr "Nút đã đổi tên" #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Add Node..." -msgstr "" +msgstr "Thêm Nút ..." #: editor/plugins/animation_blend_tree_editor_plugin.cpp #: editor/plugins/root_motion_editor_plugin.cpp @@ -4166,49 +4140,46 @@ msgid "Edit Filtered Tracks:" msgstr "" #: editor/plugins/animation_blend_tree_editor_plugin.cpp -#, fuzzy msgid "Enable Filtering" -msgstr "Äổi" +msgstr "KÃch hoạt lá»c" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Toggle Autoplay" -msgstr "" +msgstr "Chuyển đổi Tá»± động chạy" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Animation Name:" -msgstr "" +msgstr "Tên hoạt ảnh má»›i:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "New Anim" -msgstr "" +msgstr "Hoạt ảnh má»›i" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Change Animation Name:" -msgstr "" +msgstr "Äổi tên Hoạt ảnh:" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Delete Animation?" -msgstr "" +msgstr "Xoá Hoạt ảnh?" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Remove Animation" -msgstr "Xóa Animation" +msgstr "Xoá Hoạt ảnh" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Invalid animation name!" -msgstr "Lá»–I: Tên animation không hợp lệ!" +msgstr "Tên Hoạt ảnh không hợp lệ!" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Animation name already exists!" -msgstr "Lá»–I: Tên animation trùng lặp!" +msgstr "Tên Hoạt ảnh đã tồn tại!" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/sprite_frames_editor_plugin.cpp msgid "Rename Animation" -msgstr "Äổi tên Animation" +msgstr "Äổi tên Hoạt ảnh" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Blend Next Changed" @@ -4220,58 +4191,55 @@ msgstr "Äổi Thá»i gian Chuyển Animation" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Load Animation" -msgstr "Load Animation" +msgstr "Nạp Hoạt ảnh" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Duplicate Animation" -msgstr "Tạo Animation bản sao" +msgstr "Nhân bản Hoạt ảnh" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "No animation to copy!" -msgstr "Lá»–I: Không có animation để copy!" +msgstr "Không có hoạt ảnh để sao chép!" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "No animation resource on clipboard!" -msgstr "Lá»–I: Không có animation trên clipboard!" +msgstr "Không có hoạt ảnh trên Clipboard!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Pasted Animation" -msgstr "Animation đã Dán" +msgstr "Äã dán Hoạt ảnh" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Paste Animation" -msgstr "Dán Animation" +msgstr "Dán Hoạt ảnh" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "No animation to edit!" -msgstr "Lá»–I: Không có animation để chỉnh!" +msgstr "Không có hoạt ảnh để chỉnh sá»a!" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from current pos. (A)" -msgstr "Chạy animation ngược lại từ vị trà hiện tại. (A)" +msgstr "Chạy hoạt ảnh đã chá»n ngược lại từ vị trà hiện tại. (A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation backwards from end. (Shift+A)" -msgstr "Chạy animation ngược lại từ cuối. (Shift+A)" +msgstr "Chạy hoạt ảnh đã chá»n ngược lại từ cuối. (Shift+A)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Stop animation playback. (S)" -msgstr "Ngưng chạy animation. (S)" +msgstr "Ngưng chạy hoạt ảnh. (S)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from start. (Shift+D)" -msgstr "Chạy animation từ đầu. (Shift+D)" +msgstr "Chạy hoạt ảnh đã chá»n từ đầu. (Shift+D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Play selected animation from current pos. (D)" -msgstr "Chạy animation từ vị trà hiện tại. (D)" +msgstr "Chạy hoạt ảnh đã chá»n từ vị trà hiện tại. (D)" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation position (in seconds)." -msgstr "Vị trà animation (đơn vị giây)." +msgstr "Vị trà hoạt ảnh (giây)." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Scale animation playback globally for the node." @@ -4279,17 +4247,16 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Tools" -msgstr "Các Công cụ Animation" +msgstr "Công cụ Hoạt ảnh" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Animation" -msgstr "" +msgstr "Hoạt ảnh" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Edit Transitions..." -msgstr "Chuyển tiếp" +msgstr "Chỉnh sá»a Chuyển tiếp ..." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Open in Inspector" @@ -4297,11 +4264,11 @@ msgstr "" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Display list of animations in player." -msgstr "Hiển thị danh sách các animation trong player." +msgstr "Hiển thị danh sách các hoạt ảnh trong player." #: editor/plugins/animation_player_editor_plugin.cpp msgid "Autoplay on Load" -msgstr "Tá»± động chạy khi Load" +msgstr "Tá»± động chạy khi nạp" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Enable Onion Skinning" @@ -4341,9 +4308,8 @@ msgid "3 steps" msgstr "3 bước" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Differences Only" -msgstr "Chỉ khác biệt" +msgstr "Chỉ khác nhau" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Force White Modulate" @@ -4354,17 +4320,16 @@ msgid "Include Gizmos (3D)" msgstr "Kèm Gizmos (3D)" #: editor/plugins/animation_player_editor_plugin.cpp -#, fuzzy msgid "Pin AnimationPlayer" -msgstr "Dán Animation" +msgstr "ÄÃnh AnimationPlayer" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Create New Animation" -msgstr "Tạo Animation má»›i" +msgstr "Tạo Hoạt ảnh má»›i" #: editor/plugins/animation_player_editor_plugin.cpp msgid "Animation Name:" -msgstr "Tên Animation:" +msgstr "Tên Hoạt ảnh:" #: editor/plugins/animation_player_editor_plugin.cpp #: editor/plugins/resource_preloader_editor_plugin.cpp @@ -4387,27 +4352,25 @@ msgid "Cross-Animation Blend Times" msgstr "" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Move Node" -msgstr "Di chuyển Node(s)" +msgstr "Di chuyển Nút" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Add Transition" -msgstr "Chuyển tiếp: " +msgstr "Thêm Chuyển tiếp" #: editor/plugins/animation_state_machine_editor.cpp #: modules/visual_script/visual_script_editor.cpp msgid "Add Node" -msgstr "" +msgstr "Thêm Nút" #: editor/plugins/animation_state_machine_editor.cpp msgid "End" -msgstr "" +msgstr "Cuối" #: editor/plugins/animation_state_machine_editor.cpp msgid "Immediate" -msgstr "" +msgstr "Láºp tức" #: editor/plugins/animation_state_machine_editor.cpp msgid "Sync" @@ -4430,18 +4393,16 @@ msgid "No playback resource set at path: %s." msgstr "" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Node Removed" -msgstr "Xóa" +msgstr "Nút đã được gỡ" #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Transition Removed" -msgstr "Chuyển tiếp: " +msgstr "Chuyển tiếp đã gỡ" #: editor/plugins/animation_state_machine_editor.cpp msgid "Set Start Node (Autoplay)" -msgstr "" +msgstr "Gán Nút bắt đầu (Tá»± động chạy)" #: editor/plugins/animation_state_machine_editor.cpp msgid "" @@ -4449,30 +4410,31 @@ msgid "" "RMB to add new nodes.\n" "Shift+LMB to create connections." msgstr "" +"Chá»n và di chuyển các nút.\n" +"RMB để thêm các nút má»›i.\n" +"Shift+LMB để tạo các kết nối." #: editor/plugins/animation_state_machine_editor.cpp msgid "Create new nodes." -msgstr "Tạo nodes má»›i." +msgstr "Tạo các nút má»›i." #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Connect nodes." -msgstr "Kết nối đến Node:" +msgstr "Kết nối các nút." #: editor/plugins/animation_state_machine_editor.cpp -#, fuzzy msgid "Remove selected node or transition." -msgstr "Bá» track Ä‘ang chá»n." +msgstr "Xoá nút và chuyển tiếp đã chá»n." #: editor/plugins/animation_state_machine_editor.cpp msgid "Toggle autoplay this animation on start, restart or seek to zero." msgstr "" -"Báºt tắt tá»± động chạy cá»§a animation nà y khi bắt đầu, khởi động lại hoặc lùi " -"vá» 0." +"Chuyển đổi tá»± động chạy cá»§a hoạt ảnh khi bắt đầu, khởi động lại hoặc lùi vá» " +"0." #: editor/plugins/animation_state_machine_editor.cpp msgid "Set the end animation. This is useful for sub-transitions." -msgstr "Äặt kết thúc animation. Hữu dụng cho sub-transitions." +msgstr "Äặt kết thúc hoạt ảnh. Hữu dụng cho sub-transitions." #: editor/plugins/animation_state_machine_editor.cpp msgid "Transition: " @@ -4481,7 +4443,7 @@ msgstr "Chuyển tiếp: " #: editor/plugins/animation_tree_editor_plugin.cpp #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "AnimationTree" -msgstr "AnimationTree" +msgstr "Cây Hoạt ảnh" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "New name:" @@ -4493,9 +4455,8 @@ msgid "Scale:" msgstr "Tá»· lệ:" #: editor/plugins/animation_tree_player_editor_plugin.cpp -#, fuzzy msgid "Fade In (s):" -msgstr "Tăng dần (s):" +msgstr "Má» dần (s):" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Fade Out (s):" @@ -4571,13 +4532,12 @@ msgid "Animation tree is invalid." msgstr "Animation tree vô hiệu." #: editor/plugins/animation_tree_player_editor_plugin.cpp -#, fuzzy msgid "Animation Node" -msgstr "Animation Node" +msgstr "Nút Hoạt ảnh" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "OneShot Node" -msgstr "" +msgstr "Nút Chạy má»™t lần" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Mix Node" @@ -4609,7 +4569,7 @@ msgstr "" #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Import Animations..." -msgstr "" +msgstr "Nháºp và o các hoạt ảnh ..." #: editor/plugins/animation_tree_player_editor_plugin.cpp msgid "Edit Node Filters" @@ -4633,7 +4593,7 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Connection error, please try again." -msgstr "" +msgstr "Kết ná»—i lá»—i, thá» lại." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Can't connect to host:" @@ -4670,7 +4630,7 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Asset Download Error:" -msgstr "" +msgstr "Lá»—i tải nguyên liệu:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Downloading (%s / %s)..." @@ -4702,21 +4662,19 @@ msgstr "Lá»—i tải" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Download for this asset is already in progress!" -msgstr "" +msgstr "Tải xuống nguyên liệu nà y đã được tiến hà nh!" #: editor/plugins/asset_library_editor_plugin.cpp msgid "First" msgstr "Äầu tiên" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Previous" -msgstr "Thư mục trước" +msgstr "Trước đó" #: editor/plugins/asset_library_editor_plugin.cpp -#, fuzzy msgid "Next" -msgstr "Tìm tiếp theo" +msgstr "Tiếp theo" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Last" @@ -4734,16 +4692,16 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp msgid "Sort:" -msgstr "" +msgstr "Sắp xếp:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Reverse" -msgstr "" +msgstr "Ngược lại" #: editor/plugins/asset_library_editor_plugin.cpp #: editor/project_settings_editor.cpp msgid "Category:" -msgstr "" +msgstr "Danh mục:" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Site:" @@ -4751,19 +4709,19 @@ msgstr "" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Support..." -msgstr "" +msgstr "Há»— trợ ..." #: editor/plugins/asset_library_editor_plugin.cpp msgid "Official" -msgstr "" +msgstr "ChÃnh thức" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Testing" -msgstr "" +msgstr "Kiểm tra" #: editor/plugins/asset_library_editor_plugin.cpp msgid "Assets ZIP File" -msgstr "" +msgstr "Tệp tin ZIP Nguyên liệu" #: editor/plugins/baked_lightmap_editor_plugin.cpp msgid "" @@ -4789,11 +4747,11 @@ msgstr "" #: editor/plugins/camera_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/rename_dialog.cpp msgid "Preview" -msgstr "" +msgstr "Xem thá»" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Configure Snap" -msgstr "" +msgstr "Cấu hình Snap" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Grid Offset:" @@ -4840,95 +4798,92 @@ msgid "Create new horizontal and vertical guides" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Move pivot" -msgstr "Di chuyển đến..." +msgstr "Di chuyển trục" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotate CanvasItem" -msgstr "" +msgstr "Xoay CanvasItem" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move anchor" -msgstr "" +msgstr "Di chuyển neo" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Resize CanvasItem" -msgstr "" +msgstr "Äổi kÃch thước CanvasItem" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Scale CanvasItem" -msgstr "" +msgstr "Tỉ lệ CanvasItem" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move CanvasItem" -msgstr "" +msgstr "Di chuyển CanvasItem" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" "Children of containers have their anchors and margins values overridden by " "their parent." msgstr "" +"Mục con trong thùng chứa có giá trị neo và lá» cá»§a chúng được ghi đè bởi cha " +"chúng." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Presets for the anchors and margins values of a Control node." -msgstr "" +msgstr "Äặt trước giá trị neo và lá» cá»§a nút Control." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "" "When active, moving Control nodes changes their anchors instead of their " "margins." msgstr "" +"Khi hoạt động, các nút Control di chuyển thay đổi các neo thay vì lá» cá»§a " +"chúng." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Anchors only" -msgstr "" +msgstr "Chỉ các neo" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change Anchors and Margins" -msgstr "" +msgstr "Äổi Neo và Lá»" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Change Anchors" -msgstr "" +msgstr "Äổi các Neo" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Lock Selected" -msgstr "Xoá lá»±a chá»n" +msgstr "Khoá lá»±a chá»n" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Unlock Selected" -msgstr "Xoá lá»±a chá»n" +msgstr "Mở khoá Lá»±a chá»n" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Group Selected" -msgstr "Di chuyển Lá»±a chá»n" +msgstr "Nhóm Lá»±a chá»n" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp -#, fuzzy msgid "Ungroup Selected" -msgstr "Di chuyển Lá»±a chá»n" +msgstr "Bá» nhóm đã chá»n" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Paste Pose" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Create Custom Bone(s) from Node(s)" -msgstr "Tạo từ Scene" +msgstr "Tạo xương tuỳ chỉnh từ Nút" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Clear Bones" -msgstr "Xoá Auto-Advance" +msgstr "Xoá khung xương" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Make IK Chain" @@ -4947,21 +4902,20 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/texture_region_editor_plugin.cpp #: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp -#, fuzzy msgid "Zoom Reset" -msgstr "Thu nhá»" +msgstr "Äặt lại Thu phóng" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Select Mode" -msgstr "" +msgstr "Chế độ chá»n" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Drag: Rotate" -msgstr "" +msgstr "Kéo: Xoay" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Alt+Drag: Move" -msgstr "" +msgstr "Alt+Kéo: Di chuyển" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Press 'v' to Change Pivot, 'Shift+v' to Drag Pivot (while moving)." @@ -4973,16 +4927,15 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Move Mode" -msgstr "" +msgstr "Chế độ Di chuyển" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Rotate Mode" -msgstr "" +msgstr "Chế độ Xoay" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Scale Mode" -msgstr "Báºt tắt Chức năng" +msgstr "Chế độ Tỉ lệ" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp @@ -4990,6 +4943,8 @@ msgid "" "Show a list of all objects at the position clicked\n" "(same as Alt+RMB in select mode)." msgstr "" +"Hiện thị danh sách tất cả đối tượng có vị trà đã nhấp.\n" +"(giống Alt+RMB trong chế độ chá»n)." #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Click to change object's rotation pivot." @@ -5005,7 +4960,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Snap" -msgstr "" +msgstr "Sá» dụng Snap" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snapping Options" @@ -5013,7 +4968,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Snap to Grid" -msgstr "" +msgstr "Snap dạng lưới" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Use Rotation Snap" @@ -5081,9 +5036,8 @@ msgid "Restores the object's children's ability to be selected." msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Skeleton Options" -msgstr "Xóa Point" +msgstr "Cà i đặt Khung xương" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Bones" @@ -5100,12 +5054,12 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp msgid "View" -msgstr "" +msgstr "Hiện thị" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/polygon_2d_editor_plugin.cpp msgid "Show Grid" -msgstr "" +msgstr "Hiện lưới" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Helpers" @@ -5113,7 +5067,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Rulers" -msgstr "" +msgstr "Hiện thước" #: editor/plugins/canvas_item_editor_plugin.cpp msgid "Show Guides" @@ -5212,7 +5166,7 @@ msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp msgid "Create Node" -msgstr "" +msgstr "Tạo Nút" #: editor/plugins/canvas_item_editor_plugin.cpp #: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp @@ -5220,7 +5174,6 @@ msgid "Error instancing scene from %s" msgstr "" #: editor/plugins/canvas_item_editor_plugin.cpp -#, fuzzy msgid "Change Default Type" msgstr "Äổi dạng mặc định" @@ -5231,17 +5184,16 @@ msgid "" msgstr "" #: editor/plugins/collision_polygon_editor_plugin.cpp -#, fuzzy msgid "Create Polygon3D" -msgstr "Tạo" +msgstr "Tạo Polygon3D" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly" -msgstr "" +msgstr "Sá»a Poly" #: editor/plugins/collision_polygon_editor_plugin.cpp msgid "Edit Poly (Remove Point)" -msgstr "" +msgstr "Sá»a Poly (Xoá Ä‘iểm)" #: editor/plugins/collision_shape_2d_editor_plugin.cpp msgid "Set Handle" @@ -5250,7 +5202,7 @@ msgstr "" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Error loading image:" -msgstr "" +msgstr "Lá»—i tải nạp hình ảnh:" #: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp @@ -5263,6 +5215,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "Restart ngay" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -5340,14 +5300,12 @@ msgid "Load Curve Preset" msgstr "" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Add Point" -msgstr "Di chuyển đến..." +msgstr "Thêm Ä‘iểm" #: editor/plugins/curve_editor_plugin.cpp -#, fuzzy msgid "Remove Point" -msgstr "Di chuyển đến..." +msgstr "Xoá Ä‘iểm" #: editor/plugins/curve_editor_plugin.cpp #, fuzzy @@ -6184,10 +6142,20 @@ msgid "Find Next" msgstr "Tìm tiếp theo" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter scripts" +msgstr "Lá»c các thuá»™c tÃnh" + +#: editor/plugins/script_editor_plugin.cpp msgid "Toggle alphabetical sorting of the method list." msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +msgid "Filter methods" +msgstr "Lá»c các nút" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "" @@ -6423,20 +6391,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +msgstr "Tạo các Ä‘iểm." + #: editor/plugins/script_text_editor.cpp scene/gui/line_edit.cpp #: scene/gui/text_edit.cpp msgid "Cut" msgstr "Cắt" -#: 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 "" @@ -8031,51 +8003,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8083,203 +8011,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9934,6 +9686,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "Thu gá»n Tất cả" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -9963,8 +9720,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "Tạo các nút má»›i." #: editor/scene_tree_dock.cpp msgid "" @@ -10212,7 +9970,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10618,54 +10376,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11250,7 +10960,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11299,7 +11009,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11309,7 +11019,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11376,14 +11086,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11462,7 +11179,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11491,6 +11208,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11525,8 +11246,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11537,7 +11258,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11553,7 +11276,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11564,7 +11287,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11599,7 +11324,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "Không có kết nối đến input '%s' cá»§a node '%s'." #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11612,8 +11337,9 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." -msgstr "" +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." +msgstr "Animation tree vô hiệu." #: scene/animation/animation_tree_player.cpp msgid "This node has been deprecated. Use AnimationTree instead." @@ -11624,7 +11350,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11637,10 +11367,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11652,23 +11387,24 @@ msgid "Please Confirm..." msgstr "Xin hãy xác nháºn..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Các popup sẽ mặc định là ẩn trừ khi bạn gá»i popup() hoặc bất kì function nà o " "có dạng popup*(). Có thể để popup nhìn thấy được để chỉnh sá»a, nhưng chúng " "sẽ ẩn khi chạy." #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11711,6 +11447,11 @@ msgid "Input" msgstr "Nháºp" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "nguồn vô hiệu cho shader." + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "nguồn vô hiệu cho shader." @@ -11730,6 +11471,9 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#~ msgid "Enabled Classes" +#~ msgstr "Các lá»›p đã báºt" + #, fuzzy #~ msgid "Path to Node:" #~ msgstr "ÄÆ°á»ng đến Node:" diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po index 230854316d..a789fbbaaa 100644 --- a/editor/translations/zh_CN.po +++ b/editor/translations/zh_CN.po @@ -46,12 +46,14 @@ # qjyqjyqjyqjy <qjyqjyqjyqjy@sina.com.cn>, 2019. # liushuyu011 <liushuyu011@gmail.com>, 2019. # DS <dseqrasd@126.com>, 2019. +# ZeroAurora <zeroaurora@qq.com>, 2019. +# Gary Wang <wzc782970009@gmail.com>, 2019. msgid "" msgstr "" "Project-Id-Version: Chinese (Simplified) (Godot Engine)\n" "POT-Creation-Date: 2018-01-20 12:15+0200\n" -"PO-Revision-Date: 2019-06-16 19:42+0000\n" -"Last-Translator: yzt <834950797@qq.com>\n" +"PO-Revision-Date: 2019-07-09 10:47+0000\n" +"Last-Translator: Gary Wang <wzc782970009@gmail.com>\n" "Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/" "godot-engine/godot/zh_Hans/>\n" "Language: zh_CN\n" @@ -59,7 +61,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 3.7-dev\n" +"X-Generator: Weblate 3.8-dev\n" #: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp #: modules/visual_script/visual_script_builtin_funcs.cpp @@ -118,9 +120,8 @@ msgid "Time:" msgstr "æ—¶é—´:" #: editor/animation_bezier_editor.cpp -#, fuzzy msgid "Value:" -msgstr "值" +msgstr "值:" #: editor/animation_bezier_editor.cpp msgid "Insert Key Here" @@ -473,7 +474,16 @@ msgstr "" #: editor/animation_track_editor.cpp msgid "Warning: Editing imported animation" -msgstr "" +msgstr "è¦å‘Š: æ£åœ¨ç¼–辑导入的动画" + +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "全选" + +#: editor/animation_track_editor.cpp +msgid "Select None" +msgstr "å–æ¶ˆé€‰æ‹©" #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." @@ -649,6 +659,10 @@ msgstr "转到行" msgid "Line Number:" msgstr "行å·:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "æ— åŒ¹é…项" @@ -698,7 +712,7 @@ msgstr "缩å°" msgid "Reset Zoom" msgstr "é‡ç½®ç¼©æ”¾" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "è¦å‘Š" @@ -719,24 +733,21 @@ msgid "" msgstr "找ä¸åˆ°ç›®æ ‡æ–¹æ³•ï¼ è¯·æŒ‡å®šä¸€ä¸ªæœ‰æ•ˆçš„æ–¹æ³•æˆ–æŠŠè„šæœ¬é™„åŠ åˆ°ç›®æ ‡èŠ‚ç‚¹ã€‚" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Node:" msgstr "连接到节点:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect to Script:" -msgstr "æ— æ³•è¿žæŽ¥åˆ°æœåС噍:" +msgstr "连接到脚本:" #: editor/connections_dialog.cpp #, fuzzy msgid "From Signal:" -msgstr "ä¿¡å·:" +msgstr "ä¿¡å·æº:" #: editor/connections_dialog.cpp -#, fuzzy msgid "Scene does not contain any script." -msgstr "节点ä¸åŒ…å«å‡ 何。" +msgstr "节点ä¸åŒ…å«è„šæœ¬ã€‚" #: editor/connections_dialog.cpp editor/editor_autoload_settings.cpp #: editor/groups_editor.cpp editor/plugins/item_list_editor_plugin.cpp @@ -775,7 +786,7 @@ msgstr "å»¶æ—¶" #: editor/connections_dialog.cpp msgid "" "Defers the signal, storing it in a queue and only firing it at idle time." -msgstr "" +msgstr "延迟信å·è§¦å‘ï¼Œå°†å…¶æ·»åŠ åˆ°ä¿¡å·é˜Ÿåˆ—,在引擎空闲时触å‘。" #: editor/connections_dialog.cpp msgid "Oneshot" @@ -783,12 +794,11 @@ msgstr "啿¬¡" #: editor/connections_dialog.cpp msgid "Disconnects the signal after its first emission." -msgstr "" +msgstr "ä¿¡å·è§¦å‘åŽè‡ªåЍ喿¶ˆè¿žæŽ¥ã€‚" #: editor/connections_dialog.cpp -#, fuzzy msgid "Cannot connect signal" -msgstr "连接信å·ï¼š " +msgstr "æ— æ³•è¿žæŽ¥ä¿¡å·" #: editor/connections_dialog.cpp editor/dependency_editor.cpp #: editor/export_template_manager.cpp editor/groups_editor.cpp @@ -809,6 +819,11 @@ msgid "Connect" msgstr "连接" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "ä¿¡å·:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "连接'%s'到'%s'" @@ -830,14 +845,12 @@ msgid "Disconnect" msgstr "åˆ é™¤ä¿¡å·è¿žæŽ¥" #: editor/connections_dialog.cpp -#, fuzzy msgid "Connect a Signal to a Method" -msgstr "连接信å·ï¼š " +msgstr "连接信å·åˆ°æ–¹æ³•" #: editor/connections_dialog.cpp -#, fuzzy msgid "Edit Connection:" -msgstr "编辑广æ’订阅: " +msgstr "编辑连接:" #: editor/connections_dialog.cpp msgid "Are you sure you want to remove all connections from the \"%s\" signal?" @@ -913,11 +926,10 @@ msgid "Dependencies For:" msgstr "ä¾èµ–项:" #: editor/dependency_editor.cpp -#, fuzzy msgid "" "Scene '%s' is currently being edited.\n" "Changes will only take effect when reloaded." -msgstr "场景'%s'å·²è¢«ä¿®æ”¹ï¼Œé‡æ–°åŠ è½½åŽç”Ÿæ•ˆã€‚" +msgstr "场景 '%s' å·²è¢«ä¿®æ”¹ï¼Œé‡æ–°åŠ è½½åŽç”Ÿæ•ˆã€‚" #: editor/dependency_editor.cpp #, fuzzy @@ -971,7 +983,8 @@ msgid "Owners Of:" msgstr "拥有者:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "确定从项目ä¸åˆ é™¤æ–‡ä»¶ï¼Ÿï¼ˆæ¤æ“ä½œæ— æ³•æ’¤é”€ï¼‰" #: editor/dependency_editor.cpp @@ -1014,9 +1027,8 @@ msgid "Permanently delete %d item(s)? (No undo!)" msgstr "æ°¸ä¹…åˆ é™¤é€‰ä¸çš„%dæ¡é¡¹ç›®å—ï¼Ÿï¼ˆæ¤æ“ä½œæ— æ³•æ’¤é”€ï¼ï¼‰" #: editor/dependency_editor.cpp -#, fuzzy msgid "Show Dependencies" -msgstr "ä¾èµ–" +msgstr "显示ä¾èµ–" #: editor/dependency_editor.cpp editor/editor_node.cpp msgid "Orphan Resource Explorer" @@ -1277,7 +1289,7 @@ msgstr "打开音频Bus布局" #: editor/editor_audio_buses.cpp msgid "There is no '%s' file." -msgstr "" +msgstr "文件 '%s' ä¸å˜åœ¨ã€‚" #: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp msgid "Layout" @@ -1334,23 +1346,20 @@ msgid "Valid characters:" msgstr "å—ç¬¦åˆæ³•:" #: editor/editor_autoload_settings.cpp -#, fuzzy msgid "Must not collide with an existing engine class name." -msgstr "åç§°éžæ³•,与引擎内置类型å称冲çªã€‚" +msgstr "与引擎内置类型å称冲çªã€‚" #: editor/editor_autoload_settings.cpp -#, fuzzy -msgid "Must not collide with an existing buit-in type name." -msgstr "åç§°éžæ³•,与引擎内置类型å称冲çªã€‚" +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 "åç§°éžæ³•,与已å˜åœ¨çš„全局常é‡å称冲çªã€‚" +msgstr "与已å˜åœ¨çš„全局常é‡å称冲çªã€‚" #: editor/editor_autoload_settings.cpp msgid "Keyword cannot be used as an autoload name." -msgstr "" +msgstr "该å称已被用作其他 autoload å 用。" #: editor/editor_autoload_settings.cpp msgid "Autoload '%s' already exists!" @@ -1436,9 +1445,8 @@ msgid "[unsaved]" msgstr "[未ä¿å˜]" #: editor/editor_dir_dialog.cpp -#, fuzzy msgid "Please select a base directory first." -msgstr "请先选择一个目录" +msgstr "请先选择一个目录。" #: editor/editor_dir_dialog.cpp msgid "Choose a Directory" @@ -1516,122 +1524,109 @@ msgstr "找ä¸åˆ°è‡ªå®šä¹‰å‘布包。" 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 -#, fuzzy msgid "3D Editor" -msgstr "编辑器" +msgstr "3D编辑器" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Script Editor" -msgstr "打开脚本编辑器" +msgstr "脚本编辑器" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Asset Library" -msgstr "打开资æºå•†åº—" +msgstr "资产库" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Scene Tree Editing" -msgstr "åœºæ™¯æ ‘:" +msgstr "åœºæ™¯æ ‘ç¼–è¾‘" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Dock" -msgstr "导入" +msgstr "坼入颿¿" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Node Dock" -msgstr "节点已移动" +msgstr "èŠ‚ç‚¹é¢æ¿" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Filesystem Dock" -msgstr "文件系统" +msgid "FileSystem and Import Docks" +msgstr "æ–‡ä»¶ç³»ç»Ÿå’Œå¯¼å…¥é¢æ¿" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase profile '%s'? (no undo)" -msgstr "全部替æ¢ï¼ˆæ— 法撤销)" +msgstr "åˆ é™¤é…置文件 '%s'? ï¼ˆæ— æ³•æ’¤é”€ï¼‰" #: editor/editor_feature_profile.cpp msgid "Profile must be a valid filename and must not contain '.'" -msgstr "" +msgstr "é…置文件必须是有效的文件å,并且ä¸èƒ½åŒ…å« '.'" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Profile with this name already exists." -msgstr "åŒå的文件夹已ç»å˜åœ¨ã€‚" +msgstr "åŒåçš„é…置文件已ç»å˜åœ¨ã€‚" #: editor/editor_feature_profile.cpp msgid "(Editor Disabled, Properties Disabled)" -msgstr "" +msgstr "(编辑器已ç¦ç”¨ï¼Œå±žæ€§å·²ç¦ç”¨ï¼‰" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Properties Disabled)" -msgstr "仅属性" +msgstr "(属性已ç¦ç”¨ï¼‰" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "(Editor Disabled)" -msgstr "ç¦ç”¨å‰ªè¾‘" +msgstr "(编辑器已ç¦ç”¨ï¼‰" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options:" -msgstr "类说明:" +msgstr "类选项:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enable Contextual Editor" -msgstr "打开下一个编辑器" +msgstr "å¯ç”¨ä¸Šä¸‹æ–‡ç¼–辑器" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Properties:" -msgstr "属性:" +msgstr "å¯ç”¨çš„属性:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Features:" -msgstr "功能" +msgstr "å¯ç”¨çš„功能:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Enabled Classes:" -msgstr "æœç´¢ç±»åž‹" +msgstr "å¯ç”¨çš„类:" #: editor/editor_feature_profile.cpp msgid "File '%s' format is invalid, import aborted." -msgstr "" +msgstr "文件 '%s' æ ¼å¼æ— æ•ˆï¼Œå¯¼å…¥ä¸æ¢ã€‚" #: editor/editor_feature_profile.cpp +#, fuzzy msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." -msgstr "" +msgstr "é…置文件 '%s' å·²å˜åœ¨ã€‚在导入之å‰é¦–先远程处ç†ï¼Œå¯¼å…¥å·²ä¸æ¢ã€‚" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Error saving profile to path: '%s'." -msgstr "åŠ è½½æ¨¡æ¿ %s 时出错" +msgstr "å°†é…置文件ä¿å˜åˆ°è·¯å¾„时出错: '%s'。" #: editor/editor_feature_profile.cpp msgid "Unset" -msgstr "" +msgstr "未设置" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" -msgstr "当å‰ç‰ˆæœ¬:" +msgid "Current Profile:" +msgstr "当å‰é…置文件" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Make Current" -msgstr "当å‰:" +msgstr "设为当å‰" #: editor/editor_feature_profile.cpp #: editor/plugins/animation_player_editor_plugin.cpp @@ -1650,43 +1645,32 @@ msgstr "导出" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Available Profiles" -msgstr "有效节点:" +msgid "Available Profiles:" +msgstr "å¯ç”¨é…置文件" #: editor/editor_feature_profile.cpp -#, fuzzy -msgid "Enabled Classes" -msgstr "æœç´¢ç±»åž‹" - -#: editor/editor_feature_profile.cpp -#, fuzzy msgid "Class Options" -msgstr "类说明" +msgstr "类选项" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "New profile name:" -msgstr "æ–°åç§°:" +msgstr "æ–°çš„é…置文件å称:" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Erase Profile" -msgstr "擦除区域" +msgstr "åˆ é™¤é…置文件" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Import Profile(s)" -msgstr "已导入的项目" +msgstr "导入é…置文件" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Export Profile" -msgstr "导出项目" +msgstr "导出é…置文件" #: editor/editor_feature_profile.cpp -#, fuzzy msgid "Manage Editor Feature Profiles" -msgstr "管ç†å¯¼å‡ºæ¨¡æ¿" +msgstr "管ç†ç¼–辑器功能é…置文件" #: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp msgid "Select Current Folder" @@ -1809,9 +1793,8 @@ msgid "(Un)favorite current folder." msgstr "ï¼ˆå–æ¶ˆï¼‰æ”¶è—当剿–‡ä»¶å¤¹ã€‚" #: editor/editor_file_dialog.cpp -#, fuzzy msgid "Toggle visibility of hidden files." -msgstr "åˆ‡æ¢æ˜¾ç¤ºéšè—文件" +msgstr "åˆ‡æ¢æ˜¾ç¤ºéšè—文件。" #: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp msgid "View items as a grid of thumbnails." @@ -1844,10 +1827,11 @@ msgid "ScanSources" msgstr "æ‰«ææºæ–‡ä»¶" #: editor/editor_file_system.cpp +#, fuzzy msgid "" "There are multiple importers for different types pointing to file %s, import " "aborted" -msgstr "" +msgstr "%s 文件å˜åœ¨å¤šç§å¯¼å…¥æ–¹å¼ã€è‡ªåŠ¨å¯¼å…¥å¤±è´¥ã€‚" #: editor/editor_file_system.cpp msgid "(Re)Importing Assets" @@ -2242,9 +2226,8 @@ msgid "Open Base Scene" msgstr "打开父场景" #: editor/editor_node.cpp -#, fuzzy msgid "Quick Open..." -msgstr "快速打开场景..." +msgstr "快速打开..." #: editor/editor_node.cpp msgid "Quick Open Scene..." @@ -2469,7 +2452,7 @@ msgstr "å…³é—å…¶ä»–æ ‡ç¾é¡µ" #: editor/editor_node.cpp msgid "Close Tabs to the Right" -msgstr "" +msgstr "å…³é—å³ä¾§" #: editor/editor_node.cpp #, fuzzy @@ -2608,7 +2591,7 @@ msgstr "æ‰“å¼€é¡¹ç›®æ•°æ®æ–‡ä»¶å¤¹" #: editor/editor_node.cpp msgid "Install Android Build Template" -msgstr "" +msgstr "安装 Android 构建模æ¿" #: editor/editor_node.cpp msgid "Quit to Project List" @@ -2709,10 +2692,30 @@ 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 "Automatically Open Screenshots" +msgstr "自动打开截图" + +#: editor/editor_node.cpp +msgid "Open in an external image editor." +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 "打开“编辑器设置/æ•°æ®\"文件夹" @@ -2725,9 +2728,8 @@ msgid "Open Editor Settings Folder" msgstr "æ‰“å¼€â€œç¼–è¾‘å™¨è®¾ç½®â€æ–‡ä»¶å¤¹" #: editor/editor_node.cpp -#, fuzzy msgid "Manage Editor Features" -msgstr "管ç†å¯¼å‡ºæ¨¡æ¿" +msgstr "管ç†ç¼–辑器功能" #: editor/editor_node.cpp editor/project_export.cpp msgid "Manage Export Templates" @@ -2820,15 +2822,18 @@ msgid "Spins when the editor window redraws." msgstr "编辑器窗å£é‡ç»˜æ—¶æ—‹è½¬ã€‚" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "æŒç»æ›´æ–°UI" +#, fuzzy +msgid "Update Continuously" +msgstr "连ç»" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "有更改时更新UI" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "ç¦ç”¨è‡ªåŠ¨æ›´æ–°" #: editor/editor_node.cpp @@ -2857,7 +2862,7 @@ msgstr "ä¸ä¿å˜" #: editor/editor_node.cpp msgid "Android build template is missing, please install relevant templates." -msgstr "" +msgstr "缺失 Android 构建模æ¿ï¼Œè¯·å®‰è£…相应的模æ¿ã€‚" #: editor/editor_node.cpp #, fuzzy @@ -3019,7 +3024,7 @@ msgstr "æ—¶é—´" msgid "Calls" msgstr "调用次数" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "å¯ç”¨" @@ -3121,6 +3126,11 @@ 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 "新建帧:" @@ -3132,11 +3142,6 @@ msgstr "新建值:" msgid "Add Key/Value Pair" msgstr "æ·»åŠ å¸§/值对" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "移除项目" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3633,6 +3638,7 @@ msgid "Nodes not in Group" msgstr "ä¸åœ¨åˆ†ç»„ä¸çš„节点" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp msgid "Filter nodes" msgstr "ç›é€‰èŠ‚ç‚¹" @@ -3785,11 +3791,11 @@ msgstr "å¦å˜ä¸º..." #: editor/inspector_dock.cpp msgid "Copy Params" -msgstr "æ‹·è´å‚æ•°" +msgstr "å¤åˆ¶å‚æ•°" #: editor/inspector_dock.cpp msgid "Paste Params" -msgstr "粘贴帧" +msgstr "ç²˜è´´å‚æ•°" #: editor/inspector_dock.cpp msgid "Edit Resource Clipboard" @@ -5247,6 +5253,14 @@ msgid "Load Emission Mask" msgstr "åŠ è½½Emission Mask(å‘å°„å±è”½ï¼‰" #: 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 +#, fuzzy +msgid "Restart" +msgstr "ç«‹å³é‡æ–°å¯åЍ" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "清除Emission Mask(å‘å°„å±è”½ï¼‰" @@ -6158,10 +6172,20 @@ msgid "Find Next" msgstr "查找下一项" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 +#, fuzzy +msgid "Filter methods" +msgstr "ç›é€‰æ¨¡å¼ï¼š" + +#: editor/plugins/script_editor_plugin.cpp msgid "Sort" msgstr "排åº" @@ -6344,7 +6368,7 @@ msgstr "ä¿¡å·" #: editor/plugins/script_text_editor.cpp msgid "Target" -msgstr "å¹³å°" +msgstr "æž„å»ºç›®æ ‡" #: editor/plugins/script_text_editor.cpp #, fuzzy @@ -6397,20 +6421,24 @@ msgid "Syntax Highlighter" msgstr "è¯æ³•高亮显示" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +msgstr "" + +#: editor/plugins/script_text_editor.cpp #: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp msgid "Bookmarks" -msgstr "" +msgstr "书ç¾" + +#: editor/plugins/script_text_editor.cpp +#, fuzzy +msgid "Breakpoints" +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 "åˆ é™¤çº¿" @@ -7354,7 +7382,7 @@ msgstr "" #: editor/plugins/theme_editor_plugin.cpp msgid "Submenu" -msgstr "" +msgstr "åèœå•(Submenu)" #: editor/plugins/theme_editor_plugin.cpp #, fuzzy @@ -7478,9 +7506,8 @@ msgid "Mirror Y" msgstr "沿Y轴翻转" #: editor/plugins/tile_map_editor_plugin.cpp -#, fuzzy msgid "Disable Autotile" -msgstr "智能瓦片" +msgstr "ç¦ç”¨æ™ºèƒ½ç£è´´(Autotile)" #: editor/plugins/tile_map_editor_plugin.cpp #, fuzzy @@ -7817,9 +7844,8 @@ msgid "Scalar" msgstr "缩放:" #: editor/plugins/visual_shader_editor_plugin.cpp -#, fuzzy msgid "Vector" -msgstr "å±žæ€§é¢æ¿" +msgstr "å‘é‡" #: editor/plugins/visual_shader_editor_plugin.cpp msgid "Boolean" @@ -8010,51 +8036,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8063,203 +8045,27 @@ msgid "Input parameter." msgstr "å¸é™„到父节点" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -9953,6 +9759,11 @@ msgid "Add Child Node" msgstr "æ·»åŠ å节点" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "全部折å " + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "更改类型" @@ -9981,7 +9792,8 @@ msgid "Delete (No Confirm)" msgstr "ç¡®è®¤åˆ é™¤" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" +#, fuzzy +msgid "Add/Create a New Node." msgstr "æ·»åŠ /创建节点" #: editor/scene_tree_dock.cpp @@ -10249,7 +10061,7 @@ msgstr "æ ˆè¿½è¸ª" msgid "Pick one or more items from the list to display the graph." msgstr "从列表ä¸é€‰å–一个或多个项目以显示图形。" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "错误" @@ -10651,54 +10463,6 @@ msgstr "拾å–è·ç¦»:" msgid "Class name can't be a reserved keyword" msgstr "ç±»åä¸èƒ½æ˜¯ä¿ç•™å…³é”®å—" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "æ£åœ¨åˆ›ç”Ÿæˆå†³æ–¹æ¡ˆ..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "æ£åœ¨ç”ŸæˆC#项目..." - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create solution." -msgstr "创建解决方案失败。" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "ä¿å˜è§£å†³æ–¹æ¡ˆå¤±è´¥ã€‚" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "完æˆ" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "创建C#项目失败。" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "Mono" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "关于C#支æŒ" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "创建C#解决方案" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "构建" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Build Project" -msgstr "构建项目" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "View log" -msgstr "查看日志" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "å†…éƒ¨å¼‚å¸¸å †æ ˆè¿½æœ”ç»“æŸ" @@ -11172,7 +10936,7 @@ msgstr "æ ‡è¯†ç¬¦å—æ®µä¸èƒ½ä¸ºç©º." #: platform/iphone/export/export.cpp msgid "The character '%s' is not allowed in Identifier." -msgstr "æ ‡è¯†ç¬¦ä¸ä¸å…许使用å—符 '% s' 。" +msgstr "æ ‡è¯†ç¬¦ä¸ä¸å…许使用å—符 '%s' 。" #: platform/iphone/export/export.cpp msgid "A digit cannot be the first character in a Identifier segment." @@ -11276,8 +11040,9 @@ msgid "Invalid splash screen image dimensions (should be 620x300)." msgstr "å¯åŠ¨ç”»é¢å›¾ç‰‡å°ºå¯¸æ— 效(应为620x300)。" #: scene/2d/animated_sprite.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" "SpriteFrames资æºå¿…须是通过AnimatedSprite节点的frames属性创建的,å¦åˆ™æ— 法显示" @@ -11336,8 +11101,9 @@ msgid "" msgstr "CPUParticles2D动画需è¦ä½¿ç”¨å¯ç”¨äº†â€œç²’å动画â€çš„CanvasItemMaterial。" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "光照的形状与纹ç†å¿…é¡»æä¾›ç»™çº¹ç†å±žæ€§ã€‚" @@ -11347,7 +11113,8 @@ msgid "" msgstr "æ¤é®å…‰ä½“必须设置é®å…‰å½¢çжæ‰èƒ½èµ·åˆ°é®å…‰ä½œç”¨ã€‚" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "æ¤é®å…‰ä½“çš„é®å…‰å½¢çŠ¶ä¸ºç©ºï¼Œè¯·ä¸ºå…¶ç»˜åˆ¶ä¸€ä¸ªé®å…‰å½¢çжï¼" #: scene/2d/navigation_polygon.cpp @@ -11424,14 +11191,26 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." msgstr "该骨骼没有一个åˆé€‚çš„ REST 姿势。请到 Skeleton2D 节点ä¸è®¾ç½®ä¸€ä¸ªã€‚" +#: 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节点下。" + #: scene/2d/visibility_notifier_2d.cpp +#, fuzzy msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"VisibilityEnabler2D works best when used with the edited scene root directly " "as parent." msgstr "VisibilityEnable2Dç±»åž‹çš„èŠ‚ç‚¹ç”¨äºŽåœºæ™¯çš„æ ¹èŠ‚ç‚¹æ‰èƒ½èŽ·å¾—æœ€å¥½çš„æ•ˆæžœã€‚" #: scene/3d/arvr_nodes.cpp -msgid "ARVRCamera must have an ARVROrigin node as its parent" +#, fuzzy +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "ARVRCamera 必须处于 ARVROrigin 节点之下" #: scene/3d/arvr_nodes.cpp @@ -11519,9 +11298,10 @@ msgstr "" "在Areaã€StaticBodyã€RigidBody或KinematicBody节点下。" #: scene/3d/collision_shape.cpp +#, fuzzy msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" "CollisionShape节点必须拥有一个形状æ‰èƒ½è¿›è¡Œç¢°æ’žæ£€æµ‹å·¥ä½œï¼Œè¯·ä¸ºå®ƒåˆ›å»ºä¸€ä¸ªå½¢çŠ¶èµ„" "æºï¼" @@ -11555,6 +11335,10 @@ msgstr "" "GLES2视频驱动程åºä¸æ”¯æŒå…¨å±€å…‰ç…§æŽ¢æµ‹å™¨ã€‚\n" "请改用已烘焙ç¯å…‰è´´å›¾ã€‚" +#: 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 "æ¤èŠ‚ç‚¹éœ€è¦è®¾ç½®NavigationMeshèµ„æºæ‰èƒ½æ£å¸¸å·¥ä½œã€‚" @@ -11592,9 +11376,10 @@ msgid "PathFollow only works when set as a child of a Path node." msgstr "PathFollowç±»åž‹çš„èŠ‚ç‚¹åªæœ‰ä½œä¸ºPath类型节点的å节点æ‰èƒ½æ£å¸¸å·¥ä½œã€‚" #: scene/3d/path.cpp +#, fuzzy msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" "PathFollow ROTATION_ORIENTED需è¦åœ¨å…¶çˆ¶è·¯å¾„的曲线资æºä¸å¯ç”¨â€œUp Vectorâ€ã€‚" @@ -11609,7 +11394,10 @@ msgstr "" "建议您修改å节点的碰撞形状。" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +#, fuzzy +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "path属性必须指å‘ä¸€ä¸ªåˆæ³•çš„Spatial节点æ‰èƒ½æ£å¸¸å·¥ä½œã€‚" #: scene/3d/soft_body.cpp @@ -11627,8 +11415,9 @@ msgstr "" "建议修改å节点的碰撞体形状尺寸。" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" "SpriteFrame资æºå¿…须是通过AnimatedSprite3D节点的Frames属性创建的,å¦åˆ™æ— 法显示" @@ -11643,8 +11432,10 @@ msgstr "" "VehicleBodyçš„å节点。" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." -msgstr "WorldEnvironment需è¦ä¸€ä¸ªçŽ¯å¢ƒèµ„æºã€‚" +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." +msgstr "" #: scene/3d/world_environment.cpp msgid "" @@ -11680,7 +11471,8 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "没有任何物体连接到节点 '%s' 的输入 '%s' 。" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +#, fuzzy +msgid "No root AnimationNode for the graph is set." msgstr "å›¾è¡¨æ²¡æœ‰è®¾ç½®åŠ¨ç”»èŠ‚ç‚¹ä½œä¸ºæ ¹èŠ‚ç‚¹ã€‚" #: scene/animation/animation_tree.cpp @@ -11692,7 +11484,8 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "åŠ¨ç”»æ’æ”¾å™¨çš„è·¯å¾„æ²¡æœ‰åŠ è½½ä¸€ä¸ª AnimationPlayer 节点。" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +#, fuzzy +msgid "The AnimationPlayer root node is not a valid node." msgstr "AnimationPlayer çš„æ ¹èŠ‚ç‚¹ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„节点。" #: scene/animation/animation_tree_player.cpp @@ -11704,8 +11497,13 @@ msgid "Pick a color from the screen." msgstr "从å±å¹•ä¸é€‰æ‹©ä¸€ç§é¢œè‰²ã€‚" #: scene/gui/color_picker.cpp -msgid "Raw Mode" -msgstr "Raw 模å¼" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +#, fuzzy +msgid "Raw" +msgstr "å航" #: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." @@ -11718,14 +11516,21 @@ msgstr "将当å‰é¢œè‰²æ·»åŠ ä¸ºé¢„è®¾ã€‚" #: scene/gui/container.cpp #, fuzzy msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"If you don't intend to add a script, use a plain Control node instead." msgstr "" "除éžåœ¨è„šæœ¬å†…é…置其å项的放置行为,å¦åˆ™å®¹å™¨æœ¬èº«æ²¡æœ‰ç”¨å¤„。\n" "å¦‚æžœæ‚¨ä¸æ‰“ç®—æ·»åŠ è„šæœ¬ï¼Œè¯·ä½¿ç”¨ç®€å•的“控件â€èŠ‚ç‚¹ã€‚" +#: 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 "" +"由于该控件的 Mouse Filter 设置为 \"Ignore\" å› æ¤å®ƒçš„ Hint Tooltip å°†ä¸ä¼šå±•" +"示。将 Mouse Filter 设置为 \"Stop\" 或 \"Pass\" å¯ä¿®æ£æ¤é—®é¢˜ã€‚" + #: scene/gui/dialogs.cpp msgid "Alert!" msgstr "æç¤ºï¼" @@ -11735,22 +11540,25 @@ msgid "Please Confirm..." msgstr "请确认..." #: scene/gui/popup.cpp +#, fuzzy msgid "" "Popups will hide by default unless you call popup() or any of the popup*() " -"functions. Making them visible for editing is fine though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" "Popupå¯¹è±¡é»˜è®¤ä¿æŒéšè—,除éžä½ 调用popup()或其他popup相关方法。编辑时å¯ä»¥è®©å®ƒä»¬" "ä¿æŒå¯è§ï¼Œä½†å®ƒåœ¨è¿è¡Œæ—¶ä»¬ä¼šè‡ªåЍéšè—。" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +#, fuzzy +msgid "If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0." msgstr "如果exp_edit为true, 则min_value必须为>0。" #: scene/gui/scroll_container.cpp +#, fuzzy 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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" "ScrollContainer旨在与å•ä¸ªåæŽ§ä»¶é…åˆä½¿ç”¨ã€‚\n" @@ -11798,6 +11606,11 @@ msgid "Input" msgstr "输入" #: scene/resources/visual_shader_nodes.cpp +#, fuzzy +msgid "Invalid source for preview." +msgstr "éžæ³•çš„ç€è‰²å™¨æºã€‚" + +#: scene/resources/visual_shader_nodes.cpp msgid "Invalid source for shader." msgstr "éžæ³•çš„ç€è‰²å™¨æºã€‚" @@ -11815,7 +11628,55 @@ msgstr "å˜é‡åªèƒ½åœ¨é¡¶ç‚¹å‡½æ•°ä¸æŒ‡å®šã€‚" #: servers/visual/shader_language.cpp msgid "Constants cannot be modified." -msgstr "" +msgstr "ä¸å…许修改常é‡ã€‚" + +#~ msgid "Generating solution..." +#~ msgstr "æ£åœ¨åˆ›ç”Ÿæˆå†³æ–¹æ¡ˆ..." + +#~ msgid "Generating C# project..." +#~ msgstr "æ£åœ¨ç”ŸæˆC#项目..." + +#~ msgid "Failed to create solution." +#~ msgstr "创建解决方案失败。" + +#~ msgid "Failed to save solution." +#~ msgstr "ä¿å˜è§£å†³æ–¹æ¡ˆå¤±è´¥ã€‚" + +#~ msgid "Done" +#~ msgstr "完æˆ" + +#~ msgid "Failed to create C# project." +#~ msgstr "创建C#项目失败。" + +#~ msgid "Mono" +#~ msgstr "Mono" + +#~ msgid "About C# support" +#~ msgstr "关于C#支æŒ" + +#~ msgid "Create C# solution" +#~ msgstr "创建C#解决方案" + +#~ msgid "Builds" +#~ msgstr "构建" + +#~ msgid "Build Project" +#~ msgstr "构建项目" + +#~ msgid "View log" +#~ msgstr "查看日志" + +#~ msgid "WorldEnvironment needs an Environment resource." +#~ msgstr "WorldEnvironment需è¦ä¸€ä¸ªçŽ¯å¢ƒèµ„æºã€‚" + +#~ msgid "Enabled Classes" +#~ msgstr "å¯ç”¨çš„ç±»" + +#~ msgid "Update Always" +#~ msgstr "æŒç»æ›´æ–°UI" + +#~ msgid "Raw Mode" +#~ msgstr "Raw 模å¼" #~ msgid "Path to Node:" #~ msgstr "节点路径:" @@ -12374,9 +12235,6 @@ msgstr "" #~ msgid "Toggle Spatial Visible" #~ msgstr "切æ¢Spatialå¯è§" -#~ msgid "Toggle CanvasItem Visible" -#~ msgstr "切æ¢CanvasItemå¯è§" - #~ msgid "Condition" #~ msgstr "æ¡ä»¶" @@ -13308,9 +13166,6 @@ msgstr "" #~ msgid "Images:" #~ msgstr "图片:" -#~ msgid "Select None" -#~ msgstr "å–æ¶ˆé€‰æ‹©" - #~ msgid "Group" #~ msgstr "分组" diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po index eea5cd2804..4488955481 100644 --- a/editor/translations/zh_HK.po +++ b/editor/translations/zh_HK.po @@ -468,6 +468,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "å…¨é¸" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "ä¸é¸" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "" @@ -660,6 +670,10 @@ msgstr "跳到行" msgid "Line Number:" msgstr "行數:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "沒有相åŒ" @@ -711,7 +725,7 @@ msgstr "縮å°" msgid "Reset Zoom" msgstr "é‡è¨ç¸®æ”¾æ¯”例" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "" @@ -818,6 +832,11 @@ msgid "Connect" msgstr "連到" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "訊號:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "ç”± '%s' 連到 '%s'" @@ -987,7 +1006,7 @@ msgstr "" #: editor/dependency_editor.cpp #, fuzzy -msgid "Remove selected files from the project? (no undo)" +msgid "Remove selected files from the project? (Can't be restored)" msgstr "從專案ä¸åˆªé™¤æ‰€é¸çš„æª”案?(æ¤å‹•作無法復原)" #: editor/dependency_editor.cpp @@ -1381,7 +1400,7 @@ msgstr "有效å稱。" #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "有效å稱。" #: editor/editor_autoload_settings.cpp @@ -1565,6 +1584,10 @@ msgstr "" 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 #, fuzzy msgid "3D Editor" @@ -1597,7 +1620,7 @@ msgstr "移動模å¼" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "檔案系統" #: editor/editor_feature_profile.cpp @@ -1657,7 +1680,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1672,7 +1695,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "新增資料夾" #: editor/editor_feature_profile.cpp @@ -1695,12 +1718,9 @@ msgid "Export" msgstr "匯出" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp -msgid "Enabled Classes" -msgstr "" +#, fuzzy +msgid "Available Profiles:" +msgstr "篩é¸:" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2793,11 +2813,35 @@ msgid "Editor Layout" msgstr "編輯器佈局" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "儲å˜å ´æ™¯" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "編輯器è¨å®š" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "è¦é›¢é–‹ç·¨è¼¯å™¨å—Ž?" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "全螢幕" #: editor/editor_node.cpp #, fuzzy +msgid "Toggle System Console" +msgstr "(ä¸ï¼‰é¡¯ç¤ºéš±è—的文件" + +#: editor/editor_node.cpp +#, fuzzy msgid "Open Editor Data/Settings Folder" msgstr "編輯器è¨å®š" @@ -2909,15 +2953,17 @@ msgid "Spins when the editor window redraws." msgstr "" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "ä¸åœæ›´æ–°" +#, fuzzy +msgid "Update Continuously" +msgstr "連續" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "當改變時更新" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +msgid "Hide Update Spinner" msgstr "" #: editor/editor_node.cpp @@ -3118,7 +3164,7 @@ msgstr "時間:" msgid "Calls" msgstr "" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "" @@ -3220,20 +3266,20 @@ msgid "Page: " msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Key:" +#: editor/plugins/theme_editor_plugin.cpp +msgid "Remove Item" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "New Value:" +msgid "New Key:" msgstr "" #: editor/editor_properties_array_dict.cpp -msgid "Add Key/Value Pair" +msgid "New Value:" msgstr "" #: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" +msgid "Add Key/Value Pair" msgstr "" #: editor/editor_run_native.cpp @@ -3773,6 +3819,7 @@ msgid "Nodes not in Group" msgstr "" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp #, fuzzy msgid "Filter nodes" msgstr "篩é¸:" @@ -5452,6 +5499,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "å„²å˜æª”案" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6391,11 +6446,21 @@ msgid "Find Next" msgstr "" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 #, fuzzy +msgid "Filter methods" +msgstr "篩é¸:" + +#: editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Sort" msgstr "排åºï¼š" @@ -6640,20 +6705,24 @@ msgid "Syntax Highlighter" msgstr "" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +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 #, fuzzy msgid "Delete Line" @@ -8287,51 +8356,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8339,203 +8364,27 @@ msgid "Input parameter." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10231,6 +10080,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "關閉" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10262,8 +10116,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "新增" #: editor/scene_tree_dock.cpp msgid "" @@ -10522,7 +10377,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "錯誤" @@ -10938,60 +10793,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "資æºåŠ è¼‰å¤±æ•—ã€‚" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to save solution." -msgstr "資æºåŠ è¼‰å¤±æ•—ã€‚" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create C# project." -msgstr "資æºåŠ è¼‰å¤±æ•—ã€‚" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Create C# solution" -msgstr "縮放selection" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "專案" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "檔案" - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11599,7 +11400,7 @@ msgstr "" #: scene/2d/animated_sprite.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "" @@ -11648,7 +11449,7 @@ msgstr "" #: scene/2d/light_2d.cpp msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "" @@ -11658,7 +11459,7 @@ msgid "" msgstr "" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "" #: scene/2d/navigation_polygon.cpp @@ -11725,14 +11526,21 @@ 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 "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11811,7 +11619,7 @@ msgstr "" #: scene/3d/collision_shape.cpp msgid "" "A shape must be provided for CollisionShape to function. Please create a " -"shape resource for it!" +"shape resource for it." msgstr "" #: scene/3d/collision_shape.cpp @@ -11840,6 +11648,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11874,8 +11686,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11886,7 +11698,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11902,7 +11716,7 @@ msgstr "" #: scene/3d/sprite_3d.cpp msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." msgstr "" @@ -11913,7 +11727,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11951,7 +11767,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "ç”± '%s' 連到 '%s'" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11964,7 +11780,7 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." +msgid "The AnimationPlayer root node is not a valid node." msgstr "" #: scene/animation/animation_tree_player.cpp @@ -11976,7 +11792,11 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" +msgstr "" + +#: scene/gui/color_picker.cpp +msgid "Raw" msgstr "" #: scene/gui/color_picker.cpp @@ -11989,10 +11809,15 @@ msgstr "" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -12006,18 +11831,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -12061,6 +11886,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "無效å—åž‹" + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "無效å—åž‹" @@ -12080,6 +11910,33 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "資æºåŠ è¼‰å¤±æ•—ã€‚" + +#, fuzzy +#~ msgid "Failed to save solution." +#~ msgstr "資æºåŠ è¼‰å¤±æ•—ã€‚" + +#, fuzzy +#~ msgid "Failed to create C# project." +#~ msgstr "資æºåŠ è¼‰å¤±æ•—ã€‚" + +#, fuzzy +#~ msgid "Create C# solution" +#~ msgstr "縮放selection" + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "專案" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "檔案" + +#~ msgid "Update Always" +#~ msgstr "ä¸åœæ›´æ–°" + #~ msgid "Delete selected files?" #~ msgstr "è¦åˆªé™¤é¸ä¸æª”案?" diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po index 730ca41148..27afde910f 100644 --- a/editor/translations/zh_TW.po +++ b/editor/translations/zh_TW.po @@ -58,7 +58,7 @@ msgstr "無效的內å˜åœ°å€é¡žåž‹ %sï¼ŒåŸºç¤Žåž‹å¼ %s" #: core/math/expression.cpp msgid "Invalid named index '%s' for base type %s" -msgstr "基本類型 %s 的命å索引 '% s' 無效" +msgstr "基本類型 %s 的命å索引 '%s' 無效" #: core/math/expression.cpp msgid "Invalid arguments to construct '%s'" @@ -462,6 +462,16 @@ msgstr "" msgid "Warning: Editing imported animation" msgstr "" +#: editor/animation_track_editor.cpp editor/plugins/script_text_editor.cpp +#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp +msgid "Select All" +msgstr "鏿“‡å…¨éƒ¨" + +#: editor/animation_track_editor.cpp +#, fuzzy +msgid "Select None" +msgstr "鏿“‡æ¨¡å¼" + #: editor/animation_track_editor.cpp msgid "Only show tracks from nodes selected in tree." msgstr "åƒ…é¡¯ç¤ºæ¨¹ä¸æ‰€é¸ç¯€é»žçš„軌跡。" @@ -645,6 +655,10 @@ msgstr "å‰å¾€ç¬¬...行" msgid "Line Number:" msgstr "行號:" +#: editor/code_editor.cpp +msgid "Found %d match(es)." +msgstr "" + #: editor/code_editor.cpp editor/editor_help.cpp msgid "No Matches" msgstr "ç„¡ç¬¦åˆæ¢ä»¶" @@ -694,7 +708,7 @@ msgstr "縮å°" msgid "Reset Zoom" msgstr "é‡è¨ç¸®æ”¾å¤§å°" -#: editor/code_editor.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/code_editor.cpp msgid "Warnings" msgstr "è¦å‘Š" @@ -806,6 +820,11 @@ msgid "Connect" msgstr "連接" #: editor/connections_dialog.cpp +#, fuzzy +msgid "Signal:" +msgstr "訊號:" + +#: editor/connections_dialog.cpp msgid "Connect '%s' to '%s'" msgstr "連接 '%s' 到 '%s'" @@ -975,7 +994,8 @@ msgid "Owners Of:" msgstr "æ“æœ‰è€…:" #: editor/dependency_editor.cpp -msgid "Remove selected files from the project? (no undo)" +#, fuzzy +msgid "Remove selected files from the project? (Can't be restored)" msgstr "æ¤å‹•作無法復原, 確定è¦å¾žå°ˆæ¡ˆä¸åˆªé™¤æ‰€é¸çš„æª”案?" #: editor/dependency_editor.cpp @@ -1362,7 +1382,7 @@ msgstr "䏿£ç¢ºçš„åå—。åå—ä¸èƒ½èˆ‡ç¾æœ‰çš„ engine class åè¡çªã€‚" #: editor/editor_autoload_settings.cpp #, fuzzy -msgid "Must not collide with an existing buit-in type name." +msgid "Must not collide with an existing built-in type name." msgstr "無效å稱.ä¸èƒ½èˆ‡ç¾æœ‰çš„內置類型å稱沖çª." #: editor/editor_autoload_settings.cpp @@ -1542,6 +1562,10 @@ msgstr "找ä¸åˆ°è‡ªå®šç¾©ç™¼ä½ˆç¯„本。" 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 #, fuzzy msgid "3D Editor" @@ -1574,7 +1598,7 @@ msgstr "節點å稱:" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Filesystem Dock" +msgid "FileSystem and Import Docks" msgstr "文件系統" #: editor/editor_feature_profile.cpp @@ -1636,7 +1660,7 @@ msgstr "" #: editor/editor_feature_profile.cpp msgid "" -"Profile '%s' already exists. Remote it first before importing, import " +"Profile '%s' already exists. Remove it first before importing, import " "aborted." msgstr "" @@ -1651,7 +1675,7 @@ msgstr "" #: editor/editor_feature_profile.cpp #, fuzzy -msgid "Current Profile" +msgid "Current Profile:" msgstr "ç•¶å‰ç‰ˆæœ¬:" #: editor/editor_feature_profile.cpp @@ -1675,13 +1699,9 @@ msgid "Export" msgstr "輸出" #: editor/editor_feature_profile.cpp -msgid "Available Profiles" -msgstr "" - -#: editor/editor_feature_profile.cpp #, fuzzy -msgid "Enabled Classes" -msgstr "æœå°‹ Class" +msgid "Available Profiles:" +msgstr "效能:" #: editor/editor_feature_profile.cpp #, fuzzy @@ -2756,10 +2776,34 @@ msgid "Editor Layout" msgstr "編輯器佈局" #: editor/editor_node.cpp +#, fuzzy +msgid "Take Screenshot" +msgstr "儲å˜å ´æ™¯" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Screenshots are stored in the Editor Data/Settings Folder." +msgstr "開啟 編輯器數據/è¨å®š 資料夾" + +#: editor/editor_node.cpp +msgid "Automatically Open Screenshots" +msgstr "" + +#: editor/editor_node.cpp +#, fuzzy +msgid "Open in an external image editor." +msgstr "開啟下一個編輯器" + +#: editor/editor_node.cpp msgid "Toggle Fullscreen" msgstr "全螢幕顯示" #: editor/editor_node.cpp +#, fuzzy +msgid "Toggle System Console" +msgstr "åˆ‡æ›æ¨¡å¼" + +#: editor/editor_node.cpp msgid "Open Editor Data/Settings Folder" msgstr "開啟 編輯器數據/è¨å®š 資料夾" @@ -2869,15 +2913,18 @@ msgid "Spins when the editor window redraws." msgstr "åœ¨é‡æ–°ç¹ªè£½(repaint)編輯器視窗時,來個旋轉ï¼" #: editor/editor_node.cpp -msgid "Update Always" -msgstr "總是自動更新" +#, fuzzy +msgid "Update Continuously" +msgstr "連續" #: editor/editor_node.cpp -msgid "Update Changes" +#, fuzzy +msgid "Update When Changed" msgstr "有更動時自動更新" #: editor/editor_node.cpp -msgid "Disable Update Spinner" +#, fuzzy +msgid "Hide Update Spinner" msgstr "ç¦æ¢è‡ªå‹•æ›´æ–°" #: editor/editor_node.cpp @@ -3069,7 +3116,7 @@ msgstr "時間" msgid "Calls" msgstr "調用" -#: editor/editor_properties.cpp +#: editor/editor_properties.cpp editor/script_create_dialog.cpp msgid "On" msgstr "啟用" @@ -3170,6 +3217,11 @@ 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 "新建帧:" @@ -3182,11 +3234,6 @@ msgstr "數值" msgid "Add Key/Value Pair" msgstr "" -#: editor/editor_properties_array_dict.cpp -#: editor/plugins/theme_editor_plugin.cpp -msgid "Remove Item" -msgstr "ç§»é™¤é …ç›®" - #: editor/editor_run_native.cpp msgid "" "No runnable export preset found for this platform.\n" @@ -3336,7 +3383,7 @@ msgstr "下載完æˆã€‚" msgid "" "Templates installation failed. The problematic templates archives can be " "found at '%s'." -msgstr "範本安è£å¤±æ•—。有å•é¡Œçš„ç¯„æœ¬å˜æª”å¯ä»¥åœ¨ \"% s\" 䏿‰¾åˆ°ã€‚" +msgstr "範本安è£å¤±æ•—。有å•é¡Œçš„ç¯„æœ¬å˜æª”å¯ä»¥åœ¨ \"%s\" 䏿‰¾åˆ°ã€‚" #: editor/export_template_manager.cpp #, fuzzy @@ -3712,6 +3759,7 @@ msgid "Nodes not in Group" msgstr "ä¸åœ¨çµ„ä¸çš„節點" #: editor/groups_editor.cpp editor/scene_tree_dock.cpp +#: editor/scene_tree_editor.cpp #, fuzzy msgid "Filter nodes" msgstr "éŽæ¿¾æª”案..." @@ -5373,6 +5421,14 @@ 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 +#, fuzzy +msgid "Restart" +msgstr "釿–°é–‹å§‹(ç§’):" + +#: editor/plugins/cpu_particles_2d_editor_plugin.cpp #: editor/plugins/particles_2d_editor_plugin.cpp msgid "Clear Emission Mask" msgstr "" @@ -6312,11 +6368,21 @@ msgid "Find Next" msgstr "查找下一個" #: editor/plugins/script_editor_plugin.cpp +#, fuzzy +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 #, fuzzy +msgid "Filter methods" +msgstr "éŽæ¿¾æª”案..." + +#: editor/plugins/script_editor_plugin.cpp +#, fuzzy msgid "Sort" msgstr "排åº:" @@ -6558,20 +6624,24 @@ msgid "Syntax Highlighter" msgstr "高亮顯示語法" #: editor/plugins/script_text_editor.cpp +msgid "Go To" +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 +#, fuzzy +msgid "Breakpoints" +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 #, fuzzy msgid "Delete Line" @@ -8196,51 +8266,7 @@ msgid "Boolean uniform." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_camera' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'inv_projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'viewport_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'texture_pixel_size' input parameter for all shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for all shader modes." +msgid "'%s' input parameter for all shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -8249,203 +8275,27 @@ msgid "Input parameter." msgstr "å¸é™„到父級節點" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'binormal' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex and fragment shader modes." +msgid "'%s' input parameter for vertex and fragment shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'fragcoord' input parameter for fragment and light shader modes." +msgid "'%s' input parameter for fragment and light shader modes." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment shader mode." +msgid "'%s' input parameter for fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment shader mode." +msgid "'%s' input parameter for light shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'side' input parameter for fragment shader mode." +msgid "'%s' input parameter for vertex shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'uv2' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'view' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'albedo' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'attenuation' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'diffuse' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'roughness' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'specular' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transmission' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'modelview' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_size' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'tangent' input parameter for vertex and fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_pass' input parameter for vertex and fragment shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'point_coord' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_pixel_size' input parameter for fragment shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'screen_uv' input parameter for fragment and light shader modes." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_alpha' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_height' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_uv' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'light_vec' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'normal' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'shadow_color' input parameter for light shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'extra' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'projection' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'vertex' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'world' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'active' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'color' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'custom_alpha' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'delta' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'emission_transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'index' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'lifetime' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'restart' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'time' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'transform' input parameter for vertex shader mode." -msgstr "" - -#: editor/plugins/visual_shader_editor_plugin.cpp -msgid "'velocity' input parameter for vertex shader mode." +msgid "'%s' input parameter for vertex and fragment shader mode." msgstr "" #: editor/plugins/visual_shader_editor_plugin.cpp @@ -10135,6 +9985,11 @@ msgid "Add Child Node" msgstr "" #: editor/scene_tree_dock.cpp +#, fuzzy +msgid "Expand/Collapse All" +msgstr "å–代全部" + +#: editor/scene_tree_dock.cpp msgid "Change Type" msgstr "" @@ -10165,8 +10020,9 @@ msgid "Delete (No Confirm)" msgstr "" #: editor/scene_tree_dock.cpp -msgid "Add/Create a New Node" -msgstr "" +#, fuzzy +msgid "Add/Create a New Node." +msgstr "新增 %s" #: editor/scene_tree_dock.cpp msgid "" @@ -10423,7 +10279,7 @@ msgstr "" msgid "Pick one or more items from the list to display the graph." msgstr "" -#: editor/script_editor_debugger.cpp modules/mono/editor/mono_bottom_panel.cpp +#: editor/script_editor_debugger.cpp msgid "Errors" msgstr "" @@ -10857,57 +10713,6 @@ msgstr "" msgid "Class name can't be a reserved keyword" msgstr "" -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating solution..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Generating C# project..." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -#, fuzzy -msgid "Failed to create solution." -msgstr "無法新增資料夾" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to save solution." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Done" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Failed to create C# project." -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Mono" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "About C# support" -msgstr "" - -#: modules/mono/editor/godotsharp_editor.cpp -msgid "Create C# solution" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -msgid "Builds" -msgstr "" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "Build Project" -msgstr "專案è¨å®š" - -#: modules/mono/editor/mono_bottom_panel.cpp -#, fuzzy -msgid "View log" -msgstr "éŽæ¿¾æª”案..." - #: modules/mono/mono_gd/gd_mono_utils.cpp msgid "End of inner exception stack trace" msgstr "" @@ -11503,8 +11308,9 @@ 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 " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite to display frames." msgstr "SpriteFrames資æºå¿…é ˆåœ¨Frames屬性ä¸è¢«å‰µå»ºæˆ–è¨ç½®æ‰èƒ½å¤ é¡¯ç¤ºå‹•ç•«æ ¼ã€‚" @@ -11558,8 +11364,9 @@ msgid "" msgstr "" #: scene/2d/light_2d.cpp +#, fuzzy msgid "" -"A texture with the shape of the light must be supplied to the 'texture' " +"A texture with the shape of the light must be supplied to the \"Texture\" " "property." msgstr "光照形狀的æè³ªå¿…é ˆè¢«è³¦èˆ‡åœ¨æè³ªçš„屬性ä¸ã€‚" @@ -11569,7 +11376,8 @@ msgid "" msgstr "æ¤é®å…‰é«”å¿…é ˆè¢«å»ºç«‹æˆ–è¨ç½®é®è”½å½¢ç‹€æ‰èƒ½ç™¼æ®é®è”½ä½œç”¨ã€‚" #: scene/2d/light_occluder_2d.cpp -msgid "The occluder polygon for this occluder is empty. Please draw a polygon!" +#, fuzzy +msgid "The occluder polygon for this occluder is empty. Please draw a polygon." msgstr "æ¤é®å…‰é«”沒有被賦予形狀,請繪製一個å§ï¼" #: scene/2d/navigation_polygon.cpp @@ -11636,14 +11444,24 @@ msgid "" "This bone lacks a proper REST pose. Go to the Skeleton2D node and set one." 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這類的節點下。" + #: scene/2d/visibility_notifier_2d.cpp msgid "" -"VisibilityEnable2D works best when used with the edited scene root directly " +"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" +msgid "ARVRCamera must have an ARVROrigin node as its parent." msgstr "" #: scene/3d/arvr_nodes.cpp @@ -11720,10 +11538,11 @@ 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 "" +"shape resource for it." +msgstr "CollisionShape2Då¿…é ˆè¢«è³¦äºˆå½¢ç‹€æ‰èƒ½é‹ä½œï¼Œè«‹ç‚ºå®ƒå»ºç«‹å€‹å½¢ç‹€å§ï¼" #: scene/3d/collision_shape.cpp msgid "" @@ -11751,6 +11570,10 @@ msgid "" "Use a BakedLightmap instead." 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 "" @@ -11785,8 +11608,8 @@ msgstr "" #: scene/3d/path.cpp msgid "" -"PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent " -"Path's Curve resource." +"PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its " +"parent Path's Curve resource." msgstr "" #: scene/3d/physics_body.cpp @@ -11797,7 +11620,9 @@ msgid "" msgstr "" #: scene/3d/remote_transform.cpp -msgid "Path property must point to a valid Spatial node to work." +msgid "" +"The \"Remote Path\" property must point to a valid Spatial or Spatial-" +"derived node to work." msgstr "" #: scene/3d/soft_body.cpp @@ -11812,10 +11637,11 @@ msgid "" msgstr "" #: scene/3d/sprite_3d.cpp +#, fuzzy msgid "" -"A SpriteFrames resource must be created or set in the 'Frames' property in " +"A SpriteFrames resource must be created or set in the \"Frames\" property in " "order for AnimatedSprite3D to display frames." -msgstr "" +msgstr "SpriteFrames資æºå¿…é ˆåœ¨Frames屬性ä¸è¢«å‰µå»ºæˆ–è¨ç½®æ‰èƒ½å¤ é¡¯ç¤ºå‹•ç•«æ ¼ã€‚" #: scene/3d/vehicle_body.cpp msgid "" @@ -11824,7 +11650,9 @@ msgid "" msgstr "" #: scene/3d/world_environment.cpp -msgid "WorldEnvironment needs an Environment resource." +msgid "" +"WorldEnvironment requires its \"Environment\" property to contain an " +"Environment to have a visible effect." msgstr "" #: scene/3d/world_environment.cpp @@ -11862,7 +11690,7 @@ msgid "Nothing connected to input '%s' of node '%s'." msgstr "å°‡ '%s' 從 '%s' 䏿–·é€£æŽ¥" #: scene/animation/animation_tree.cpp -msgid "A root AnimationNode for the graph is not set." +msgid "No root AnimationNode for the graph is set." msgstr "" #: scene/animation/animation_tree.cpp @@ -11875,8 +11703,9 @@ msgid "Path set for AnimationPlayer does not lead to an AnimationPlayer node." msgstr "" #: scene/animation/animation_tree.cpp -msgid "AnimationPlayer root is not a valid node." -msgstr "" +#, fuzzy +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." @@ -11887,10 +11716,15 @@ msgid "Pick a color from the screen." msgstr "" #: scene/gui/color_picker.cpp -msgid "Raw Mode" +msgid "HSV" msgstr "" #: scene/gui/color_picker.cpp +#, fuzzy +msgid "Raw" +msgstr "å航" + +#: scene/gui/color_picker.cpp msgid "Switch between hexadecimal and code values." msgstr "" @@ -11901,10 +11735,15 @@ msgstr "將目å‰é¡è‰²è¨ç‚ºé è¨" #: scene/gui/container.cpp msgid "" -"Container by itself serves no purpose unless a script configures it's " +"Container by itself serves no purpose unless a script configures its " "children placement behavior.\n" -"If you don't intend to add a script, then please use a plain 'Control' node " -"instead." +"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 @@ -11918,18 +11757,18 @@ 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 though, but they will " -"hide upon running." +"functions. Making them visible for editing is fine, but they will hide upon " +"running." msgstr "" #: scene/gui/range.cpp -msgid "If exp_edit is true min_value must be > 0." +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 " +"Use a container as child (VBox, HBox, etc.), or a Control and set the custom " "minimum size manually." msgstr "" @@ -11975,6 +11814,11 @@ msgstr "" #: scene/resources/visual_shader_nodes.cpp #, fuzzy +msgid "Invalid source for preview." +msgstr "無效的å—體大å°ã€‚" + +#: scene/resources/visual_shader_nodes.cpp +#, fuzzy msgid "Invalid source for shader." msgstr "無效的å—體大å°ã€‚" @@ -11994,6 +11838,25 @@ msgstr "" msgid "Constants cannot be modified." msgstr "" +#, fuzzy +#~ msgid "Failed to create solution." +#~ msgstr "無法新增資料夾" + +#, fuzzy +#~ msgid "Build Project" +#~ msgstr "專案è¨å®š" + +#, fuzzy +#~ msgid "View log" +#~ msgstr "éŽæ¿¾æª”案..." + +#, fuzzy +#~ msgid "Enabled Classes" +#~ msgstr "æœå°‹ Class" + +#~ msgid "Update Always" +#~ msgstr "總是自動更新" + #~ msgid "Path to Node:" #~ msgstr "節點路徑:" diff --git a/main/input_default.cpp b/main/input_default.cpp index 199fcfcf66..a03d015fc3 100644 --- a/main/input_default.cpp +++ b/main/input_default.cpp @@ -873,7 +873,7 @@ void InputDefault::joy_axis(int p_device, int p_axis, const JoyAxis &p_value) { return; } float deadzone = p_value.min == 0 ? 0.5f : 0.0f; - bool pressed = p_value.value > deadzone ? true : false; + bool pressed = p_value.value > deadzone; if (pressed == joy_buttons_pressed.has(_combine_device(map.index, p_device))) { // button already pressed or released, this is an axis bounce value return; diff --git a/main/main.cpp b/main/main.cpp index d3e816eb48..7e69864e1e 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1374,7 +1374,7 @@ bool Main::start() { { DirAccessRef da = DirAccess::open(doc_tool); if (!da) { - ERR_EXPLAIN("Argument supplied to --doctool must be a base godot build directory"); + ERR_EXPLAIN("Argument supplied to --doctool must be a base Godot build directory"); ERR_FAIL_V(false); } } @@ -1392,12 +1392,23 @@ bool Main::start() { doc_data_classes[name] = path; if (!checked_paths.has(path)) { checked_paths.insert(path); + + // Create the module documentation directory if it doesn't exist + DirAccess *da = DirAccess::create_for_path(path); + da->make_dir_recursive(path); + memdelete(da); + docsrc.load_classes(path); print_line("Loading docs from: " + path); } } String index_path = doc_tool.plus_file("doc/classes"); + // Create the main documentation directory if it doesn't exist + DirAccess *da = DirAccess::create_for_path(index_path); + da->make_dir_recursive(index_path); + memdelete(da); + docsrc.load_classes(index_path); checked_paths.insert(index_path); print_line("Loading docs from: " + index_path); diff --git a/main/main_builders.py b/main/main_builders.py index 038a7d17f5..c48aaaa572 100644 --- a/main/main_builders.py +++ b/main/main_builders.py @@ -19,7 +19,7 @@ def make_splash(target, source, env): g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") g.write("#ifndef BOOT_SPLASH_H\n") g.write("#define BOOT_SPLASH_H\n") - g.write('static const Color boot_splash_bg_color = Color::html("#232323");\n') + g.write('static const Color boot_splash_bg_color = Color(0.14, 0.14, 0.14);\n') g.write("static const unsigned char boot_splash_png[] = {\n") for i in range(len(buf)): g.write(byte_to_str(buf[i]) + ",\n") @@ -38,7 +38,7 @@ def make_splash_editor(target, source, env): g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") g.write("#ifndef BOOT_SPLASH_EDITOR_H\n") g.write("#define BOOT_SPLASH_EDITOR_H\n") - g.write('static const Color boot_splash_editor_bg_color = Color::html("#232323");\n') + g.write('static const Color boot_splash_editor_bg_color = Color(0.14, 0.14, 0.14);\n') g.write("static const unsigned char boot_splash_editor_png[] = {\n") for i in range(len(buf)): g.write(byte_to_str(buf[i]) + ",\n") diff --git a/main/tests/test_shader_lang.cpp b/main/tests/test_shader_lang.cpp index dcb19b7df7..d66e706b6f 100644 --- a/main/tests/test_shader_lang.cpp +++ b/main/tests/test_shader_lang.cpp @@ -197,6 +197,13 @@ static String dump_node_code(SL::Node *p_node, int p_level) { case SL::Node::TYPE_VARIABLE_DECLARATION: { // FIXME: Implement } break; + case SL::Node::TYPE_ARRAY: { + SL::ArrayNode *vnode = (SL::ArrayNode *)p_node; + code = vnode->name; + } break; + case SL::Node::TYPE_ARRAY_DECLARATION: { + // FIXME: Implement + } break; case SL::Node::TYPE_CONSTANT: { SL::ConstantNode *cnode = (SL::ConstantNode *)p_node; return get_constant_text(cnode->datatype, cnode->values); diff --git a/methods.py b/methods.py index 3ed44329a7..bb4adfb70b 100644 --- a/methods.py +++ b/methods.py @@ -26,7 +26,7 @@ def disable_warnings(self): warn_flags = ['/Wall', '/W4', '/W3', '/W2', '/W1', '/WX'] self.Append(CCFLAGS=['/w']) self.Append(CFLAGS=['/w']) - self.Append(CPPFLAGS=['/w']) + self.Append(CXXFLAGS=['/w']) self['CCFLAGS'] = [x for x in self['CCFLAGS'] if not x in warn_flags] self['CFLAGS'] = [x for x in self['CFLAGS'] if not x in warn_flags] self['CXXFLAGS'] = [x for x in self['CXXFLAGS'] if not x in warn_flags] diff --git a/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist b/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist index b7cd94e3d5..e7c4f8f340 100644 --- a/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist +++ b/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist @@ -36,6 +36,8 @@ <string>$camera_usage_description</string> <key>NSPhotoLibraryUsageDescription</key> <string>$photolibrary_usage_description</string> + <key>NSMicrophoneUsageDescription</key> + <string>$microphone_usage_description</string> <key>UIRequiresFullScreen</key> <true/> <key>UIStatusBarHidden</key> diff --git a/modules/SCsub b/modules/SCsub index 67f5893db4..36c2472c42 100644 --- a/modules/SCsub +++ b/modules/SCsub @@ -13,7 +13,7 @@ env.modules_sources = [ for x in env.module_list: if (x in env.disabled_modules): continue - env_modules.Append(CPPFLAGS=["-DMODULE_" + x.upper() + "_ENABLED"]) + env_modules.Append(CPPDEFINES=["MODULE_" + x.upper() + "_ENABLED"]) SConscript(x + "/SCsub") if env.split_modules: diff --git a/modules/assimp/SCsub b/modules/assimp/SCsub index 0da7e432e2..8a77e4f803 100644 --- a/modules/assimp/SCsub +++ b/modules/assimp/SCsub @@ -17,60 +17,60 @@ env_assimp.Prepend(CPPPATH=['#thirdparty/zlib/']) env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/openddlparser/include']) env_assimp.Prepend(CPPPATH=['#thirdparty/assimp/contrib/rapidjson/include']) env_assimp.Prepend(CPPPATH=['.']) -#env_assimp.Append(CPPFLAGS=['-DASSIMP_DOUBLE_PRECISION']) # TODO default to what godot is compiled with for future double support -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_BOOST_WORKAROUND']) -env_assimp.Append(CPPFLAGS=['-DOPENDDLPARSER_BUILD']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_OWN_ZLIB']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_EXPORT']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_X_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_AMF_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_3DS_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_MD3_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_MD5_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_MDL_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_MD2_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_PLY_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_ASE_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_OBJ_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_HMP_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_SMD_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_MDC_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_MD5_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_STL_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_LWO_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_DXF_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_NFF_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_RAW_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_SIB_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_OFF_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_AC_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_BVH_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_IRRMESH_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_IRR_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_Q3D_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_B3D_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_COLLADA_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_TERRAGEN_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_CSM_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_3D_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_LWS_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_OGRE_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_OPENGEX_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_MS3D_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_COB_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_BLEND_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_Q3BSP_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_NDO_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_STEP_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_IFC_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_XGL_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_ASSBIN_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_GLTF_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_C4D_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_3MF_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_NO_X3D_IMPORTER']) +#env_assimp.Append(CPPDEFINES=['ASSIMP_DOUBLE_PRECISION']) # TODO default to what godot is compiled with for future double support +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_BOOST_WORKAROUND']) +env_assimp.Append(CPPDEFINES=['OPENDDLPARSER_BUILD']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_OWN_ZLIB']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_EXPORT']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_X_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_AMF_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_3DS_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MD3_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MD5_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MDL_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MD2_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_PLY_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_ASE_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_OBJ_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_HMP_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_SMD_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MDC_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MD5_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_STL_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_LWO_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_DXF_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_NFF_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_RAW_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_SIB_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_OFF_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_AC_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_BVH_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_IRRMESH_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_IRR_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_Q3D_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_B3D_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_COLLADA_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_TERRAGEN_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_CSM_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_3D_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_LWS_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_OGRE_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_OPENGEX_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_MS3D_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_COB_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_BLEND_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_Q3BSP_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_NDO_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_STEP_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_IFC_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_XGL_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_ASSBIN_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_GLTF_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_C4D_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_3MF_IMPORTER']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_NO_X3D_IMPORTER']) -env_assimp.Append(CPPFLAGS=['-DASSIMP_BUILD_SINGLETHREADED']) +env_assimp.Append(CPPDEFINES=['ASSIMP_BUILD_SINGLETHREADED']) if (not env.msvc): env_assimp.Append(CXXFLAGS=['-std=c++11']) @@ -78,14 +78,14 @@ elif (env.msvc == False and env['platform'] == 'windows'): env_assimp.Append(LDFLAGS=['-pthread']) if(env['platform'] == 'windows'): - env_assimp.Append(CPPFLAGS=['-DPLATFORM_WINDOWS']) - env_assimp.Append(CPPFLAGS=['-DPLATFORM=WINDOWS']) + env_assimp.Append(CPPDEFINES=['PLATFORM_WINDOWS']) + env_assimp.Append(CPPDEFINES=[('PLATFORM', 'WINDOWS')]) elif(env['platform'] == 'x11'): - env_assimp.Append(CPPFLAGS=['-DPLATFORM_LINUX']) - env_assimp.Append(CPPFLAGS=['-DPLATFORM=LINUX']) + env_assimp.Append(CPPDEFINES=['PLATFORM_LINUX']) + env_assimp.Append(CPPDEFINES=[('PLATFORM', 'LINUX')]) elif(env['platform'] == 'osx'): - env_assimp.Append(CPPFLAGS=['-DPLATFORM_DARWIN']) - env_assimp.Append(CPPFLAGS=['-DPLATFORM=DARWIN']) + env_assimp.Append(CPPDEFINES=['PLATFORM_DARWIN']) + env_assimp.Append(CPPDEFINES=[('PLATFORM', 'DARWIN')]) env_thirdparty = env_assimp.Clone() env_thirdparty.disable_warnings() diff --git a/modules/assimp/editor_scene_importer_assimp.cpp b/modules/assimp/editor_scene_importer_assimp.cpp index 093e2f3006..f23c66dbcf 100644 --- a/modules/assimp/editor_scene_importer_assimp.cpp +++ b/modules/assimp/editor_scene_importer_assimp.cpp @@ -854,7 +854,7 @@ Ref<Material> EditorSceneImporterAssimp::_generate_material_from_index(ImportSta if (found) { Ref<Texture> texture = _load_texture(state, path); - if (texture != NULL) { + if (texture.is_valid()) { _set_texture_mapping_mode(map_mode, texture); mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true); mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, texture); diff --git a/modules/bmp/image_loader_bmp.cpp b/modules/bmp/image_loader_bmp.cpp index a7e8dec11e..88732dff33 100644 --- a/modules/bmp/image_loader_bmp.cpp +++ b/modules/bmp/image_loader_bmp.cpp @@ -47,9 +47,6 @@ Error ImageLoaderBMP::convert_to_image(Ref<Image> p_image, size_t height = (size_t)p_header.bmp_info_header.bmp_height; size_t bits_per_pixel = (size_t)p_header.bmp_info_header.bmp_bit_count; - if (p_header.bmp_info_header.bmp_compression != BI_RGB) { - err = FAILED; - } // Check whether we can load it if (bits_per_pixel == 1) { @@ -238,11 +235,16 @@ Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f, bmp_header.bmp_info_header.bmp_colors_used = f->get_32(); bmp_header.bmp_info_header.bmp_important_colors = f->get_32(); - // Compressed bitmaps not supported, stop parsing - if (bmp_header.bmp_info_header.bmp_compression != BI_RGB) { - ERR_EXPLAIN("Unsupported bmp file: " + f->get_path()); - f->close(); - ERR_FAIL_V(ERR_UNAVAILABLE); + switch (bmp_header.bmp_info_header.bmp_compression) { + case BI_RLE8: + case BI_RLE4: + case BI_CMYKRLE8: + case BI_CMYKRLE4: { + // Stop parsing + ERR_EXPLAIN("Compressed BMP files are not supported: " + f->get_path()); + f->close(); + ERR_FAIL_V(ERR_UNAVAILABLE); + } break; } // Don't rely on sizeof(bmp_file_header) as structure padding // adds 2 bytes offset leading to misaligned color table reading @@ -257,8 +259,8 @@ Error ImageLoaderBMP::load_image(Ref<Image> p_image, FileAccess *f, if (bmp_header.bmp_info_header.bmp_bit_count <= 8) { // Support 256 colors max color_table_size = 1 << bmp_header.bmp_info_header.bmp_bit_count; + ERR_FAIL_COND_V(color_table_size == 0, ERR_BUG); } - ERR_FAIL_COND_V(color_table_size == 0, ERR_BUG); PoolVector<uint8_t> bmp_color_table; // Color table is usually 4 bytes per color -> [B][G][R][0] diff --git a/modules/bmp/image_loader_bmp.h b/modules/bmp/image_loader_bmp.h index 0082cf778a..2debb19a1c 100644 --- a/modules/bmp/image_loader_bmp.h +++ b/modules/bmp/image_loader_bmp.h @@ -42,15 +42,15 @@ protected: enum bmp_compression_s { BI_RGB = 0x00, - BI_RLE8 = 0x01, - BI_RLE4 = 0x02, + BI_RLE8 = 0x01, // compressed + BI_RLE4 = 0x02, // compressed BI_BITFIELDS = 0x03, BI_JPEG = 0x04, BI_PNG = 0x05, BI_ALPHABITFIELDS = 0x06, BI_CMYK = 0x0b, - BI_CMYKRLE8 = 0x0c, - BI_CMYKRLE4 = 0x0d + BI_CMYKRLE8 = 0x0c, // compressed + BI_CMYKRLE4 = 0x0d // compressed }; struct bmp_header_s { diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub index 2fe7a1b4c0..ecc8a9b481 100644 --- a/modules/bullet/SCsub +++ b/modules/bullet/SCsub @@ -192,7 +192,7 @@ if env['builtin_bullet']: else: env_bullet.Prepend(CPPPATH=[thirdparty_dir]) # if env['target'] == "debug" or env['target'] == "release_debug": - # env_bullet.Append(CPPFLAGS=['-DBT_DEBUG']) + # env_bullet.Append(CPPDEFINES=['BT_DEBUG']) env_thirdparty = env_bullet.Clone() env_thirdparty.disable_warnings() diff --git a/modules/bullet/rigid_body_bullet.cpp b/modules/bullet/rigid_body_bullet.cpp index 085cce9733..8d21b25b20 100644 --- a/modules/bullet/rigid_body_bullet.cpp +++ b/modules/bullet/rigid_body_bullet.cpp @@ -728,12 +728,12 @@ bool RigidBodyBullet::is_axis_locked(PhysicsServer::BodyAxis p_axis) const { void RigidBodyBullet::reload_axis_lock() { - btBody->setLinearFactor(btVector3(!is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_X), !is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_Y), !is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_Z))); + btBody->setLinearFactor(btVector3(float(!is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_X)), float(!is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_Y)), float(!is_axis_locked(PhysicsServer::BODY_AXIS_LINEAR_Z)))); if (PhysicsServer::BODY_MODE_CHARACTER == mode) { /// When character angular is always locked btBody->setAngularFactor(btVector3(0., 0., 0.)); } else { - btBody->setAngularFactor(btVector3(!is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_X), !is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_Y), !is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_Z))); + btBody->setAngularFactor(btVector3(float(!is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_X)), float(!is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_Y)), float(!is_axis_locked(PhysicsServer::BODY_AXIS_ANGULAR_Z)))); } } diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp index d4069b901f..e6bfa5525d 100644 --- a/modules/csg/csg_gizmos.cpp +++ b/modules/csg/csg_gizmos.cpp @@ -34,8 +34,18 @@ CSGShapeSpatialGizmoPlugin::CSGShapeSpatialGizmoPlugin() { - Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/csg", Color(0.2, 0.5, 1, 0.1)); - create_material("shape_material", gizmo_color); + Color gizmo_color = EDITOR_DEF("editors/3d_gizmos/gizmo_colors/csg", Color(0.0, 0.4, 1, 0.15)); + create_material("shape_union_material", gizmo_color); + create_material("shape_union_solid_material", gizmo_color); + gizmo_color.invert(); + create_material("shape_subtraction_material", gizmo_color); + create_material("shape_subtraction_solid_material", gizmo_color); + gizmo_color.r = 0.95; + gizmo_color.g = 0.95; + gizmo_color.b = 0.95; + create_material("shape_intersection_material", gizmo_color); + create_material("shape_intersection_solid_material", gizmo_color); + create_handle_material("handles"); } @@ -120,6 +130,10 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), Vector3(4096, 0, 0), sg[0], sg[1], ra, rb); float d = ra.x; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; @@ -135,6 +149,10 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); float d = ra[p_idx]; + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } + if (d < 0.001) d = 0.001; @@ -154,6 +172,9 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); float d = axis.dot(ra); + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } if (d < 0.001) d = 0.001; @@ -173,6 +194,9 @@ void CSGShapeSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_i Vector3 ra, rb; Geometry::get_closest_points_between_segments(Vector3(), axis * 4096, sg[0], sg[1], ra, rb); float d = axis.dot(ra); + if (SpatialEditor::get_singleton()->is_snap_enabled()) { + d = Math::stepify(d, SpatialEditor::get_singleton()->get_translate_snap()); + } if (d < 0.001) d = 0.001; @@ -297,7 +321,19 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { p_gizmo->clear(); - Ref<Material> material = get_material("shape_material", p_gizmo); + Ref<Material> material; + switch (cs->get_operation()) { + case CSGShape::OPERATION_UNION: + material = get_material("shape_union_material", p_gizmo); + break; + case CSGShape::OPERATION_INTERSECTION: + material = get_material("shape_intersection_material", p_gizmo); + break; + case CSGShape::OPERATION_SUBTRACTION: + material = get_material("shape_subtraction_material", p_gizmo); + break; + } + Ref<Material> handles_material = get_material("handles"); PoolVector<Vector3> faces = cs->get_brush_faces(); @@ -320,6 +356,30 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) { p_gizmo->add_lines(lines, material); p_gizmo->add_collision_segments(lines); + if (p_gizmo->is_selected()) { + // Draw a translucent representation of the CSG node + Ref<ArrayMesh> mesh = memnew(ArrayMesh); + Array array; + array.resize(Mesh::ARRAY_MAX); + array[Mesh::ARRAY_VERTEX] = faces; + mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, array); + + Ref<Material> solid_material; + switch (cs->get_operation()) { + case CSGShape::OPERATION_UNION: + solid_material = get_material("shape_union_solid_material", p_gizmo); + break; + case CSGShape::OPERATION_INTERSECTION: + solid_material = get_material("shape_intersection_solid_material", p_gizmo); + break; + case CSGShape::OPERATION_SUBTRACTION: + solid_material = get_material("shape_subtraction_solid_material", p_gizmo); + break; + } + + p_gizmo->add_mesh(mesh, false, RID(), solid_material); + } + if (Object::cast_to<CSGSphere>(cs)) { CSGSphere *s = Object::cast_to<CSGSphere>(cs); diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp index a496a214fd..23725c4960 100644 --- a/modules/csg/csg_shape.cpp +++ b/modules/csg/csg_shape.cpp @@ -436,10 +436,10 @@ void CSGShape::_update_shape() { } // unset write access - surfaces.write[i].verticesw = PoolVector<Vector3>::Write(); - surfaces.write[i].normalsw = PoolVector<Vector3>::Write(); - surfaces.write[i].uvsw = PoolVector<Vector2>::Write(); - surfaces.write[i].tansw = PoolVector<float>::Write(); + surfaces.write[i].verticesw.release(); + surfaces.write[i].normalsw.release(); + surfaces.write[i].uvsw.release(); + surfaces.write[i].tansw.release(); if (surfaces[i].last_added == 0) continue; @@ -557,6 +557,7 @@ void CSGShape::set_operation(Operation p_operation) { operation = p_operation; _make_dirty(); + update_gizmo(); } CSGShape::Operation CSGShape::get_operation() const { diff --git a/modules/csg/doc_classes/CSGBox.xml b/modules/csg/doc_classes/CSGBox.xml index d100c01205..14f5a1952e 100644 --- a/modules/csg/doc_classes/CSGBox.xml +++ b/modules/csg/doc_classes/CSGBox.xml @@ -17,7 +17,7 @@ <member name="height" type="float" setter="set_height" getter="get_height" default="2.0"> Height of the box measured from the center of the box. </member> - <member name="material" type="Material" setter="set_material" getter="get_material" default="null"> + <member name="material" type="Material" setter="set_material" getter="get_material"> The material used to render the box. </member> <member name="width" type="float" setter="set_width" getter="get_width" default="2.0"> diff --git a/modules/csg/doc_classes/CSGCylinder.xml b/modules/csg/doc_classes/CSGCylinder.xml index 643eb7c7f4..9fc0281887 100644 --- a/modules/csg/doc_classes/CSGCylinder.xml +++ b/modules/csg/doc_classes/CSGCylinder.xml @@ -17,7 +17,7 @@ <member name="height" type="float" setter="set_height" getter="get_height" default="1.0"> The height of the cylinder. </member> - <member name="material" type="Material" setter="set_material" getter="get_material" default="null"> + <member name="material" type="Material" setter="set_material" getter="get_material"> The material used to render the cylinder. </member> <member name="radius" type="float" setter="set_radius" getter="get_radius" default="1.0"> diff --git a/modules/csg/doc_classes/CSGMesh.xml b/modules/csg/doc_classes/CSGMesh.xml index daa08decb6..afe0bc262d 100644 --- a/modules/csg/doc_classes/CSGMesh.xml +++ b/modules/csg/doc_classes/CSGMesh.xml @@ -11,9 +11,9 @@ <methods> </methods> <members> - <member name="material" type="Material" setter="set_material" getter="get_material" default="null"> + <member name="material" type="Material" setter="set_material" getter="get_material"> </member> - <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh" default="null"> + <member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh"> The mesh resource to use as a CSG shape. </member> </members> diff --git a/modules/csg/doc_classes/CSGPolygon.xml b/modules/csg/doc_classes/CSGPolygon.xml index 48f5d730cc..0ecee92cd5 100644 --- a/modules/csg/doc_classes/CSGPolygon.xml +++ b/modules/csg/doc_classes/CSGPolygon.xml @@ -14,7 +14,7 @@ <member name="depth" type="float" setter="set_depth" getter="get_depth" default="1.0"> Extrusion depth when [member mode] is [constant MODE_DEPTH]. </member> - <member name="material" type="Material" setter="set_material" getter="get_material" default="null"> + <member name="material" type="Material" setter="set_material" getter="get_material"> Material to use for the resulting mesh. </member> <member name="mode" type="int" setter="set_mode" getter="get_mode" enum="CSGPolygon.Mode" default="0"> diff --git a/modules/csg/doc_classes/CSGShape.xml b/modules/csg/doc_classes/CSGShape.xml index 91f54f8246..755d8df67e 100644 --- a/modules/csg/doc_classes/CSGShape.xml +++ b/modules/csg/doc_classes/CSGShape.xml @@ -92,7 +92,7 @@ Only intersecting geometry remains, the rest is removed. </constant> <constant name="OPERATION_SUBTRACTION" value="2" enum="Operation"> - The second shape is susbtracted from the first, leaving a dent with it's shape. + The second shape is subtracted from the first, leaving a dent with its shape. </constant> </constants> </class> diff --git a/modules/csg/doc_classes/CSGSphere.xml b/modules/csg/doc_classes/CSGSphere.xml index 0a62644179..714e725acb 100644 --- a/modules/csg/doc_classes/CSGSphere.xml +++ b/modules/csg/doc_classes/CSGSphere.xml @@ -11,7 +11,7 @@ <methods> </methods> <members> - <member name="material" type="Material" setter="set_material" getter="get_material" default="null"> + <member name="material" type="Material" setter="set_material" getter="get_material"> The material used to render the sphere. </member> <member name="radial_segments" type="int" setter="set_radial_segments" getter="get_radial_segments" default="12"> diff --git a/modules/csg/doc_classes/CSGTorus.xml b/modules/csg/doc_classes/CSGTorus.xml index 156fb185e7..5dc6bb8380 100644 --- a/modules/csg/doc_classes/CSGTorus.xml +++ b/modules/csg/doc_classes/CSGTorus.xml @@ -14,7 +14,7 @@ <member name="inner_radius" type="float" setter="set_inner_radius" getter="get_inner_radius" default="2.0"> The inner radius of the torus. </member> - <member name="material" type="Material" setter="set_material" getter="get_material" default="null"> + <member name="material" type="Material" setter="set_material" getter="get_material"> The material used to render the torus. </member> <member name="outer_radius" type="float" setter="set_outer_radius" getter="get_outer_radius" default="3.0"> diff --git a/modules/cvtt/image_compress_cvtt.cpp b/modules/cvtt/image_compress_cvtt.cpp index 024e9ffc3b..17b0038780 100644 --- a/modules/cvtt/image_compress_cvtt.cpp +++ b/modules/cvtt/image_compress_cvtt.cpp @@ -388,8 +388,8 @@ void image_decompress_cvtt(Image *p_image) { h >>= 1; } - rb = PoolVector<uint8_t>::Read(); - wb = PoolVector<uint8_t>::Write(); + rb.release(); + wb.release(); p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); } diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp index 50fdc8ab20..4628bd9a5b 100644 --- a/modules/dds/texture_loader_dds.cpp +++ b/modules/dds/texture_loader_dds.cpp @@ -31,7 +31,7 @@ #include "texture_loader_dds.h" #include "core/os/file_access.h" -#define PF_FOURCC(s) (((s)[3] << 24U) | ((s)[2] << 16U) | ((s)[1] << 8U) | ((s)[0])) +#define PF_FOURCC(s) ((uint32_t)(((s)[3] << 24U) | ((s)[2] << 16U) | ((s)[1] << 8U) | ((s)[0]))) enum { DDS_MAGIC = 0x20534444, @@ -251,7 +251,6 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, src_data.resize(size); PoolVector<uint8_t>::Write wb = src_data.write(); f->get_buffer(wb.ptr(), size); - wb = PoolVector<uint8_t>::Write(); } else if (info.palette) { @@ -296,8 +295,6 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, if (colsize == 4) wb[dst_ofs + 3] = palette[src_ofs + 3]; } - - wb = PoolVector<uint8_t>::Write(); } else { //uncompressed generic... @@ -444,8 +441,6 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path, default: { } } - - wb = PoolVector<uint8_t>::Write(); } Ref<Image> img = memnew(Image(width, height, mipmaps - 1, info.format, src_data)); diff --git a/modules/enet/SCsub b/modules/enet/SCsub index 78d8d43414..485c33b1a8 100644 --- a/modules/enet/SCsub +++ b/modules/enet/SCsub @@ -22,7 +22,7 @@ if env['builtin_enet']: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_enet.Prepend(CPPPATH=[thirdparty_dir]) - env_enet.Append(CPPFLAGS=["-DGODOT_ENET"]) + env_enet.Append(CPPDEFINES=["GODOT_ENET"]) env_thirdparty = env_enet.Clone() env_thirdparty.disable_warnings() diff --git a/modules/etc/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp index f302834222..ff925480b8 100644 --- a/modules/etc/texture_loader_pkm.cpp +++ b/modules/etc/texture_loader_pkm.cpp @@ -80,7 +80,7 @@ RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path, src_data.resize(size); PoolVector<uint8_t>::Write wb = src_data.write(); f->get_buffer(wb.ptr(), size); - wb = PoolVector<uint8_t>::Write(); + wb.release(); int mipmaps = h.format; int width = h.origWidth; diff --git a/modules/freetype/SCsub b/modules/freetype/SCsub index 0ea581220e..b47377cbc4 100644 --- a/modules/freetype/SCsub +++ b/modules/freetype/SCsub @@ -65,16 +65,16 @@ if env['builtin_freetype']: # Also needed in main env for scene/ env.Prepend(CPPPATH=[thirdparty_dir + "/include"]) - env_freetype.Append(CPPFLAGS=['-DFT2_BUILD_LIBRARY', '-DFT_CONFIG_OPTION_USE_PNG']) + env_freetype.Append(CPPDEFINES=['FT2_BUILD_LIBRARY', 'FT_CONFIG_OPTION_USE_PNG']) if (env['target'] != 'release'): - env_freetype.Append(CPPFLAGS=['-DZLIB_DEBUG']) + env_freetype.Append(CPPDEFINES=['ZLIB_DEBUG']) # Also requires libpng headers if env['builtin_libpng']: env_freetype.Prepend(CPPPATH=["#thirdparty/libpng"]) sfnt = thirdparty_dir + 'src/sfnt/sfnt.c' - # Must be done after all CPPFLAGS are being set so we can copy them. + # Must be done after all CPPDEFINES are being set so we can copy them. if env['platform'] == 'javascript': # Forcibly undefine this macro so SIMD is not used in this file, # since currently unsupported in WASM @@ -103,4 +103,4 @@ if env['builtin_freetype']: # Godot source files env_freetype.add_source_files(env.modules_sources, "*.cpp") # Used in scene/, needs to be in main env -env.Append(CPPFLAGS=['-DFREETYPE_ENABLED']) +env.Append(CPPDEFINES=['FREETYPE_ENABLED']) diff --git a/modules/gdnative/doc_classes/GDNative.xml b/modules/gdnative/doc_classes/GDNative.xml index 95ed1fc048..8750ddc56d 100644 --- a/modules/gdnative/doc_classes/GDNative.xml +++ b/modules/gdnative/doc_classes/GDNative.xml @@ -33,7 +33,7 @@ </method> </methods> <members> - <member name="library" type="GDNativeLibrary" setter="set_library" getter="get_library" default="null"> + <member name="library" type="GDNativeLibrary" setter="set_library" getter="get_library"> </member> </members> <constants> diff --git a/modules/gdnative/doc_classes/NativeScript.xml b/modules/gdnative/doc_classes/NativeScript.xml index 460471386d..e34e209374 100644 --- a/modules/gdnative/doc_classes/NativeScript.xml +++ b/modules/gdnative/doc_classes/NativeScript.xml @@ -53,7 +53,7 @@ <members> <member name="class_name" type="String" setter="set_class_name" getter="get_class_name" default=""""> </member> - <member name="library" type="GDNativeLibrary" setter="set_library" getter="get_library" default="null"> + <member name="library" type="GDNativeLibrary" setter="set_library" getter="get_library"> </member> <member name="script_class_icon_path" type="String" setter="set_script_class_icon_path" getter="get_script_class_icon_path" default=""""> </member> diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp index a27935bfe2..4eb9a2a0a3 100644 --- a/modules/gdnative/gdnative.cpp +++ b/modules/gdnative/gdnative.cpp @@ -48,7 +48,7 @@ static const bool default_reloadable = true; // Defined in gdnative_api_struct.gen.cpp extern const godot_gdnative_core_api_struct api_struct; -Map<String, Vector<Ref<GDNative> > > *GDNativeLibrary::loaded_libraries = NULL; +Map<String, Vector<Ref<GDNative> > > GDNativeLibrary::loaded_libraries; GDNativeLibrary::GDNativeLibrary() { config_file.instance(); @@ -57,10 +57,6 @@ GDNativeLibrary::GDNativeLibrary() { load_once = default_load_once; singleton = default_singleton; reloadable = default_reloadable; - - if (GDNativeLibrary::loaded_libraries == NULL) { - GDNativeLibrary::loaded_libraries = memnew((Map<String, Vector<Ref<GDNative> > >)); - } } GDNativeLibrary::~GDNativeLibrary() { @@ -318,10 +314,10 @@ bool GDNative::initialize() { #endif if (library->should_load_once()) { - if (GDNativeLibrary::loaded_libraries->has(lib_path)) { + if (GDNativeLibrary::loaded_libraries.has(lib_path)) { // already loaded. Don't load again. // copy some of the stuff instead - this->native_handle = (*GDNativeLibrary::loaded_libraries)[lib_path][0]->native_handle; + this->native_handle = GDNativeLibrary::loaded_libraries[lib_path][0]->native_handle; initialized = true; return true; } @@ -377,11 +373,11 @@ bool GDNative::initialize() { initialized = true; - if (library->should_load_once() && !GDNativeLibrary::loaded_libraries->has(lib_path)) { + if (library->should_load_once() && !GDNativeLibrary::loaded_libraries.has(lib_path)) { Vector<Ref<GDNative> > gdnatives; gdnatives.resize(1); gdnatives.write[0] = Ref<GDNative>(this); - GDNativeLibrary::loaded_libraries->insert(lib_path, gdnatives); + GDNativeLibrary::loaded_libraries.insert(lib_path, gdnatives); } return true; @@ -395,7 +391,7 @@ bool GDNative::terminate() { } if (library->should_load_once()) { - Vector<Ref<GDNative> > *gdnatives = &(*GDNativeLibrary::loaded_libraries)[library->get_current_library_path()]; + Vector<Ref<GDNative> > *gdnatives = &GDNativeLibrary::loaded_libraries[library->get_current_library_path()]; if (gdnatives->size() > 1) { // there are other GDNative's still using this library, so we actually don't terminate gdnatives->erase(Ref<GDNative>(this)); @@ -405,7 +401,7 @@ bool GDNative::terminate() { // we're the last one, terminate! gdnatives->clear(); // whew this looks scary, but all it does is remove the entry completely - GDNativeLibrary::loaded_libraries->erase(GDNativeLibrary::loaded_libraries->find(library->get_current_library_path())); + GDNativeLibrary::loaded_libraries.erase(GDNativeLibrary::loaded_libraries.find(library->get_current_library_path())); } } diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h index 005d1d2bff..408af26753 100644 --- a/modules/gdnative/gdnative.h +++ b/modules/gdnative/gdnative.h @@ -47,7 +47,7 @@ class GDNative; class GDNativeLibrary : public Resource { GDCLASS(GDNativeLibrary, Resource); - static Map<String, Vector<Ref<GDNative> > > *loaded_libraries; + static Map<String, Vector<Ref<GDNative> > > loaded_libraries; friend class GDNativeLibraryResourceLoader; friend class GDNative; diff --git a/modules/gdnative/nativescript/SCsub b/modules/gdnative/nativescript/SCsub index 5841ad5531..92c9d6630d 100644 --- a/modules/gdnative/nativescript/SCsub +++ b/modules/gdnative/nativescript/SCsub @@ -4,7 +4,6 @@ Import('env') Import('env_gdnative') env_gdnative.add_source_files(env.modules_sources, '*.cpp') -env_gdnative.Append(CPPFLAGS=['-DGDAPI_BUILT_IN']) if "platform" in env and env["platform"] in ["x11", "iphone"]: env.Append(LINKFLAGS=["-rdynamic"]) diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp index 4bbadc62e7..9de073fc8e 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.cpp +++ b/modules/gdnative/pluginscript/pluginscript_language.cpp @@ -159,7 +159,7 @@ String PluginScriptLanguage::make_function(const String &p_class, const String & return String(); } -Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) { +Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_force, String &r_call_hint) { if (_desc.complete_code) { Array options; godot_error tmp = _desc.complete_code( @@ -171,7 +171,8 @@ Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_ &r_force, (godot_string *)&r_call_hint); for (int i = 0; i < options.size(); i++) { - r_options->push_back(String(options[i])); + ScriptCodeCompletionOption option(options[i], ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + r_options->push_back(option); } return (Error)tmp; } diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h index a11e916975..7b3844d0b0 100644 --- a/modules/gdnative/pluginscript/pluginscript_language.h +++ b/modules/gdnative/pluginscript/pluginscript_language.h @@ -81,7 +81,7 @@ public: virtual bool can_inherit_from_file() { return true; } virtual int find_function(const String &p_function, const String &p_code) const; virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; - virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint); + virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_force, String &r_call_hint); virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const; virtual void add_global_constant(const StringName &p_variable, const Variant &p_value); diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp index 55d44ceec8..6ff6262b56 100644 --- a/modules/gdnative/register_types.cpp +++ b/modules/gdnative/register_types.cpp @@ -100,6 +100,11 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty } String entry_lib_path = config->get_value("entry", key); + if (!entry_lib_path.begins_with("res://")) { + print_line("Skipping export of out-of-project library " + entry_lib_path); + continue; + } + add_shared_object(entry_lib_path, tags); } } @@ -129,6 +134,10 @@ void GDNativeExportPlugin::_export_file(const String &p_path, const String &p_ty Vector<String> dependency_paths = config->get_value("dependencies", key); for (int i = 0; i < dependency_paths.size(); i++) { + if (!dependency_paths[i].begins_with("res://")) { + print_line("Skipping export of out-of-project library " + dependency_paths[i]); + continue; + } add_shared_object(dependency_paths[i], tags); } } diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp index 62b65fe96b..963b40529d 100644 --- a/modules/gdscript/editor/gdscript_highlighter.cpp +++ b/modules/gdscript/editor/gdscript_highlighter.cpp @@ -370,8 +370,8 @@ void GDScriptSyntaxHighlighter::_update_cache() { bool default_theme = text_editor_color_theme == "Default"; bool dark_theme = settings->is_dark_theme(); - function_definition_color = Color::html(default_theme ? "#01e1ff" : dark_theme ? "#01e1ff" : "#00a5ba"); - node_path_color = Color::html(default_theme ? "#64c15a" : dark_theme ? "64c15a" : "#518b4b"); + function_definition_color = default_theme ? Color(0.0, 0.88, 1.0) : dark_theme ? Color(0.0, 0.88, 1.0) : Color(0.0, 0.65, 0.73); + node_path_color = default_theme ? Color(0.39, 0.76, 0.35) : dark_theme ? Color(0.39, 0.76, 0.35) : Color(0.32, 0.55, 0.29); EDITOR_DEF("text_editor/highlighting/gdscript/function_definition_color", function_definition_color); EDITOR_DEF("text_editor/highlighting/gdscript/node_path_color", node_path_color); diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 1756f6eabc..a5ad23c75d 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -458,7 +458,7 @@ public: virtual bool can_inherit_from_file() { return true; } virtual int find_function(const String &p_function, const String &p_code) const; virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; - virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint); + virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint); #ifdef TOOLS_ENABLED virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result); #endif diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 26b14a6148..521b5ed538 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -159,7 +159,11 @@ bool GDScriptLanguage::validate(const String &p_script, int &r_line_error, int & for (int i = 0; i < cl->subclasses.size(); i++) { for (int j = 0; j < cl->subclasses[i]->functions.size(); j++) { - funcs[cl->subclasses[i]->functions[j]->line] = String(cl->subclasses[i]->name) + "." + String(cl->subclasses[i]->functions[j]->name); + funcs[cl->subclasses[i]->functions[j]->line] = String(cl->subclasses[i]->name) + "." + cl->subclasses[i]->functions[j]->name; + } + for (int j = 0; j < cl->subclasses[i]->static_functions.size(); j++) { + + funcs[cl->subclasses[i]->static_functions[j]->line] = String(cl->subclasses[i]->name) + "." + cl->subclasses[i]->static_functions[j]->name; } } @@ -509,12 +513,14 @@ struct GDScriptCompletionIdentifier { assigned_expression(NULL) {} }; -static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Set<String> &r_list) { +static void _get_directory_contents(EditorFileSystemDirectory *p_dir, Map<String, ScriptCodeCompletionOption> &r_list) { const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; for (int i = 0; i < p_dir->get_file_count(); i++) { - r_list.insert(quote_style + p_dir->get_file_path(i) + quote_style); + ScriptCodeCompletionOption option(p_dir->get_file_path(i), ScriptCodeCompletionOption::KIND_FILE_PATH); + option.insert_text = quote_style + option.display + quote_style; + r_list.insert(option.display, option); } for (int i = 0; i < p_dir->get_subdir_count(); i++) { @@ -1807,14 +1813,15 @@ static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_functio return arghint; } -static void _find_enumeration_candidates(const String p_enum_hint, Set<String> &r_result) { +static void _find_enumeration_candidates(const String p_enum_hint, Map<String, ScriptCodeCompletionOption> &r_result) { if (p_enum_hint.find(".") == -1) { // Global constant StringName current_enum = p_enum_hint; for (int i = 0; i < GlobalConstants::get_global_constant_count(); i++) { if (GlobalConstants::get_global_constant_enum(i) == current_enum) { - r_result.insert(GlobalConstants::get_global_constant_name(i)); + ScriptCodeCompletionOption option(GlobalConstants::get_global_constant_name(i), ScriptCodeCompletionOption::KIND_ENUM); + r_result.insert(option.display, option); } } } else { @@ -1829,15 +1836,17 @@ static void _find_enumeration_candidates(const String p_enum_hint, Set<String> & ClassDB::get_enum_constants(class_name, enum_name, &enum_constants); for (List<StringName>::Element *E = enum_constants.front(); E; E = E->next()) { String candidate = class_name + "." + E->get(); - r_result.insert(candidate); + ScriptCodeCompletionOption option(candidate, ScriptCodeCompletionOption::KIND_ENUM); + r_result.insert(option.display, option); } } } -static void _find_identifiers_in_block(const GDScriptCompletionContext &p_context, Set<String> &r_result) { +static void _find_identifiers_in_block(const GDScriptCompletionContext &p_context, Map<String, ScriptCodeCompletionOption> &r_result) { for (Map<StringName, GDScriptParser::LocalVarNode *>::Element *E = p_context.block->variables.front(); E; E = E->next()) { if (E->get()->line < p_context.line) { - r_result.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_VARIABLE); + r_result.insert(option.display, option); } } if (p_context.block->parent_block) { @@ -1847,40 +1856,47 @@ static void _find_identifiers_in_block(const GDScriptCompletionContext &p_contex } } -static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Set<String> &r_result); +static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result); -static void _find_identifiers_in_class(const GDScriptCompletionContext &p_context, bool p_static, bool p_only_functions, bool p_parent_only, Set<String> &r_result) { +static void _find_identifiers_in_class(const GDScriptCompletionContext &p_context, bool p_static, bool p_only_functions, bool p_parent_only, Map<String, ScriptCodeCompletionOption> &r_result) { if (!p_parent_only) { if (!p_static && !p_only_functions) { for (int i = 0; i < p_context._class->variables.size(); i++) { - r_result.insert(p_context._class->variables[i].identifier); + ScriptCodeCompletionOption option(p_context._class->variables[i].identifier, ScriptCodeCompletionOption::KIND_MEMBER); + r_result.insert(option.display, option); } } if (!p_only_functions) { for (Map<StringName, GDScriptParser::ClassNode::Constant>::Element *E = p_context._class->constant_expressions.front(); E; E = E->next()) { - r_result.insert(E->key()); + ScriptCodeCompletionOption option(E->key(), ScriptCodeCompletionOption::KIND_CONSTANT); + r_result.insert(option.display, option); } for (int i = 0; i < p_context._class->subclasses.size(); i++) { - r_result.insert(p_context._class->subclasses[i]->name); + ScriptCodeCompletionOption option(p_context._class->subclasses[i]->name, ScriptCodeCompletionOption::KIND_CLASS); + r_result.insert(option.display, option); } } for (int i = 0; i < p_context._class->static_functions.size(); i++) { + ScriptCodeCompletionOption option(p_context._class->static_functions[i]->name.operator String(), ScriptCodeCompletionOption::KIND_FUNCTION); if (p_context._class->static_functions[i]->arguments.size()) { - r_result.insert(p_context._class->static_functions[i]->name.operator String() + "("); + option.insert_text += "("; } else { - r_result.insert(p_context._class->static_functions[i]->name.operator String() + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } if (!p_static) { for (int i = 0; i < p_context._class->functions.size(); i++) { + ScriptCodeCompletionOption option(p_context._class->functions[i]->name.operator String(), ScriptCodeCompletionOption::KIND_FUNCTION); if (p_context._class->functions[i]->arguments.size()) { - r_result.insert(p_context._class->functions[i]->name.operator String() + "("); + option.insert_text += "("; } else { - r_result.insert(p_context._class->functions[i]->name.operator String() + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } } } @@ -1898,12 +1914,14 @@ static void _find_identifiers_in_class(const GDScriptCompletionContext &p_contex _find_identifiers_in_base(c, base_type, p_only_functions, r_result); } -static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Set<String> &r_result) { +static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result) { GDScriptParser::DataType base_type = p_base.type; bool _static = base_type.is_meta_type; if (_static && base_type.kind != GDScriptParser::DataType::BUILTIN) { - r_result.insert("new("); + ScriptCodeCompletionOption option("new", ScriptCodeCompletionOption::KIND_FUNCTION); + option.insert_text += "("; + r_result.insert(option.display, option); } while (base_type.has_type) { @@ -1921,26 +1939,31 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context if (script.is_valid()) { if (!_static && !p_only_functions) { for (const Set<StringName>::Element *E = script->get_members().front(); E; E = E->next()) { - r_result.insert(E->get().operator String()); + ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_MEMBER); + r_result.insert(option.display, option); } } if (!p_only_functions) { for (const Map<StringName, Variant>::Element *E = script->get_constants().front(); E; E = E->next()) { - r_result.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); + r_result.insert(option.display, option); } } for (const Map<StringName, GDScriptFunction *>::Element *E = script->get_member_functions().front(); E; E = E->next()) { if (!_static || E->get()->is_static()) { + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_FUNCTION); if (E->get()->get_argument_count()) { - r_result.insert(E->key().operator String() + "("); + option.insert_text += "("; } else { - r_result.insert(E->key().operator String() + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } } if (!p_only_functions) { for (const Map<StringName, Ref<GDScript> >::Element *E = script->get_subclasses().front(); E; E = E->next()) { - r_result.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + r_result.insert(option.display, option); } } base_type = GDScriptParser::DataType(); @@ -1964,25 +1987,29 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context List<PropertyInfo> members; scr->get_script_property_list(&members); for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) { - r_result.insert(E->get().name); + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); + r_result.insert(option.display, option); } } if (!p_only_functions) { Map<StringName, Variant> constants; scr->get_constants(&constants); for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { - r_result.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); + r_result.insert(option.display, option); } } List<MethodInfo> methods; scr->get_script_method_list(&methods); for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION); if (E->get().arguments.size()) { - r_result.insert(E->get().name + "("); + option.insert_text += "("; } else { - r_result.insert(E->get().name + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } Ref<Script> base_script = scr->get_base_script(); @@ -2009,7 +2036,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context List<String> constants; ClassDB::get_integer_constant_list(type, &constants); for (List<String>::Element *E = constants.front(); E; E = E->next()) { - r_result.insert(E->get()); + ScriptCodeCompletionOption option(E->get(), ScriptCodeCompletionOption::KIND_CONSTANT); + r_result.insert(option.display, option); } if (!_static) { @@ -2022,7 +2050,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context if (E->get().name.find("/") != -1) { continue; } - r_result.insert(E->get().name); + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); + r_result.insert(option.display, option); } } } @@ -2035,11 +2064,13 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context if (E->get().name.begins_with("_")) { continue; } + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION); if (E->get().arguments.size()) { - r_result.insert(E->get().name + "("); + option.insert_text += "("; } else { - r_result.insert(E->get().name + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } } @@ -2058,7 +2089,8 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context for (List<PropertyInfo>::Element *E = members.front(); E; E = E->next()) { if (String(E->get().name).find("/") == -1) { - r_result.insert(E->get().name); + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_MEMBER); + r_result.insert(option.display, option); } } } @@ -2066,11 +2098,13 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context List<MethodInfo> methods; tmp.get_method_list(&methods); for (List<MethodInfo>::Element *E = methods.front(); E; E = E->next()) { + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_FUNCTION); if (E->get().arguments.size()) { - r_result.insert(E->get().name + "("); + option.insert_text += "("; } else { - r_result.insert(E->get().name + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } return; @@ -2082,7 +2116,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context } } -static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p_only_functions, Set<String> &r_result) { +static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p_only_functions, Map<String, ScriptCodeCompletionOption> &r_result) { const GDScriptParser::BlockNode *block = p_context.block; @@ -2091,7 +2125,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p const GDScriptParser::FunctionNode *f = p_context.function; for (int i = 0; i < f->arguments.size(); i++) { - r_result.insert(f->arguments[i].operator String()); + ScriptCodeCompletionOption option(f->arguments[i].operator String(), ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + r_result.insert(option.display, option); } } @@ -2116,11 +2151,13 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p for (int i = 0; i < GDScriptFunctions::FUNC_MAX; i++) { MethodInfo mi = GDScriptFunctions::get_info(GDScriptFunctions::Function(i)); + ScriptCodeCompletionOption option(String(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))), ScriptCodeCompletionOption::KIND_FUNCTION); if (mi.arguments.size() || (mi.flags & METHOD_FLAG_VARARG)) { - r_result.insert(String(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))) + "("); + option.insert_text += "("; } else { - r_result.insert(String(GDScriptFunctions::get_func_name(GDScriptFunctions::Function(i))) + "()"); + option.insert_text += "()"; } + r_result.insert(option.display, option); } static const char *_type_names[Variant::VARIANT_MAX] = { @@ -2130,7 +2167,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p }; for (int i = 0; i < Variant::VARIANT_MAX; i++) { - r_result.insert(_type_names[i]); + ScriptCodeCompletionOption option(_type_names[i], ScriptCodeCompletionOption::KIND_CLASS); + r_result.insert(option.display, option); } static const char *_keywords[] = { @@ -2144,7 +2182,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p const char **kw = _keywords; while (*kw) { - r_result.insert(*kw); + ScriptCodeCompletionOption option(*kw, ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + r_result.insert(option.display, option); kw++; } @@ -2158,7 +2197,8 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p } String path = ProjectSettings::get_singleton()->get(s); if (path.begins_with("*")) { - r_result.insert(s.get_slice("/", 1)); + ScriptCodeCompletionOption option(s.get_slice("/", 1), ScriptCodeCompletionOption::KIND_CONSTANT); + r_result.insert(option.display, option); } } @@ -2166,16 +2206,18 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p List<StringName> named_scripts; ScriptServer::get_global_class_list(&named_scripts); for (List<StringName>::Element *E = named_scripts.front(); E; E = E->next()) { - r_result.insert(E->get().operator String()); + ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + r_result.insert(option.display, option); } // Native classes for (const Map<StringName, int>::Element *E = GDScriptLanguage::get_singleton()->get_global_map().front(); E; E = E->next()) { - r_result.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + r_result.insert(option.display, option); } } -static void _find_call_arguments(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, int p_argidx, bool p_static, Set<String> &r_result, String &r_arghint) { +static void _find_call_arguments(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, int p_argidx, bool p_static, Map<String, ScriptCodeCompletionOption> &r_result, String &r_arghint) { Variant base = p_base.value; GDScriptParser::DataType base_type = p_base.type; @@ -2199,7 +2241,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con if ((p_method == "connect" || p_method == "emit_signal") && p_argidx == 0) { for (int i = 0; i < base_type.class_type->_signals.size(); i++) { - r_result.insert(quote_style + base_type.class_type->_signals[i].name.operator String() + quote_style); + ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } @@ -2212,7 +2256,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con List<MethodInfo> signals; gds->get_script_signal_list(&signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - r_result.insert(quote_style + E->get().name + quote_style); + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_SIGNAL); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } Ref<GDScript> base_script = gds->get_base_script(); @@ -2250,7 +2296,8 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con List<String> options; obj->get_argument_options(p_method, p_argidx, &options); for (List<String>::Element *F = options.front(); F; F = F->next()) { - r_result.insert(F->get()); + ScriptCodeCompletionOption option(F->get(), ScriptCodeCompletionOption::KIND_FUNCTION); + r_result.insert(option.display, option); } } } @@ -2271,7 +2318,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con List<MethodInfo> signals; ClassDB::get_signal_list(class_name, &signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - r_result.insert(quote_style + E->get().name + quote_style); + ScriptCodeCompletionOption option(E->get().name, ScriptCodeCompletionOption::KIND_SIGNAL); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } @@ -2286,7 +2335,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con continue; } String name = s.get_slice("/", 1); - r_result.insert(quote_style + "/root/" + name + quote_style); + ScriptCodeCompletionOption option("/root/" + name, ScriptCodeCompletionOption::KIND_NODE_PATH); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } @@ -2300,7 +2351,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con continue; } String name = s.get_slice("/", 1); - r_result.insert(quote_style + name + quote_style); + ScriptCodeCompletionOption option(name, ScriptCodeCompletionOption::KIND_CONSTANT); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } @@ -2333,7 +2386,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con } } -static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Set<String> &r_result, bool &r_forced, String &r_arghint) { +static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Map<String, ScriptCodeCompletionOption> &r_result, bool &r_forced, String &r_arghint) { const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; @@ -2451,17 +2504,19 @@ static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDS _find_call_arguments(p_context, ci, function, p_argidx, _static, r_result, r_arghint); if (function == "connect" && p_argidx == 2) { - Set<String> methods; + Map<String, ScriptCodeCompletionOption> methods; _find_identifiers_in_base(p_context, connect_base, true, methods); - for (Set<String>::Element *E = methods.front(); E; E = E->next()) { - r_result.insert(quote_style + E->get().replace("(", "").replace(")", "") + quote_style); + for (Map<String, ScriptCodeCompletionOption>::Element *E = methods.front(); E; E = E->next()) { + ScriptCodeCompletionOption &option = E->value(); + option.insert_text = quote_style + option.display + quote_style; + r_result.insert(option.display, option); } } r_forced = r_result.size() > 0; } -Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) { +Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) { const String quote_style = EDITOR_DEF("text_editor/completion/use_single_quotes", false) ? "'" : "\""; @@ -2469,7 +2524,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path parser.parse(p_code, p_path.get_base_dir(), false, p_path, true); r_forced = false; - Set<String> options; + Map<String, ScriptCodeCompletionOption> options; GDScriptCompletionContext context; context._class = parser.get_completion_class(); context.block = parser.get_completion_block(); @@ -2490,7 +2545,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path List<StringName> constants; Variant::get_constants_for_type(parser.get_completion_built_in_constant(), &constants); for (List<StringName>::Element *E = constants.front(); E; E = E->next()) { - options.insert(E->get().operator String()); + ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CONSTANT); + options.insert(option.display, option); } } break; case GDScriptParser::COMPLETION_PARENT_FUNCTION: { @@ -2515,9 +2571,11 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path r_forced = true; String idopt = opt.unquote(); if (idopt.replace("/", "_").is_valid_identifier()) { - options.insert(idopt); + ScriptCodeCompletionOption option(idopt, ScriptCodeCompletionOption::KIND_NODE_PATH); + options.insert(option.display, option); } else { - options.insert(opt); + ScriptCodeCompletionOption option(opt, ScriptCodeCompletionOption::KIND_NODE_PATH); + options.insert(option.display, option); } } } @@ -2532,7 +2590,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path continue; } String name = s.get_slice("/", 1); - options.insert(quote_style + "/root/" + name + quote_style); + ScriptCodeCompletionOption option(quote_style + "/root/" + name + quote_style, ScriptCodeCompletionOption::KIND_NODE_PATH); + options.insert(option.display, option); } } } break; @@ -2655,7 +2714,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path } method_hint += ":"; - options.insert(method_hint); + ScriptCodeCompletionOption option(method_hint, ScriptCodeCompletionOption::KIND_FUNCTION); + options.insert(option.display, option); } } break; case GDScriptParser::COMPLETION_YIELD: { @@ -2673,7 +2733,9 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path switch (base_type.kind) { case GDScriptParser::DataType::CLASS: { for (int i = 0; i < base_type.class_type->_signals.size(); i++) { - options.insert(quote_style + base_type.class_type->_signals[i].name.operator String() + quote_style); + ScriptCodeCompletionOption option(base_type.class_type->_signals[i].name.operator String(), ScriptCodeCompletionOption::KIND_SIGNAL); + option.insert_text = quote_style + option.display + quote_style; + options.insert(option.display, option); } base_type = base_type.class_type->base_type; } break; @@ -2684,7 +2746,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path List<MethodInfo> signals; scr->get_script_signal_list(&signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - options.insert(quote_style + E->get().name + quote_style); + ScriptCodeCompletionOption option(quote_style + E->get().name + quote_style, ScriptCodeCompletionOption::KIND_SIGNAL); + options.insert(option.display, option); } Ref<Script> base_script = scr->get_base_script(); if (base_script.is_valid()) { @@ -2711,7 +2774,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path List<MethodInfo> signals; ClassDB::get_signal_list(class_name, &signals); for (List<MethodInfo>::Element *E = signals.front(); E; E = E->next()) { - options.insert(quote_style + E->get().name + quote_style); + ScriptCodeCompletionOption option(quote_style + E->get().name + quote_style, ScriptCodeCompletionOption::KIND_SIGNAL); + options.insert(option.display, option); } } break; default: { @@ -2748,18 +2812,21 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path c.line = E->value().expression->line; if (_guess_expression_type(c, E->value().expression, constant)) { if (constant.type.has_type && constant.type.is_meta_type) { - options.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } } for (int i = 0; i < clss->subclasses.size(); i++) { if (clss->subclasses[i]->name != StringName()) { - options.insert(clss->subclasses[i]->name.operator String()); + ScriptCodeCompletionOption option(clss->subclasses[i]->name.operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } clss = clss->owner; for (int i = 0; i < Variant::VARIANT_MAX; i++) { - options.insert(Variant::get_type_name((Variant::Type)i)); + ScriptCodeCompletionOption option(Variant::get_type_name((Variant::Type)i), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } @@ -2773,18 +2840,21 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path if (Engine::get_singleton()->has_singleton(class_name)) { continue; } - options.insert(class_name); + ScriptCodeCompletionOption option(class_name, ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } // Named scripts List<StringName> named_scripts; ScriptServer::get_global_class_list(&named_scripts); for (List<StringName>::Element *E = named_scripts.front(); E; E = E->next()) { - options.insert(E->get().operator String()); + ScriptCodeCompletionOption option(E->get().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } if (parser.get_completion_identifier_is_function()) { - options.insert("void"); + ScriptCodeCompletionOption option("void", ScriptCodeCompletionOption::KIND_PLAIN_TEXT); + options.insert(option.display, option); } r_forced = true; } break; @@ -2831,13 +2901,15 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path c2.line = E->value().expression->line; if (_guess_expression_type(c2, E->value().expression, constant)) { if (constant.type.has_type && constant.type.is_meta_type) { - options.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } } for (int i = 0; i < base_type.class_type->subclasses.size(); i++) { if (base_type.class_type->subclasses[i]->name != StringName()) { - options.insert(base_type.class_type->subclasses[i]->name.operator String()); + ScriptCodeCompletionOption option(base_type.class_type->subclasses[i]->name.operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } @@ -2855,7 +2927,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path for (Map<StringName, Variant>::Element *E = constants.front(); E; E = E->next()) { Ref<Script> const_scr = E->value(); if (const_scr.is_valid()) { - options.insert(E->key().operator String()); + ScriptCodeCompletionOption option(E->key().operator String(), ScriptCodeCompletionOption::KIND_CLASS); + options.insert(option.display, option); } } Ref<Script> base_script = scr->get_base_script(); @@ -2877,7 +2950,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path } break; } - for (Set<String>::Element *E = options.front(); E; E = E->next()) { + for (Map<String, ScriptCodeCompletionOption>::Element *E = options.front(); E; E = E->next()) { r_options->push_back(E->get()); } @@ -2886,7 +2959,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path #else -Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<String> *r_options, bool &r_forced, String &r_call_hint) { +Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint) { return OK; } diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index d5e74c07c9..42f349ffc0 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -1784,20 +1784,9 @@ GDScriptFunction::~GDScriptFunction() { Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { - if (state.instance_id && !ObjectDB::get_instance(state.instance_id)) { -#ifdef DEBUG_ENABLED - ERR_EXPLAIN("Resumed function '" + String(function->get_name()) + "()' after yield, but class instance is gone. At script: " + state.script->get_path() + ":" + itos(state.line)); - ERR_FAIL_V(Variant()); -#else - return Variant(); -#endif - } - Variant arg; r_error.error = Variant::CallError::CALL_OK; - ERR_FAIL_COND_V(!function, Variant()); - if (p_argcount == 0) { r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; @@ -1823,44 +1812,7 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar return Variant(); } - state.result = arg; - Variant ret = function->call(NULL, NULL, 0, r_error, &state); - - bool completed = true; - - // If the return value is a GDScriptFunctionState reference, - // then the function did yield again after resuming. - if (ret.is_ref()) { - GDScriptFunctionState *gdfs = Object::cast_to<GDScriptFunctionState>(ret); - if (gdfs && gdfs->function == function) { - completed = false; - gdfs->first_state = first_state.is_valid() ? first_state : Ref<GDScriptFunctionState>(this); - } - } - - function = NULL; //cleaned up; - state.result = Variant(); - - if (completed) { - if (first_state.is_valid()) { - first_state->emit_signal("completed", ret); - } else { - emit_signal("completed", ret); - } - } - -#ifdef DEBUG_ENABLED - if (ScriptDebugger::get_singleton()) - GDScriptLanguage::get_singleton()->exit_function(); - if (state.stack_size) { - //free stack - Variant *stack = (Variant *)state.stack.ptr(); - for (int i = 0; i < state.stack_size; i++) - stack[i].~Variant(); - } -#endif - - return ret; + return resume(arg); } bool GDScriptFunctionState::is_valid(bool p_extended_check) const { diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 9ab86a5459..fa430b5364 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -125,7 +125,7 @@ bool GDScriptParser::_enter_indent_block(BlockNode *p_block) { } } -bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete) { +bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete, bool p_parsing_constant) { if (tokenizer->get_token() == GDScriptTokenizer::TK_PARENTHESIS_CLOSE) { tokenizer->advance(); @@ -149,7 +149,7 @@ bool GDScriptParser::_parse_arguments(Node *p_parent, Vector<Node *> &p_args, bo return false; } - Node *arg = _parse_expression(p_parent, p_static); + Node *arg = _parse_expression(p_parent, p_static, false, p_parsing_constant); if (!arg) { return false; } @@ -639,7 +639,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s id->name = identifier; op->arguments.push_back(id); - if (!_parse_arguments(op, op->arguments, p_static, true)) + if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) return NULL; expr = op; @@ -731,7 +731,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s completion_node = op; } if (!replaced) { - if (!_parse_arguments(op, op->arguments, p_static, true)) + if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) return NULL; expr = op; } @@ -826,11 +826,12 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } // Check parents for the constant - if (!bfn && cln->extends_file != StringName()) { - Ref<GDScript> parent = ResourceLoader::load(cln->extends_file); - if (parent.is_valid() && parent->is_valid()) { + if (!bfn) { + // Using current_class instead of cln here, since cln is const* + _determine_inheritance(current_class, false); + if (cln->base_type.has_type && cln->base_type.kind == DataType::GDSCRIPT && cln->base_type.script_type->is_valid()) { Map<StringName, Variant> parent_constants; - parent->get_constants(&parent_constants); + current_class->base_type.script_type->get_constants(&parent_constants); if (parent_constants.has(identifier)) { ConstantNode *constant = alloc_node<ConstantNode>(); constant->value = parent_constants[identifier]; @@ -1112,7 +1113,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } } else { tokenizer->advance(); - if (!_parse_arguments(op, op->arguments, p_static)) { + if (!_parse_arguments(op, op->arguments, p_static, false, p_parsing_constant)) { return NULL; } } @@ -1164,22 +1165,14 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s tokenizer->advance(); IdentifierNode *id = alloc_node<IdentifierNode>(); - if (tokenizer->get_token() == GDScriptTokenizer::TK_BUILT_IN_FUNC) { - //small hack so built in funcs don't obfuscate methods - - id->name = GDScriptFunctions::get_func_name(tokenizer->get_token_built_in_func()); - tokenizer->advance(); - - } else { - StringName identifier; - if (_get_completable_identifier(COMPLETION_METHOD, identifier)) { - completion_node = op; - //indexing stuff - } - - id->name = identifier; + StringName identifier; + if (_get_completable_identifier(COMPLETION_METHOD, identifier)) { + completion_node = op; + //indexing stuff } + id->name = identifier; + op->arguments.push_back(expr); // call what op->arguments.push_back(id); // call func //get arguments @@ -1188,7 +1181,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s _make_completable_call(0); completion_node = op; } - if (!_parse_arguments(op, op->arguments, p_static, true)) + if (!_parse_arguments(op, op->arguments, p_static, true, p_parsing_constant)) return NULL; expr = op; @@ -2218,6 +2211,8 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran p_block->has_return = true; + bool catch_all_appeared = false; + while (true) { while (tokenizer->get_token() == GDScriptTokenizer::TK_NEWLINE && _parse_newline()) @@ -2228,7 +2223,7 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran return; if (indent_level > tab_level.back()->get()) { - return; // go back a level + break; // go back a level } if (pending_newline != -1) { @@ -2243,12 +2238,20 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran branch->patterns.push_back(_parse_pattern(p_static)); if (!branch->patterns[0]) { - return; + break; } bool has_binding = branch->patterns[0]->pt_type == PatternNode::PT_BIND; bool catch_all = has_binding || branch->patterns[0]->pt_type == PatternNode::PT_WILDCARD; +#ifdef DEBUG_ENABLED + // Branches after a wildcard or binding are unreachable + if (catch_all_appeared && !current_function->has_unreachable_code) { + _add_warning(GDScriptWarning::UNREACHABLE_CODE, -1, current_function->name.operator String()); + current_function->has_unreachable_code = true; + } +#endif + while (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); branch->patterns.push_back(_parse_pattern(p_static)); @@ -2266,6 +2269,8 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran catch_all = catch_all || pt == PatternNode::PT_WILDCARD; } + catch_all_appeared = catch_all_appeared || catch_all; + if (!_enter_indent_block()) { _set_error("Expected block in pattern branch"); return; @@ -2281,6 +2286,11 @@ void GDScriptParser::_parse_pattern_block(BlockNode *p_block, Vector<PatternBran p_branches.push_back(branch); } + + // Even if all branches return, there is possibility of default fallthrough + if (!catch_all_appeared) { + p_block->has_return = false; + } } void GDScriptParser::_generate_pattern(PatternNode *p_pattern, Node *p_node_to_match, Node *&p_resulting_node, Map<StringName, Node *> &p_bindings) { @@ -5084,6 +5094,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { if (tokenizer->get_token() == GDScriptTokenizer::TK_COMMA) { tokenizer->advance(); + } else if (tokenizer->is_token_literal(0, true)) { + _set_error("Unexpected identifier"); + return; } if (enum_name != "") { @@ -5158,9 +5171,11 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } } -void GDScriptParser::_determine_inheritance(ClassNode *p_class) { +void GDScriptParser::_determine_inheritance(ClassNode *p_class, bool p_recursive) { - if (p_class->extends_used) { + if (p_class->base_type.has_type) { + // Already determined + } else if (p_class->extends_used) { //do inheritance String path = p_class->extends_file; @@ -5355,9 +5370,11 @@ void GDScriptParser::_determine_inheritance(ClassNode *p_class) { p_class->base_type.native_type = "Reference"; } - // Recursively determine subclasses - for (int i = 0; i < p_class->subclasses.size(); i++) { - _determine_inheritance(p_class->subclasses[i]); + if (p_recursive) { + // Recursively determine subclasses + for (int i = 0; i < p_class->subclasses.size(); i++) { + _determine_inheritance(p_class->subclasses[i], p_recursive); + } } } diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index 5e4de11357..62d7bdb393 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -582,7 +582,7 @@ private: #endif // DEBUG_ENABLED bool _recover_from_completion(); - bool _parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete = false); + bool _parse_arguments(Node *p_parent, Vector<Node *> &p_args, bool p_static, bool p_can_codecomplete = false, bool p_parsing_constant = false); bool _enter_indent_block(BlockNode *p_block = NULL); bool _parse_newline(); Node *_parse_expression(Node *p_parent, bool p_static, bool p_allow_assign = false, bool p_parsing_constant = false); @@ -599,7 +599,7 @@ private: void _parse_class(ClassNode *p_class); bool _end_statement(); - void _determine_inheritance(ClassNode *p_class); + void _determine_inheritance(ClassNode *p_class, bool p_recursive = true); bool _parse_type(DataType &r_type, bool p_can_be_void = false); DataType _resolve_type(const DataType &p_source, int p_line); DataType _type_from_variant(const Variant &p_value) const; diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml index 325432579f..1bd3d72066 100644 --- a/modules/gridmap/doc_classes/GridMap.xml +++ b/modules/gridmap/doc_classes/GridMap.xml @@ -210,7 +210,7 @@ </member> <member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" default="1"> </member> - <member name="mesh_library" type="MeshLibrary" setter="set_mesh_library" getter="get_mesh_library" default="null"> + <member name="mesh_library" type="MeshLibrary" setter="set_mesh_library" getter="get_mesh_library"> The assigned [MeshLibrary]. </member> <member name="theme" type="MeshLibrary" setter="set_theme" getter="get_theme"> diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp index 20e454c218..5a21833ffa 100644 --- a/modules/gridmap/grid_map_editor_plugin.cpp +++ b/modules/gridmap/grid_map_editor_plugin.cpp @@ -345,7 +345,7 @@ void GridMapEditor::_validate_selection() { _update_selection_transform(); } -void GridMapEditor::_set_selection(bool p_active, const Vector3 p_begin, const Vector3 p_end) { +void GridMapEditor::_set_selection(bool p_active, const Vector3 &p_begin, const Vector3 &p_end) { selection.active = p_active; selection.begin = p_begin; @@ -578,7 +578,7 @@ void GridMapEditor::_update_paste_indicator() { return; } - Vector3 center = 0.5 * Vector3(node->get_center_x(), node->get_center_y(), node->get_center_z()); + Vector3 center = 0.5 * Vector3(float(node->get_center_x()), float(node->get_center_y()), float(node->get_center_z())); Vector3 scale = (Vector3(1, 1, 1) + (paste_indicator.end - paste_indicator.begin)) * node->get_cell_size(); Transform xf; xf.scale(scale); diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h index da36165d4e..b9be925ff7 100644 --- a/modules/gridmap/grid_map_editor_plugin.h +++ b/modules/gridmap/grid_map_editor_plugin.h @@ -222,7 +222,7 @@ class GridMapEditor : public VBoxContainer { void _do_paste(); void _update_selection_transform(); void _validate_selection(); - void _set_selection(bool p_active, const Vector3 p_begin = Vector3(), const Vector3 p_end = Vector3()); + void _set_selection(bool p_active, const Vector3 &p_begin = Vector3(), const Vector3 &p_end = Vector3()); void _floor_changed(float p_value); void _floor_mouse_exited(); diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp index 5493223cb0..dcd8b8aebd 100644 --- a/modules/jpg/image_loader_jpegd.cpp +++ b/modules/jpg/image_loader_jpegd.cpp @@ -96,7 +96,7 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p else fmt = Image::FORMAT_RGB8; - dw = PoolVector<uint8_t>::Write(); + dw.release(); p_image->create(image_width, image_height, 0, fmt, data); return OK; @@ -117,8 +117,6 @@ Error ImageLoaderJPG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force Error err = jpeg_load_image_from_buffer(p_image.ptr(), w.ptr(), src_image_len); - w = PoolVector<uint8_t>::Write(); - return err; } diff --git a/modules/mbedtls/stream_peer_mbed_tls.cpp b/modules/mbedtls/stream_peer_mbed_tls.cpp index 3541eff25a..4bb7557150 100755 --- a/modules/mbedtls/stream_peer_mbed_tls.cpp +++ b/modules/mbedtls/stream_peer_mbed_tls.cpp @@ -33,8 +33,6 @@ #include "core/io/stream_peer_tcp.h" #include "core/os/file_access.h" -#include <mbedtls/platform_util.h> - static void my_debug(void *ctx, int level, const char *file, int line, const char *str) { diff --git a/modules/mbedtls/stream_peer_mbed_tls.h b/modules/mbedtls/stream_peer_mbed_tls.h index 3ddbea3ce4..ab87b779c1 100755 --- a/modules/mbedtls/stream_peer_mbed_tls.h +++ b/modules/mbedtls/stream_peer_mbed_tls.h @@ -37,7 +37,6 @@ #include <mbedtls/ctr_drbg.h> #include <mbedtls/debug.h> #include <mbedtls/entropy.h> -#include <mbedtls/net.h> #include <mbedtls/ssl.h> #include <stdio.h> diff --git a/modules/mono/SCsub b/modules/mono/SCsub index 6c3ecee272..cc60e64a11 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -1,5 +1,8 @@ #!/usr/bin/env python +import build_scripts.tls_configure as tls_configure +import build_scripts.mono_configure as mono_configure + Import('env') Import('env_modules') @@ -26,27 +29,36 @@ if env_mono['mono_glue']: import os.path if not os.path.isfile('glue/mono_glue.gen.cpp'): - raise RuntimeError('Missing mono glue sources. Did you forget to generate them?') + raise RuntimeError("Mono glue sources not found. Did you forget to run '--generate-mono-glue'?") if env_mono['tools'] or env_mono['target'] != 'release': env_mono.Append(CPPDEFINES=['GD_MONO_HOT_RELOAD']) # Configure Thread Local Storage -import build_scripts.tls_configure as tls_configure - conf = Configure(env_mono) tls_configure.configure(conf) env_mono = conf.Finish() # Configure Mono -import build_scripts.mono_configure as mono_configure - mono_configure.configure(env, env_mono) -# Build GodotSharpTools +# Build Godot API solution + +if env_mono['tools'] and env_mono['mono_glue']: + import build_scripts.api_solution_build as api_solution_build + api_solution_build.build(env_mono) -import build_scripts.godotsharptools_build as godotsharptools_build +# Build GodotTools -godotsharptools_build.build(env_mono) +if env_mono['tools']: + import build_scripts.godot_tools_build as godot_tools_build + if env_mono['mono_glue']: + godot_tools_build.build(env_mono) + else: + # Building without the glue sources so the Godot API solution may be missing. + # GodotTools depends on the Godot API solution. As such, we will only build + # GodotTools.ProjectEditor which doesn't depend on the Godot API solution and + # is required by the bindings generator in order to be able to generated it. + godot_tools_build.build_project_editor_only(env_mono) diff --git a/modules/mono/__init__.py b/modules/mono/__init__.py new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/modules/mono/__init__.py diff --git a/modules/mono/build_scripts/api_solution_build.py b/modules/mono/build_scripts/api_solution_build.py new file mode 100644 index 0000000000..1fe00a3028 --- /dev/null +++ b/modules/mono/build_scripts/api_solution_build.py @@ -0,0 +1,66 @@ +# Build the Godot API solution + +import os + +from SCons.Script import Dir + + +def build_api_solution(source, target, env): + # source and target elements are of type SCons.Node.FS.File, hence why we convert them to str + + module_dir = env['module_dir'] + + solution_path = os.path.join(module_dir, 'glue/Managed/Generated/GodotSharp.sln') + + if not os.path.isfile(solution_path): + raise RuntimeError("Godot API solution not found. Did you forget to run '--generate-mono-glue'?") + + build_config = env['solution_build_config'] + + extra_msbuild_args = ['/p:NoWarn=1591'] # Ignore missing documentation warnings + + from .solution_builder import build_solution + build_solution(env, solution_path, build_config, extra_msbuild_args=extra_msbuild_args) + + # Copy targets + + core_src_dir = os.path.abspath(os.path.join(solution_path, os.pardir, 'GodotSharp', 'bin', build_config)) + editor_src_dir = os.path.abspath(os.path.join(solution_path, os.pardir, 'GodotSharpEditor', 'bin', build_config)) + + dst_dir = os.path.abspath(os.path.join(str(target[0]), os.pardir)) + + if not os.path.isdir(dst_dir): + assert not os.path.isfile(dst_dir) + os.makedirs(dst_dir) + + def copy_target(target_path): + from shutil import copy + filename = os.path.basename(target_path) + + src_path = os.path.join(core_src_dir, filename) + if not os.path.isfile(src_path): + src_path = os.path.join(editor_src_dir, filename) + + copy(src_path, target_path) + + for scons_target in target: + copy_target(str(scons_target)) + + +def build(env_mono): + assert env_mono['tools'] + + target_filenames = [ + 'GodotSharp.dll', 'GodotSharp.pdb', 'GodotSharp.xml', + 'GodotSharpEditor.dll', 'GodotSharpEditor.pdb', 'GodotSharpEditor.xml' + ] + + for build_config in ['Debug', 'Release']: + output_dir = Dir('#bin').abspath + editor_api_dir = os.path.join(output_dir, 'GodotSharp', 'Api', build_config) + + targets = [os.path.join(editor_api_dir, filename) for filename in target_filenames] + + cmd = env_mono.CommandNoCache(targets, [], build_api_solution, + module_dir=os.getcwd(), solution_build_config=build_config) + env_mono.AlwaysBuild(cmd) diff --git a/modules/mono/build_scripts/godot_tools_build.py b/modules/mono/build_scripts/godot_tools_build.py new file mode 100644 index 0000000000..c47cfc8a38 --- /dev/null +++ b/modules/mono/build_scripts/godot_tools_build.py @@ -0,0 +1,112 @@ +# Build GodotTools solution + +import os + +from SCons.Script import Dir + + +def build_godot_tools(source, target, env): + # source and target elements are of type SCons.Node.FS.File, hence why we convert them to str + + module_dir = env['module_dir'] + + solution_path = os.path.join(module_dir, 'editor/GodotTools/GodotTools.sln') + build_config = 'Debug' if env['target'] == 'debug' else 'Release' + + from . solution_builder import build_solution, nuget_restore + nuget_restore(env, solution_path) + build_solution(env, solution_path, build_config) + + # Copy targets + + solution_dir = os.path.abspath(os.path.join(solution_path, os.pardir)) + + src_dir = os.path.join(solution_dir, 'GodotTools', 'bin', build_config) + dst_dir = os.path.abspath(os.path.join(str(target[0]), os.pardir)) + + if not os.path.isdir(dst_dir): + assert not os.path.isfile(dst_dir) + os.makedirs(dst_dir) + + def copy_target(target_path): + from shutil import copy + filename = os.path.basename(target_path) + copy(os.path.join(src_dir, filename), target_path) + + for scons_target in target: + copy_target(str(scons_target)) + + +def build_godot_tools_project_editor(source, target, env): + # source and target elements are of type SCons.Node.FS.File, hence why we convert them to str + + module_dir = env['module_dir'] + + project_name = 'GodotTools.ProjectEditor' + + csproj_dir = os.path.join(module_dir, 'editor/GodotTools', project_name) + csproj_path = os.path.join(csproj_dir, project_name + '.csproj') + build_config = 'Debug' if env['target'] == 'debug' else 'Release' + + from . solution_builder import build_solution, nuget_restore + + # Make sure to restore NuGet packages in the project directory for the project to find it + nuget_restore(env, os.path.join(csproj_dir, 'packages.config'), '-PackagesDirectory', + os.path.join(csproj_dir, 'packages')) + + build_solution(env, csproj_path, build_config) + + # Copy targets + + src_dir = os.path.join(csproj_dir, 'bin', build_config) + dst_dir = os.path.abspath(os.path.join(str(target[0]), os.pardir)) + + if not os.path.isdir(dst_dir): + assert not os.path.isfile(dst_dir) + os.makedirs(dst_dir) + + def copy_target(target_path): + from shutil import copy + filename = os.path.basename(target_path) + copy(os.path.join(src_dir, filename), target_path) + + for scons_target in target: + copy_target(str(scons_target)) + + +def build(env_mono): + assert env_mono['tools'] + + output_dir = Dir('#bin').abspath + editor_tools_dir = os.path.join(output_dir, 'GodotSharp', 'Tools') + editor_api_dir = os.path.join(output_dir, 'GodotSharp', 'Api', 'Debug') + + source_filenames = ['GodotSharp.dll', 'GodotSharpEditor.dll'] + sources = [os.path.join(editor_api_dir, filename) for filename in source_filenames] + + target_filenames = ['GodotTools.dll', 'GodotTools.BuildLogger.dll', 'GodotTools.ProjectEditor.dll', 'DotNet.Glob.dll', 'GodotTools.Core.dll'] + + if env_mono['target'] == 'debug': + target_filenames += ['GodotTools.pdb', 'GodotTools.BuildLogger.pdb', 'GodotTools.ProjectEditor.pdb', 'GodotTools.Core.pdb'] + + targets = [os.path.join(editor_tools_dir, filename) for filename in target_filenames] + + cmd = env_mono.CommandNoCache(targets, sources, build_godot_tools, module_dir=os.getcwd()) + env_mono.AlwaysBuild(cmd) + + +def build_project_editor_only(env_mono): + assert env_mono['tools'] + + output_dir = Dir('#bin').abspath + editor_tools_dir = os.path.join(output_dir, 'GodotSharp', 'Tools') + + target_filenames = ['GodotTools.ProjectEditor.dll', 'DotNet.Glob.dll', 'GodotTools.Core.dll'] + + if env_mono['target'] == 'debug': + target_filenames += ['GodotTools.ProjectEditor.pdb', 'GodotTools.Core.pdb'] + + targets = [os.path.join(editor_tools_dir, filename) for filename in target_filenames] + + cmd = env_mono.CommandNoCache(targets, [], build_godot_tools_project_editor, module_dir=os.getcwd()) + env_mono.AlwaysBuild(cmd) diff --git a/modules/mono/build_scripts/make_android_mono_config.py b/modules/mono/build_scripts/make_android_mono_config.py new file mode 100644 index 0000000000..cd9210897d --- /dev/null +++ b/modules/mono/build_scripts/make_android_mono_config.py @@ -0,0 +1,69 @@ + +def generate_compressed_config(config_src, output_dir): + import os.path + from compat import byte_to_str + + # Header file + with open(os.path.join(output_dir, 'android_mono_config.gen.h'), 'w') as header: + header.write('''/* THIS FILE IS GENERATED DO NOT EDIT */ +#ifndef ANDROID_MONO_CONFIG_GEN_H +#define ANDROID_MONO_CONFIG_GEN_H + +#ifdef ANDROID_ENABLED + +#include "core/ustring.h" + +String get_godot_android_mono_config(); + +#endif // ANDROID_ENABLED + +#endif // ANDROID_MONO_CONFIG_GEN_H +''') + + # Source file + with open(os.path.join(output_dir, 'android_mono_config.gen.cpp'), 'w') as cpp: + with open(config_src, 'rb') as f: + buf = f.read() + decompr_size = len(buf) + import zlib + buf = zlib.compress(buf) + compr_size = len(buf) + + bytes_seq_str = '' + for i, buf_idx in enumerate(range(compr_size)): + if i > 0: + bytes_seq_str += ', ' + bytes_seq_str += byte_to_str(buf[buf_idx]) + + cpp.write('''/* THIS FILE IS GENERATED DO NOT EDIT */ +#include "android_mono_config.gen.h" + +#ifdef ANDROID_ENABLED + +#include "core/io/compression.h" +#include "core/pool_vector.h" + +namespace { + +// config +static const int config_compressed_size = %d; +static const int config_uncompressed_size = %d; +static const unsigned char config_compressed_data[] = { %s }; + +} // namespace + +String get_godot_android_mono_config() { + PoolVector<uint8_t> data; + data.resize(config_uncompressed_size); + PoolVector<uint8_t>::Write w = data.write(); + Compression::decompress(w.ptr(), config_uncompressed_size, config_compressed_data, + config_compressed_size, Compression::MODE_DEFLATE); + String s; + if (s.parse_utf8((const char *)w.ptr(), data.size())) { + ERR_FAIL_V(String()); + } + return s; +} + +#endif // ANDROID_ENABLED +''' % (compr_size, decompr_size, bytes_seq_str)) diff --git a/modules/mono/build_scripts/make_cs_compressed_header.py b/modules/mono/build_scripts/make_cs_compressed_header.py index 1f9177cef8..ed49db5bb2 100644 --- a/modules/mono/build_scripts/make_cs_compressed_header.py +++ b/modules/mono/build_scripts/make_cs_compressed_header.py @@ -23,30 +23,31 @@ def generate_header(src, dst, version_dst): latest_mtime = mtime if mtime > latest_mtime else latest_mtime with open(filepath, 'rb') as f: buf = f.read() - decomp_size = len(buf) + decompr_size = len(buf) import zlib buf = zlib.compress(buf) + compr_size = len(buf) name = str(cs_file_count) header.write('\n') header.write('// ' + filepath_src_rel + '\n') - header.write('static const int _cs_' + name + '_compressed_size = ' + str(len(buf)) + ';\n') - header.write('static const int _cs_' + name + '_uncompressed_size = ' + str(decomp_size) + ';\n') + header.write('static const int _cs_' + name + '_compressed_size = ' + str(compr_size) + ';\n') + header.write('static const int _cs_' + name + '_uncompressed_size = ' + str(decompr_size) + ';\n') header.write('static const unsigned char _cs_' + name + '_compressed[] = { ') - for i, buf_idx in enumerate(range(len(buf))): + for i, buf_idx in enumerate(range(compr_size)): if i > 0: header.write(', ') header.write(byte_to_str(buf[buf_idx])) + header.write(' };\n') inserted_files += '\tr_files.insert("' + filepath_src_rel.replace('\\', '\\\\') + '", ' \ - 'CompressedFile(_cs_' + name + '_compressed_size, ' \ + 'GodotCsCompressedFile(_cs_' + name + '_compressed_size, ' \ '_cs_' + name + '_uncompressed_size, ' \ '_cs_' + name + '_compressed));\n' - header.write(' };\n') - header.write('\nstruct CompressedFile\n' '{\n' + header.write('\nstruct GodotCsCompressedFile\n' '{\n' '\tint compressed_size;\n' '\tint uncompressed_size;\n' '\tconst unsigned char* data;\n' - '\n\tCompressedFile(int p_comp_size, int p_uncomp_size, const unsigned char* p_data)\n' + '\n\tGodotCsCompressedFile(int p_comp_size, int p_uncomp_size, const unsigned char* p_data)\n' '\t{\n' '\t\tcompressed_size = p_comp_size;\n' '\t\tuncompressed_size = p_uncomp_size;\n' - '\t\tdata = p_data;\n' '\t}\n' '\n\tCompressedFile() {}\n' '};\n' - '\nvoid get_compressed_files(Map<String, CompressedFile>& r_files)\n' '{\n' + inserted_files + '}\n' + '\t\tdata = p_data;\n' '\t}\n' '\n\tGodotCsCompressedFile() {}\n' '};\n' + '\nvoid get_compressed_files(Map<String, GodotCsCompressedFile>& r_files)\n' '{\n' + inserted_files + '}\n' ) header.write('\n#endif // TOOLS_ENABLED\n') header.write('\n#endif // CS_COMPRESSED_H\n') diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index c549640d61..9f0eb58896 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -1,10 +1,8 @@ -import imp import os import os.path import sys import subprocess -from distutils.version import LooseVersion from SCons.Script import Dir, Environment if os.name == 'nt': @@ -41,7 +39,7 @@ def copy_file(src_dir, dst_dir, name): dst_dir = Dir(dst_dir).abspath if not os.path.isdir(dst_dir): - os.mkdir(dst_dir) + os.makedirs(dst_dir) copy(src_path, dst_dir) @@ -58,6 +56,12 @@ def configure(env, env_mono): mono_lib_names = ['mono-2.0-sgen', 'monosgen-2.0'] + is_travis = os.environ.get('TRAVIS') == 'true' + + if is_travis: + # Travis CI may have a Mono version lower than 5.12 + env_mono.Append(CPPDEFINES=['NO_PENDING_EXCEPTIONS']) + if is_android and not env['android_arch'] in android_arch_dirs: raise RuntimeError('This module does not support for the specified \'android_arch\': ' + env['android_arch']) @@ -65,6 +69,10 @@ def configure(env, env_mono): # TODO: Implement this. We have to add the data directory to the apk, concretely the Api and Tools folders. raise RuntimeError('This module does not currently support building for android with tools enabled') + if is_android and mono_static: + # When static linking and doing something that requires libmono-native, we get a dlopen error as libmono-native seems to depend on libmonosgen-2.0 + raise RuntimeError('Linking Mono statically is not currently supported on Android') + if (os.getenv('MONO32_PREFIX') or os.getenv('MONO64_PREFIX')) and not mono_prefix: print("WARNING: The environment variables 'MONO32_PREFIX' and 'MONO64_PREFIX' are deprecated; use the 'mono_prefix' SCons parameter instead") @@ -79,9 +87,6 @@ def configure(env, env_mono): print('Found Mono root directory: ' + mono_root) - mono_version = mono_root_try_find_mono_version(mono_root) - configure_for_mono_version(env_mono, mono_version) - mono_lib_path = os.path.join(mono_root, 'lib') env.Append(LIBPATH=mono_lib_path) @@ -160,9 +165,6 @@ def configure(env, env_mono): if mono_root: print('Found Mono root directory: ' + mono_root) - mono_version = mono_root_try_find_mono_version(mono_root) - configure_for_mono_version(env_mono, mono_version) - mono_lib_path = os.path.join(mono_root, 'lib') env.Append(LIBPATH=mono_lib_path) @@ -173,7 +175,7 @@ def configure(env, env_mono): if not mono_lib: raise RuntimeError('Could not find mono library in: ' + mono_lib_path) - env_mono.Append(CPPFLAGS=['-D_REENTRANT']) + env_mono.Append(CPPDEFINES=['_REENTRANT']) if mono_static: mono_lib_file = os.path.join(mono_lib_path, 'lib' + mono_lib + '.a') @@ -188,7 +190,7 @@ def configure(env, env_mono): if is_apple: env.Append(LIBS=['iconv', 'pthread']) elif is_android: - env.Append(LIBS=['m', 'dl']) + pass # Nothing else: env.Append(LIBS=['m', 'rt', 'dl', 'pthread']) @@ -205,9 +207,6 @@ def configure(env, env_mono): # TODO: Add option to force using pkg-config print('Mono root directory not found. Using pkg-config instead') - mono_version = pkgconfig_try_find_mono_version() - configure_for_mono_version(env_mono, mono_version) - env.ParseConfig('pkg-config monosgen-2 --libs') env_mono.ParseConfig('pkg-config monosgen-2 --cflags') @@ -236,6 +235,14 @@ def configure(env, env_mono): mono_root = subprocess.check_output(['pkg-config', 'mono-2', '--variable=prefix']).decode('utf8').strip() make_template_dir(env, mono_root) + elif not tools_enabled and is_android: + # Compress Android Mono Config + from . import make_android_mono_config + config_file_path = os.path.join(mono_root, 'etc', 'mono', 'config') + make_android_mono_config.generate_compressed_config(config_file_path, 'mono_gd/') + + # Copy the required shared libraries + copy_mono_shared_libs(env, mono_root, None) if copy_mono_root: if not mono_root: @@ -270,9 +277,8 @@ def make_template_dir(env, mono_root): # Copy etc/mono/ - if platform != 'android': - template_mono_config_dir = os.path.join(template_mono_root_dir, 'etc', 'mono') - copy_mono_etc_dir(mono_root, template_mono_config_dir, env['platform']) + template_mono_config_dir = os.path.join(template_mono_root_dir, 'etc', 'mono') + copy_mono_etc_dir(mono_root, template_mono_config_dir, env['platform']) # Copy the required shared libraries @@ -390,17 +396,6 @@ def copy_mono_shared_libs(env, mono_root, target_mono_root_dir): copy_if_exists(os.path.join(mono_root, 'lib', lib_file_name), target_mono_lib_dir) -def configure_for_mono_version(env, mono_version): - if mono_version is None: - if os.getenv('MONO_VERSION'): - mono_version = os.getenv('MONO_VERSION') - else: - raise RuntimeError("Mono JIT compiler version not found; specify one manually with the 'MONO_VERSION' environment variable") - print('Found Mono JIT compiler version: ' + str(mono_version)) - if mono_version >= LooseVersion('5.12.0'): - env.Append(CPPFLAGS=['-DHAS_PENDING_EXCEPTIONS']) - - def pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext): tmpenv = Environment() tmpenv.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH')) @@ -410,36 +405,3 @@ def pkgconfig_try_find_mono_root(mono_lib_names, sharedlib_ext): if name_found and os.path.isdir(os.path.join(hint_dir, '..', 'include', 'mono-2.0')): return os.path.join(hint_dir, '..') return '' - - -def pkgconfig_try_find_mono_version(): - from compat import decode_utf8 - - lines = subprocess.check_output(['pkg-config', 'monosgen-2', '--modversion']).splitlines() - greater_version = None - for line in lines: - try: - version = LooseVersion(decode_utf8(line)) - if greater_version is None or version > greater_version: - greater_version = version - except ValueError: - pass - return greater_version - - -def mono_root_try_find_mono_version(mono_root): - from compat import decode_utf8 - - mono_bin = os.path.join(mono_root, 'bin') - if os.path.isfile(os.path.join(mono_bin, 'mono')): - mono_binary = os.path.join(mono_bin, 'mono') - elif os.path.isfile(os.path.join(mono_bin, 'mono.exe')): - mono_binary = os.path.join(mono_bin, 'mono.exe') - else: - return None - output = subprocess.check_output([mono_binary, '--version']) - first_line = decode_utf8(output.splitlines()[0]) - try: - return LooseVersion(first_line.split()[len('Mono JIT compiler version'.split())]) - except (ValueError, IndexError): - return None diff --git a/modules/mono/build_scripts/mono_reg_utils.py b/modules/mono/build_scripts/mono_reg_utils.py index 583708bf07..b2c48f0a61 100644 --- a/modules/mono/build_scripts/mono_reg_utils.py +++ b/modules/mono/build_scripts/mono_reg_utils.py @@ -116,5 +116,3 @@ def find_msbuild_tools_path_reg(): return value except (WindowsError, OSError): return '' - - return '' diff --git a/modules/mono/build_scripts/godotsharptools_build.py b/modules/mono/build_scripts/solution_builder.py index 17f9a990af..d1529a64d2 100644 --- a/modules/mono/build_scripts/godotsharptools_build.py +++ b/modules/mono/build_scripts/solution_builder.py @@ -1,8 +1,8 @@ -# Build GodotSharpTools solution import os -from SCons.Script import Builder, Dir + +verbose = False def find_nuget_unix(): @@ -108,10 +108,14 @@ def find_msbuild_windows(env): if not mono_root: raise RuntimeError('Cannot find mono root directory') - framework_path = os.path.join(mono_root, 'lib', 'mono', '4.5') mono_bin_dir = os.path.join(mono_root, 'bin') msbuild_mono = os.path.join(mono_bin_dir, 'msbuild.bat') + msbuild_tools_path = find_msbuild_tools_path_reg() + + if msbuild_tools_path: + return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), {}) + if os.path.isfile(msbuild_mono): # The (Csc/Vbc/Fsc)ToolExe environment variables are required when # building with Mono's MSBuild. They must point to the batch files @@ -121,24 +125,52 @@ def find_msbuild_windows(env): 'VbcToolExe': os.path.join(mono_bin_dir, 'vbc.bat'), 'FscToolExe': os.path.join(mono_bin_dir, 'fsharpc.bat') } - return (msbuild_mono, framework_path, mono_msbuild_env) + return (msbuild_mono, mono_msbuild_env) - msbuild_tools_path = find_msbuild_tools_path_reg() + return None - if msbuild_tools_path: - return (os.path.join(msbuild_tools_path, 'MSBuild.exe'), framework_path, {}) - return None +def run_command(command, args, env_override=None, name=None): + def cmd_args_to_str(cmd_args): + return ' '.join([arg if not ' ' in arg else '"%s"' % arg for arg in cmd_args]) + args = [command] + args + + if name is None: + name = os.path.basename(command) + + if verbose: + print("Running '%s': %s" % (name, cmd_args_to_str(args))) -def mono_build_solution(source, target, env): import subprocess - from shutil import copyfile + try: + if env_override is None: + subprocess.check_call(args) + else: + subprocess.check_call(args, env=env_override) + except subprocess.CalledProcessError as e: + raise RuntimeError("'%s' exited with error code: %s" % (name, e.returncode)) + + +def nuget_restore(env, *args): + global verbose + verbose = env['verbose'] + + # Find NuGet + nuget_path = find_nuget_windows(env) if os.name == 'nt' else find_nuget_unix() + if nuget_path is None: + raise RuntimeError('Cannot find NuGet executable') + + print('NuGet path: ' + nuget_path) + + # Do NuGet restore + run_command(nuget_path, ['restore'] + list(args), name='nuget restore') - sln_path = os.path.abspath(str(source[0])) - target_path = os.path.abspath(str(target[0])) - framework_path = '' +def build_solution(env, solution_path, build_config, extra_msbuild_args=[]): + global verbose + verbose = env['verbose'] + msbuild_env = os.environ.copy() # Needed when running from Developer Command Prompt for VS @@ -151,8 +183,7 @@ def mono_build_solution(source, target, env): if msbuild_info is None: raise RuntimeError('Cannot find MSBuild executable') msbuild_path = msbuild_info[0] - framework_path = msbuild_info[1] - msbuild_env.update(msbuild_info[2]) + msbuild_env.update(msbuild_info[1]) else: msbuild_path = find_msbuild_unix('msbuild') if msbuild_path is None: @@ -175,64 +206,9 @@ def mono_build_solution(source, target, env): print('MSBuild path: ' + msbuild_path) - # Find NuGet - nuget_path = find_nuget_windows(env) if os.name == 'nt' else find_nuget_unix() - if nuget_path is None: - raise RuntimeError('Cannot find NuGet executable') - - print('NuGet path: ' + nuget_path) - - # Do NuGet restore - - try: - subprocess.check_call([nuget_path, 'restore', sln_path]) - except subprocess.CalledProcessError: - raise RuntimeError('GodotSharpTools: NuGet restore failed') - # Build solution - build_config = 'Release' - - msbuild_args = [ - msbuild_path, - sln_path, - '/p:Configuration=' + build_config, - ] - - if framework_path: - msbuild_args += ['/p:FrameworkPathOverride=' + framework_path] - - try: - subprocess.check_call(msbuild_args, env=msbuild_env) - except subprocess.CalledProcessError: - raise RuntimeError('GodotSharpTools: Build failed') - - # Copy files - - src_dir = os.path.abspath(os.path.join(sln_path, os.pardir, 'bin', build_config)) - dst_dir = os.path.abspath(os.path.join(target_path, os.pardir)) - asm_file = 'GodotSharpTools.dll' - - if not os.path.isdir(dst_dir): - if os.path.exists(dst_dir): - raise RuntimeError('Target directory is a file') - os.makedirs(dst_dir) - - copyfile(os.path.join(src_dir, asm_file), os.path.join(dst_dir, asm_file)) - - # Dependencies - copyfile(os.path.join(src_dir, "DotNet.Glob.dll"), os.path.join(dst_dir, "DotNet.Glob.dll")) - -def build(env_mono): - if not env_mono['tools']: - return - - output_dir = Dir('#bin').abspath - editor_tools_dir = os.path.join(output_dir, 'GodotSharp', 'Tools') + msbuild_args = [solution_path, '/p:Configuration=' + build_config] + msbuild_args += extra_msbuild_args - mono_sln_builder = Builder(action=mono_build_solution) - env_mono.Append(BUILDERS={'MonoBuildSolution': mono_sln_builder}) - env_mono.MonoBuildSolution( - os.path.join(editor_tools_dir, 'GodotSharpTools.dll'), - 'editor/GodotSharpTools/GodotSharpTools.sln' - ) + run_command(msbuild_path, msbuild_args, env_override=msbuild_env, name='msbuild') diff --git a/modules/mono/class_db_api_json.cpp b/modules/mono/class_db_api_json.cpp new file mode 100644 index 0000000000..71ccdb7aab --- /dev/null +++ b/modules/mono/class_db_api_json.cpp @@ -0,0 +1,242 @@ +/*************************************************************************/ +/* class_db_api_json.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 "class_db_api_json.h" + +#include "core/io/json.h" +#include "core/os/file_access.h" +#include "core/project_settings.h" +#include "core/version.h" + +void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) { + Dictionary classes_dict; + + List<StringName> names; + + const StringName *k = NULL; + + while ((k = ClassDB::classes.next(k))) { + + names.push_back(*k); + } + //must be alphabetically sorted for hash to compute + names.sort_custom<StringName::AlphCompare>(); + + for (List<StringName>::Element *E = names.front(); E; E = E->next()) { + + ClassDB::ClassInfo *t = ClassDB::classes.getptr(E->get()); + ERR_FAIL_COND(!t); + if (t->api != p_api || !t->exposed) + continue; + + Dictionary class_dict; + classes_dict[t->name] = class_dict; + + class_dict["inherits"] = t->inherits; + + { //methods + + List<StringName> snames; + + k = NULL; + + while ((k = t->method_map.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + Array methods; + + for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { + Dictionary method_dict; + methods.push_back(method_dict); + + MethodBind *mb = t->method_map[F->get()]; + method_dict["name"] = mb->get_name(); + method_dict["argument_count"] = mb->get_argument_count(); + method_dict["return_type"] = mb->get_argument_type(-1); + + Array arguments; + method_dict["arguments"] = arguments; + + for (int i = 0; i < mb->get_argument_count(); i++) { + Dictionary argument_dict; + arguments.push_back(argument_dict); + const PropertyInfo info = mb->get_argument_info(i); + argument_dict["type"] = info.type; + argument_dict["name"] = info.name; + argument_dict["hint"] = info.hint; + argument_dict["hint_string"] = info.hint_string; + } + + method_dict["default_argument_count"] = mb->get_default_argument_count(); + + Array default_arguments; + method_dict["default_arguments"] = default_arguments; + + for (int i = 0; i < mb->get_default_argument_count(); i++) { + Dictionary default_argument_dict; + default_arguments.push_back(default_argument_dict); + //hash should not change, i hope for tis + Variant da = mb->get_default_argument(i); + default_argument_dict["value"] = da; + } + + method_dict["hint_flags"] = mb->get_hint_flags(); + } + + if (!methods.empty()) { + class_dict["methods"] = methods; + } + } + + { //constants + + List<StringName> snames; + + k = NULL; + + while ((k = t->constant_map.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + Array constants; + + for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { + Dictionary constant_dict; + constants.push_back(constant_dict); + + constant_dict["name"] = F->get(); + constant_dict["value"] = t->constant_map[F->get()]; + } + + if (!constants.empty()) { + class_dict["constants"] = constants; + } + } + + { //signals + + List<StringName> snames; + + k = NULL; + + while ((k = t->signal_map.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + Array signals; + + for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { + Dictionary signal_dict; + signals.push_back(signal_dict); + + MethodInfo &mi = t->signal_map[F->get()]; + signal_dict["name"] = F->get(); + + Array arguments; + signal_dict["arguments"] = arguments; + for (int i = 0; i < mi.arguments.size(); i++) { + Dictionary argument_dict; + arguments.push_back(argument_dict); + argument_dict["type"] = mi.arguments[i].type; + } + } + + if (!signals.empty()) { + class_dict["signals"] = signals; + } + } + + { //properties + + List<StringName> snames; + + k = NULL; + + while ((k = t->property_setget.next(k))) { + + snames.push_back(*k); + } + + snames.sort_custom<StringName::AlphCompare>(); + + Array properties; + + for (List<StringName>::Element *F = snames.front(); F; F = F->next()) { + Dictionary property_dict; + properties.push_back(property_dict); + + ClassDB::PropertySetGet *psg = t->property_setget.getptr(F->get()); + + property_dict["name"] = F->get(); + property_dict["setter"] = psg->setter; + property_dict["getter"] = psg->getter; + } + + if (!properties.empty()) { + class_dict["property_setget"] = properties; + } + } + + Array property_list; + + //property list + for (List<PropertyInfo>::Element *F = t->property_list.front(); F; F = F->next()) { + Dictionary property_dict; + property_list.push_back(property_dict); + + property_dict["name"] = F->get().name; + property_dict["type"] = F->get().type; + property_dict["hint"] = F->get().hint; + property_dict["hint_string"] = F->get().hint_string; + property_dict["usage"] = F->get().usage; + } + + if (!property_list.empty()) { + class_dict["property_list"] = property_list; + } + } + + FileAccessRef f = FileAccess::open(p_output_file, FileAccess::WRITE); + ERR_FAIL_COND(!f); + f->store_string(JSON::print(classes_dict, /*indent: */ "\t")); + f->close(); + + print_line(String() + "ClassDB API JSON written to: " + ProjectSettings::get_singleton()->globalize_path(p_output_file)); +} diff --git a/modules/mono/editor/dotnet_solution.h b/modules/mono/class_db_api_json.h index 18933364fa..0aa9c20930 100644 --- a/modules/mono/editor/dotnet_solution.h +++ b/modules/mono/class_db_api_json.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* dotnet_solution.h */ +/* class_db_api_json.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 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 */ @@ -28,36 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef NET_SOLUTION_H -#define NET_SOLUTION_H +#ifndef CLASS_DB_API_JSON_H +#define CLASS_DB_API_JSON_H -#include "core/map.h" +#include "core/class_db.h" #include "core/ustring.h" -struct DotNetSolution { - String name; +void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api); - struct ProjectInfo { - String guid; - String relpath; // Must be relative to the solution directory - Vector<String> configs; - }; - - void add_new_project(const String &p_name, const ProjectInfo &p_project_info); - bool has_project(const String &p_name) const; - const ProjectInfo &get_project_info(const String &p_name) const; - bool remove_project(const String &p_name); - - Error save(); - - bool set_path(const String &p_existing_path); - String get_path(); - - DotNetSolution(const String &p_name); - -private: - String path; - Map<String, ProjectInfo> projects; -}; - -#endif // NET_SOLUTION_H +#endif // CLASS_DB_API_JSON_H diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index 9522eaee77..078a490b22 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -42,9 +42,13 @@ #include "editor/bindings_generator.h" #include "editor/csharp_project.h" #include "editor/editor_node.h" -#include "editor/godotsharp_editor.h" #endif +#ifdef DEBUG_METHODS_ENABLED +#include "class_db_api_json.h" +#endif + +#include "editor/editor_internal_calls.h" #include "godotsharp_dirs.h" #include "mono_gd/gd_mono_class.h" #include "mono_gd/gd_mono_marshal.h" @@ -65,8 +69,8 @@ static bool _create_project_solution_if_needed() { if (!FileAccess::exists(sln_path) || !FileAccess::exists(csproj_path)) { // A solution does not yet exist, create a new one - CRASH_COND(GodotSharpEditor::get_singleton() == NULL); - return GodotSharpEditor::get_singleton()->call("_create_project_solution"); + CRASH_COND(CSharpLanguage::get_singleton()->get_godotsharp_editor() == NULL); + return CSharpLanguage::get_singleton()->get_godotsharp_editor()->call("CreateProjectSolution"); } return true; @@ -96,32 +100,36 @@ Error CSharpLanguage::execute_file(const String &p_path) { return OK; } -#ifdef TOOLS_ENABLED -void gdsharp_editor_init_callback() { +void CSharpLanguage::init() { - EditorNode *editor = EditorNode::get_singleton(); - editor->add_child(memnew(GodotSharpEditor(editor))); -} +#ifdef DEBUG_METHODS_ENABLED + if (OS::get_singleton()->get_cmdline_args().find("--class_db_to_json")) { + class_db_api_to_json("user://class_db_api.json", ClassDB::API_CORE); +#ifdef TOOLS_ENABLED + class_db_api_to_json("user://class_db_api_editor.json", ClassDB::API_EDITOR); +#endif + } #endif - -void CSharpLanguage::init() { gdmono = memnew(GDMono); gdmono->initialize(); -#ifndef MONO_GLUE_ENABLED - WARN_PRINT("This binary is built with `mono_glue=no` and cannot be used for scripting"); +#if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED) + // Generate bindings here, before loading assemblies. `initialize_load_assemblies` aborts + // the applications if the api assemblies or the main tools assembly is missing, but this + // is not a problem for BindingsGenerator as it only needs the tools project editor assembly. + List<String> cmdline_args = OS::get_singleton()->get_cmdline_args(); + BindingsGenerator::handle_cmdline_args(cmdline_args); #endif -#if defined(TOOLS_ENABLED) && defined(DEBUG_METHODS_ENABLED) - if (gdmono->get_editor_tools_assembly() != NULL) { - List<String> cmdline_args = OS::get_singleton()->get_cmdline_args(); - BindingsGenerator::handle_cmdline_args(cmdline_args); - } +#ifndef MONO_GLUE_ENABLED + print_line("Run this binary with `--generate-mono-glue path/to/modules/mono/glue`"); #endif + gdmono->initialize_load_assemblies(); + #ifdef TOOLS_ENABLED - EditorNode::add_init_callback(&gdsharp_editor_init_callback); + EditorNode::add_init_callback(&_editor_init_callback); GLOBAL_DEF("mono/export/include_scripts_content", false); #endif @@ -664,7 +672,7 @@ void CSharpLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft CRASH_COND(!Engine::get_singleton()->is_editor_hint()); #ifdef TOOLS_ENABLED - MonoReloadNode::get_singleton()->restart_reload_timer(); + get_godotsharp_editor()->get_node(NodePath("HotReloadAssemblyWatcher"))->call("RestartTimer"); #endif #ifdef GD_MONO_HOT_RELOAD @@ -682,19 +690,20 @@ bool CSharpLanguage::is_assembly_reloading_needed() { GDMonoAssembly *proj_assembly = gdmono->get_project_assembly(); - String name = ProjectSettings::get_singleton()->get("application/config/name"); - if (name.empty()) { - name = "UnnamedProject"; + String appname = ProjectSettings::get_singleton()->get("application/config/name"); + String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); + if (appname_safe.empty()) { + appname_safe = "UnnamedProject"; } - name += ".dll"; + appname_safe += ".dll"; if (proj_assembly) { String proj_asm_path = proj_assembly->get_path(); if (!FileAccess::exists(proj_assembly->get_path())) { // Maybe it wasn't loaded from the default path, so check this as well - proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name); + proj_asm_path = GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe); if (!FileAccess::exists(proj_asm_path)) return false; // No assembly to load } @@ -702,18 +711,10 @@ bool CSharpLanguage::is_assembly_reloading_needed() { if (FileAccess::get_modified_time(proj_asm_path) <= proj_assembly->get_modified_time()) return false; // Already up to date } else { - if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(name))) + if (!FileAccess::exists(GodotSharpDirs::get_res_temp_assemblies_dir().plus_file(appname_safe))) return false; // No assembly to load } -#ifdef TOOLS_ENABLED - if (!gdmono->get_core_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_CORE)) - return false; // The core API assembly to load is invalidated - - if (!gdmono->get_editor_api_assembly() && gdmono->metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR)) - return false; // The editor API assembly to load is invalidated -#endif - return true; } @@ -730,58 +731,93 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { SCOPED_MUTEX_LOCK(script_instances_mutex); for (SelfList<CSharpScript> *elem = script_list.first(); elem; elem = elem->next()) { - if (elem->self()->get_path().is_resource_file()) { - // Cast to CSharpScript to avoid being erased by accident - scripts.push_back(Ref<CSharpScript>(elem->self())); - } + // Cast to CSharpScript to avoid being erased by accident + scripts.push_back(Ref<CSharpScript>(elem->self())); } } List<Ref<CSharpScript> > to_reload; + // We need to keep reference instances alive during reloading + List<Ref<Reference> > ref_instances; + + for (Map<Object *, CSharpScriptBinding>::Element *E = script_bindings.front(); E; E = E->next()) { + CSharpScriptBinding &script_binding = E->value(); + Reference *ref = Object::cast_to<Reference>(script_binding.owner); + if (ref) { + ref_instances.push_back(Ref<Reference>(ref)); + } + } + // As scripts are going to be reloaded, must proceed without locking here scripts.sort_custom<CSharpScriptDepSort>(); // Update in inheritance dependency order for (List<Ref<CSharpScript> >::Element *E = scripts.front(); E; E = E->next()) { - Ref<CSharpScript> &script = E->get(); to_reload.push_back(script); + if (script->get_path().empty()) { + script->tied_class_name_for_reload = script->script_class->get_name(); + script->tied_class_namespace_for_reload = script->script_class->get_namespace(); + } + // Script::instances are deleted during managed object disposal, which happens on domain finalize. // Only placeholders are kept. Therefore we need to keep a copy before that happens. for (Set<Object *>::Element *F = script->instances.front(); F; F = F->next()) { - script->pending_reload_instances.insert(F->get()->get_instance_id()); + Object *obj = F->get(); + script->pending_reload_instances.insert(obj->get_instance_id()); + + Reference *ref = Object::cast_to<Reference>(obj); + if (ref) { + ref_instances.push_back(Ref<Reference>(ref)); + } } #ifdef TOOLS_ENABLED for (Set<PlaceHolderScriptInstance *>::Element *F = script->placeholders.front(); F; F = F->next()) { - script->pending_reload_instances.insert(F->get()->get_owner()->get_instance_id()); + Object *obj = F->get()->get_owner(); + script->pending_reload_instances.insert(obj->get_instance_id()); + + Reference *ref = Object::cast_to<Reference>(obj); + if (ref) { + ref_instances.push_back(Ref<Reference>(ref)); + } } #endif - // FIXME: What about references? Need to keep them alive if only managed code references them. - // Save state and remove script from instances Map<ObjectID, CSharpScript::StateBackup> &owners_map = script->pending_reload_state; - while (script->instances.front()) { - Object *obj = script->instances.front()->get(); - // Save instance info - CSharpScript::StateBackup state; + for (Set<Object *>::Element *F = script->instances.front(); F; F = F->next()) { + Object *obj = F->get(); ERR_CONTINUE(!obj->get_script_instance()); - // TODO: Proper state backup (Not only variants, serialize managed state of scripts) - obj->get_script_instance()->get_property_state(state.properties); + CSharpInstance *csi = static_cast<CSharpInstance *>(obj->get_script_instance()); - Ref<MonoGCHandle> gchandle = CAST_CSHARP_INSTANCE(obj->get_script_instance())->gchandle; - if (gchandle.is_valid()) - gchandle->release(); + // Call OnBeforeSerialize + if (csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) + obj->get_script_instance()->call_multilevel(string_names.on_before_serialize); + + // Save instance info + CSharpScript::StateBackup state; + + // TODO: Proper state backup (Not only variants, serialize managed state of scripts) + csi->get_properties_state_for_reloading(state.properties); owners_map[obj->get_instance_id()] = state; + } + } + + // After the state of all instances is saved, clear scripts and script instances + for (List<Ref<CSharpScript> >::Element *E = scripts.front(); E; E = E->next()) { + Ref<CSharpScript> &script = E->get(); + + while (script->instances.front()) { + Object *obj = script->instances.front()->get(); obj->set_script(RefPtr()); // Remove script and existing script instances (placeholder are not removed before domain reload) } @@ -824,26 +860,80 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { scr->pending_reload_state.erase(obj_id); } } + return; } + List<Ref<CSharpScript> > to_reload_state; + for (List<Ref<CSharpScript> >::Element *E = to_reload.front(); E; E = E->next()) { + Ref<CSharpScript> script = E->get(); - Ref<CSharpScript> scr = E->get(); + if (!script->get_path().empty()) { #ifdef TOOLS_ENABLED - scr->exports_invalidated = true; + script->exports_invalidated = true; +#endif + script->signals_invalidated = true; + + script->reload(p_soft_reload); + script->update_exports(); + + if (!script->valid) { + script->pending_reload_instances.clear(); + continue; + } + } else { + const StringName &class_namespace = script->tied_class_namespace_for_reload; + const StringName &class_name = script->tied_class_name_for_reload; + GDMonoAssembly *project_assembly = gdmono->get_project_assembly(); + + // Search in project and tools assemblies first as those are the most likely to have the class + GDMonoClass *script_class = (project_assembly ? project_assembly->get_class(class_namespace, class_name) : NULL); + +#ifdef TOOLS_ENABLED + if (!script_class) { + GDMonoAssembly *tools_assembly = gdmono->get_tools_assembly(); + script_class = (tools_assembly ? tools_assembly->get_class(class_namespace, class_name) : NULL); + } #endif - scr->signals_invalidated = true; - scr->reload(p_soft_reload); - scr->update_exports(); + + if (!script_class) { + script_class = gdmono->get_class(class_namespace, class_name); + } + + if (!script_class) { + // The class was removed, can't reload + script->pending_reload_instances.clear(); + continue; + } + + bool obj_type = CACHED_CLASS(GodotObject)->is_assignable_from(script_class); + if (!obj_type) { + // The class no longer inherits Godot.Object, can't reload + script->pending_reload_instances.clear(); + continue; + } + + GDMonoClass *native = GDMonoUtils::get_class_native_base(script_class); + + CSharpScript::initialize_for_managed_type(script, script_class, native); + } + + String native_name = NATIVE_GDMONOCLASS_NAME(script->native); { - for (Set<ObjectID>::Element *F = scr->pending_reload_instances.front(); F; F = F->next()) { + for (Set<ObjectID>::Element *F = script->pending_reload_instances.front(); F; F = F->next()) { ObjectID obj_id = F->get(); Object *obj = ObjectDB::get_instance(obj_id); if (!obj) { - scr->pending_reload_state.erase(obj_id); + script->pending_reload_state.erase(obj_id); + continue; + } + + if (!ClassDB::is_parent_class(obj->get_class_name(), native_name)) { + // No longer inherits the same compatible type, can't reload + script->pending_reload_state.erase(obj_id); continue; } @@ -855,28 +945,20 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { // Non-placeholder script instances are removed in godot_icall_Object_Disposed. CRASH_COND(!si->is_placeholder()); - if (scr->is_tool() || ScriptServer::is_scripting_enabled()) { + if (script->is_tool() || ScriptServer::is_scripting_enabled()) { // Replace placeholder with a script instance - CSharpScript::StateBackup &state_backup = scr->pending_reload_state[obj_id]; + CSharpScript::StateBackup &state_backup = script->pending_reload_state[obj_id]; // Backup placeholder script instance state before replacing it with a script instance si->get_property_state(state_backup.properties); - ScriptInstance *script_instance = scr->instance_create(obj); + ScriptInstance *script_instance = script->instance_create(obj); if (script_instance) { - scr->placeholders.erase(static_cast<PlaceHolderScriptInstance *>(si)); + script->placeholders.erase(static_cast<PlaceHolderScriptInstance *>(si)); obj->set_script_instance(script_instance); } - - // TODO: Restore serialized state - - for (List<Pair<StringName, Variant> >::Element *G = state_backup.properties.front(); G; G = G->next()) { - script_instance->set(G->get().first, G->get().second); - } - - scr->pending_reload_state.erase(obj_id); } continue; @@ -885,20 +967,42 @@ void CSharpLanguage::reload_assemblies(bool p_soft_reload) { CRASH_COND(si != NULL); #endif // Re-create script instance + obj->set_script(script.get_ref_ptr()); // will create the script instance as well + } + } - obj->set_script(scr.get_ref_ptr()); // will create the script instance as well + to_reload_state.push_back(script); + } - // TODO: Restore serialized state + for (List<Ref<CSharpScript> >::Element *E = to_reload_state.front(); E; E = E->next()) { + Ref<CSharpScript> script = E->get(); - for (List<Pair<StringName, Variant> >::Element *G = scr->pending_reload_state[obj_id].properties.front(); G; G = G->next()) { - obj->get_script_instance()->set(G->get().first, G->get().second); - } + for (Set<ObjectID>::Element *F = script->pending_reload_instances.front(); F; F = F->next()) { + ObjectID obj_id = F->get(); + Object *obj = ObjectDB::get_instance(obj_id); - scr->pending_reload_state.erase(obj_id); + if (!obj) { + script->pending_reload_state.erase(obj_id); + continue; + } + + ERR_CONTINUE(!obj->get_script_instance()); + + // TODO: Restore serialized state + + CSharpScript::StateBackup &state_backup = script->pending_reload_state[obj_id]; + + for (List<Pair<StringName, Variant> >::Element *G = state_backup.properties.front(); G; G = G->next()) { + obj->get_script_instance()->set(G->get().first, G->get().second); } - scr->pending_reload_instances.clear(); + // Call OnAfterDeserialization + CSharpInstance *csi = CAST_CSHARP_INSTANCE(obj->get_script_instance()); + if (csi && csi->script->script_class->implements_interface(CACHED_CLASS(ISerializationListener))) + obj->get_script_instance()->call_multilevel(string_names.on_after_deserialize); } + + script->pending_reload_instances.clear(); } #ifdef TOOLS_ENABLED @@ -963,12 +1067,12 @@ void CSharpLanguage::get_recognized_extensions(List<String> *p_extensions) const #ifdef TOOLS_ENABLED Error CSharpLanguage::open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { - return GodotSharpEditor::get_singleton()->open_in_external_editor(p_script, p_line, p_col); + return (Error)(int)get_godotsharp_editor()->call("OpenInExternalEditor", p_script, p_line, p_col); } bool CSharpLanguage::overrides_external_editor() { - return GodotSharpEditor::get_singleton()->overrides_external_editor(); + return get_godotsharp_editor()->call("OverridesExternalEditor"); } #endif @@ -1026,6 +1130,34 @@ void CSharpLanguage::_on_scripts_domain_unloaded() { scripts_metadata_invalidated = true; } +#ifdef TOOLS_ENABLED +void CSharpLanguage::_editor_init_callback() { + + register_editor_internal_calls(); + + // Initialize GodotSharpEditor + + GDMonoClass *editor_klass = GDMono::get_singleton()->get_tools_assembly()->get_class("GodotTools", "GodotSharpEditor"); + CRASH_COND(editor_klass == NULL); + + MonoObject *mono_object = mono_object_new(mono_domain_get(), editor_klass->get_mono_ptr()); + CRASH_COND(mono_object == NULL); + + MonoException *exc = NULL; + GDMonoUtils::runtime_object_init(mono_object, editor_klass, &exc); + UNHANDLED_EXCEPTION(exc); + + EditorPlugin *godotsharp_editor = Object::cast_to<EditorPlugin>(GDMonoMarshal::mono_object_to_variant(mono_object)); + CRASH_COND(godotsharp_editor == NULL); + + // Enable it as a plugin + EditorNode::add_editor_plugin(godotsharp_editor); + godotsharp_editor->enable_plugin(); + + get_singleton()->godotsharp_editor = godotsharp_editor; +} +#endif + void CSharpLanguage::set_language_index(int p_idx) { ERR_FAIL_COND(lang_idx != -1); @@ -1083,6 +1215,10 @@ CSharpLanguage::CSharpLanguage() { lang_idx = -1; scripts_metadata_invalidated = true; + +#ifdef TOOLS_ENABLED + godotsharp_editor = NULL; +#endif } CSharpLanguage::~CSharpLanguage() { @@ -1138,6 +1274,7 @@ bool CSharpLanguage::setup_csharp_script_binding(CSharpScriptBinding &r_script_b r_script_binding.type_name = type_name; r_script_binding.wrapper_class = type_class; // cache r_script_binding.gchandle = MonoGCHandle::create_strong(mono_object); + r_script_binding.owner = p_object; // Tie managed to unmanaged Reference *ref = Object::cast_to<Reference>(p_object); @@ -1222,6 +1359,9 @@ void CSharpLanguage::refcount_incremented_instance_binding(Object *p_object) { CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); Ref<MonoGCHandle> &gchandle = script_binding.gchandle; + if (!script_binding.inited) + return; + if (ref_owner->reference_get_count() > 1 && gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 // The reference count was increased after the managed side was the only one referencing our owner. // This means the owner is being referenced again by the unmanaged side, @@ -1246,14 +1386,17 @@ bool CSharpLanguage::refcount_decremented_instance_binding(Object *p_object) { CRASH_COND(!ref_owner); #endif - int refcount = ref_owner->reference_get_count(); - void *data = p_object->get_script_instance_binding(get_language_index()); CRASH_COND(!data); CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); Ref<MonoGCHandle> &gchandle = script_binding.gchandle; + int refcount = ref_owner->reference_get_count(); + + if (!script_binding.inited) + return refcount == 0; + if (refcount == 1 && gchandle.is_valid() && !gchandle->is_weak()) { // The managed side also holds a reference, hence 1 instead of 0 // If owner owner is no longer referenced by the unmanaged side, // the managed instance takes responsibility of deleting the owner when GCed. @@ -1416,6 +1559,31 @@ bool CSharpInstance::get(const StringName &p_name, Variant &r_ret) const { return false; } +void CSharpInstance::get_properties_state_for_reloading(List<Pair<StringName, Variant> > &r_state) { + + List<PropertyInfo> pinfo; + get_property_list(&pinfo); + + for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) { + Pair<StringName, Variant> state_pair; + state_pair.first = E->get().name; + + ManagedType managedType; + + GDMonoField *field = script->script_class->get_field(state_pair.first); + if (!field) + continue; // Properties ignored. We get the property baking fields instead. + + managedType = field->get_type(); + + if (GDMonoMarshal::managed_to_variant_type(managedType) != Variant::NIL) { // If we can marshal it + if (get(state_pair.first, state_pair.second)) { + r_state.push_back(state_pair); + } + } + } +} + void CSharpInstance::get_property_list(List<PropertyInfo> *p_properties) const { for (Map<StringName, PropertyInfo>::Element *E = script->member_info.front(); E; E = E->next()) { @@ -1613,17 +1781,18 @@ MonoObject *CSharpInstance::_internal_new_managed() { ERR_FAIL_NULL_V(owner, NULL); ERR_FAIL_COND_V(script.is_null(), NULL); - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, script->script_class->get_mono_ptr()); + MonoObject *mono_object = mono_object_new(mono_domain_get(), script->script_class->get_mono_ptr()); if (!mono_object) { // Important to clear this before destroying the script instance here script = Ref<CSharpScript>(); - owner = NULL; bool die = _unreference_owner_unsafe(); // Not ok for the owner to die here. If there is a situation where this can happen, it will be considered a bug. CRASH_COND(die == true); + owner = NULL; + ERR_EXPLAIN("Failed to allocate memory for the object"); ERR_FAIL_V(NULL); } @@ -1939,7 +2108,16 @@ CSharpInstance::~CSharpInstance() { CRASH_COND(data == NULL); CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->get(); - CRASH_COND(!script_binding.inited); + + if (!script_binding.inited) { + SCOPED_MUTEX_LOCK(CSharpLanguage::get_singleton()->get_language_bind_mutex()); + + if (!script_binding.inited) { // Other thread may have set it up + // Already had a binding that needs to be setup + CSharpLanguage::get_singleton()->setup_csharp_script_binding(script_binding, owner); + CRASH_COND(!script_binding.inited); + } + } bool die = _unreference_owner_unsafe(); CRASH_COND(die == true); // The "instance binding" should be holding a reference @@ -1981,6 +2159,52 @@ void CSharpScript::_update_exports_values(Map<StringName, Variant> &values, List propnames.push_back(E->get()); } } + +void CSharpScript::_update_member_info_no_exports() { + + if (exports_invalidated) { + exports_invalidated = false; + + member_info.clear(); + + GDMonoClass *top = script_class; + + while (top && top != native) { + PropertyInfo prop_info; + bool exported; + + const Vector<GDMonoField *> &fields = top->get_all_fields(); + + for (int i = fields.size() - 1; i >= 0; i--) { + GDMonoField *field = fields[i]; + + if (_get_member_export(field, /* inspect export: */ false, prop_info, exported)) { + StringName member_name = field->get_name(); + + member_info[member_name] = prop_info; + exported_members_cache.push_front(prop_info); + exported_members_defval_cache[member_name] = Variant(); + } + } + + const Vector<GDMonoProperty *> &properties = top->get_all_properties(); + + for (int i = properties.size() - 1; i >= 0; i--) { + GDMonoProperty *property = properties[i]; + + if (_get_member_export(property, /* inspect export: */ false, prop_info, exported)) { + StringName member_name = property->get_name(); + + member_info[member_name] = prop_info; + exported_members_cache.push_front(prop_info); + exported_members_defval_cache[member_name] = Variant(); + } + } + + top = top->get_parent_class(); + } + } +} #endif bool CSharpScript::_update_exports() { @@ -2007,7 +2231,7 @@ bool CSharpScript::_update_exports() { // Here we create a temporary managed instance of the class to get the initial values - MonoObject *tmp_object = mono_object_new(SCRIPTS_DOMAIN, script_class->get_mono_ptr()); + MonoObject *tmp_object = mono_object_new(mono_domain_get(), script_class->get_mono_ptr()); if (!tmp_object) { ERR_PRINT("Failed to allocate temporary MonoObject"); @@ -2048,18 +2272,18 @@ bool CSharpScript::_update_exports() { for (int i = fields.size() - 1; i >= 0; i--) { GDMonoField *field = fields[i]; - if (_get_member_export(field, prop_info, exported)) { - StringName name = field->get_name(); + if (_get_member_export(field, /* inspect export: */ true, prop_info, exported)) { + StringName member_name = field->get_name(); if (exported) { - member_info[name] = prop_info; + member_info[member_name] = prop_info; exported_members_cache.push_front(prop_info); if (tmp_object) { - exported_members_defval_cache[name] = GDMonoMarshal::mono_object_to_variant(field->get_value(tmp_object)); + exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(field->get_value(tmp_object)); } } else { - member_info[name] = prop_info; + member_info[member_name] = prop_info; } } } @@ -2069,25 +2293,25 @@ bool CSharpScript::_update_exports() { for (int i = properties.size() - 1; i >= 0; i--) { GDMonoProperty *property = properties[i]; - if (_get_member_export(property, prop_info, exported)) { - StringName name = property->get_name(); + if (_get_member_export(property, /* inspect export: */ true, prop_info, exported)) { + StringName member_name = property->get_name(); if (exported) { - member_info[name] = prop_info; + member_info[member_name] = prop_info; exported_members_cache.push_front(prop_info); if (tmp_object) { MonoException *exc = NULL; MonoObject *ret = property->get_value(tmp_object, &exc); if (exc) { - exported_members_defval_cache[name] = Variant(); + exported_members_defval_cache[member_name] = Variant(); GDMonoUtils::debug_print_unhandled_exception(exc); } else { - exported_members_defval_cache[name] = GDMonoMarshal::mono_object_to_variant(ret); + exported_members_defval_cache[member_name] = GDMonoMarshal::mono_object_to_variant(ret); } } } else { - member_info[name] = prop_info; + member_info[member_name] = prop_info; } } } @@ -2196,7 +2420,7 @@ bool CSharpScript::_get_signal(GDMonoClass *p_class, GDMonoClass *p_delegate, Ve * Returns false if there was an error, otherwise true. * If there was an error, r_prop_info and r_exported are not assigned any value. */ -bool CSharpScript::_get_member_export(IMonoClassMember *p_member, PropertyInfo &r_prop_info, bool &r_exported) { +bool CSharpScript::_get_member_export(IMonoClassMember *p_member, bool p_inspect_export, PropertyInfo &r_prop_info, bool &r_exported) { // Goddammit, C++. All I wanted was some nested functions. #define MEMBER_FULL_QUALIFIED_NAME(m_member) \ @@ -2221,26 +2445,30 @@ bool CSharpScript::_get_member_export(IMonoClassMember *p_member, PropertyInfo & CRASH_NOW(); } - Variant::Type variant_type = GDMonoMarshal::managed_to_variant_type(type); - - if (!p_member->has_attribute(CACHED_CLASS(ExportAttribute))) { - r_prop_info = PropertyInfo(variant_type, (String)p_member->get_name(), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_SCRIPT_VARIABLE); - r_exported = false; - return true; - } + bool exported = p_member->has_attribute(CACHED_CLASS(ExportAttribute)); if (p_member->get_member_type() == IMonoClassMember::MEMBER_TYPE_PROPERTY) { GDMonoProperty *property = static_cast<GDMonoProperty *>(p_member); if (!property->has_getter()) { - ERR_PRINTS("Read-only property cannot be exported: " + MEMBER_FULL_QUALIFIED_NAME(p_member)); + if (exported) + ERR_PRINTS("Read-only property cannot be exported: " + MEMBER_FULL_QUALIFIED_NAME(p_member)); return false; } if (!property->has_setter()) { - ERR_PRINTS("Set-only property (without getter) cannot be exported: " + MEMBER_FULL_QUALIFIED_NAME(p_member)); + if (exported) + ERR_PRINTS("Write-only property (without getter) cannot be exported: " + MEMBER_FULL_QUALIFIED_NAME(p_member)); return false; } } + Variant::Type variant_type = GDMonoMarshal::managed_to_variant_type(type); + + if (!p_inspect_export || !exported) { + r_prop_info = PropertyInfo(variant_type, (String)p_member->get_name(), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_SCRIPT_VARIABLE); + r_exported = false; + return true; + } + MonoObject *attr = p_member->get_attribute(CACHED_CLASS(ExportAttribute)); PropertyHint hint = PROPERTY_HINT_NONE; @@ -2460,33 +2688,58 @@ void CSharpScript::_bind_methods() { Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native) { - // This method should not fail + // This method should not fail, only assertions allowed - CRASH_COND(!p_class); + CRASH_COND(p_class == NULL); - // TODO: Cache the 'CSharpScript' associated with this 'p_class' instead of allocating a new one every time + // TODO OPTIMIZE: Cache the 'CSharpScript' associated with this 'p_class' instead of allocating a new one every time Ref<CSharpScript> script = memnew(CSharpScript); - script->name = p_class->get_name(); - script->script_class = p_class; - script->native = p_native; + initialize_for_managed_type(script, p_class, p_native); + + return script; +} + +void CSharpScript::initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native) { + + // This method should not fail, only assertions allowed - CRASH_COND(script->native == NULL); + CRASH_COND(p_class == NULL); - GDMonoClass *base = script->script_class->get_parent_class(); + p_script->name = p_class->get_name(); + p_script->script_class = p_class; + p_script->native = p_native; + + CRASH_COND(p_script->native == NULL); + + GDMonoClass *base = p_script->script_class->get_parent_class(); + + if (base != p_script->native) + p_script->base = base; + + p_script->valid = true; + p_script->tool = p_script->script_class->has_attribute(CACHED_CLASS(ToolAttribute)); + + if (!p_script->tool) { + GDMonoClass *nesting_class = p_script->script_class->get_nesting_class(); + p_script->tool = nesting_class && nesting_class->has_attribute(CACHED_CLASS(ToolAttribute)); + } - if (base != script->native) - script->base = base; +#if TOOLS_ENABLED + if (!p_script->tool) { + p_script->tool = p_script->script_class->get_assembly() == GDMono::get_singleton()->get_tools_assembly(); + } +#endif #ifdef DEBUG_ENABLED // For debug builds, we must fetch from all native base methods as well. // Native base methods must be fetched before the current class. // Not needed if the script class itself is a native class. - if (script->script_class != script->native) { - GDMonoClass *native_top = script->native; + if (p_script->script_class != p_script->native) { + GDMonoClass *native_top = p_script->native; while (native_top) { - native_top->fetch_methods_with_godot_api_checks(script->native); + native_top->fetch_methods_with_godot_api_checks(p_script->native); if (native_top == CACHED_CLASS(GodotObject)) break; @@ -2496,18 +2749,19 @@ Ref<CSharpScript> CSharpScript::create_for_managed_type(GDMonoClass *p_class, GD } #endif - script->script_class->fetch_methods_with_godot_api_checks(script->native); + p_script->script_class->fetch_methods_with_godot_api_checks(p_script->native); // Need to fetch method from base classes as well - GDMonoClass *top = script->script_class; - while (top && top != script->native) { - top->fetch_methods_with_godot_api_checks(script->native); + GDMonoClass *top = p_script->script_class; + while (top && top != p_script->native) { + top->fetch_methods_with_godot_api_checks(p_script->native); top = top->get_parent_class(); } - script->load_script_signals(script->script_class, script->native); - - return script; + p_script->load_script_signals(p_script->script_class, p_script->native); +#ifdef TOOLS_ENABLED + p_script->_update_member_info_no_exports(); +#endif } bool CSharpScript::can_instance() const { @@ -2515,7 +2769,8 @@ bool CSharpScript::can_instance() const { #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint()) { - if (get_path().find("::") == -1) { // Ignore if built-in script. Can happen if the file is deleted... + // Hack to lower the risk of attached scripts not being added to the C# project + if (!get_path().empty() && get_path().find("::") == -1) { // Ignore if built-in script. Can happen if the file is deleted... if (_create_project_solution_if_needed()) { CSharpProject::add_item(GodotSharpDirs::get_project_csproj_path(), "Compile", @@ -2567,7 +2822,9 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg GDMonoMethod *ctor = script_class->get_method(CACHED_STRING_NAME(dotctor), p_argcount); if (ctor == NULL) { if (p_argcount == 0) { - ERR_PRINTS("Cannot create script instance because the class does not define a parameterless constructor: " + get_path()); + String path = get_path(); + ERR_PRINTS("Cannot create script instance. The class '" + script_class->get_full_name() + + "' does not define a parameterless constructor." + (path.empty() ? String() : ". Path: " + path)); } ERR_EXPLAIN("Constructor not found"); @@ -2609,7 +2866,7 @@ CSharpInstance *CSharpScript::_create_instance(const Variant **p_args, int p_arg /* STEP 2, INITIALIZE AND CONSTRUCT */ - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, script_class->get_mono_ptr()); + MonoObject *mono_object = mono_object_new(mono_domain_get(), script_class->get_mono_ptr()); if (!mono_object) { // Important to clear this before destroying the script instance here @@ -2690,7 +2947,7 @@ ScriptInstance *CSharpScript::instance_create(Object *p_this) { #endif if (native) { - String native_name = native->get_name(); + String native_name = NATIVE_GDMONOCLASS_NAME(native); if (!ClassDB::is_parent_class(p_this->get_class_name(), native_name)) { if (ScriptDebugger::get_singleton()) { CSharpLanguage::get_singleton()->debug_break_parse(get_path(), 0, "Script inherits from native type '" + native_name + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'"); @@ -2816,11 +3073,22 @@ Error CSharpScript::reload(bool p_keep_state) { if (script_class) { #ifdef DEBUG_ENABLED - print_verbose("Found class " + script_class->get_namespace() + "." + script_class->get_name() + " for script " + get_path()); + print_verbose("Found class " + script_class->get_full_name() + " for script " + get_path()); #endif tool = script_class->has_attribute(CACHED_CLASS(ToolAttribute)); + if (!tool) { + GDMonoClass *nesting_class = script_class->get_nesting_class(); + tool = nesting_class && nesting_class->has_attribute(CACHED_CLASS(ToolAttribute)); + } + +#if TOOLS_ENABLED + if (!tool) { + tool = script_class->get_assembly() == GDMono::get_singleton()->get_tools_assembly(); + } +#endif + native = GDMonoUtils::get_class_native_base(script_class); CRASH_COND(native == NULL); @@ -3018,7 +3286,8 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p #endif #ifdef TOOLS_ENABLED - if (Engine::get_singleton()->is_editor_hint() && mono_domain_get() == NULL) { + MonoDomain *domain = mono_domain_get(); + if (Engine::get_singleton()->is_editor_hint() && domain == NULL) { CRASH_COND(Thread::get_caller_id() == Thread::get_main_id()); @@ -3026,8 +3295,8 @@ RES ResourceFormatLoaderCSharpScript::load(const String &p_path, const String &p // because this may be called by one of the editor's worker threads. // Attach this thread temporarily to reload the script. - if (SCRIPTS_DOMAIN) { - MonoThread *mono_thread = mono_thread_attach(SCRIPTS_DOMAIN); + if (domain) { + MonoThread *mono_thread = mono_thread_attach(domain); CRASH_COND(mono_thread == NULL); script->reload(); mono_thread_detach(mono_thread); @@ -3127,5 +3396,7 @@ CSharpLanguage::StringNameCache::StringNameCache() { _get_property_list = StaticCString::create("_get_property_list"); _notification = StaticCString::create("_notification"); _script_source = StaticCString::create("script/source"); + on_before_serialize = StaticCString::create("OnBeforeSerialize"); + on_after_deserialize = StaticCString::create("OnAfterDeserialize"); dotctor = StaticCString::create(".ctor"); } diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h index a2f1ec8f27..eb168f344d 100644 --- a/modules/mono/csharp_script.h +++ b/modules/mono/csharp_script.h @@ -41,6 +41,10 @@ #include "mono_gd/gd_mono_header.h" #include "mono_gd/gd_mono_internals.h" +#ifdef TOOLS_ENABLED +#include "editor/editor_plugin.h" +#endif + class CSharpScript; class CSharpInstance; class CSharpLanguage; @@ -92,6 +96,8 @@ class CSharpScript : public Script { Set<ObjectID> pending_reload_instances; Map<ObjectID, StateBackup> pending_reload_state; + StringName tied_class_name_for_reload; + StringName tied_class_namespace_for_reload; #endif String source; @@ -115,6 +121,7 @@ class CSharpScript : public Script { bool placeholder_fallback_enabled; bool exports_invalidated; void _update_exports_values(Map<StringName, Variant> &values, List<PropertyInfo> &propnames); + void _update_member_info_no_exports(); virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder); #endif @@ -127,7 +134,7 @@ class CSharpScript : public Script { bool _update_exports(); #ifdef TOOLS_ENABLED - bool _get_member_export(IMonoClassMember *p_member, PropertyInfo &r_prop_info, bool &r_exported); + bool _get_member_export(IMonoClassMember *p_member, bool p_inspect_export, PropertyInfo &r_prop_info, bool &r_exported); static int _try_get_member_export_hint(IMonoClassMember *p_member, ManagedType p_type, Variant::Type p_variant_type, bool p_allow_generics, PropertyHint &r_hint, String &r_hint_string); #endif @@ -137,6 +144,7 @@ class CSharpScript : public Script { // Do not use unless you know what you are doing friend void GDMonoInternals::tie_managed_to_unmanaged(MonoObject *, Object *); static Ref<CSharpScript> create_for_managed_type(GDMonoClass *p_class, GDMonoClass *p_native); + static void initialize_for_managed_type(Ref<CSharpScript> p_script, GDMonoClass *p_class, GDMonoClass *p_native); protected: static void _bind_methods(); @@ -226,6 +234,8 @@ class CSharpInstance : public ScriptInstance { MultiplayerAPI::RPCMode _member_get_rpc_mode(IMonoClassMember *p_member) const; + void get_properties_state_for_reloading(List<Pair<StringName, Variant> > &r_state); + public: MonoObject *get_mono_object() const; @@ -276,6 +286,7 @@ struct CSharpScriptBinding { StringName type_name; GDMonoClass *wrapper_class; Ref<MonoGCHandle> gchandle; + Object *owner; }; class CSharpLanguage : public ScriptLanguage { @@ -305,6 +316,8 @@ class CSharpLanguage : public ScriptLanguage { StringName _notification; StringName _script_source; StringName dotctor; // .ctor + StringName on_before_serialize; // OnBeforeSerialize + StringName on_after_deserialize; // OnAfterDeserialize StringNameCache(); }; @@ -324,6 +337,12 @@ class CSharpLanguage : public ScriptLanguage { friend class GDMono; void _on_scripts_domain_unloaded(); +#ifdef TOOLS_ENABLED + EditorPlugin *godotsharp_editor; + + static void _editor_init_callback(); +#endif + public: StringNameCache string_names; @@ -336,6 +355,10 @@ public: _FORCE_INLINE_ static CSharpLanguage *get_singleton() { return singleton; } +#ifdef TOOLS_ENABLED + _FORCE_INLINE_ EditorPlugin *get_godotsharp_editor() const { return godotsharp_editor; } +#endif + static void release_script_gchandle(Ref<MonoGCHandle> &p_gchandle); static void release_script_gchandle(MonoObject *p_expected_obj, Ref<MonoGCHandle> &p_gchandle); diff --git a/modules/mono/editor/GodotSharpTools/.gitignore b/modules/mono/editor/GodotSharpTools/.gitignore deleted file mode 100644 index 296ad48834..0000000000 --- a/modules/mono/editor/GodotSharpTools/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# nuget packages -packages
\ No newline at end of file diff --git a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs deleted file mode 100644 index e5044feb75..0000000000 --- a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs +++ /dev/null @@ -1,425 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security; -using Microsoft.Build.Framework; - -namespace GodotSharpTools.Build -{ - public class BuildInstance : IDisposable - { - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static void godot_icall_BuildInstance_ExitCallback(string solution, string config, int exitCode); - - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static string godot_icall_BuildInstance_get_MSBuildPath(); - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static string godot_icall_BuildInstance_get_MonoWindowsBinDir(); - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static bool godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows(); - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static bool godot_icall_BuildInstance_get_PrintBuildOutput(); - - private static string GetMSBuildPath() - { - string msbuildPath = godot_icall_BuildInstance_get_MSBuildPath(); - - if (msbuildPath == null) - throw new FileNotFoundException("Cannot find the MSBuild executable."); - - return msbuildPath; - } - - private static string MonoWindowsBinDir - { - get - { - string monoWinBinDir = godot_icall_BuildInstance_get_MonoWindowsBinDir(); - - if (monoWinBinDir == null) - throw new FileNotFoundException("Cannot find the Windows Mono binaries directory."); - - return monoWinBinDir; - } - } - - private static bool UsingMonoMSBuildOnWindows - { - get - { - return godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows(); - } - } - - private static bool PrintBuildOutput - { - get - { - return godot_icall_BuildInstance_get_PrintBuildOutput(); - } - } - - private string solution; - private string config; - - private Process process; - - private int exitCode; - public int ExitCode { get { return exitCode; } } - - public bool IsRunning { get { return process != null && !process.HasExited; } } - - public BuildInstance(string solution, string config) - { - this.solution = solution; - this.config = config; - } - - public bool Build(string loggerAssemblyPath, string loggerOutputDir, string[] customProperties = null) - { - List<string> customPropertiesList = new List<string>(); - - if (customProperties != null) - customPropertiesList.AddRange(customProperties); - - string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customPropertiesList); - - ProcessStartInfo startInfo = new ProcessStartInfo(GetMSBuildPath(), compilerArgs); - - bool redirectOutput = !IsDebugMSBuildRequested() && !PrintBuildOutput; - - if (!redirectOutput) // TODO: or if stdout verbose - Console.WriteLine($"Running: \"{startInfo.FileName}\" {startInfo.Arguments}"); - - startInfo.RedirectStandardOutput = redirectOutput; - startInfo.RedirectStandardError = redirectOutput; - startInfo.UseShellExecute = false; - - if (UsingMonoMSBuildOnWindows) - { - // These environment variables are required for Mono's MSBuild to find the compilers. - // We use the batch files in Mono's bin directory to make sure the compilers are executed with mono. - string monoWinBinDir = MonoWindowsBinDir; - startInfo.EnvironmentVariables.Add("CscToolExe", Path.Combine(monoWinBinDir, "csc.bat")); - startInfo.EnvironmentVariables.Add("VbcToolExe", Path.Combine(monoWinBinDir, "vbc.bat")); - startInfo.EnvironmentVariables.Add("FscToolExe", Path.Combine(monoWinBinDir, "fsharpc.bat")); - } - - // Needed when running from Developer Command Prompt for VS - RemovePlatformVariable(startInfo.EnvironmentVariables); - - using (Process process = new Process()) - { - process.StartInfo = startInfo; - - process.Start(); - - if (redirectOutput) - { - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - } - - process.WaitForExit(); - - exitCode = process.ExitCode; - } - - return true; - } - - public bool BuildAsync(string loggerAssemblyPath, string loggerOutputDir, string[] customProperties = null) - { - if (process != null) - throw new InvalidOperationException("Already in use"); - - List<string> customPropertiesList = new List<string>(); - - if (customProperties != null) - customPropertiesList.AddRange(customProperties); - - string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customPropertiesList); - - ProcessStartInfo startInfo = new ProcessStartInfo(GetMSBuildPath(), compilerArgs); - - bool redirectOutput = !IsDebugMSBuildRequested() && !PrintBuildOutput; - - if (!redirectOutput) // TODO: or if stdout verbose - Console.WriteLine($"Running: \"{startInfo.FileName}\" {startInfo.Arguments}"); - - startInfo.RedirectStandardOutput = redirectOutput; - startInfo.RedirectStandardError = redirectOutput; - startInfo.UseShellExecute = false; - - if (UsingMonoMSBuildOnWindows) - { - // These environment variables are required for Mono's MSBuild to find the compilers. - // We use the batch files in Mono's bin directory to make sure the compilers are executed with mono. - string monoWinBinDir = MonoWindowsBinDir; - startInfo.EnvironmentVariables.Add("CscToolExe", Path.Combine(monoWinBinDir, "csc.bat")); - startInfo.EnvironmentVariables.Add("VbcToolExe", Path.Combine(monoWinBinDir, "vbc.bat")); - startInfo.EnvironmentVariables.Add("FscToolExe", Path.Combine(monoWinBinDir, "fsharpc.bat")); - } - - // Needed when running from Developer Command Prompt for VS - RemovePlatformVariable(startInfo.EnvironmentVariables); - - process = new Process(); - process.StartInfo = startInfo; - process.EnableRaisingEvents = true; - process.Exited += new EventHandler(BuildProcess_Exited); - - process.Start(); - - if (redirectOutput) - { - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - } - - return true; - } - - private string BuildArguments(string loggerAssemblyPath, string loggerOutputDir, List<string> customProperties) - { - string arguments = string.Format(@"""{0}"" /v:normal /t:Rebuild ""/p:{1}"" ""/l:{2},{3};{4}""", - solution, - "Configuration=" + config, - typeof(GodotBuildLogger).FullName, - loggerAssemblyPath, - loggerOutputDir - ); - - foreach (string customProperty in customProperties) - { - arguments += " /p:" + customProperty; - } - - return arguments; - } - - private void RemovePlatformVariable(StringDictionary environmentVariables) - { - // EnvironmentVariables is case sensitive? Seriously? - - List<string> platformEnvironmentVariables = new List<string>(); - - foreach (string env in environmentVariables.Keys) - { - if (env.ToUpper() == "PLATFORM") - platformEnvironmentVariables.Add(env); - } - - foreach (string env in platformEnvironmentVariables) - environmentVariables.Remove(env); - } - - private void BuildProcess_Exited(object sender, System.EventArgs e) - { - exitCode = process.ExitCode; - - godot_icall_BuildInstance_ExitCallback(solution, config, exitCode); - - Dispose(); - } - - private static bool IsDebugMSBuildRequested() - { - return Environment.GetEnvironmentVariable("GODOT_DEBUG_MSBUILD")?.Trim() == "1"; - } - - public void Dispose() - { - if (process != null) - { - process.Dispose(); - process = null; - } - } - } - - public class GodotBuildLogger : ILogger - { - public string Parameters { get; set; } - public LoggerVerbosity Verbosity { get; set; } - - public void Initialize(IEventSource eventSource) - { - if (null == Parameters) - throw new LoggerException("Log directory was not set."); - - string[] parameters = Parameters.Split(new[] { ';' }); - - string logDir = parameters[0]; - - if (String.IsNullOrEmpty(logDir)) - throw new LoggerException("Log directory was not set."); - - if (parameters.Length > 1) - throw new LoggerException("Too many parameters passed."); - - string logFile = Path.Combine(logDir, "msbuild_log.txt"); - string issuesFile = Path.Combine(logDir, "msbuild_issues.csv"); - - try - { - if (!Directory.Exists(logDir)) - Directory.CreateDirectory(logDir); - - this.logStreamWriter = new StreamWriter(logFile); - this.issuesStreamWriter = new StreamWriter(issuesFile); - } - catch (Exception ex) - { - if - ( - ex is UnauthorizedAccessException - || ex is ArgumentNullException - || ex is PathTooLongException - || ex is DirectoryNotFoundException - || ex is NotSupportedException - || ex is ArgumentException - || ex is SecurityException - || ex is IOException - ) - { - throw new LoggerException("Failed to create log file: " + ex.Message); - } - else - { - // Unexpected failure - throw; - } - } - - eventSource.ProjectStarted += new ProjectStartedEventHandler(eventSource_ProjectStarted); - eventSource.TaskStarted += new TaskStartedEventHandler(eventSource_TaskStarted); - eventSource.MessageRaised += new BuildMessageEventHandler(eventSource_MessageRaised); - eventSource.WarningRaised += new BuildWarningEventHandler(eventSource_WarningRaised); - eventSource.ErrorRaised += new BuildErrorEventHandler(eventSource_ErrorRaised); - eventSource.ProjectFinished += new ProjectFinishedEventHandler(eventSource_ProjectFinished); - } - - void eventSource_ErrorRaised(object sender, BuildErrorEventArgs e) - { - string line = String.Format("{0}({1},{2}): error {3}: {4}", e.File, e.LineNumber, e.ColumnNumber, e.Code, e.Message); - - if (e.ProjectFile.Length > 0) - line += string.Format(" [{0}]", e.ProjectFile); - - WriteLine(line); - - string errorLine = String.Format(@"error,{0},{1},{2},{3},{4},{5}", - e.File.CsvEscape(), e.LineNumber, e.ColumnNumber, - e.Code.CsvEscape(), e.Message.CsvEscape(), e.ProjectFile.CsvEscape()); - issuesStreamWriter.WriteLine(errorLine); - } - - void eventSource_WarningRaised(object sender, BuildWarningEventArgs e) - { - string line = String.Format("{0}({1},{2}): warning {3}: {4}", e.File, e.LineNumber, e.ColumnNumber, e.Code, e.Message, e.ProjectFile); - - if (e.ProjectFile != null && e.ProjectFile.Length > 0) - line += string.Format(" [{0}]", e.ProjectFile); - - WriteLine(line); - - string warningLine = String.Format(@"warning,{0},{1},{2},{3},{4},{5}", - e.File.CsvEscape(), e.LineNumber, e.ColumnNumber, - e.Code.CsvEscape(), e.Message.CsvEscape(), e.ProjectFile != null ? e.ProjectFile.CsvEscape() : string.Empty); - issuesStreamWriter.WriteLine(warningLine); - } - - void eventSource_MessageRaised(object sender, BuildMessageEventArgs e) - { - // BuildMessageEventArgs adds Importance to BuildEventArgs - // Let's take account of the verbosity setting we've been passed in deciding whether to log the message - if ((e.Importance == MessageImportance.High && IsVerbosityAtLeast(LoggerVerbosity.Minimal)) - || (e.Importance == MessageImportance.Normal && IsVerbosityAtLeast(LoggerVerbosity.Normal)) - || (e.Importance == MessageImportance.Low && IsVerbosityAtLeast(LoggerVerbosity.Detailed)) - ) - { - WriteLineWithSenderAndMessage(String.Empty, e); - } - } - - void eventSource_TaskStarted(object sender, TaskStartedEventArgs e) - { - // TaskStartedEventArgs adds ProjectFile, TaskFile, TaskName - // To keep this log clean, this logger will ignore these events. - } - - void eventSource_ProjectStarted(object sender, ProjectStartedEventArgs e) - { - WriteLine(e.Message); - indent++; - } - - void eventSource_ProjectFinished(object sender, ProjectFinishedEventArgs e) - { - indent--; - WriteLine(e.Message); - } - - /// <summary> - /// Write a line to the log, adding the SenderName - /// </summary> - private void WriteLineWithSender(string line, BuildEventArgs e) - { - if (0 == String.Compare(e.SenderName, "MSBuild", true /*ignore case*/)) - { - // Well, if the sender name is MSBuild, let's leave it out for prettiness - WriteLine(line); - } - else - { - WriteLine(e.SenderName + ": " + line); - } - } - - /// <summary> - /// Write a line to the log, adding the SenderName and Message - /// (these parameters are on all MSBuild event argument objects) - /// </summary> - private void WriteLineWithSenderAndMessage(string line, BuildEventArgs e) - { - if (0 == String.Compare(e.SenderName, "MSBuild", true /*ignore case*/)) - { - // Well, if the sender name is MSBuild, let's leave it out for prettiness - WriteLine(line + e.Message); - } - else - { - WriteLine(e.SenderName + ": " + line + e.Message); - } - } - - private void WriteLine(string line) - { - for (int i = indent; i > 0; i--) - { - logStreamWriter.Write("\t"); - } - logStreamWriter.WriteLine(line); - } - - public void Shutdown() - { - logStreamWriter.Close(); - issuesStreamWriter.Close(); - } - - public bool IsVerbosityAtLeast(LoggerVerbosity checkVerbosity) - { - return this.Verbosity >= checkVerbosity; - } - - private StreamWriter logStreamWriter; - private StreamWriter issuesStreamWriter; - private int indent; - } -} diff --git a/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs b/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs deleted file mode 100644 index 44a43f0ddd..0000000000 --- a/modules/mono/editor/GodotSharpTools/Editor/GodotSharpExport.cs +++ /dev/null @@ -1,75 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Runtime.CompilerServices; - -namespace GodotSharpTools.Editor -{ - public static class GodotSharpExport - { - public static void _ExportBegin(string[] features, bool debug, string path, int flags) - { - var featureSet = new HashSet<string>(features); - - if (PlatformHasTemplateDir(featureSet)) - { - string templateDirName = "data.mono"; - - if (featureSet.Contains("Windows")) - { - templateDirName += ".windows"; - templateDirName += featureSet.Contains("64") ? ".64" : ".32"; - } - else if (featureSet.Contains("X11")) - { - templateDirName += ".x11"; - templateDirName += featureSet.Contains("64") ? ".64" : ".32"; - } - else - { - throw new NotSupportedException("Target platform not supported"); - } - - templateDirName += debug ? ".release_debug" : ".release"; - - string templateDirPath = Path.Combine(GetTemplatesDir(), templateDirName); - - if (!Directory.Exists(templateDirPath)) - throw new FileNotFoundException("Data template directory not found"); - - string outputDir = new FileInfo(path).Directory.FullName; - - string outputDataDir = Path.Combine(outputDir, GetDataDirName()); - - if (Directory.Exists(outputDataDir)) - Directory.Delete(outputDataDir, recursive: true); // Clean first - - Directory.CreateDirectory(outputDataDir); - - foreach (string dir in Directory.GetDirectories(templateDirPath, "*", SearchOption.AllDirectories)) - { - Directory.CreateDirectory(Path.Combine(outputDataDir, dir.Substring(templateDirPath.Length + 1))); - } - - foreach (string file in Directory.GetFiles(templateDirPath, "*", SearchOption.AllDirectories)) - { - File.Copy(file, Path.Combine(outputDataDir, file.Substring(templateDirPath.Length + 1))); - } - } - } - - public static bool PlatformHasTemplateDir(HashSet<string> featureSet) - { - // OSX export templates are contained in a zip, so we place - // our custom template inside it and let Godot do the rest. - return !featureSet.Any(f => new[] {"OSX", "Android"}.Contains(f)); - } - - [MethodImpl(MethodImplOptions.InternalCall)] - extern static string GetTemplatesDir(); - - [MethodImpl(MethodImplOptions.InternalCall)] - extern static string GetDataDirName(); - } -} diff --git a/modules/mono/editor/GodotSharpTools/GodotSharpTools.sln b/modules/mono/editor/GodotSharpTools/GodotSharpTools.sln deleted file mode 100644 index 5f7d0e8a39..0000000000 --- a/modules/mono/editor/GodotSharpTools/GodotSharpTools.sln +++ /dev/null @@ -1,17 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotSharpTools", "GodotSharpTools.csproj", "{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Debug|Any CPU.Build.0 = Debug|Any CPU - {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection -EndGlobal diff --git a/modules/mono/editor/GodotSharpTools/Project/ProjectUtils.cs b/modules/mono/editor/GodotSharpTools/Project/ProjectUtils.cs deleted file mode 100644 index a13f4fd6ef..0000000000 --- a/modules/mono/editor/GodotSharpTools/Project/ProjectUtils.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System.Collections.Generic; -using System.IO; -using DotNet.Globbing; -using Microsoft.Build.Construction; - -namespace GodotSharpTools.Project -{ - public static class ProjectUtils - { - public static void AddItemToProjectChecked(string projectPath, string itemType, string include) - { - var dir = Directory.GetParent(projectPath).FullName; - var root = ProjectRootElement.Open(projectPath); - var normalizedInclude = include.RelativeToPath(dir).Replace("/", "\\"); - - if (root.AddItemChecked(itemType, normalizedInclude)) - root.Save(); - } - - private static string[] GetAllFilesRecursive(string rootDirectory, string mask) - { - string[] files = Directory.GetFiles(rootDirectory, mask, SearchOption.AllDirectories); - - // We want relative paths - for (int i = 0; i < files.Length; i++) { - files[i] = files[i].RelativeToPath(rootDirectory); - } - - return files; - } - - public static string[] GetIncludeFiles(string projectPath, string itemType) - { - var result = new List<string>(); - var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs"); - - GlobOptions globOptions = new GlobOptions(); - globOptions.Evaluation.CaseInsensitive = false; - - var root = ProjectRootElement.Open(projectPath); - - foreach (var itemGroup in root.ItemGroups) - { - if (itemGroup.Condition.Length != 0) - continue; - - foreach (var item in itemGroup.Items) - { - if (item.ItemType != itemType) - continue; - - string normalizedInclude = item.Include.NormalizePath(); - - var glob = Glob.Parse(normalizedInclude, globOptions); - - // TODO Check somehow if path has no blog to avoid the following loop... - - foreach (var existingFile in existingFiles) - { - if (glob.IsMatch(existingFile)) - { - result.Add(existingFile); - } - } - } - } - - return result.ToArray(); - } - } -} diff --git a/modules/mono/editor/GodotSharpTools/Utils/OS.cs b/modules/mono/editor/GodotSharpTools/Utils/OS.cs deleted file mode 100644 index 148e954e77..0000000000 --- a/modules/mono/editor/GodotSharpTools/Utils/OS.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Linq; -using System.Runtime.CompilerServices; - -namespace GodotSharpTools.Utils -{ - public static class OS - { - [MethodImpl(MethodImplOptions.InternalCall)] - extern static string GetPlatformName(); - - const string HaikuName = "Haiku"; - const string OSXName = "OSX"; - const string ServerName = "Server"; - const string UWPName = "UWP"; - const string WindowsName = "Windows"; - const string X11Name = "X11"; - - public static bool IsHaiku() - { - return HaikuName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); - } - - public static bool IsOSX() - { - return OSXName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); - } - - public static bool IsServer() - { - return ServerName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); - } - - public static bool IsUWP() - { - return UWPName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); - } - - public static bool IsWindows() - { - return WindowsName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); - } - - public static bool IsX11() - { - return X11Name.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); - } - - static bool? IsUnixCache = null; - static readonly string[] UnixPlatforms = new string[] { HaikuName, OSXName, ServerName, X11Name }; - - public static bool IsUnix() - { - if (IsUnixCache.HasValue) - return IsUnixCache.Value; - - string osName = GetPlatformName(); - IsUnixCache = UnixPlatforms.Any(p => p.Equals(osName, StringComparison.OrdinalIgnoreCase)); - return IsUnixCache.Value; - } - } -} diff --git a/modules/mono/editor/GodotTools/.gitignore b/modules/mono/editor/GodotTools/.gitignore new file mode 100644 index 0000000000..48e2f914d8 --- /dev/null +++ b/modules/mono/editor/GodotTools/.gitignore @@ -0,0 +1,356 @@ +# Rider +.idea/ + +# Visual Studio Code +.vscode/ + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs new file mode 100644 index 0000000000..a0f6f1ff32 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotBuildLogger.cs @@ -0,0 +1,186 @@ +using System; +using System.IO; +using System.Security; +using Microsoft.Build.Framework; +using GodotTools.Core; + +namespace GodotTools.BuildLogger +{ + public class GodotBuildLogger : ILogger + { + public static readonly string AssemblyPath = Path.GetFullPath(typeof(GodotBuildLogger).Assembly.Location); + + public string Parameters { get; set; } + public LoggerVerbosity Verbosity { get; set; } + + public void Initialize(IEventSource eventSource) + { + if (null == Parameters) + throw new LoggerException("Log directory was not set."); + + var parameters = Parameters.Split(new[] {';'}); + + string logDir = parameters[0]; + + if (string.IsNullOrEmpty(logDir)) + throw new LoggerException("Log directory was not set."); + + if (parameters.Length > 1) + throw new LoggerException("Too many parameters passed."); + + string logFile = Path.Combine(logDir, "msbuild_log.txt"); + string issuesFile = Path.Combine(logDir, "msbuild_issues.csv"); + + try + { + if (!Directory.Exists(logDir)) + Directory.CreateDirectory(logDir); + + logStreamWriter = new StreamWriter(logFile); + issuesStreamWriter = new StreamWriter(issuesFile); + } + catch (Exception ex) + { + if (ex is UnauthorizedAccessException + || ex is ArgumentNullException + || ex is PathTooLongException + || ex is DirectoryNotFoundException + || ex is NotSupportedException + || ex is ArgumentException + || ex is SecurityException + || ex is IOException) + { + throw new LoggerException("Failed to create log file: " + ex.Message); + } + else + { + // Unexpected failure + throw; + } + } + + eventSource.ProjectStarted += eventSource_ProjectStarted; + eventSource.TaskStarted += eventSource_TaskStarted; + eventSource.MessageRaised += eventSource_MessageRaised; + eventSource.WarningRaised += eventSource_WarningRaised; + eventSource.ErrorRaised += eventSource_ErrorRaised; + eventSource.ProjectFinished += eventSource_ProjectFinished; + } + + void eventSource_ErrorRaised(object sender, BuildErrorEventArgs e) + { + string line = $"{e.File}({e.LineNumber},{e.ColumnNumber}): error {e.Code}: {e.Message}"; + + if (e.ProjectFile.Length > 0) + line += $" [{e.ProjectFile}]"; + + WriteLine(line); + + string errorLine = $@"error,{e.File.CsvEscape()},{e.LineNumber},{e.ColumnNumber}," + + $@"{e.Code.CsvEscape()},{e.Message.CsvEscape()},{e.ProjectFile.CsvEscape()}"; + issuesStreamWriter.WriteLine(errorLine); + } + + void eventSource_WarningRaised(object sender, BuildWarningEventArgs e) + { + string line = $"{e.File}({e.LineNumber},{e.ColumnNumber}): warning {e.Code}: {e.Message}"; + + if (!string.IsNullOrEmpty(e.ProjectFile)) + line += $" [{e.ProjectFile}]"; + + WriteLine(line); + + string warningLine = $@"warning,{e.File.CsvEscape()},{e.LineNumber},{e.ColumnNumber},{e.Code.CsvEscape()}," + + $@"{e.Message.CsvEscape()},{(e.ProjectFile != null ? e.ProjectFile.CsvEscape() : string.Empty)}"; + issuesStreamWriter.WriteLine(warningLine); + } + + private void eventSource_MessageRaised(object sender, BuildMessageEventArgs e) + { + // BuildMessageEventArgs adds Importance to BuildEventArgs + // Let's take account of the verbosity setting we've been passed in deciding whether to log the message + if (e.Importance == MessageImportance.High && IsVerbosityAtLeast(LoggerVerbosity.Minimal) + || e.Importance == MessageImportance.Normal && IsVerbosityAtLeast(LoggerVerbosity.Normal) + || e.Importance == MessageImportance.Low && IsVerbosityAtLeast(LoggerVerbosity.Detailed)) + { + WriteLineWithSenderAndMessage(string.Empty, e); + } + } + + private void eventSource_TaskStarted(object sender, TaskStartedEventArgs e) + { + // TaskStartedEventArgs adds ProjectFile, TaskFile, TaskName + // To keep this log clean, this logger will ignore these events. + } + + private void eventSource_ProjectStarted(object sender, ProjectStartedEventArgs e) + { + WriteLine(e.Message); + indent++; + } + + private void eventSource_ProjectFinished(object sender, ProjectFinishedEventArgs e) + { + indent--; + WriteLine(e.Message); + } + + /// <summary> + /// Write a line to the log, adding the SenderName + /// </summary> + private void WriteLineWithSender(string line, BuildEventArgs e) + { + if (0 == string.Compare(e.SenderName, "MSBuild", StringComparison.OrdinalIgnoreCase)) + { + // Well, if the sender name is MSBuild, let's leave it out for prettiness + WriteLine(line); + } + else + { + WriteLine(e.SenderName + ": " + line); + } + } + + /// <summary> + /// Write a line to the log, adding the SenderName and Message + /// (these parameters are on all MSBuild event argument objects) + /// </summary> + private void WriteLineWithSenderAndMessage(string line, BuildEventArgs e) + { + if (0 == string.Compare(e.SenderName, "MSBuild", StringComparison.OrdinalIgnoreCase)) + { + // Well, if the sender name is MSBuild, let's leave it out for prettiness + WriteLine(line + e.Message); + } + else + { + WriteLine(e.SenderName + ": " + line + e.Message); + } + } + + private void WriteLine(string line) + { + for (int i = indent; i > 0; i--) + { + logStreamWriter.Write("\t"); + } + + logStreamWriter.WriteLine(line); + } + + public void Shutdown() + { + logStreamWriter.Close(); + issuesStreamWriter.Close(); + } + + private bool IsVerbosityAtLeast(LoggerVerbosity checkVerbosity) + { + return Verbosity >= checkVerbosity; + } + + private StreamWriter logStreamWriter; + private StreamWriter issuesStreamWriter; + private int indent; + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj new file mode 100644 index 0000000000..f3ac353c0f --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/GodotTools.BuildLogger.csproj @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>GodotTools.BuildLogger</RootNamespace> + <AssemblyName>GodotTools.BuildLogger</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugSymbols>true</DebugSymbols> + <DebugType>portable</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <PlatformTarget>AnyCPU</PlatformTarget> + <DebugType>portable</DebugType> + <Optimize>true</Optimize> + <OutputPath>bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <ItemGroup> + <Reference Include="Microsoft.Build.Framework" /> + <Reference Include="System" /> + <Reference Include="System.Core" /> + <Reference Include="System.Data" /> + <Reference Include="System.Xml" /> + </ItemGroup> + <ItemGroup> + <Compile Include="GodotBuildLogger.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj"> + <Project>{639e48bd-44e5-4091-8edd-22d36dc0768d}</Project> + <Name>GodotTools.Core</Name> + </ProjectReference> + </ItemGroup> + <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> + <!-- To modify your build process, add your task inside one of the targets below and uncomment it. + Other similar extension points exist, see Microsoft.Common.targets. + <Target Name="BeforeBuild"> + </Target> + <Target Name="AfterBuild"> + </Target> + --> +</Project>
\ No newline at end of file diff --git a/modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..8717c4901e --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.BuildLogger/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("GodotTools.BuildLogger")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Godot Engine contributors")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("6CE9A984-37B1-4F8A-8FE9-609F05F071B3")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj new file mode 100644 index 0000000000..f36b40f87c --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.Core/GodotTools.Core.csproj @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</ProjectGuid> + <OutputType>Library</OutputType> + <RootNamespace>GodotTools.Core</RootNamespace> + <AssemblyName>GodotTools.Core</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug</OutputPath> + <DefineConstants>DEBUG;</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <ConsolePause>false</ConsolePause> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <Optimize>true</Optimize> + <OutputPath>bin\Release</OutputPath> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <ConsolePause>false</ConsolePause> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + </ItemGroup> + <ItemGroup> + <Compile Include="ProcessExtensions.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="StringExtensions.cs" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/ProcessExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.Core/ProcessExtensions.cs new file mode 100644 index 0000000000..43d40f2ad9 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.Core/ProcessExtensions.cs @@ -0,0 +1,38 @@ +using System; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; + +namespace GodotTools.Core +{ + public static class ProcessExtensions + { + public static async Task WaitForExitAsync(this Process process, CancellationToken cancellationToken = default(CancellationToken)) + { + var tcs = new TaskCompletionSource<bool>(); + + void ProcessExited(object sender, EventArgs e) + { + tcs.TrySetResult(true); + } + + process.EnableRaisingEvents = true; + process.Exited += ProcessExited; + + try + { + if (process.HasExited) + return; + + using (cancellationToken.Register(() => tcs.TrySetCanceled())) + { + await tcs.Task; + } + } + finally + { + process.Exited -= ProcessExited; + } + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools.Core/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.Core/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..699ae6e741 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.Core/Properties/AssemblyInfo.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("GodotTools.Core")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Godot Engine contributors")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] diff --git a/modules/mono/editor/GodotSharpTools/StringExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs index b0436d2f18..8cd7e76303 100644 --- a/modules/mono/editor/GodotSharpTools/StringExtensions.cs +++ b/modules/mono/editor/GodotTools/GodotTools.Core/StringExtensions.cs @@ -1,7 +1,8 @@ using System; +using System.Collections.Generic; using System.IO; -namespace GodotSharpTools +namespace GodotTools.Core { public static class StringExtensions { @@ -25,7 +26,7 @@ namespace GodotSharpTools path = path.Replace('\\', '/'); - string[] parts = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); + string[] parts = path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries); path = string.Join(Path.DirectorySeparatorChar.ToString(), parts).Trim(); @@ -37,18 +38,40 @@ namespace GodotSharpTools public static bool IsAbsolutePath(this string path) { return path.StartsWith("/", StringComparison.Ordinal) || - path.StartsWith("\\", StringComparison.Ordinal) || - path.StartsWith(driveRoot, StringComparison.Ordinal); + path.StartsWith("\\", StringComparison.Ordinal) || + path.StartsWith(driveRoot, StringComparison.Ordinal); } public static string CsvEscape(this string value, char delimiter = ',') { - bool hasSpecialChar = value.IndexOfAny(new char[] { '\"', '\n', '\r', delimiter }) != -1; + bool hasSpecialChar = value.IndexOfAny(new char[] {'\"', '\n', '\r', delimiter}) != -1; if (hasSpecialChar) return "\"" + value.Replace("\"", "\"\"") + "\""; return value; } + + public static string ToSafeDirName(this string dirName, bool allowDirSeparator) + { + var invalidChars = new List<string> {":", "*", "?", "\"", "<", ">", "|"}; + + if (allowDirSeparator) + { + // Directory separators are allowed, but disallow ".." to avoid going up the filesystem + invalidChars.Add(".."); + } + else + { + invalidChars.Add("/"); + } + + string safeDirName = dirName.Replace("\\", "/").Trim(); + + foreach (string invalidChar in invalidChars) + safeDirName = safeDirName.Replace(invalidChar, "-"); + + return safeDirName; + } } } diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ApiAssembliesInfo.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ApiAssembliesInfo.cs new file mode 100644 index 0000000000..345a472185 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ApiAssembliesInfo.cs @@ -0,0 +1,15 @@ +namespace GodotTools +{ + public static class ApiAssemblyNames + { + public const string SolutionName = "GodotSharp"; + public const string Core = "GodotSharp"; + public const string Editor = "GodotSharpEditor"; + } + + public enum ApiAssemblyType + { + Core, + Editor + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ApiSolutionGenerator.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ApiSolutionGenerator.cs new file mode 100644 index 0000000000..bfae2afc13 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ApiSolutionGenerator.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; +using System.IO; + +namespace GodotTools.ProjectEditor +{ + public static class ApiSolutionGenerator + { + public static void GenerateApiSolution(string solutionDir, + string coreProjDir, IEnumerable<string> coreCompileItems, + string editorProjDir, IEnumerable<string> editorCompileItems) + { + var solution = new DotNetSolution(ApiAssemblyNames.SolutionName); + + solution.DirectoryPath = solutionDir; + + // GodotSharp project + + const string coreApiAssemblyName = ApiAssemblyNames.Core; + + string coreGuid = ProjectGenerator.GenCoreApiProject(coreProjDir, coreCompileItems); + + var coreProjInfo = new DotNetSolution.ProjectInfo + { + Guid = coreGuid, + PathRelativeToSolution = Path.Combine(coreApiAssemblyName, $"{coreApiAssemblyName}.csproj") + }; + coreProjInfo.Configs.Add("Debug"); + coreProjInfo.Configs.Add("Release"); + + solution.AddNewProject(coreApiAssemblyName, coreProjInfo); + + // GodotSharpEditor project + + const string editorApiAssemblyName = ApiAssemblyNames.Editor; + + string editorGuid = ProjectGenerator.GenEditorApiProject(editorProjDir, + $"../{coreApiAssemblyName}/{coreApiAssemblyName}.csproj", editorCompileItems); + + var editorProjInfo = new DotNetSolution.ProjectInfo(); + editorProjInfo.Guid = editorGuid; + editorProjInfo.PathRelativeToSolution = Path.Combine(editorApiAssemblyName, $"{editorApiAssemblyName}.csproj"); + editorProjInfo.Configs.Add("Debug"); + editorProjInfo.Configs.Add("Release"); + + solution.AddNewProject(editorApiAssemblyName, editorProjInfo); + + // Save solution + + solution.Save(); + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs new file mode 100644 index 0000000000..76cb249acf --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/DotNetSolution.cs @@ -0,0 +1,122 @@ +using GodotTools.Core; +using System.Collections.Generic; +using System.IO; + +namespace GodotTools.ProjectEditor +{ + public class DotNetSolution + { + private string directoryPath; + private readonly Dictionary<string, ProjectInfo> projects = new Dictionary<string, ProjectInfo>(); + + public string Name { get; } + + public string DirectoryPath + { + get => directoryPath; + set => directoryPath = value.IsAbsolutePath() ? value : Path.GetFullPath(value); + } + + public class ProjectInfo + { + public string Guid; + public string PathRelativeToSolution; + public List<string> Configs = new List<string>(); + } + + public void AddNewProject(string name, ProjectInfo projectInfo) + { + projects[name] = projectInfo; + } + + public bool HasProject(string name) + { + return projects.ContainsKey(name); + } + + public ProjectInfo GetProjectInfo(string name) + { + return projects[name]; + } + + public bool RemoveProject(string name) + { + return projects.Remove(name); + } + + public void Save() + { + if (!Directory.Exists(DirectoryPath)) + throw new FileNotFoundException("The solution directory does not exist."); + + string projectsDecl = string.Empty; + string slnPlatformsCfg = string.Empty; + string projPlatformsCfg = string.Empty; + + bool isFirstProject = true; + + foreach (var pair in projects) + { + string name = pair.Key; + ProjectInfo projectInfo = pair.Value; + + if (!isFirstProject) + projectsDecl += "\n"; + + projectsDecl += string.Format(ProjectDeclaration, + name, projectInfo.PathRelativeToSolution.Replace("/", "\\"), projectInfo.Guid); + + for (int i = 0; i < projectInfo.Configs.Count; i++) + { + string config = projectInfo.Configs[i]; + + if (i != 0 || !isFirstProject) + { + slnPlatformsCfg += "\n"; + projPlatformsCfg += "\n"; + } + + slnPlatformsCfg += string.Format(SolutionPlatformsConfig, config); + projPlatformsCfg += string.Format(ProjectPlatformsConfig, projectInfo.Guid, config); + } + + isFirstProject = false; + } + + string solutionPath = Path.Combine(DirectoryPath, Name + ".sln"); + string content = string.Format(SolutionTemplate, projectsDecl, slnPlatformsCfg, projPlatformsCfg); + + File.WriteAllText(solutionPath, content); + } + + public DotNetSolution(string name) + { + Name = name; + } + + const string SolutionTemplate = +@"Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +{0} +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution +{1} + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution +{2} + EndGlobalSection +EndGlobal +"; + + const string ProjectDeclaration = +@"Project(""{{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}}"") = ""{0}"", ""{1}"", ""{{{2}}}"" +EndProject"; + + const string SolutionPlatformsConfig = +@" {0}|Any CPU = {0}|Any CPU"; + + const string ProjectPlatformsConfig = +@" {{{0}}}.{1}|Any CPU.ActiveCfg = {1}|Any CPU + {{{0}}}.{1}|Any CPU.Build.0 = {1}|Any CPU"; + } +} diff --git a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj index 2871c041f5..08b8ba3946 100644 --- a/modules/mono/editor/GodotSharpTools/GodotSharpTools.csproj +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/GodotTools.ProjectEditor.csproj @@ -1,12 +1,12 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ProjectGuid>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</ProjectGuid> <OutputType>Library</OutputType> - <RootNamespace>GodotSharpTools</RootNamespace> - <AssemblyName>GodotSharpTools</AssemblyName> + <RootNamespace>GodotTools.ProjectEditor</RootNamespace> + <AssemblyName>GodotTools.ProjectEditor</AssemblyName> <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> <BaseIntermediateOutputPath>obj</BaseIntermediateOutputPath> </PropertyGroup> @@ -21,7 +21,6 @@ <ConsolePause>false</ConsolePause> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <DebugType>portable</DebugType> <Optimize>true</Optimize> <OutputPath>bin\Release</OutputPath> <ErrorReport>prompt</ErrorReport> @@ -31,25 +30,35 @@ <ItemGroup> <Reference Include="System" /> <Reference Include="Microsoft.Build" /> - <Reference Include="Microsoft.Build.Framework" /> <Reference Include="DotNet.Glob, Version=2.1.1.0, Culture=neutral, PublicKeyToken=b68cc888b4f632d1, processorArchitecture=MSIL"> - <HintPath>packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath> + <!-- + When building Godot with 'mono_glue=no' SCons will build this project alone instead of the + entire solution. $(SolutionDir) is not defined in that case, so we need to workaround that. + We make SCons restore the NuGet packages in the project directory instead in this case. + --> + <HintPath Condition=" '$(SolutionDir)' != '' ">$(SolutionDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath> + <HintPath>$(ProjectDir)\packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath> + <HintPath>packages\DotNet.Glob.2.1.1\lib\net45\DotNet.Glob.dll</HintPath> <!-- Are you happy CI? --> </Reference> </ItemGroup> <ItemGroup> - <Compile Include="StringExtensions.cs" /> - <Compile Include="Build\BuildSystem.cs" /> - <Compile Include="Editor\MonoDevelopInstance.cs" /> - <Compile Include="Project\ProjectExtensions.cs" /> - <Compile Include="Project\IdentifierUtils.cs" /> - <Compile Include="Project\ProjectGenerator.cs" /> - <Compile Include="Project\ProjectUtils.cs" /> + <Compile Include="ApiAssembliesInfo.cs" /> + <Compile Include="ApiSolutionGenerator.cs" /> + <Compile Include="DotNetSolution.cs" /> <Compile Include="Properties\AssemblyInfo.cs" /> - <Compile Include="Utils\OS.cs" /> - <Compile Include="Editor\GodotSharpExport.cs" /> + <Compile Include="IdentifierUtils.cs" /> + <Compile Include="ProjectExtensions.cs" /> + <Compile Include="ProjectGenerator.cs" /> + <Compile Include="ProjectUtils.cs" /> </ItemGroup> <ItemGroup> <None Include="packages.config" /> </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj"> + <Project>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</Project> + <Name>GodotTools.Core</Name> + </ProjectReference> + </ItemGroup> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> -</Project>
\ No newline at end of file +</Project> diff --git a/modules/mono/editor/GodotSharpTools/Project/IdentifierUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/IdentifierUtils.cs index 83e2d2cf8d..f93eb9a1fa 100644 --- a/modules/mono/editor/GodotSharpTools/Project/IdentifierUtils.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/IdentifierUtils.cs @@ -3,7 +3,7 @@ using System.Collections.Generic; using System.Globalization; using System.Text; -namespace GodotSharpTools.Project +namespace GodotTools.ProjectEditor { public static class IdentifierUtils { @@ -12,7 +12,7 @@ namespace GodotSharpTools.Project if (string.IsNullOrEmpty(qualifiedIdentifier)) throw new ArgumentException($"{nameof(qualifiedIdentifier)} cannot be empty", nameof(qualifiedIdentifier)); - string[] identifiers = qualifiedIdentifier.Split(new[] { '.' }); + string[] identifiers = qualifiedIdentifier.Split('.'); for (int i = 0; i < identifiers.Length; i++) { @@ -66,8 +66,6 @@ namespace GodotSharpTools.Project if (identifierBuilder.Length > startIndex || @char == '_') identifierBuilder.Append(@char); break; - default: - break; } } @@ -97,14 +95,14 @@ namespace GodotSharpTools.Project } else { - if (_doubleUnderscoreKeywords.Contains(value)) + if (DoubleUnderscoreKeywords.Contains(value)) return true; } - return _keywords.Contains(value); + return Keywords.Contains(value); } - static HashSet<string> _doubleUnderscoreKeywords = new HashSet<string> + private static readonly HashSet<string> DoubleUnderscoreKeywords = new HashSet<string> { "__arglist", "__makeref", @@ -112,7 +110,7 @@ namespace GodotSharpTools.Project "__refvalue", }; - static HashSet<string> _keywords = new HashSet<string> + private static readonly HashSet<string> Keywords = new HashSet<string> { "as", "do", diff --git a/modules/mono/editor/GodotSharpTools/Project/ProjectExtensions.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs index 647d9ac81d..36961eb45e 100644 --- a/modules/mono/editor/GodotSharpTools/Project/ProjectExtensions.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectExtensions.cs @@ -1,8 +1,9 @@ +using GodotTools.Core; using System; using DotNet.Globbing; using Microsoft.Build.Construction; -namespace GodotSharpTools.Project +namespace GodotTools.ProjectEditor { public static class ProjectExtensions { diff --git a/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs index f4ab11a222..4f21871f1a 100644 --- a/modules/mono/editor/GodotSharpTools/Project/ProjectGenerator.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectGenerator.cs @@ -1,17 +1,19 @@ +using GodotTools.Core; using System; +using System.Collections.Generic; using System.IO; using Microsoft.Build.Construction; -namespace GodotSharpTools.Project +namespace GodotTools.ProjectEditor { public static class ProjectGenerator { - public const string CoreApiProjectName = "GodotSharp"; - public const string EditorApiProjectName = "GodotSharpEditor"; - const string CoreApiProjectGuid = "{AEBF0036-DA76-4341-B651-A3F2856AB2FA}"; - const string EditorApiProjectGuid = "{8FBEC238-D944-4074-8548-B3B524305905}"; + private const string CoreApiProjectName = "GodotSharp"; + private const string EditorApiProjectName = "GodotSharpEditor"; + private const string CoreApiProjectGuid = "{AEBF0036-DA76-4341-B651-A3F2856AB2FA}"; + private const string EditorApiProjectGuid = "{8FBEC238-D944-4074-8548-B3B524305905}"; - public static string GenCoreApiProject(string dir, string[] compileItems) + public static string GenCoreApiProject(string dir, IEnumerable<string> compileItems) { string path = Path.Combine(dir, CoreApiProjectName + ".csproj"); @@ -24,8 +26,8 @@ namespace GodotSharpTools.Project mainGroup.SetProperty("BaseIntermediateOutputPath", "obj"); GenAssemblyInfoFile(root, dir, CoreApiProjectName, - new string[] { "[assembly: InternalsVisibleTo(\"" + EditorApiProjectName + "\")]" }, - new string[] { "System.Runtime.CompilerServices" }); + new[] {"[assembly: InternalsVisibleTo(\"" + EditorApiProjectName + "\")]"}, + new[] {"System.Runtime.CompilerServices"}); foreach (var item in compileItems) { @@ -37,7 +39,7 @@ namespace GodotSharpTools.Project return CoreApiProjectGuid; } - public static string GenEditorApiProject(string dir, string coreApiProjPath, string[] compileItems) + public static string GenEditorApiProject(string dir, string coreApiProjPath, IEnumerable<string> compileItems) { string path = Path.Combine(dir, EditorApiProjectName + ".csproj"); @@ -64,7 +66,7 @@ namespace GodotSharpTools.Project return EditorApiProjectGuid; } - public static string GenGameProject(string dir, string name, string[] compileItems) + public static string GenGameProject(string dir, string name, IEnumerable<string> compileItems) { string path = Path.Combine(dir, name + ".csproj"); @@ -74,6 +76,8 @@ namespace GodotSharpTools.Project mainGroup.SetProperty("OutputPath", Path.Combine(".mono", "temp", "bin", "$(Configuration)")); mainGroup.SetProperty("BaseIntermediateOutputPath", Path.Combine(".mono", "temp", "obj")); mainGroup.SetProperty("IntermediateOutputPath", Path.Combine("$(BaseIntermediateOutputPath)", "$(Configuration)")); + mainGroup.SetProperty("ApiConfiguration", "Debug").Condition = " '$(Configuration)' != 'Release' "; + mainGroup.SetProperty("ApiConfiguration", "Release").Condition = " '$(Configuration)' == 'Release' "; var toolsGroup = root.AddPropertyGroup(); toolsGroup.Condition = " '$(Configuration)|$(Platform)' == 'Tools|AnyCPU' "; @@ -86,12 +90,12 @@ namespace GodotSharpTools.Project toolsGroup.AddProperty("ConsolePause", "false"); var coreApiRef = root.AddItem("Reference", CoreApiProjectName); - coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", CoreApiProjectName + ".dll")); + coreApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", CoreApiProjectName + ".dll")); coreApiRef.AddMetadata("Private", "False"); var editorApiRef = root.AddItem("Reference", EditorApiProjectName); editorApiRef.Condition = " '$(Configuration)' == 'Tools' "; - editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", EditorApiProjectName + ".dll")); + editorApiRef.AddMetadata("HintPath", Path.Combine("$(ProjectDir)", ".mono", "assemblies", "$(ApiConfiguration)", EditorApiProjectName + ".dll")); editorApiRef.AddMetadata("Private", "False"); GenAssemblyInfoFile(root, dir, name); @@ -108,7 +112,6 @@ namespace GodotSharpTools.Project public static void GenAssemblyInfoFile(ProjectRootElement root, string dir, string name, string[] assemblyLines = null, string[] usingDirectives = null) { - string propertiesDir = Path.Combine(dir, "Properties"); if (!Directory.Exists(propertiesDir)) Directory.CreateDirectory(propertiesDir); @@ -124,12 +127,9 @@ namespace GodotSharpTools.Project string assemblyLinesText = string.Empty; if (assemblyLines != null) - { - foreach (var assemblyLine in assemblyLines) - assemblyLinesText += string.Join("\n", assemblyLines) + "\n"; - } + assemblyLinesText += string.Join("\n", assemblyLines) + "\n"; - string content = string.Format(assemblyInfoTemplate, usingDirectivesText, name, assemblyLinesText); + string content = string.Format(AssemblyInfoTemplate, usingDirectivesText, name, assemblyLinesText); string assemblyInfoFile = Path.Combine(propertiesDir, "AssemblyInfo.cs"); @@ -194,8 +194,8 @@ namespace GodotSharpTools.Project } } - private const string assemblyInfoTemplate = -@"using System.Reflection;{0} + private const string AssemblyInfoTemplate = + @"using System.Reflection;{0} // Information about this assembly is defined by the following attributes. // Change them to the values specific to your project. diff --git a/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs new file mode 100644 index 0000000000..1edc426e00 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/ProjectUtils.cs @@ -0,0 +1,175 @@ +using GodotTools.Core; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using DotNet.Globbing; +using Microsoft.Build.Construction; + +namespace GodotTools.ProjectEditor +{ + public static class ProjectUtils + { + public static void AddItemToProjectChecked(string projectPath, string itemType, string include) + { + var dir = Directory.GetParent(projectPath).FullName; + var root = ProjectRootElement.Open(projectPath); + Debug.Assert(root != null); + + var normalizedInclude = include.RelativeToPath(dir).Replace("/", "\\"); + + if (root.AddItemChecked(itemType, normalizedInclude)) + root.Save(); + } + + private static string[] GetAllFilesRecursive(string rootDirectory, string mask) + { + string[] files = Directory.GetFiles(rootDirectory, mask, SearchOption.AllDirectories); + + // We want relative paths + for (int i = 0; i < files.Length; i++) + { + files[i] = files[i].RelativeToPath(rootDirectory); + } + + return files; + } + + public static string[] GetIncludeFiles(string projectPath, string itemType) + { + var result = new List<string>(); + var existingFiles = GetAllFilesRecursive(Path.GetDirectoryName(projectPath), "*.cs"); + + var globOptions = new GlobOptions(); + globOptions.Evaluation.CaseInsensitive = false; + + var root = ProjectRootElement.Open(projectPath); + + foreach (var itemGroup in root.ItemGroups) + { + if (itemGroup.Condition.Length != 0) + continue; + + foreach (var item in itemGroup.Items) + { + if (item.ItemType != itemType) + continue; + + string normalizedInclude = item.Include.NormalizePath(); + + var glob = Glob.Parse(normalizedInclude, globOptions); + + // TODO Check somehow if path has no blob to avoid the following loop... + + foreach (var existingFile in existingFiles) + { + if (glob.IsMatch(existingFile)) + { + result.Add(existingFile); + } + } + } + } + + return result.ToArray(); + } + + /// Simple function to make sure the Api assembly references are configured correctly + public static void FixApiHintPath(string projectPath) + { + var root = ProjectRootElement.Open(projectPath); + Debug.Assert(root != null); + + bool dirty = false; + + void AddPropertyIfNotPresent(string name, string condition, string value) + { + if (root.PropertyGroups + .Any(g => g.Condition == string.Empty || g.Condition == condition && + g.Properties + .Any(p => p.Name == name && + p.Value == value && + (p.Condition == condition || g.Condition == condition)))) + { + return; + } + + root.AddProperty(name, value).Condition = condition; + dirty = true; + } + + AddPropertyIfNotPresent(name: "ApiConfiguration", + condition: " '$(Configuration)' != 'Release' ", + value: "Debug"); + AddPropertyIfNotPresent(name: "ApiConfiguration", + condition: " '$(Configuration)' == 'Release' ", + value: "Release"); + + void SetReferenceHintPath(string referenceName, string condition, string hintPath) + { + foreach (var itemGroup in root.ItemGroups.Where(g => + g.Condition == string.Empty || g.Condition == condition)) + { + var references = itemGroup.Items.Where(item => + item.ItemType == "Reference" && + item.Include == referenceName && + (item.Condition == condition || itemGroup.Condition == condition)); + + var referencesWithHintPath = references.Where(reference => + reference.Metadata.Any(m => m.Name == "HintPath")); + + if (referencesWithHintPath.Any(reference => reference.Metadata + .Any(m => m.Name == "HintPath" && m.Value == hintPath))) + { + // Found a Reference item with the right HintPath + return; + } + + var referenceWithHintPath = referencesWithHintPath.FirstOrDefault(); + if (referenceWithHintPath != null) + { + // Found a Reference item with a wrong HintPath + foreach (var metadata in referenceWithHintPath.Metadata.ToList() + .Where(m => m.Name == "HintPath")) + { + // Safe to remove as we duplicate with ToList() to loop + referenceWithHintPath.RemoveChild(metadata); + } + + referenceWithHintPath.AddMetadata("HintPath", hintPath); + dirty = true; + return; + } + + var referenceWithoutHintPath = references.FirstOrDefault(); + if (referenceWithoutHintPath != null) + { + // Found a Reference item without a HintPath + referenceWithoutHintPath.AddMetadata("HintPath", hintPath); + dirty = true; + return; + } + } + + // Found no Reference item at all. Add it. + root.AddItem("Reference", referenceName).Condition = condition; + dirty = true; + } + + const string coreProjectName = "GodotSharp"; + const string editorProjectName = "GodotSharpEditor"; + + const string coreCondition = ""; + const string editorCondition = " '$(Configuration)' == 'Tools' "; + + var coreHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{coreProjectName}.dll"; + var editorHintPath = $"$(ProjectDir)/.mono/assemblies/$(ApiConfiguration)/{editorProjectName}.dll"; + + SetReferenceHintPath(coreProjectName, coreCondition, coreHintPath); + SetReferenceHintPath(editorProjectName, editorCondition, editorHintPath); + + if (dirty) + root.Save(); + } + } +} diff --git a/modules/mono/editor/GodotSharpTools/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs index 7115d8fc71..09333850fc 100644 --- a/modules/mono/editor/GodotSharpTools/Properties/AssemblyInfo.cs +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/Properties/AssemblyInfo.cs @@ -4,12 +4,12 @@ using System.Runtime.CompilerServices; // Information about this assembly is defined by the following attributes. // Change them to the values specific to your project. -[assembly: AssemblyTitle("GodotSharpTools")] +[assembly: AssemblyTitle("GodotTools.ProjectEditor")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("ignacio")] +[assembly: AssemblyCopyright("Godot Engine contributors")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/modules/mono/editor/GodotSharpTools/packages.config b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config index 2c7cb0bd4b..13915000e4 100644 --- a/modules/mono/editor/GodotSharpTools/packages.config +++ b/modules/mono/editor/GodotTools/GodotTools.ProjectEditor/packages.config @@ -1,4 +1,4 @@ -<?xml version="1.0" encoding="utf-8"?> +<?xml version="1.0" encoding="utf-8"?> <packages> <package id="DotNet.Glob" version="2.1.1" targetFramework="net45" /> </packages>
\ No newline at end of file diff --git a/modules/mono/editor/GodotTools/GodotTools.sln b/modules/mono/editor/GodotTools/GodotTools.sln new file mode 100644 index 0000000000..6f7d44bec2 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools.sln @@ -0,0 +1,35 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2012 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.ProjectEditor", "GodotTools.ProjectEditor\GodotTools.ProjectEditor.csproj", "{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools", "GodotTools\GodotTools.csproj", "{27B00618-A6F2-4828-B922-05CAEB08C286}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.Core", "GodotTools.Core\GodotTools.Core.csproj", "{639E48BD-44E5-4091-8EDD-22D36DC0768D}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GodotTools.BuildLogger", "GodotTools.BuildLogger\GodotTools.BuildLogger.csproj", "{6CE9A984-37B1-4F8A-8FE9-609F05F071B3}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}.Release|Any CPU.Build.0 = Release|Any CPU + {27B00618-A6F2-4828-B922-05CAEB08C286}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {27B00618-A6F2-4828-B922-05CAEB08C286}.Debug|Any CPU.Build.0 = Debug|Any CPU + {27B00618-A6F2-4828-B922-05CAEB08C286}.Release|Any CPU.ActiveCfg = Release|Any CPU + {27B00618-A6F2-4828-B922-05CAEB08C286}.Release|Any CPU.Build.0 = Release|Any CPU + {639E48BD-44E5-4091-8EDD-22D36DC0768D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {639E48BD-44E5-4091-8EDD-22D36DC0768D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {639E48BD-44E5-4091-8EDD-22D36DC0768D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {639E48BD-44E5-4091-8EDD-22D36DC0768D}.Release|Any CPU.Build.0 = Release|Any CPU + {6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CE9A984-37B1-4F8A-8FE9-609F05F071B3}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs new file mode 100644 index 0000000000..f849356919 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Build/BuildSystem.cs @@ -0,0 +1,172 @@ +using GodotTools.Core; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; +using GodotTools.BuildLogger; +using GodotTools.Internals; +using GodotTools.Utils; +using Directory = System.IO.Directory; + +namespace GodotTools.Build +{ + public static class BuildSystem + { + private static string GetMsBuildPath() + { + string msbuildPath = MsBuildFinder.FindMsBuild(); + + if (msbuildPath == null) + throw new FileNotFoundException("Cannot find the MSBuild executable."); + + return msbuildPath; + } + + private static string MonoWindowsBinDir + { + get + { + string monoWinBinDir = Path.Combine(Internal.MonoWindowsInstallRoot, "bin"); + + if (!Directory.Exists(monoWinBinDir)) + throw new FileNotFoundException("Cannot find the Windows Mono install bin directory."); + + return monoWinBinDir; + } + } + + private static Godot.EditorSettings EditorSettings => + GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); + + private static bool UsingMonoMsBuildOnWindows + { + get + { + if (OS.IsWindows()) + { + return (GodotSharpBuilds.BuildTool) EditorSettings.GetSetting("mono/builds/build_tool") + == GodotSharpBuilds.BuildTool.MsBuildMono; + } + + return false; + } + } + + private static bool PrintBuildOutput => + (bool) EditorSettings.GetSetting("mono/builds/print_build_output"); + + private static Process LaunchBuild(string solution, string config, string loggerOutputDir, IEnumerable<string> customProperties = null) + { + var customPropertiesList = new List<string>(); + + if (customProperties != null) + customPropertiesList.AddRange(customProperties); + + string compilerArgs = BuildArguments(solution, config, loggerOutputDir, customPropertiesList); + + var startInfo = new ProcessStartInfo(GetMsBuildPath(), compilerArgs); + + bool redirectOutput = !IsDebugMsBuildRequested() && !PrintBuildOutput; + + if (!redirectOutput || Godot.OS.IsStdoutVerbose()) + Console.WriteLine($"Running: \"{startInfo.FileName}\" {startInfo.Arguments}"); + + startInfo.RedirectStandardOutput = redirectOutput; + startInfo.RedirectStandardError = redirectOutput; + startInfo.UseShellExecute = false; + + if (UsingMonoMsBuildOnWindows) + { + // These environment variables are required for Mono's MSBuild to find the compilers. + // We use the batch files in Mono's bin directory to make sure the compilers are executed with mono. + string monoWinBinDir = MonoWindowsBinDir; + startInfo.EnvironmentVariables.Add("CscToolExe", Path.Combine(monoWinBinDir, "csc.bat")); + startInfo.EnvironmentVariables.Add("VbcToolExe", Path.Combine(monoWinBinDir, "vbc.bat")); + startInfo.EnvironmentVariables.Add("FscToolExe", Path.Combine(monoWinBinDir, "fsharpc.bat")); + } + + // Needed when running from Developer Command Prompt for VS + RemovePlatformVariable(startInfo.EnvironmentVariables); + + var process = new Process {StartInfo = startInfo}; + + process.Start(); + + if (redirectOutput) + { + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + } + + return process; + } + + public static int Build(MonoBuildInfo monoBuildInfo) + { + return Build(monoBuildInfo.Solution, monoBuildInfo.Configuration, + monoBuildInfo.LogsDirPath, monoBuildInfo.CustomProperties); + } + + public static async Task<int> BuildAsync(MonoBuildInfo monoBuildInfo) + { + return await BuildAsync(monoBuildInfo.Solution, monoBuildInfo.Configuration, + monoBuildInfo.LogsDirPath, monoBuildInfo.CustomProperties); + } + + public static int Build(string solution, string config, string loggerOutputDir, IEnumerable<string> customProperties = null) + { + using (var process = LaunchBuild(solution, config, loggerOutputDir, customProperties)) + { + process.WaitForExit(); + + return process.ExitCode; + } + } + + public static async Task<int> BuildAsync(string solution, string config, string loggerOutputDir, IEnumerable<string> customProperties = null) + { + using (var process = LaunchBuild(solution, config, loggerOutputDir, customProperties)) + { + await process.WaitForExitAsync(); + + return process.ExitCode; + } + } + + private static string BuildArguments(string solution, string config, string loggerOutputDir, List<string> customProperties) + { + string arguments = $@"""{solution}"" /v:normal /t:Rebuild ""/p:{"Configuration=" + config}"" " + + $@"""/l:{typeof(GodotBuildLogger).FullName},{GodotBuildLogger.AssemblyPath};{loggerOutputDir}"""; + + foreach (string customProperty in customProperties) + { + arguments += " /p:" + customProperty; + } + + return arguments; + } + + private static void RemovePlatformVariable(StringDictionary environmentVariables) + { + // EnvironmentVariables is case sensitive? Seriously? + + var platformEnvironmentVariables = new List<string>(); + + foreach (string env in environmentVariables.Keys) + { + if (env.ToUpper() == "PLATFORM") + platformEnvironmentVariables.Add(env); + } + + foreach (string env in platformEnvironmentVariables) + environmentVariables.Remove(env); + } + + private static bool IsDebugMsBuildRequested() + { + return Environment.GetEnvironmentVariable("GODOT_DEBUG_MSBUILD")?.Trim() == "1"; + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs new file mode 100644 index 0000000000..f0068385f4 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Build/MsBuildFinder.cs @@ -0,0 +1,210 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Godot; +using GodotTools.Internals; +using Directory = System.IO.Directory; +using Environment = System.Environment; +using File = System.IO.File; +using Path = System.IO.Path; +using OS = GodotTools.Utils.OS; + +namespace GodotTools.Build +{ + public static class MsBuildFinder + { + private static string _msbuildToolsPath = string.Empty; + private static string _msbuildUnixPath = string.Empty; + private static string _xbuildUnixPath = string.Empty; + + public static string FindMsBuild() + { + var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); + var buildTool = (GodotSharpBuilds.BuildTool) editorSettings.GetSetting("mono/builds/build_tool"); + + if (OS.IsWindows()) + { + switch (buildTool) + { + case GodotSharpBuilds.BuildTool.MsBuildVs: + { + if (_msbuildToolsPath.Empty() || !File.Exists(_msbuildToolsPath)) + { + // Try to search it again if it wasn't found last time or if it was removed from its location + _msbuildToolsPath = FindMsBuildToolsPathOnWindows(); + + if (_msbuildToolsPath.Empty()) + { + throw new FileNotFoundException($"Cannot find executable for '{GodotSharpBuilds.PropNameMsbuildVs}'. Tried with path: {_msbuildToolsPath}"); + } + } + + if (!_msbuildToolsPath.EndsWith("\\")) + _msbuildToolsPath += "\\"; + + return Path.Combine(_msbuildToolsPath, "MSBuild.exe"); + } + + case GodotSharpBuilds.BuildTool.MsBuildMono: + { + string msbuildPath = Path.Combine(Internal.MonoWindowsInstallRoot, "bin", "msbuild.bat"); + + if (!File.Exists(msbuildPath)) + { + throw new FileNotFoundException($"Cannot find executable for '{GodotSharpBuilds.PropNameMsbuildMono}'. Tried with path: {msbuildPath}"); + } + + return msbuildPath; + } + + case GodotSharpBuilds.BuildTool.XBuild: + { + string xbuildPath = Path.Combine(Internal.MonoWindowsInstallRoot, "bin", "xbuild.bat"); + + if (!File.Exists(xbuildPath)) + { + throw new FileNotFoundException($"Cannot find executable for '{GodotSharpBuilds.PropNameXbuild}'. Tried with path: {xbuildPath}"); + } + + return xbuildPath; + } + + default: + throw new IndexOutOfRangeException("Invalid build tool in editor settings"); + } + } + + if (OS.IsUnix()) + { + if (buildTool == GodotSharpBuilds.BuildTool.XBuild) + { + if (_xbuildUnixPath.Empty() || !File.Exists(_xbuildUnixPath)) + { + // Try to search it again if it wasn't found last time or if it was removed from its location + _xbuildUnixPath = FindBuildEngineOnUnix("msbuild"); + } + + if (_xbuildUnixPath.Empty()) + { + throw new FileNotFoundException($"Cannot find binary for '{GodotSharpBuilds.PropNameXbuild}'"); + } + } + else + { + if (_msbuildUnixPath.Empty() || !File.Exists(_msbuildUnixPath)) + { + // Try to search it again if it wasn't found last time or if it was removed from its location + _msbuildUnixPath = FindBuildEngineOnUnix("msbuild"); + } + + if (_msbuildUnixPath.Empty()) + { + throw new FileNotFoundException($"Cannot find binary for '{GodotSharpBuilds.PropNameMsbuildMono}'"); + } + } + + return buildTool != GodotSharpBuilds.BuildTool.XBuild ? _msbuildUnixPath : _xbuildUnixPath; + } + + throw new PlatformNotSupportedException(); + } + + private static IEnumerable<string> MsBuildHintDirs + { + get + { + var result = new List<string>(); + + if (OS.IsOSX()) + { + result.Add("/Library/Frameworks/Mono.framework/Versions/Current/bin/"); + result.Add("/usr/local/var/homebrew/linked/mono/bin/"); + } + + result.Add("/opt/novell/mono/bin/"); + + return result; + } + } + + private static string FindBuildEngineOnUnix(string name) + { + string ret = OS.PathWhich(name); + + if (!ret.Empty()) + return ret; + + string retFallback = OS.PathWhich($"{name}.exe"); + + if (!retFallback.Empty()) + return retFallback; + + foreach (string hintDir in MsBuildHintDirs) + { + string hintPath = Path.Combine(hintDir, name); + + if (File.Exists(hintPath)) + return hintPath; + } + + return string.Empty; + } + + private static string FindMsBuildToolsPathOnWindows() + { + if (!OS.IsWindows()) + throw new PlatformNotSupportedException(); + + // Try to find 15.0 with vswhere + + string vsWherePath = Environment.GetEnvironmentVariable(Internal.GodotIs32Bits() ? "ProgramFiles" : "ProgramFiles(x86)"); + vsWherePath += "\\Microsoft Visual Studio\\Installer\\vswhere.exe"; + + var vsWhereArgs = new[] {"-latest", "-products", "*", "-requires", "Microsoft.Component.MSBuild"}; + + var outputArray = new Godot.Collections.Array<string>(); + int exitCode = Godot.OS.Execute(vsWherePath, vsWhereArgs, + blocking: true, output: (Godot.Collections.Array) outputArray); + + if (exitCode == 0) + return string.Empty; + + if (outputArray.Count == 0) + return string.Empty; + + var lines = outputArray[0].Split('\n'); + + foreach (string line in lines) + { + int sepIdx = line.IndexOf(':'); + + if (sepIdx <= 0) + continue; + + string key = line.Substring(0, sepIdx); // No need to trim + + if (key != "installationPath") + continue; + + string value = line.Substring(sepIdx + 1).StripEdges(); + + if (value.Empty()) + throw new FormatException("installationPath value is empty"); + + if (!value.EndsWith("\\")) + value += "\\"; + + // Since VS2019, the directory is simply named "Current" + string msbuildDir = Path.Combine(value, "MSBuild\\Current\\Bin"); + + if (Directory.Exists(msbuildDir)) + return msbuildDir; + + // Directory name "15.0" is used in VS 2017 + return Path.Combine(value, "MSBuild\\15.0\\Bin"); + } + + return string.Empty; + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs b/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs new file mode 100644 index 0000000000..4535ed7247 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/CSharpProject.cs @@ -0,0 +1,127 @@ +using Godot; +using System; +using Godot.Collections; +using GodotTools.Internals; +using GodotTools.ProjectEditor; +using static GodotTools.Internals.Globals; +using File = GodotTools.Utils.File; +using Directory = GodotTools.Utils.Directory; + +namespace GodotTools +{ + public static class CSharpProject + { + public static string GenerateGameProject(string dir, string name) + { + try + { + return ProjectGenerator.GenGameProject(dir, name, compileItems: new string[] { }); + } + catch (Exception e) + { + GD.PushError(e.ToString()); + return string.Empty; + } + } + + public static void AddItem(string projectPath, string itemType, string include) + { + if (!(bool) GlobalDef("mono/project/auto_update_project", true)) + return; + + ProjectUtils.AddItemToProjectChecked(projectPath, itemType, include); + } + + public static void FixApiHintPath(string projectPath) + { + try + { + ProjectUtils.FixApiHintPath(projectPath); + } + catch (Exception e) + { + GD.PushError(e.ToString()); + } + } + + private static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + + private static ulong ConvertToTimestamp(this DateTime value) + { + TimeSpan elapsedTime = value - Epoch; + return (ulong) elapsedTime.TotalSeconds; + } + + public static void GenerateScriptsMetadata(string projectPath, string outputPath) + { + if (File.Exists(outputPath)) + File.Delete(outputPath); + + var oldDict = Internal.GetScriptsMetadataOrNothing(); + var newDict = new Godot.Collections.Dictionary<string, object>(); + + foreach (var includeFile in ProjectUtils.GetIncludeFiles(projectPath, "Compile")) + { + string projectIncludeFile = ("res://" + includeFile).SimplifyGodotPath(); + + ulong modifiedTime = File.GetLastWriteTime(projectIncludeFile).ConvertToTimestamp(); + + if (oldDict.TryGetValue(projectIncludeFile, out var oldFileVar)) + { + var oldFileDict = (Dictionary) oldFileVar; + + if (ulong.TryParse(oldFileDict["modified_time"] as string, out ulong storedModifiedTime)) + { + if (storedModifiedTime == modifiedTime) + { + // No changes so no need to parse again + newDict[projectIncludeFile] = oldFileDict; + continue; + } + } + } + + ScriptClassParser.ParseFileOrThrow(projectIncludeFile, out var classes); + + string searchName = System.IO.Path.GetFileNameWithoutExtension(projectIncludeFile); + + var classDict = new Dictionary(); + + foreach (var classDecl in classes) + { + if (classDecl.BaseCount == 0) + continue; // Does not inherit nor implement anything, so it can't be a script class + + string classCmp = classDecl.Nested ? + classDecl.Name.Substring(classDecl.Name.LastIndexOf(".", StringComparison.Ordinal) + 1) : + classDecl.Name; + + if (classCmp != searchName) + continue; + + classDict["namespace"] = classDecl.Namespace; + classDict["class_name"] = classDecl.Name; + classDict["nested"] = classDecl.Nested; + break; + } + + if (classDict.Count == 0) + continue; // Not found + + newDict[projectIncludeFile] = new Dictionary {["modified_time"] = $"{modifiedTime}", ["class"] = classDict}; + } + + if (newDict.Count > 0) + { + string json = JSON.Print(newDict); + + string baseDir = outputPath.GetBaseDir(); + + if (!Directory.Exists(baseDir)) + Directory.CreateDirectory(baseDir); + + File.WriteAllText(outputPath, json); + } + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs new file mode 100644 index 0000000000..a884b0ead0 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpBuilds.cs @@ -0,0 +1,277 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using GodotTools.Build; +using GodotTools.Internals; +using GodotTools.Utils; +using static GodotTools.Internals.Globals; +using Error = Godot.Error; +using File = GodotTools.Utils.File; +using Directory = GodotTools.Utils.Directory; + +namespace GodotTools +{ + public static class GodotSharpBuilds + { + private static readonly List<MonoBuildInfo> BuildsInProgress = new List<MonoBuildInfo>(); + + public const string PropNameMsbuildMono = "MSBuild (Mono)"; + public const string PropNameMsbuildVs = "MSBuild (VS Build Tools)"; + public const string PropNameXbuild = "xbuild (Deprecated)"; + + public const string MsBuildIssuesFileName = "msbuild_issues.csv"; + public const string MsBuildLogFileName = "msbuild_log.txt"; + + public enum BuildTool + { + MsBuildMono, + MsBuildVs, + XBuild // Deprecated + } + + private static void RemoveOldIssuesFile(MonoBuildInfo buildInfo) + { + var issuesFile = GetIssuesFilePath(buildInfo); + + if (!File.Exists(issuesFile)) + return; + + File.Delete(issuesFile); + } + + private static string _ApiFolderName(ApiAssemblyType apiType) + { + ulong apiHash = apiType == ApiAssemblyType.Core ? + Internal.GetCoreApiHash() : + Internal.GetEditorApiHash(); + return $"{apiHash}_{BindingsGenerator.Version}_{BindingsGenerator.CsGlueVersion}"; + } + + private static void ShowBuildErrorDialog(string message) + { + GodotSharpEditor.Instance.ShowErrorDialog(message, "Build error"); + GodotSharpEditor.Instance.MonoBottomPanel.ShowBuildTab(); + } + + public static void RestartBuild(MonoBuildTab buildTab) => throw new NotImplementedException(); + public static void StopBuild(MonoBuildTab buildTab) => throw new NotImplementedException(); + + private static string GetLogFilePath(MonoBuildInfo buildInfo) + { + return Path.Combine(buildInfo.LogsDirPath, MsBuildLogFileName); + } + + private static string GetIssuesFilePath(MonoBuildInfo buildInfo) + { + return Path.Combine(Godot.ProjectSettings.LocalizePath(buildInfo.LogsDirPath), MsBuildIssuesFileName); + } + + private static void PrintVerbose(string text) + { + if (Godot.OS.IsStdoutVerbose()) + Godot.GD.Print(text); + } + + public static bool Build(MonoBuildInfo buildInfo) + { + if (BuildsInProgress.Contains(buildInfo)) + throw new InvalidOperationException("A build is already in progress"); + + BuildsInProgress.Add(buildInfo); + + try + { + MonoBuildTab buildTab = GodotSharpEditor.Instance.MonoBottomPanel.GetBuildTabFor(buildInfo); + buildTab.OnBuildStart(); + + // Required in order to update the build tasks list + Internal.GodotMainIteration(); + + try + { + RemoveOldIssuesFile(buildInfo); + } + catch (IOException e) + { + buildTab.OnBuildExecFailed($"Cannot remove issues file: {GetIssuesFilePath(buildInfo)}"); + Console.Error.WriteLine(e); + } + + try + { + int exitCode = BuildSystem.Build(buildInfo); + + if (exitCode != 0) + PrintVerbose($"MSBuild exited with code: {exitCode}. Log file: {GetLogFilePath(buildInfo)}"); + + buildTab.OnBuildExit(exitCode == 0 ? MonoBuildTab.BuildResults.Success : MonoBuildTab.BuildResults.Error); + + return exitCode == 0; + } + catch (Exception e) + { + buildTab.OnBuildExecFailed($"The build method threw an exception.\n{e.GetType().FullName}: {e.Message}"); + Console.Error.WriteLine(e); + return false; + } + } + finally + { + BuildsInProgress.Remove(buildInfo); + } + } + + public static async Task<bool> BuildAsync(MonoBuildInfo buildInfo) + { + if (BuildsInProgress.Contains(buildInfo)) + throw new InvalidOperationException("A build is already in progress"); + + BuildsInProgress.Add(buildInfo); + + try + { + MonoBuildTab buildTab = GodotSharpEditor.Instance.MonoBottomPanel.GetBuildTabFor(buildInfo); + + try + { + RemoveOldIssuesFile(buildInfo); + } + catch (IOException e) + { + buildTab.OnBuildExecFailed($"Cannot remove issues file: {GetIssuesFilePath(buildInfo)}"); + Console.Error.WriteLine(e); + } + + try + { + int exitCode = await BuildSystem.BuildAsync(buildInfo); + + if (exitCode != 0) + PrintVerbose($"MSBuild exited with code: {exitCode}. Log file: {GetLogFilePath(buildInfo)}"); + + buildTab.OnBuildExit(exitCode == 0 ? MonoBuildTab.BuildResults.Success : MonoBuildTab.BuildResults.Error); + + return exitCode == 0; + } + catch (Exception e) + { + buildTab.OnBuildExecFailed($"The build method threw an exception.\n{e.GetType().FullName}: {e.Message}"); + Console.Error.WriteLine(e); + return false; + } + } + finally + { + BuildsInProgress.Remove(buildInfo); + } + } + + public static bool BuildApiSolution(string apiSlnDir, string config) + { + string apiSlnFile = Path.Combine(apiSlnDir, $"{ApiAssemblyNames.SolutionName}.sln"); + + string coreApiAssemblyDir = Path.Combine(apiSlnDir, ApiAssemblyNames.Core, "bin", config); + string coreApiAssemblyFile = Path.Combine(coreApiAssemblyDir, $"{ApiAssemblyNames.Core}.dll"); + + string editorApiAssemblyDir = Path.Combine(apiSlnDir, ApiAssemblyNames.Editor, "bin", config); + string editorApiAssemblyFile = Path.Combine(editorApiAssemblyDir, $"{ApiAssemblyNames.Editor}.dll"); + + if (File.Exists(coreApiAssemblyFile) && File.Exists(editorApiAssemblyFile)) + return true; // The assemblies are in the output folder; assume the solution is already built + + var apiBuildInfo = new MonoBuildInfo(apiSlnFile, config); + + // TODO Replace this global NoWarn with '#pragma warning' directives on generated files, + // once we start to actively document manually maintained C# classes + apiBuildInfo.CustomProperties.Add("NoWarn=1591"); // Ignore missing documentation warnings + + if (Build(apiBuildInfo)) + return true; + + ShowBuildErrorDialog($"Failed to build {ApiAssemblyNames.SolutionName} solution."); + return false; + } + + public static bool BuildProjectBlocking(string config, IEnumerable<string> godotDefines) + { + if (!File.Exists(GodotSharpDirs.ProjectSlnPath)) + return true; // No solution to build + + // Make sure to update the API assemblies if they happen to be missing. Just in + // case the user decided to delete them at some point after they were loaded. + Internal.UpdateApiAssembliesFromPrebuilt(); + + using (var pr = new EditorProgress("mono_project_debug_build", "Building project solution...", 1)) + { + pr.Step("Building project solution", 0); + + var buildInfo = new MonoBuildInfo(GodotSharpDirs.ProjectSlnPath, config); + + // Add Godot defines + string constants = OS.IsWindows() ? "GodotDefineConstants=\"" : "GodotDefineConstants=\\\""; + + foreach (var godotDefine in godotDefines) + constants += $"GODOT_{godotDefine.ToUpper().Replace("-", "_").Replace(" ", "_").Replace(";", "_")};"; + + if (Internal.GodotIsRealTDouble()) + constants += "GODOT_REAL_T_IS_DOUBLE;"; + + constants += OS.IsWindows() ? "\"" : "\\\""; + + buildInfo.CustomProperties.Add(constants); + + if (!Build(buildInfo)) + { + ShowBuildErrorDialog("Failed to build project solution"); + return false; + } + } + + return true; + } + + public static bool EditorBuildCallback() + { + if (!File.Exists(GodotSharpDirs.ProjectSlnPath)) + return true; // No solution to build + + string editorScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor"); + string playerScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor_player"); + + CSharpProject.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath); + + if (File.Exists(editorScriptsMetadataPath)) + File.Copy(editorScriptsMetadataPath, playerScriptsMetadataPath); + + var godotDefines = new[] + { + Godot.OS.GetName(), + Internal.GodotIs32Bits() ? "32" : "64" + }; + + return BuildProjectBlocking("Tools", godotDefines); + } + + public static void Initialize() + { + // Build tool settings + + EditorDef("mono/builds/build_tool", OS.IsWindows() ? BuildTool.MsBuildVs : BuildTool.MsBuildMono); + + var editorSettings = GodotSharpEditor.Instance.GetEditorInterface().GetEditorSettings(); + + editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary + { + ["type"] = Godot.Variant.Type.Int, + ["name"] = "mono/builds/build_tool", + ["hint"] = Godot.PropertyHint.Enum, + ["hint_string"] = OS.IsWindows() ? + $"{PropNameMsbuildMono},{PropNameMsbuildVs},{PropNameXbuild}" : + $"{PropNameMsbuildMono},{PropNameXbuild}" + }); + + EditorDef("mono/builds/print_build_output", false); + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs new file mode 100644 index 0000000000..90dec43412 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -0,0 +1,491 @@ +using Godot; +using GodotTools.Utils; +using System; +using System.Collections.Generic; +using System.IO; +using GodotTools.Internals; +using GodotTools.ProjectEditor; +using static GodotTools.Internals.Globals; +using File = GodotTools.Utils.File; +using Path = System.IO.Path; +using OS = GodotTools.Utils.OS; + +namespace GodotTools +{ + public class GodotSharpEditor : EditorPlugin, ISerializationListener + { + private EditorSettings editorSettings; + + private PopupMenu menuPopup; + + private AcceptDialog errorDialog; + private AcceptDialog aboutDialog; + private CheckBox aboutDialogCheckBox; + + private ToolButton bottomPanelBtn; + + private MonoDevelopInstance monoDevelopInstance; + private MonoDevelopInstance visualStudioForMacInstance; + + private WeakRef exportPluginWeak; // TODO Use WeakReference once we have proper serialization + + public MonoBottomPanel MonoBottomPanel { get; private set; } + + private bool CreateProjectSolution() + { + using (var pr = new EditorProgress("create_csharp_solution", "Generating solution...".TTR(), 2)) + { + pr.Step("Generating C# project...".TTR()); + + string resourceDir = ProjectSettings.GlobalizePath("res://"); + + string path = resourceDir; + string name = (string) ProjectSettings.GetSetting("application/config/name"); + if (name.Empty()) + name = "UnnamedProject"; + + string guid = CSharpProject.GenerateGameProject(path, name); + + if (guid.Length > 0) + { + var solution = new DotNetSolution(name) + { + DirectoryPath = path + }; + + var projectInfo = new DotNetSolution.ProjectInfo + { + Guid = guid, + PathRelativeToSolution = name + ".csproj", + Configs = new List<string> {"Debug", "Release", "Tools"} + }; + + solution.AddNewProject(name, projectInfo); + + try + { + solution.Save(); + } + catch (IOException e) + { + ShowErrorDialog("Failed to save solution. Exception message: ".TTR() + e.Message); + return false; + } + + // Make sure to update the API assemblies if they happen to be missing. Just in + // case the user decided to delete them at some point after they were loaded. + Internal.UpdateApiAssembliesFromPrebuilt(); + + pr.Step("Done".TTR()); + + // Here, after all calls to progress_task_step + CallDeferred(nameof(_RemoveCreateSlnMenuOption)); + } + else + { + ShowErrorDialog("Failed to create C# project.".TTR()); + } + + return true; + } + } + + private void _RemoveCreateSlnMenuOption() + { + menuPopup.RemoveItem(menuPopup.GetItemIndex((int) MenuOptions.CreateSln)); + bottomPanelBtn.Show(); + } + + private void _ShowAboutDialog() + { + bool showOnStart = (bool) editorSettings.GetSetting("mono/editor/show_info_on_start"); + aboutDialogCheckBox.Pressed = showOnStart; + aboutDialog.PopupCenteredMinsize(); + } + + private void _ToggleAboutDialogOnStart(bool enabled) + { + bool showOnStart = (bool) editorSettings.GetSetting("mono/editor/show_info_on_start"); + if (showOnStart != enabled) + editorSettings.SetSetting("mono/editor/show_info_on_start", enabled); + } + + private void _MenuOptionPressed(MenuOptions id) + { + switch (id) + { + case MenuOptions.CreateSln: + CreateProjectSolution(); + break; + case MenuOptions.AboutCSharp: + _ShowAboutDialog(); + break; + default: + throw new ArgumentOutOfRangeException(nameof(id), id, "Invalid menu option"); + } + } + + private void _BuildSolutionPressed() + { + if (!File.Exists(GodotSharpDirs.ProjectSlnPath)) + { + if (!CreateProjectSolution()) + return; // Failed to create solution + } + + Instance.MonoBottomPanel.BuildProjectPressed(); + } + + public override void _Notification(int what) + { + base._Notification(what); + + if (what == NotificationReady) + { + bool showInfoDialog = (bool) editorSettings.GetSetting("mono/editor/show_info_on_start"); + if (showInfoDialog) + { + aboutDialog.PopupExclusive = true; + _ShowAboutDialog(); + // Once shown a first time, it can be seen again via the Mono menu - it doesn't have to be exclusive from that time on. + aboutDialog.PopupExclusive = false; + } + } + } + + public enum MenuOptions + { + CreateSln, + AboutCSharp, + } + + public enum ExternalEditor + { + None, + VisualStudio, // TODO (Windows-only) + VisualStudioForMac, // Mac-only + MonoDevelop, + VsCode + } + + public void ShowErrorDialog(string message, string title = "Error") + { + errorDialog.WindowTitle = title; + errorDialog.DialogText = message; + errorDialog.PopupCenteredMinsize(); + } + + private static string _vsCodePath = string.Empty; + + private static readonly string[] VsCodeNames = + { + "code", "code-oss", "vscode", "vscode-oss", "visual-studio-code", "visual-studio-code-oss" + }; + + public Error OpenInExternalEditor(Script script, int line, int col) + { + var editor = (ExternalEditor) editorSettings.GetSetting("mono/editor/external_editor"); + + switch (editor) + { + case ExternalEditor.VsCode: + { + if (_vsCodePath.Empty() || !File.Exists(_vsCodePath)) + { + // Try to search it again if it wasn't found last time or if it was removed from its location + _vsCodePath = VsCodeNames.SelectFirstNotNull(OS.PathWhich, orElse: string.Empty); + } + + var args = new List<string>(); + + bool osxAppBundleInstalled = false; + + if (OS.IsOSX()) + { + // The package path is '/Applications/Visual Studio Code.app' + const string vscodeBundleId = "com.microsoft.VSCode"; + + osxAppBundleInstalled = Internal.IsOsxAppBundleInstalled(vscodeBundleId); + + if (osxAppBundleInstalled) + { + args.Add("-b"); + args.Add(vscodeBundleId); + + // The reusing of existing windows made by the 'open' command might not choose a wubdiw that is + // editing our folder. It's better to ask for a new window and let VSCode do the window management. + args.Add("-n"); + + // The open process must wait until the application finishes (which is instant in VSCode's case) + args.Add("--wait-apps"); + + args.Add("--args"); + } + } + + var resourcePath = ProjectSettings.GlobalizePath("res://"); + args.Add(resourcePath); + + string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath); + + if (line >= 0) + { + args.Add("-g"); + args.Add($"{scriptPath}:{line + 1}:{col}"); + } + else + { + args.Add(scriptPath); + } + + string command; + + if (OS.IsOSX()) + { + if (!osxAppBundleInstalled && _vsCodePath.Empty()) + { + GD.PushError("Cannot find code editor: VSCode"); + return Error.FileNotFound; + } + + command = osxAppBundleInstalled ? "/usr/bin/open" : _vsCodePath; + } + else + { + if (_vsCodePath.Empty()) + { + GD.PushError("Cannot find code editor: VSCode"); + return Error.FileNotFound; + } + + command = _vsCodePath; + } + + try + { + OS.RunProcess(command, args); + } + catch (Exception e) + { + GD.PushError($"Error when trying to run code editor: VSCode. Exception message: '{e.Message}'"); + } + + break; + } + + case ExternalEditor.VisualStudioForMac: + goto case ExternalEditor.MonoDevelop; + case ExternalEditor.MonoDevelop: + { + MonoDevelopInstance GetMonoDevelopInstance(string solutionPath) + { + if (OS.IsOSX() && editor == ExternalEditor.VisualStudioForMac) + { + if (visualStudioForMacInstance == null) + visualStudioForMacInstance = new MonoDevelopInstance(solutionPath, MonoDevelopInstance.EditorId.VisualStudioForMac); + + return visualStudioForMacInstance; + } + + if (monoDevelopInstance == null) + monoDevelopInstance = new MonoDevelopInstance(solutionPath, MonoDevelopInstance.EditorId.MonoDevelop); + + return monoDevelopInstance; + } + + string scriptPath = ProjectSettings.GlobalizePath(script.ResourcePath); + + if (line >= 0) + scriptPath += $";{line + 1};{col}"; + + GetMonoDevelopInstance(GodotSharpDirs.ProjectSlnPath).Execute(scriptPath); + + break; + } + + case ExternalEditor.None: + return Error.Unavailable; + default: + throw new ArgumentOutOfRangeException(); + } + + return Error.Ok; + } + + public bool OverridesExternalEditor() + { + return (ExternalEditor) editorSettings.GetSetting("mono/editor/external_editor") != ExternalEditor.None; + } + + public override bool Build() + { + return GodotSharpBuilds.EditorBuildCallback(); + } + + public override void EnablePlugin() + { + base.EnablePlugin(); + + if (Instance != null) + throw new InvalidOperationException(); + Instance = this; + + var editorInterface = GetEditorInterface(); + var editorBaseControl = editorInterface.GetBaseControl(); + + editorSettings = editorInterface.GetEditorSettings(); + + errorDialog = new AcceptDialog(); + editorBaseControl.AddChild(errorDialog); + + MonoBottomPanel = new MonoBottomPanel(); + + bottomPanelBtn = AddControlToBottomPanel(MonoBottomPanel, "Mono".TTR()); + + AddChild(new HotReloadAssemblyWatcher {Name = "HotReloadAssemblyWatcher"}); + + menuPopup = new PopupMenu(); + menuPopup.Hide(); + menuPopup.SetAsToplevel(true); + + AddToolSubmenuItem("Mono", menuPopup); + + // TODO: Remove or edit this info dialog once Mono support is no longer in alpha + { + menuPopup.AddItem("About C# support".TTR(), (int) MenuOptions.AboutCSharp); + aboutDialog = new AcceptDialog(); + editorBaseControl.AddChild(aboutDialog); + aboutDialog.WindowTitle = "Important: C# support is not feature-complete"; + + // We don't use DialogText as the default AcceptDialog Label doesn't play well with the TextureRect and CheckBox + // we'll add. Instead we add containers and a new autowrapped Label inside. + + // Main VBoxContainer (icon + label on top, checkbox at bottom) + var aboutVBox = new VBoxContainer(); + aboutDialog.AddChild(aboutVBox); + + // HBoxContainer for icon + label + var aboutHBox = new HBoxContainer(); + aboutVBox.AddChild(aboutHBox); + + var aboutIcon = new TextureRect(); + aboutIcon.Texture = aboutIcon.GetIcon("NodeWarning", "EditorIcons"); + aboutHBox.AddChild(aboutIcon); + + var aboutLabel = new Label(); + aboutHBox.AddChild(aboutLabel); + aboutLabel.RectMinSize = new Vector2(600, 150) * EditorScale; + aboutLabel.SizeFlagsVertical = (int) Control.SizeFlags.ExpandFill; + aboutLabel.Autowrap = true; + aboutLabel.Text = + "C# support in Godot Engine is in late alpha stage and, while already usable, " + + "it is not meant for use in production.\n\n" + + "Projects can be exported to Linux, macOS and Windows, but not yet to mobile or web platforms. " + + "Bugs and usability issues will be addressed gradually over future releases, " + + "potentially including compatibility breaking changes as new features are implemented for a better overall C# experience.\n\n" + + "If you experience issues with this Mono build, please report them on Godot's issue tracker with details about your system, MSBuild version, IDE, etc.:\n\n" + + " https://github.com/godotengine/godot/issues\n\n" + + "Your critical feedback at this stage will play a great role in shaping the C# support in future releases, so thank you!"; + + EditorDef("mono/editor/show_info_on_start", true); + + // CheckBox in main container + aboutDialogCheckBox = new CheckBox {Text = "Show this warning when starting the editor"}; + aboutDialogCheckBox.Connect("toggled", this, nameof(_ToggleAboutDialogOnStart)); + aboutVBox.AddChild(aboutDialogCheckBox); + } + + if (File.Exists(GodotSharpDirs.ProjectSlnPath) && File.Exists(GodotSharpDirs.ProjectCsProjPath)) + { + // Make sure the existing project has Api assembly references configured correctly + CSharpProject.FixApiHintPath(GodotSharpDirs.ProjectCsProjPath); + } + else + { + bottomPanelBtn.Hide(); + menuPopup.AddItem("Create C# solution".TTR(), (int) MenuOptions.CreateSln); + } + + menuPopup.Connect("id_pressed", this, nameof(_MenuOptionPressed)); + + var buildButton = new ToolButton + { + Text = "Build", + HintTooltip = "Build solution", + FocusMode = Control.FocusModeEnum.None + }; + buildButton.Connect("pressed", this, nameof(_BuildSolutionPressed)); + AddControlToContainer(CustomControlContainer.Toolbar, buildButton); + + // External editor settings + EditorDef("mono/editor/external_editor", ExternalEditor.None); + + string settingsHintStr = "Disabled"; + + if (OS.IsWindows()) + { + settingsHintStr += $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" + + $",Visual Studio Code:{(int) ExternalEditor.VsCode}"; + } + else if (OS.IsOSX()) + { + settingsHintStr += $",Visual Studio:{(int) ExternalEditor.VisualStudioForMac}" + + $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" + + $",Visual Studio Code:{(int) ExternalEditor.VsCode}"; + } + else if (OS.IsUnix()) + { + settingsHintStr += $",MonoDevelop:{(int) ExternalEditor.MonoDevelop}" + + $",Visual Studio Code:{(int) ExternalEditor.VsCode}"; + } + + editorSettings.AddPropertyInfo(new Godot.Collections.Dictionary + { + ["type"] = Variant.Type.Int, + ["name"] = "mono/editor/external_editor", + ["hint"] = PropertyHint.Enum, + ["hint_string"] = settingsHintStr + }); + + // Export plugin + var exportPlugin = new GodotSharpExport(); + AddExportPlugin(exportPlugin); + exportPluginWeak = WeakRef(exportPlugin); + + GodotSharpBuilds.Initialize(); + } + + protected override void Dispose(bool disposing) + { + base.Dispose(disposing); + + if (exportPluginWeak != null) + { + // We need to dispose our export plugin before the editor destroys EditorSettings. + // Otherwise, if the GC disposes it at a later time, EditorExportPlatformAndroid + // will be freed after EditorSettings already was, and its device polling thread + // will try to access the EditorSettings singleton, resulting in null dereferencing. + (exportPluginWeak.GetRef() as GodotSharpExport)?.Dispose(); + + exportPluginWeak.Dispose(); + } + } + + public void OnBeforeSerialize() + { + } + + public void OnAfterDeserialize() + { + Instance = this; + } + + // Singleton + + public static GodotSharpEditor Instance { get; private set; } + + private GodotSharpEditor() + { + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs new file mode 100644 index 0000000000..b80fe1fab7 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpExport.cs @@ -0,0 +1,197 @@ +using Godot; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using GodotTools.Core; +using GodotTools.Internals; +using Directory = GodotTools.Utils.Directory; +using File = GodotTools.Utils.File; +using Path = System.IO.Path; + +namespace GodotTools +{ + public class GodotSharpExport : EditorExportPlugin + { + private void AddFile(string srcPath, string dstPath, bool remap = false) + { + AddFile(dstPath, File.ReadAllBytes(srcPath), remap); + } + + public override void _ExportFile(string path, string type, string[] features) + { + base._ExportFile(path, type, features); + + if (type != Internal.CSharpLanguageType) + return; + + if (Path.GetExtension(path) != $".{Internal.CSharpLanguageExtension}") + throw new ArgumentException($"Resource of type {Internal.CSharpLanguageType} has an invalid file extension: {path}", nameof(path)); + + // TODO What if the source file is not part of the game's C# project + + bool includeScriptsContent = (bool) ProjectSettings.GetSetting("mono/export/include_scripts_content"); + + if (!includeScriptsContent) + { + // We don't want to include the source code on exported games + AddFile(path, new byte[] { }, remap: false); + Skip(); + } + } + + public override void _ExportBegin(string[] features, bool isDebug, string path, int flags) + { + base._ExportBegin(features, isDebug, path, flags); + + try + { + _ExportBeginImpl(features, isDebug, path, flags); + } + catch (Exception e) + { + GD.PushError($"Failed to export project. Exception message: {e.Message}"); + Console.Error.WriteLine(e); + } + } + + public void _ExportBeginImpl(string[] features, bool isDebug, string path, int flags) + { + // TODO Right now there is no way to stop the export process with an error + + if (File.Exists(GodotSharpDirs.ProjectSlnPath)) + { + string buildConfig = isDebug ? "Debug" : "Release"; + + string scriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, $"scripts_metadata.{(isDebug ? "debug" : "release")}"); + CSharpProject.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, scriptsMetadataPath); + + AddFile(scriptsMetadataPath, scriptsMetadataPath); + + // Turn export features into defines + var godotDefines = features; + + if (!GodotSharpBuilds.BuildProjectBlocking(buildConfig, godotDefines)) + { + GD.PushError("Failed to build project"); + return; + } + + // Add dependency assemblies + + var dependencies = new Godot.Collections.Dictionary<string, string>(); + + var projectDllName = (string) ProjectSettings.GetSetting("application/config/name"); + if (projectDllName.Empty()) + { + projectDllName = "UnnamedProject"; + } + + string projectDllSrcDir = Path.Combine(GodotSharpDirs.ResTempAssembliesBaseDir, buildConfig); + string projectDllSrcPath = Path.Combine(projectDllSrcDir, $"{projectDllName}.dll"); + + dependencies[projectDllName] = projectDllSrcPath; + + { + string templatesDir = Internal.FullTemplatesDir; + string androidBclDir = Path.Combine(templatesDir, "android-bcl"); + + string customLibDir = features.Contains("Android") && Directory.Exists(androidBclDir) ? androidBclDir : string.Empty; + + GetExportedAssemblyDependencies(projectDllName, projectDllSrcPath, buildConfig, customLibDir, dependencies); + } + + string apiConfig = isDebug ? "Debug" : "Release"; + string resAssembliesDir = Path.Combine(GodotSharpDirs.ResAssembliesBaseDir, apiConfig); + + foreach (var dependency in dependencies) + { + string dependSrcPath = dependency.Value; + string dependDstPath = Path.Combine(resAssembliesDir, dependSrcPath.GetFile()); + AddFile(dependSrcPath, dependDstPath); + } + } + + // Mono specific export template extras (data dir) + ExportDataDirectory(features, isDebug, path); + } + + private static void ExportDataDirectory(IEnumerable<string> features, bool debug, string path) + { + var featureSet = new HashSet<string>(features); + + if (!PlatformHasTemplateDir(featureSet)) + return; + + string templateDirName = "data.mono"; + + if (featureSet.Contains("Windows")) + { + templateDirName += ".windows"; + templateDirName += featureSet.Contains("64") ? ".64" : ".32"; + } + else if (featureSet.Contains("X11")) + { + templateDirName += ".x11"; + templateDirName += featureSet.Contains("64") ? ".64" : ".32"; + } + else + { + throw new NotSupportedException("Target platform not supported"); + } + + templateDirName += debug ? ".release_debug" : ".release"; + + string templateDirPath = Path.Combine(Internal.FullTemplatesDir, templateDirName); + + if (!Directory.Exists(templateDirPath)) + throw new FileNotFoundException("Data template directory not found"); + + string outputDir = new FileInfo(path).Directory?.FullName ?? + throw new FileNotFoundException("Base directory not found"); + + string outputDataDir = Path.Combine(outputDir, DataDirName); + + if (Directory.Exists(outputDataDir)) + Directory.Delete(outputDataDir, recursive: true); // Clean first + + Directory.CreateDirectory(outputDataDir); + + foreach (string dir in Directory.GetDirectories(templateDirPath, "*", SearchOption.AllDirectories)) + { + Directory.CreateDirectory(Path.Combine(outputDataDir, dir.Substring(templateDirPath.Length + 1))); + } + + foreach (string file in Directory.GetFiles(templateDirPath, "*", SearchOption.AllDirectories)) + { + File.Copy(file, Path.Combine(outputDataDir, file.Substring(templateDirPath.Length + 1))); + } + } + + private static bool PlatformHasTemplateDir(IEnumerable<string> featureSet) + { + // OSX export templates are contained in a zip, so we place + // our custom template inside it and let Godot do the rest. + return !featureSet.Any(f => new[] {"OSX", "Android"}.Contains(f)); + } + + private static string DataDirName + { + get + { + var appName = (string) ProjectSettings.GetSetting("application/config/name"); + string appNameSafe = appName.ToSafeDirName(allowDirSeparator: false); + return $"data_{appNameSafe}"; + } + } + + private static void GetExportedAssemblyDependencies(string projectDllName, string projectDllSrcPath, + string buildConfig, string customLibDir, Godot.Collections.Dictionary<string, string> dependencies) => + internal_GetExportedAssemblyDependencies(projectDllName, projectDllSrcPath, buildConfig, customLibDir, dependencies); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void internal_GetExportedAssemblyDependencies(string projectDllName, string projectDllSrcPath, + string buildConfig, string customLibDir, Godot.Collections.Dictionary<string, string> dependencies); + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj new file mode 100644 index 0000000000..01e8c87d14 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/GodotTools.csproj @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProjectGuid>{27B00618-A6F2-4828-B922-05CAEB08C286}</ProjectGuid> + <OutputType>Library</OutputType> + <RootNamespace>GodotTools</RootNamespace> + <AssemblyName>GodotTools</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + <GodotSourceRootPath>$(SolutionDir)/../../../../</GodotSourceRootPath> + <GodotApiConfiguration>Debug</GodotApiConfiguration> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>portable</DebugType> + <Optimize>false</Optimize> + <OutputPath>bin\Debug</OutputPath> + <DefineConstants>DEBUG;</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <ConsolePause>false</ConsolePause> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <Optimize>true</Optimize> + <OutputPath>bin\Release</OutputPath> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <ConsolePause>false</ConsolePause> + </PropertyGroup> + <ItemGroup> + <Reference Include="System" /> + <Reference Include="GodotSharp"> + <HintPath>$(GodotSourceRootPath)/bin/GodotSharp/Api/$(GodotApiConfiguration)/GodotSharp.dll</HintPath> + </Reference> + <Reference Include="GodotSharpEditor"> + <HintPath>$(GodotSourceRootPath)/bin/GodotSharp/Api/$(GodotApiConfiguration)/GodotSharpEditor.dll</HintPath> + </Reference> + </ItemGroup> + <ItemGroup> + <Compile Include="Build\MsBuildFinder.cs" /> + <Compile Include="Internals\BindingsGenerator.cs" /> + <Compile Include="Internals\EditorProgress.cs" /> + <Compile Include="Internals\GodotSharpDirs.cs" /> + <Compile Include="Internals\Internal.cs" /> + <Compile Include="Internals\ScriptClassParser.cs" /> + <Compile Include="Internals\Globals.cs" /> + <Compile Include="MonoDevelopInstance.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Build\BuildSystem.cs" /> + <Compile Include="Utils\Directory.cs" /> + <Compile Include="Utils\File.cs" /> + <Compile Include="Utils\OS.cs" /> + <Compile Include="GodotSharpEditor.cs" /> + <Compile Include="GodotSharpBuilds.cs" /> + <Compile Include="HotReloadAssemblyWatcher.cs" /> + <Compile Include="MonoBuildInfo.cs" /> + <Compile Include="MonoBuildTab.cs" /> + <Compile Include="MonoBottomPanel.cs" /> + <Compile Include="GodotSharpExport.cs" /> + <Compile Include="CSharpProject.cs" /> + <Compile Include="Utils\CollectionExtensions.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\GodotTools.BuildLogger\GodotTools.BuildLogger.csproj"> + <Project>{6ce9a984-37b1-4f8a-8fe9-609f05f071b3}</Project> + <Name>GodotTools.BuildLogger</Name> + </ProjectReference> + <ProjectReference Include="..\GodotTools.ProjectEditor\GodotTools.ProjectEditor.csproj"> + <Project>{A8CDAD94-C6D4-4B19-A7E7-76C53CC92984}</Project> + <Name>GodotTools.ProjectEditor</Name> + </ProjectReference> + <ProjectReference Include="..\GodotTools.Core\GodotTools.Core.csproj"> + <Project>{639E48BD-44E5-4091-8EDD-22D36DC0768D}</Project> + <Name>GodotTools.Core</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <Folder Include="Editor" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file diff --git a/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs new file mode 100644 index 0000000000..0f6f5ffadc --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/HotReloadAssemblyWatcher.cs @@ -0,0 +1,48 @@ +using Godot; +using GodotTools.Internals; +using static GodotTools.Internals.Globals; + +namespace GodotTools +{ + public class HotReloadAssemblyWatcher : Node + { + private Timer watchTimer; + + public override void _Notification(int what) + { + if (what == MainLoop.NotificationWmFocusIn) + { + RestartTimer(); + + if (Internal.IsAssembliesReloadingNeeded()) + Internal.ReloadAssemblies(softReload: false); + } + } + + private void TimerTimeout() + { + if (Internal.IsAssembliesReloadingNeeded()) + Internal.ReloadAssemblies(softReload: false); + } + + public void RestartTimer() + { + watchTimer.Stop(); + watchTimer.Start(); + } + + public override void _Ready() + { + base._Ready(); + + watchTimer = new Timer + { + OneShot = false, + WaitTime = (float) EditorDef("mono/assembly_watch_interval_sec", 0.5) + }; + watchTimer.Connect("timeout", this, nameof(TimerTimeout)); + AddChild(watchTimer); + watchTimer.Start(); + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/BindingsGenerator.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/BindingsGenerator.cs new file mode 100644 index 0000000000..1daa5e138e --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/BindingsGenerator.cs @@ -0,0 +1,87 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace GodotTools.Internals +{ + public class BindingsGenerator : IDisposable + { + class BindingsGeneratorSafeHandle : SafeHandle + { + public BindingsGeneratorSafeHandle(IntPtr handle) : base(IntPtr.Zero, true) + { + this.handle = handle; + } + + public override bool IsInvalid => handle == IntPtr.Zero; + + protected override bool ReleaseHandle() + { + internal_Dtor(handle); + return true; + } + } + + private BindingsGeneratorSafeHandle safeHandle; + private bool disposed = false; + + public bool LogPrintEnabled + { + get => internal_LogPrintEnabled(GetPtr()); + set => internal_SetLogPrintEnabled(GetPtr(), value); + } + + public static uint Version => internal_Version(); + public static uint CsGlueVersion => internal_CsGlueVersion(); + + public Godot.Error GenerateCsApi(string outputDir) => internal_GenerateCsApi(GetPtr(), outputDir); + + internal IntPtr GetPtr() + { + if (disposed) + throw new ObjectDisposedException(GetType().FullName); + + return safeHandle.DangerousGetHandle(); + } + + public void Dispose() + { + if (disposed) + return; + + if (safeHandle != null && !safeHandle.IsInvalid) + { + safeHandle.Dispose(); + safeHandle = null; + } + + disposed = true; + } + + public BindingsGenerator() + { + safeHandle = new BindingsGeneratorSafeHandle(internal_Ctor()); + } + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern IntPtr internal_Ctor(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void internal_Dtor(IntPtr handle); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern bool internal_LogPrintEnabled(IntPtr handle); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void internal_SetLogPrintEnabled(IntPtr handle, bool enabled); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern Godot.Error internal_GenerateCsApi(IntPtr handle, string outputDir); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern uint internal_Version(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern uint internal_CsGlueVersion(); + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/EditorProgress.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/EditorProgress.cs new file mode 100644 index 0000000000..70ba7c733a --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/EditorProgress.cs @@ -0,0 +1,50 @@ +using System; +using System.Runtime.CompilerServices; +using Godot; + +namespace GodotTools.Internals +{ + public class EditorProgress : IDisposable + { + public string Task { get; } + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void internal_Create(string task, string label, int amount, bool canCancel); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void internal_Dispose(string task); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern bool internal_Step(string task, string state, int step, bool forceRefresh); + + public EditorProgress(string task, string label, int amount, bool canCancel = false) + { + Task = task; + internal_Create(task, label, amount, canCancel); + } + + ~EditorProgress() + { + // Should never rely on the GC to dispose EditorProgress. + // It should be disposed immediately when the task finishes. + GD.PushError("EditorProgress disposed by the Garbage Collector"); + Dispose(); + } + + public void Dispose() + { + internal_Dispose(Task); + GC.SuppressFinalize(this); + } + + public void Step(string state, int step = -1, bool forceRefresh = true) + { + internal_Step(Task, state, step, forceRefresh); + } + + public bool TryStep(string state, int step = -1, bool forceRefresh = true) + { + return internal_Step(Task, state, step, forceRefresh); + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs new file mode 100644 index 0000000000..793f84fd77 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Globals.cs @@ -0,0 +1,33 @@ +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; + +namespace GodotTools.Internals +{ + public static class Globals + { + public static float EditorScale => internal_EditorScale(); + + public static object GlobalDef(string setting, object defaultValue, bool restartIfChanged = false) => + internal_GlobalDef(setting, defaultValue, restartIfChanged); + + public static object EditorDef(string setting, object defaultValue, bool restartIfChanged = false) => + internal_EditorDef(setting, defaultValue, restartIfChanged); + + [SuppressMessage("ReSharper", "InconsistentNaming")] + public static string TTR(this string text) => internal_TTR(text); + + // Internal Calls + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern float internal_EditorScale(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern object internal_GlobalDef(string setting, object defaultValue, bool restartIfChanged); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern object internal_EditorDef(string setting, object defaultValue, bool restartIfChanged); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_TTR(string text); + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs new file mode 100644 index 0000000000..ddf3b829b5 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/GodotSharpDirs.cs @@ -0,0 +1,91 @@ +using System.Runtime.CompilerServices; + +namespace GodotTools.Internals +{ + public static class GodotSharpDirs + { + public static string ResDataDir => internal_ResDataDir(); + public static string ResMetadataDir => internal_ResMetadataDir(); + public static string ResAssembliesBaseDir => internal_ResAssembliesBaseDir(); + public static string ResAssembliesDir => internal_ResAssembliesDir(); + public static string ResConfigDir => internal_ResConfigDir(); + public static string ResTempDir => internal_ResTempDir(); + public static string ResTempAssembliesBaseDir => internal_ResTempAssembliesBaseDir(); + public static string ResTempAssembliesDir => internal_ResTempAssembliesDir(); + + public static string MonoUserDir => internal_MonoUserDir(); + public static string MonoLogsDir => internal_MonoLogsDir(); + + #region Tools-only + public static string MonoSolutionsDir => internal_MonoSolutionsDir(); + public static string BuildLogsDirs => internal_BuildLogsDirs(); + + public static string ProjectSlnPath => internal_ProjectSlnPath(); + public static string ProjectCsProjPath => internal_ProjectCsProjPath(); + + public static string DataEditorToolsDir => internal_DataEditorToolsDir(); + public static string DataEditorPrebuiltApiDir => internal_DataEditorPrebuiltApiDir(); + #endregion + + public static string DataMonoEtcDir => internal_DataMonoEtcDir(); + public static string DataMonoLibDir => internal_DataMonoLibDir(); + + #region Windows-only + public static string DataMonoBinDir => internal_DataMonoBinDir(); + #endregion + + + #region Internal + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_ResDataDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_ResMetadataDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_ResAssembliesBaseDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_ResAssembliesDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_ResConfigDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_ResTempDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_ResTempAssembliesBaseDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_ResTempAssembliesDir(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_MonoUserDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_MonoLogsDir(); + + #region Tools-only + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_MonoSolutionsDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_BuildLogsDirs(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_ProjectSlnPath(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_ProjectCsProjPath(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_DataEditorToolsDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_DataEditorPrebuiltApiDir(); + #endregion + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_DataMonoEtcDir(); + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_DataMonoLibDir(); + + #region Windows-only + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_DataMonoBinDir(); + #endregion + + #endregion + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs new file mode 100644 index 0000000000..9526dd3c6f --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/Internal.cs @@ -0,0 +1,99 @@ +using System; +using System.Runtime.CompilerServices; +using Godot; +using Godot.Collections; + +namespace GodotTools.Internals +{ + public static class Internal + { + public const string CSharpLanguageType = "CSharpScript"; + public const string CSharpLanguageExtension = "cs"; + + public static string UpdateApiAssembliesFromPrebuilt() => + internal_UpdateApiAssembliesFromPrebuilt(); + + public static string FullTemplatesDir => + internal_FullTemplatesDir(); + + public static string SimplifyGodotPath(this string path) => internal_SimplifyGodotPath(path); + + public static bool IsOsxAppBundleInstalled(string bundleId) => internal_IsOsxAppBundleInstalled(bundleId); + + public static bool GodotIs32Bits() => internal_GodotIs32Bits(); + + public static bool GodotIsRealTDouble() => internal_GodotIsRealTDouble(); + + public static void GodotMainIteration() => internal_GodotMainIteration(); + + public static ulong GetCoreApiHash() => internal_GetCoreApiHash(); + + public static ulong GetEditorApiHash() => internal_GetEditorApiHash(); + + public static bool IsAssembliesReloadingNeeded() => internal_IsAssembliesReloadingNeeded(); + + public static void ReloadAssemblies(bool softReload) => internal_ReloadAssemblies(softReload); + + public static void ScriptEditorDebuggerReloadScripts() => internal_ScriptEditorDebuggerReloadScripts(); + + public static bool ScriptEditorEdit(Resource resource, int line, int col, bool grabFocus = true) => + internal_ScriptEditorEdit(resource, line, col, grabFocus); + + public static void EditorNodeShowScriptScreen() => internal_EditorNodeShowScriptScreen(); + + public static Dictionary<string, object> GetScriptsMetadataOrNothing() => + internal_GetScriptsMetadataOrNothing(typeof(Dictionary<string, object>)); + + public static string MonoWindowsInstallRoot => internal_MonoWindowsInstallRoot(); + + // Internal Calls + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_UpdateApiAssembliesFromPrebuilt(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_FullTemplatesDir(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_SimplifyGodotPath(this string path); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern bool internal_IsOsxAppBundleInstalled(string bundleId); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern bool internal_GodotIs32Bits(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern bool internal_GodotIsRealTDouble(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void internal_GodotMainIteration(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern ulong internal_GetCoreApiHash(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern ulong internal_GetEditorApiHash(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern bool internal_IsAssembliesReloadingNeeded(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void internal_ReloadAssemblies(bool softReload); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void internal_ScriptEditorDebuggerReloadScripts(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern bool internal_ScriptEditorEdit(Resource resource, int line, int col, bool grabFocus); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern void internal_EditorNodeShowScriptScreen(); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern Dictionary<string, object> internal_GetScriptsMetadataOrNothing(Type dictType); + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern string internal_MonoWindowsInstallRoot(); + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs b/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs new file mode 100644 index 0000000000..2497d276a9 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Internals/ScriptClassParser.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using Godot; +using Godot.Collections; + +namespace GodotTools.Internals +{ + public static class ScriptClassParser + { + public class ClassDecl + { + public string Name { get; } + public string Namespace { get; } + public bool Nested { get; } + public int BaseCount { get; } + + public ClassDecl(string name, string @namespace, bool nested, int baseCount) + { + Name = name; + Namespace = @namespace; + Nested = nested; + BaseCount = baseCount; + } + } + + [MethodImpl(MethodImplOptions.InternalCall)] + private static extern Error internal_ParseFile(string filePath, Array<Dictionary> classes); + + public static void ParseFileOrThrow(string filePath, out IEnumerable<ClassDecl> classes) + { + var classesArray = new Array<Dictionary>(); + var error = internal_ParseFile(filePath, classesArray); + if (error != Error.Ok) + throw new Exception($"Failed to determine namespace and class for script: {filePath}. Parse error: {error}"); + + var classesList = new List<ClassDecl>(); + + foreach (var classDeclDict in classesArray) + { + classesList.Add(new ClassDecl( + (string) classDeclDict["name"], + (string) classDeclDict["namespace"], + (bool) classDeclDict["nested"], + (int) classDeclDict["base_count"] + )); + } + + classes = classesList; + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs b/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs new file mode 100644 index 0000000000..53ff0891d5 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/MonoBottomPanel.cs @@ -0,0 +1,343 @@ +using Godot; +using System; +using System.IO; +using Godot.Collections; +using GodotTools.Internals; +using static GodotTools.Internals.Globals; +using File = GodotTools.Utils.File; +using Path = System.IO.Path; + +namespace GodotTools +{ + public class MonoBottomPanel : VBoxContainer + { + private EditorInterface editorInterface; + + private TabContainer panelTabs; + + private VBoxContainer panelBuildsTab; + + private ItemList buildTabsList; + private TabContainer buildTabs; + + private ToolButton warningsBtn; + private ToolButton errorsBtn; + private Button viewLogBtn; + + private void _UpdateBuildTabsList() + { + buildTabsList.Clear(); + + int currentTab = buildTabs.CurrentTab; + + bool noCurrentTab = currentTab < 0 || currentTab >= buildTabs.GetTabCount(); + + for (int i = 0; i < buildTabs.GetChildCount(); i++) + { + var tab = (MonoBuildTab) buildTabs.GetChild(i); + + if (tab == null) + continue; + + string itemName = Path.GetFileNameWithoutExtension(tab.BuildInfo.Solution); + itemName += " [" + tab.BuildInfo.Configuration + "]"; + + buildTabsList.AddItem(itemName, tab.IconTexture); + + string itemTooltip = "Solution: " + tab.BuildInfo.Solution; + itemTooltip += "\nConfiguration: " + tab.BuildInfo.Configuration; + itemTooltip += "\nStatus: "; + + if (tab.BuildExited) + itemTooltip += tab.BuildResult == MonoBuildTab.BuildResults.Success ? "Succeeded" : "Errored"; + else + itemTooltip += "Running"; + + if (!tab.BuildExited || tab.BuildResult == MonoBuildTab.BuildResults.Error) + itemTooltip += $"\nErrors: {tab.ErrorCount}"; + + itemTooltip += $"\nWarnings: {tab.WarningCount}"; + + buildTabsList.SetItemTooltip(i, itemTooltip); + + if (noCurrentTab || currentTab == i) + { + buildTabsList.Select(i); + _BuildTabsItemSelected(i); + } + } + } + + public MonoBuildTab GetBuildTabFor(MonoBuildInfo buildInfo) + { + foreach (var buildTab in new Array<MonoBuildTab>(buildTabs.GetChildren())) + { + if (buildTab.BuildInfo.Equals(buildInfo)) + return buildTab; + } + + var newBuildTab = new MonoBuildTab(buildInfo); + AddBuildTab(newBuildTab); + + return newBuildTab; + } + + private void _BuildTabsItemSelected(int idx) + { + if (idx < 0 || idx >= buildTabs.GetTabCount()) + throw new IndexOutOfRangeException(); + + buildTabs.CurrentTab = idx; + if (!buildTabs.Visible) + buildTabs.Visible = true; + + warningsBtn.Visible = true; + errorsBtn.Visible = true; + viewLogBtn.Visible = true; + } + + private void _BuildTabsNothingSelected() + { + if (buildTabs.GetTabCount() != 0) + { + // just in case + buildTabs.Visible = false; + + // This callback is called when clicking on the empty space of the list. + // ItemList won't deselect the items automatically, so we must do it ourselves. + buildTabsList.UnselectAll(); + } + + warningsBtn.Visible = false; + errorsBtn.Visible = false; + viewLogBtn.Visible = false; + } + + private void _WarningsToggled(bool pressed) + { + int currentTab = buildTabs.CurrentTab; + + if (currentTab < 0 || currentTab >= buildTabs.GetTabCount()) + throw new InvalidOperationException("No tab selected"); + + var buildTab = (MonoBuildTab) buildTabs.GetChild(currentTab); + buildTab.WarningsVisible = pressed; + buildTab.UpdateIssuesList(); + } + + private void _ErrorsToggled(bool pressed) + { + int currentTab = buildTabs.CurrentTab; + + if (currentTab < 0 || currentTab >= buildTabs.GetTabCount()) + throw new InvalidOperationException("No tab selected"); + + var buildTab = (MonoBuildTab) buildTabs.GetChild(currentTab); + buildTab.ErrorsVisible = pressed; + buildTab.UpdateIssuesList(); + } + + public void BuildProjectPressed() + { + if (!File.Exists(GodotSharpDirs.ProjectSlnPath)) + return; // No solution to build + + string editorScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor"); + string playerScriptsMetadataPath = Path.Combine(GodotSharpDirs.ResMetadataDir, "scripts_metadata.editor_player"); + + CSharpProject.GenerateScriptsMetadata(GodotSharpDirs.ProjectCsProjPath, editorScriptsMetadataPath); + + if (File.Exists(editorScriptsMetadataPath)) + { + try + { + File.Copy(editorScriptsMetadataPath, playerScriptsMetadataPath); + } + catch (IOException e) + { + GD.PushError($"Failed to copy scripts metadata file. Exception message: {e.Message}"); + return; + } + } + + var godotDefines = new[] + { + OS.GetName(), + Internal.GodotIs32Bits() ? "32" : "64" + }; + + bool buildSuccess = GodotSharpBuilds.BuildProjectBlocking("Tools", godotDefines); + + if (!buildSuccess) + return; + + // Notify running game for hot-reload + Internal.ScriptEditorDebuggerReloadScripts(); + + // Hot-reload in the editor + GodotSharpEditor.Instance.GetNode<HotReloadAssemblyWatcher>("HotReloadAssemblyWatcher").RestartTimer(); + + if (Internal.IsAssembliesReloadingNeeded()) + Internal.ReloadAssemblies(softReload: false); + } + + private void _ViewLogPressed() + { + if (!buildTabsList.IsAnythingSelected()) + return; + + var selectedItems = buildTabsList.GetSelectedItems(); + + if (selectedItems.Length != 1) + throw new InvalidOperationException($"Expected 1 selected item, got {selectedItems.Length}"); + + int selectedItem = selectedItems[0]; + + var buildTab = (MonoBuildTab) buildTabs.GetTabControl(selectedItem); + + OS.ShellOpen(Path.Combine(buildTab.BuildInfo.LogsDirPath, GodotSharpBuilds.MsBuildLogFileName)); + } + + public override void _Notification(int what) + { + base._Notification(what); + + if (what == EditorSettings.NotificationEditorSettingsChanged) + { + var editorBaseControl = editorInterface.GetBaseControl(); + panelTabs.AddStyleboxOverride("panel", editorBaseControl.GetStylebox("DebuggerPanel", "EditorStyles")); + panelTabs.AddStyleboxOverride("tab_fg", editorBaseControl.GetStylebox("DebuggerTabFG", "EditorStyles")); + panelTabs.AddStyleboxOverride("tab_bg", editorBaseControl.GetStylebox("DebuggerTabBG", "EditorStyles")); + } + } + + public void AddBuildTab(MonoBuildTab buildTab) + { + buildTabs.AddChild(buildTab); + RaiseBuildTab(buildTab); + } + + public void RaiseBuildTab(MonoBuildTab buildTab) + { + if (buildTab.GetParent() != buildTabs) + throw new InvalidOperationException("Build tab is not in the tabs list"); + + buildTabs.MoveChild(buildTab, 0); + _UpdateBuildTabsList(); + } + + public void ShowBuildTab() + { + for (int i = 0; i < panelTabs.GetTabCount(); i++) + { + if (panelTabs.GetTabControl(i) == panelBuildsTab) + { + panelTabs.CurrentTab = i; + GodotSharpEditor.Instance.MakeBottomPanelItemVisible(this); + return; + } + } + + GD.PushError("Builds tab not found"); + } + + public override void _Ready() + { + base._Ready(); + + editorInterface = GodotSharpEditor.Instance.GetEditorInterface(); + + var editorBaseControl = editorInterface.GetBaseControl(); + + SizeFlagsVertical = (int) SizeFlags.ExpandFill; + SetAnchorsAndMarginsPreset(LayoutPreset.Wide); + + panelTabs = new TabContainer + { + TabAlign = TabContainer.TabAlignEnum.Left, + RectMinSize = new Vector2(0, 228) * EditorScale, + SizeFlagsVertical = (int) SizeFlags.ExpandFill + }; + panelTabs.AddStyleboxOverride("panel", editorBaseControl.GetStylebox("DebuggerPanel", "EditorStyles")); + panelTabs.AddStyleboxOverride("tab_fg", editorBaseControl.GetStylebox("DebuggerTabFG", "EditorStyles")); + panelTabs.AddStyleboxOverride("tab_bg", editorBaseControl.GetStylebox("DebuggerTabBG", "EditorStyles")); + AddChild(panelTabs); + + { + // Builds tab + panelBuildsTab = new VBoxContainer + { + Name = "Builds".TTR(), + SizeFlagsHorizontal = (int) SizeFlags.ExpandFill + }; + panelTabs.AddChild(panelBuildsTab); + + var toolBarHBox = new HBoxContainer {SizeFlagsHorizontal = (int) SizeFlags.ExpandFill}; + panelBuildsTab.AddChild(toolBarHBox); + + var buildProjectBtn = new Button + { + Text = "Build Project".TTR(), + FocusMode = FocusModeEnum.None + }; + buildProjectBtn.Connect("pressed", this, nameof(BuildProjectPressed)); + toolBarHBox.AddChild(buildProjectBtn); + + toolBarHBox.AddSpacer(begin: false); + + warningsBtn = new ToolButton + { + Text = "Warnings".TTR(), + ToggleMode = true, + Pressed = true, + Visible = false, + FocusMode = FocusModeEnum.None + }; + warningsBtn.Connect("toggled", this, nameof(_WarningsToggled)); + toolBarHBox.AddChild(warningsBtn); + + errorsBtn = new ToolButton + { + Text = "Errors".TTR(), + ToggleMode = true, + Pressed = true, + Visible = false, + FocusMode = FocusModeEnum.None + }; + errorsBtn.Connect("toggled", this, nameof(_ErrorsToggled)); + toolBarHBox.AddChild(errorsBtn); + + toolBarHBox.AddSpacer(begin: false); + + viewLogBtn = new Button + { + Text = "View log".TTR(), + FocusMode = FocusModeEnum.None, + Visible = false + }; + viewLogBtn.Connect("pressed", this, nameof(_ViewLogPressed)); + toolBarHBox.AddChild(viewLogBtn); + + var hsc = new HSplitContainer + { + SizeFlagsHorizontal = (int) SizeFlags.ExpandFill, + SizeFlagsVertical = (int) SizeFlags.ExpandFill + }; + panelBuildsTab.AddChild(hsc); + + buildTabsList = new ItemList {SizeFlagsHorizontal = (int) SizeFlags.ExpandFill}; + buildTabsList.Connect("item_selected", this, nameof(_BuildTabsItemSelected)); + buildTabsList.Connect("nothing_selected", this, nameof(_BuildTabsNothingSelected)); + hsc.AddChild(buildTabsList); + + buildTabs = new TabContainer + { + TabAlign = TabContainer.TabAlignEnum.Left, + SizeFlagsHorizontal = (int) SizeFlags.ExpandFill, + TabsVisible = false + }; + hsc.AddChild(buildTabs); + } + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBuildInfo.cs b/modules/mono/editor/GodotTools/GodotTools/MonoBuildInfo.cs new file mode 100644 index 0000000000..858e852392 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/MonoBuildInfo.cs @@ -0,0 +1,47 @@ +using System; +using Godot; +using Godot.Collections; +using GodotTools.Internals; +using Path = System.IO.Path; + +namespace GodotTools +{ + [Serializable] + public sealed class MonoBuildInfo : Reference // TODO Remove Reference once we have proper serialization + { + public string Solution { get; } + public string Configuration { get; } + public Array<string> CustomProperties { get; } = new Array<string>(); // TODO Use List once we have proper serialization + + public string LogsDirPath => Path.Combine(GodotSharpDirs.BuildLogsDirs, $"{Solution.MD5Text()}_{Configuration}"); + + public override bool Equals(object obj) + { + if (obj is MonoBuildInfo other) + return other.Solution == Solution && other.Configuration == Configuration; + + return false; + } + + public override int GetHashCode() + { + unchecked + { + int hash = 17; + hash = hash * 29 + Solution.GetHashCode(); + hash = hash * 29 + Configuration.GetHashCode(); + return hash; + } + } + + private MonoBuildInfo() + { + } + + public MonoBuildInfo(string solution, string configuration) + { + Solution = solution; + Configuration = configuration; + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs b/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs new file mode 100644 index 0000000000..75fdacc0da --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/MonoBuildTab.cs @@ -0,0 +1,260 @@ +using Godot; +using System; +using Godot.Collections; +using GodotTools.Internals; +using File = GodotTools.Utils.File; +using Path = System.IO.Path; + +namespace GodotTools +{ + public class MonoBuildTab : VBoxContainer + { + public enum BuildResults + { + Error, + Success + } + + [Serializable] + private class BuildIssue : Reference // TODO Remove Reference once we have proper serialization + { + public bool Warning { get; set; } + public string File { get; set; } + public int Line { get; set; } + public int Column { get; set; } + public string Code { get; set; } + public string Message { get; set; } + public string ProjectFile { get; set; } + } + + private readonly Array<BuildIssue> issues = new Array<BuildIssue>(); // TODO Use List once we have proper serialization + private ItemList issuesList; + + public bool BuildExited { get; private set; } = false; + + public BuildResults? BuildResult { get; private set; } = null; + + public int ErrorCount { get; private set; } = 0; + + public int WarningCount { get; private set; } = 0; + + public bool ErrorsVisible { get; set; } = true; + public bool WarningsVisible { get; set; } = true; + + public Texture IconTexture + { + get + { + if (!BuildExited) + return GetIcon("Stop", "EditorIcons"); + + if (BuildResult == BuildResults.Error) + return GetIcon("StatusError", "EditorIcons"); + + return GetIcon("StatusSuccess", "EditorIcons"); + } + } + + public MonoBuildInfo BuildInfo { get; private set; } + + private void _LoadIssuesFromFile(string csvFile) + { + using (var file = new Godot.File()) + { + Error openError = file.Open(csvFile, Godot.File.ModeFlags.Read); + + if (openError != Error.Ok) + return; + + while (!file.EofReached()) + { + string[] csvColumns = file.GetCsvLine(); + + if (csvColumns.Length == 1 && csvColumns[0].Empty()) + return; + + if (csvColumns.Length != 7) + { + GD.PushError($"Expected 7 columns, got {csvColumns.Length}"); + continue; + } + + var issue = new BuildIssue + { + Warning = csvColumns[0] == "warning", + File = csvColumns[1], + Line = int.Parse(csvColumns[2]), + Column = int.Parse(csvColumns[3]), + Code = csvColumns[4], + Message = csvColumns[5], + ProjectFile = csvColumns[6] + }; + + if (issue.Warning) + WarningCount += 1; + else + ErrorCount += 1; + + issues.Add(issue); + } + } + } + + private void _IssueActivated(int idx) + { + if (idx < 0 || idx >= issuesList.GetItemCount()) + throw new IndexOutOfRangeException("Item list index out of range"); + + // Get correct issue idx from issue list + int issueIndex = (int) issuesList.GetItemMetadata(idx); + + if (idx < 0 || idx >= issues.Count) + throw new IndexOutOfRangeException("Issue index out of range"); + + BuildIssue issue = issues[issueIndex]; + + if (issue.ProjectFile.Empty() && issue.File.Empty()) + return; + + string projectDir = issue.ProjectFile.Length > 0 ? issue.ProjectFile.GetBaseDir() : BuildInfo.Solution.GetBaseDir(); + + string file = Path.Combine(projectDir.SimplifyGodotPath(), issue.File.SimplifyGodotPath()); + + if (!File.Exists(file)) + return; + + file = ProjectSettings.LocalizePath(file); + + if (file.StartsWith("res://")) + { + var script = (Script) ResourceLoader.Load(file, typeHint: Internal.CSharpLanguageType); + + if (script != null && Internal.ScriptEditorEdit(script, issue.Line, issue.Column)) + Internal.EditorNodeShowScriptScreen(); + } + } + + public void UpdateIssuesList() + { + issuesList.Clear(); + + using (var warningIcon = GetIcon("Warning", "EditorIcons")) + using (var errorIcon = GetIcon("Error", "EditorIcons")) + { + for (int i = 0; i < issues.Count; i++) + { + BuildIssue issue = issues[i]; + + if (!(issue.Warning ? WarningsVisible : ErrorsVisible)) + continue; + + string tooltip = string.Empty; + tooltip += $"Message: {issue.Message}"; + + if (!issue.Code.Empty()) + tooltip += $"\nCode: {issue.Code}"; + + tooltip += $"\nType: {(issue.Warning ? "warning" : "error")}"; + + string text = string.Empty; + + if (!issue.File.Empty()) + { + text += $"{issue.File}({issue.Line},{issue.Column}): "; + + tooltip += $"\nFile: {issue.File}"; + tooltip += $"\nLine: {issue.Line}"; + tooltip += $"\nColumn: {issue.Column}"; + } + + if (!issue.ProjectFile.Empty()) + tooltip += $"\nProject: {issue.ProjectFile}"; + + text += issue.Message; + + int lineBreakIdx = text.IndexOf("\n", StringComparison.Ordinal); + string itemText = lineBreakIdx == -1 ? text : text.Substring(0, lineBreakIdx); + issuesList.AddItem(itemText, issue.Warning ? warningIcon : errorIcon); + + int index = issuesList.GetItemCount() - 1; + issuesList.SetItemTooltip(index, tooltip); + issuesList.SetItemMetadata(index, i); + } + } + } + + public void OnBuildStart() + { + BuildExited = false; + + issues.Clear(); + WarningCount = 0; + ErrorCount = 0; + UpdateIssuesList(); + + GodotSharpEditor.Instance.MonoBottomPanel.RaiseBuildTab(this); + } + + public void OnBuildExit(BuildResults result) + { + BuildExited = true; + BuildResult = result; + + _LoadIssuesFromFile(Path.Combine(BuildInfo.LogsDirPath, GodotSharpBuilds.MsBuildIssuesFileName)); + UpdateIssuesList(); + + GodotSharpEditor.Instance.MonoBottomPanel.RaiseBuildTab(this); + } + + public void OnBuildExecFailed(string cause) + { + BuildExited = true; + BuildResult = BuildResults.Error; + + issuesList.Clear(); + + var issue = new BuildIssue {Message = cause, Warning = false}; + + ErrorCount += 1; + issues.Add(issue); + + UpdateIssuesList(); + + GodotSharpEditor.Instance.MonoBottomPanel.RaiseBuildTab(this); + } + + public void RestartBuild() + { + if (!BuildExited) + throw new InvalidOperationException("Build already started"); + + GodotSharpBuilds.RestartBuild(this); + } + + public void StopBuild() + { + if (!BuildExited) + throw new InvalidOperationException("Build is not in progress"); + + GodotSharpBuilds.StopBuild(this); + } + + public override void _Ready() + { + base._Ready(); + + issuesList = new ItemList {SizeFlagsVertical = (int) SizeFlags.ExpandFill}; + issuesList.Connect("item_activated", this, nameof(_IssueActivated)); + AddChild(issuesList); + } + + private MonoBuildTab() + { + } + + public MonoBuildTab(MonoBuildInfo buildInfo) + { + BuildInfo = buildInfo; + } + } +} diff --git a/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs b/modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs index fba4a8f65c..0c8d86e799 100644 --- a/modules/mono/editor/GodotSharpTools/Editor/MonoDevelopInstance.cs +++ b/modules/mono/editor/GodotTools/GodotTools/MonoDevelopInstance.cs @@ -1,11 +1,11 @@ +using GodotTools.Core; using System; using System.IO; using System.Collections.Generic; using System.Diagnostics; -using System.Runtime.InteropServices; -using System.Runtime.CompilerServices; +using GodotTools.Internals; -namespace GodotSharpTools.Editor +namespace GodotTools { public class MonoDevelopInstance { @@ -15,24 +15,24 @@ namespace GodotSharpTools.Editor VisualStudioForMac = 1 } - readonly string solutionFile; - readonly EditorId editorId; + private readonly string solutionFile; + private readonly EditorId editorId; - Process process; + private Process process; - public void Execute(string[] files) + public void Execute(params string[] files) { bool newWindow = process == null || process.HasExited; - List<string> args = new List<string>(); + var args = new List<string>(); string command; if (Utils.OS.IsOSX()) { - string bundleId = codeEditorBundleIds[editorId]; + string bundleId = CodeEditorBundleIds[editorId]; - if (IsApplicationBundleInstalled(bundleId)) + if (Internal.IsOsxAppBundleInstalled(bundleId)) { command = "open"; @@ -47,12 +47,12 @@ namespace GodotSharpTools.Editor } else { - command = codeEditorPaths[editorId]; + command = CodeEditorPaths[editorId]; } } else { - command = codeEditorPaths[editorId]; + command = CodeEditorPaths[editorId]; } args.Add("--ipc-tcp"); @@ -72,7 +72,7 @@ namespace GodotSharpTools.Editor if (newWindow) { - process = Process.Start(new ProcessStartInfo() + process = Process.Start(new ProcessStartInfo { FileName = command, Arguments = string.Join(" ", args), @@ -81,12 +81,12 @@ namespace GodotSharpTools.Editor } else { - Process.Start(new ProcessStartInfo() + Process.Start(new ProcessStartInfo { FileName = command, Arguments = string.Join(" ", args), UseShellExecute = false - }); + })?.Dispose(); } } @@ -99,45 +99,42 @@ namespace GodotSharpTools.Editor this.editorId = editorId; } - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static bool IsApplicationBundleInstalled(string bundleId); - - static readonly IReadOnlyDictionary<EditorId, string> codeEditorPaths; - static readonly IReadOnlyDictionary<EditorId, string> codeEditorBundleIds; + private static readonly IReadOnlyDictionary<EditorId, string> CodeEditorPaths; + private static readonly IReadOnlyDictionary<EditorId, string> CodeEditorBundleIds; static MonoDevelopInstance() { if (Utils.OS.IsOSX()) { - codeEditorPaths = new Dictionary<EditorId, string> + CodeEditorPaths = new Dictionary<EditorId, string> { // Rely on PATH - { EditorId.MonoDevelop, "monodevelop" }, - { EditorId.VisualStudioForMac, "VisualStudio" } + {EditorId.MonoDevelop, "monodevelop"}, + {EditorId.VisualStudioForMac, "VisualStudio"} }; - codeEditorBundleIds = new Dictionary<EditorId, string> + CodeEditorBundleIds = new Dictionary<EditorId, string> { // TODO EditorId.MonoDevelop - { EditorId.VisualStudioForMac, "com.microsoft.visual-studio" } + {EditorId.VisualStudioForMac, "com.microsoft.visual-studio"} }; } else if (Utils.OS.IsWindows()) { - codeEditorPaths = new Dictionary<EditorId, string> + CodeEditorPaths = new Dictionary<EditorId, string> { // XamarinStudio is no longer a thing, and the latest version is quite old // MonoDevelop is available from source only on Windows. The recommendation // is to use Visual Studio instead. Since there are no official builds, we // will rely on custom MonoDevelop builds being added to PATH. - { EditorId.MonoDevelop, "MonoDevelop.exe" } + {EditorId.MonoDevelop, "MonoDevelop.exe"} }; } else if (Utils.OS.IsUnix()) { - codeEditorPaths = new Dictionary<EditorId, string> + CodeEditorPaths = new Dictionary<EditorId, string> { // Rely on PATH - { EditorId.MonoDevelop, "monodevelop" } + {EditorId.MonoDevelop, "monodevelop"} }; } } diff --git a/modules/mono/editor/GodotTools/GodotTools/Properties/AssemblyInfo.cs b/modules/mono/editor/GodotTools/GodotTools/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..f5fe85c722 --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Properties/AssemblyInfo.cs @@ -0,0 +1,26 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("GodotTools")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("Godot Engine contributors")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs new file mode 100644 index 0000000000..3ae6c10bbf --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/CollectionExtensions.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +namespace GodotTools.Utils +{ + public static class CollectionExtensions + { + public static T SelectFirstNotNull<T>(this IEnumerable<T> enumerable, Func<T, T> predicate, T orElse = null) + where T : class + { + foreach (T elem in enumerable) + { + if (predicate(elem) != null) + return elem; + } + + return orElse; + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/Directory.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/Directory.cs new file mode 100644 index 0000000000..c67d48b92a --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/Directory.cs @@ -0,0 +1,40 @@ +using System.IO; +using Godot; + +namespace GodotTools.Utils +{ + public static class Directory + { + private static string GlobalizePath(this string path) + { + return ProjectSettings.GlobalizePath(path); + } + + public static bool Exists(string path) + { + return System.IO.Directory.Exists(path.GlobalizePath()); + } + + /// Create directory recursively + public static DirectoryInfo CreateDirectory(string path) + { + return System.IO.Directory.CreateDirectory(path.GlobalizePath()); + } + + public static void Delete(string path, bool recursive) + { + System.IO.Directory.Delete(path.GlobalizePath(), recursive); + } + + + public static string[] GetDirectories(string path, string searchPattern, SearchOption searchOption) + { + return System.IO.Directory.GetDirectories(path.GlobalizePath(), searchPattern, searchOption); + } + + public static string[] GetFiles(string path, string searchPattern, SearchOption searchOption) + { + return System.IO.Directory.GetFiles(path.GlobalizePath(), searchPattern, searchOption); + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/File.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/File.cs new file mode 100644 index 0000000000..e1e2188edb --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/File.cs @@ -0,0 +1,43 @@ +using System; +using Godot; + +namespace GodotTools.Utils +{ + public static class File + { + private static string GlobalizePath(this string path) + { + return ProjectSettings.GlobalizePath(path); + } + + public static void WriteAllText(string path, string contents) + { + System.IO.File.WriteAllText(path.GlobalizePath(), contents); + } + + public static bool Exists(string path) + { + return System.IO.File.Exists(path.GlobalizePath()); + } + + public static DateTime GetLastWriteTime(string path) + { + return System.IO.File.GetLastWriteTime(path.GlobalizePath()); + } + + public static void Delete(string path) + { + System.IO.File.Delete(path.GlobalizePath()); + } + + public static void Copy(string sourceFileName, string destFileName) + { + System.IO.File.Copy(sourceFileName.GlobalizePath(), destFileName.GlobalizePath(), overwrite: true); + } + + public static byte[] ReadAllBytes(string path) + { + return System.IO.File.ReadAllBytes(path.GlobalizePath()); + } + } +} diff --git a/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs new file mode 100644 index 0000000000..e48b1115db --- /dev/null +++ b/modules/mono/editor/GodotTools/GodotTools/Utils/OS.cs @@ -0,0 +1,127 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; + +namespace GodotTools.Utils +{ + public static class OS + { + [MethodImpl(MethodImplOptions.InternalCall)] + extern static string GetPlatformName(); + + const string HaikuName = "Haiku"; + const string OSXName = "OSX"; + const string ServerName = "Server"; + const string UWPName = "UWP"; + const string WindowsName = "Windows"; + const string X11Name = "X11"; + + public static bool IsHaiku() + { + return HaikuName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); + } + + public static bool IsOSX() + { + return OSXName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); + } + + public static bool IsServer() + { + return ServerName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); + } + + public static bool IsUWP() + { + return UWPName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); + } + + public static bool IsWindows() + { + return WindowsName.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); + } + + public static bool IsX11() + { + return X11Name.Equals(GetPlatformName(), StringComparison.OrdinalIgnoreCase); + } + + private static bool? _isUnixCache; + private static readonly string[] UnixPlatforms = {HaikuName, OSXName, ServerName, X11Name}; + + public static bool IsUnix() + { + if (_isUnixCache.HasValue) + return _isUnixCache.Value; + + string osName = GetPlatformName(); + _isUnixCache = UnixPlatforms.Any(p => p.Equals(osName, StringComparison.OrdinalIgnoreCase)); + return _isUnixCache.Value; + } + + public static char PathSep => IsWindows() ? ';' : ':'; + + public static string PathWhich(string name) + { + string[] windowsExts = IsWindows() ? Environment.GetEnvironmentVariable("PATHEXT")?.Split(PathSep) : null; + string[] pathDirs = Environment.GetEnvironmentVariable("PATH")?.Split(PathSep); + + var searchDirs = new List<string>(); + + if (pathDirs != null) + searchDirs.AddRange(pathDirs); + + searchDirs.Add(System.IO.Directory.GetCurrentDirectory()); // last in the list + + foreach (var dir in searchDirs) + { + string path = Path.Combine(dir, name); + + if (IsWindows() && windowsExts != null) + { + foreach (var extension in windowsExts) + { + string pathWithExtension = path + extension; + + if (File.Exists(pathWithExtension)) + return pathWithExtension; + } + } + else + { + if (File.Exists(path)) + return path; + } + } + + return null; + } + + public static void RunProcess(string command, IEnumerable<string> arguments) + { + string CmdLineArgsToString(IEnumerable<string> args) + { + return string.Join(" ", args.Select(arg => arg.Contains(" ") ? $@"""{arg}""" : arg)); + } + + ProcessStartInfo startInfo = new ProcessStartInfo(command, CmdLineArgsToString(arguments)) + { + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false + }; + + using (Process process = Process.Start(startInfo)) + { + if (process == null) + throw new Exception("No process was started"); + + process.BeginOutputReadLine(); + process.BeginErrorReadLine(); + } + } + } +} diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp index 2d618f7891..45037bf637 100644 --- a/modules/mono/editor/bindings_generator.cpp +++ b/modules/mono/editor/bindings_generator.cpp @@ -861,37 +861,33 @@ void BindingsGenerator::_generate_global_constants(StringBuilder &p_output) { p_output.append("\n#pragma warning restore CS1591\n"); } -Error BindingsGenerator::generate_cs_core_project(const String &p_solution_dir, DotNetSolution &r_solution) { - - String proj_dir = p_solution_dir.plus_file(CORE_API_ASSEMBLY_NAME); +Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir, Vector<String> &r_compile_items) { DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); ERR_FAIL_COND_V(!da, ERR_CANT_CREATE); - if (!DirAccess::exists(proj_dir)) { - Error err = da->make_dir_recursive(proj_dir); + if (!DirAccess::exists(p_proj_dir)) { + Error err = da->make_dir_recursive(p_proj_dir); ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); } - da->change_dir(proj_dir); + da->change_dir(p_proj_dir); da->make_dir("Core"); da->make_dir("ObjectType"); - String core_dir = path_join(proj_dir, "Core"); - String obj_type_dir = path_join(proj_dir, "ObjectType"); - - Vector<String> compile_items; + String core_dir = path::join(p_proj_dir, "Core"); + String obj_type_dir = path::join(p_proj_dir, "ObjectType"); // Generate source file for global scope constants and enums { StringBuilder constants_source; _generate_global_constants(constants_source); - String output_file = path_join(core_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_constants.cs"); + String output_file = path::join(core_dir, BINDINGS_GLOBAL_SCOPE_CLASS "_constants.cs"); Error save_err = _save_file(output_file, constants_source); if (save_err != OK) return save_err; - compile_items.push_back(output_file); + r_compile_items.push_back(output_file); } for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) { @@ -900,7 +896,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_solution_dir, if (itype.api_type == ClassDB::API_EDITOR) continue; - String output_file = path_join(obj_type_dir, itype.proxy_name + ".cs"); + String output_file = path::join(obj_type_dir, itype.proxy_name + ".cs"); Error err = _generate_cs_type(itype, output_file); if (err == ERR_SKIP) @@ -909,19 +905,19 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_solution_dir, if (err != OK) return err; - compile_items.push_back(output_file); + r_compile_items.push_back(output_file); } // Generate sources from compressed files - Map<String, CompressedFile> compressed_files; + Map<String, GodotCsCompressedFile> compressed_files; get_compressed_files(compressed_files); - for (Map<String, CompressedFile>::Element *E = compressed_files.front(); E; E = E->next()) { + for (Map<String, GodotCsCompressedFile>::Element *E = compressed_files.front(); E; E = E->next()) { const String &file_name = E->key(); - const CompressedFile &file_data = E->value(); + const GodotCsCompressedFile &file_data = E->value(); - String output_file = path_join(core_dir, file_name); + String output_file = path::join(core_dir, file_name); Vector<uint8_t> data; data.resize(file_data.uncompressed_size); @@ -939,7 +935,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_solution_dir, file->store_buffer(data.ptr(), data.size()); file->close(); - compile_items.push_back(output_file); + r_compile_items.push_back(output_file); } StringBuilder cs_icalls_content; @@ -975,49 +971,33 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_solution_dir, cs_icalls_content.append(INDENT1 CLOSE_BLOCK CLOSE_BLOCK); - String internal_methods_file = path_join(core_dir, BINDINGS_CLASS_NATIVECALLS ".cs"); + String internal_methods_file = path::join(core_dir, BINDINGS_CLASS_NATIVECALLS ".cs"); Error err = _save_file(internal_methods_file, cs_icalls_content); if (err != OK) return err; - compile_items.push_back(internal_methods_file); - - String guid = CSharpProject::generate_core_api_project(proj_dir, compile_items); - - DotNetSolution::ProjectInfo proj_info; - proj_info.guid = guid; - proj_info.relpath = String(CORE_API_ASSEMBLY_NAME).plus_file(CORE_API_ASSEMBLY_NAME ".csproj"); - proj_info.configs.push_back("Debug"); - proj_info.configs.push_back("Release"); - - r_solution.add_new_project(CORE_API_ASSEMBLY_NAME, proj_info); - - _log("The solution and C# project for the Core API was generated successfully\n"); + r_compile_items.push_back(internal_methods_file); return OK; } -Error BindingsGenerator::generate_cs_editor_project(const String &p_solution_dir, DotNetSolution &r_solution) { - - String proj_dir = p_solution_dir.plus_file(EDITOR_API_ASSEMBLY_NAME); +Error BindingsGenerator::generate_cs_editor_project(const String &p_proj_dir, Vector<String> &r_compile_items) { DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); ERR_FAIL_COND_V(!da, ERR_CANT_CREATE); - if (!DirAccess::exists(proj_dir)) { - Error err = da->make_dir_recursive(proj_dir); + if (!DirAccess::exists(p_proj_dir)) { + Error err = da->make_dir_recursive(p_proj_dir); ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); } - da->change_dir(proj_dir); + da->change_dir(p_proj_dir); da->make_dir("Core"); da->make_dir("ObjectType"); - String core_dir = path_join(proj_dir, "Core"); - String obj_type_dir = path_join(proj_dir, "ObjectType"); - - Vector<String> compile_items; + String core_dir = path::join(p_proj_dir, "Core"); + String obj_type_dir = path::join(p_proj_dir, "ObjectType"); for (OrderedHashMap<StringName, TypeInterface>::Element E = obj_types.front(); E; E = E.next()) { const TypeInterface &itype = E.get(); @@ -1025,7 +1005,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_solution_dir if (itype.api_type != ClassDB::API_EDITOR) continue; - String output_file = path_join(obj_type_dir, itype.proxy_name + ".cs"); + String output_file = path::join(obj_type_dir, itype.proxy_name + ".cs"); Error err = _generate_cs_type(itype, output_file); if (err == ERR_SKIP) @@ -1034,7 +1014,7 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_solution_dir if (err != OK) return err; - compile_items.push_back(output_file); + r_compile_items.push_back(output_file); } StringBuilder cs_icalls_content; @@ -1071,64 +1051,62 @@ Error BindingsGenerator::generate_cs_editor_project(const String &p_solution_dir cs_icalls_content.append(INDENT1 CLOSE_BLOCK CLOSE_BLOCK); - String internal_methods_file = path_join(core_dir, BINDINGS_CLASS_NATIVECALLS_EDITOR ".cs"); + String internal_methods_file = path::join(core_dir, BINDINGS_CLASS_NATIVECALLS_EDITOR ".cs"); Error err = _save_file(internal_methods_file, cs_icalls_content); if (err != OK) return err; - compile_items.push_back(internal_methods_file); - - String guid = CSharpProject::generate_editor_api_project(proj_dir, "../" CORE_API_ASSEMBLY_NAME "/" CORE_API_ASSEMBLY_NAME ".csproj", compile_items); - - DotNetSolution::ProjectInfo proj_info; - proj_info.guid = guid; - proj_info.relpath = String(EDITOR_API_ASSEMBLY_NAME).plus_file(EDITOR_API_ASSEMBLY_NAME ".csproj"); - proj_info.configs.push_back("Debug"); - proj_info.configs.push_back("Release"); - - r_solution.add_new_project(EDITOR_API_ASSEMBLY_NAME, proj_info); - - _log("The solution and C# project for the Editor API was generated successfully\n"); + r_compile_items.push_back(internal_methods_file); return OK; } Error BindingsGenerator::generate_cs_api(const String &p_output_dir) { + String output_dir = path::abspath(path::realpath(p_output_dir)); + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); ERR_FAIL_COND_V(!da, ERR_CANT_CREATE); - if (!DirAccess::exists(p_output_dir)) { - Error err = da->make_dir_recursive(p_output_dir); + if (!DirAccess::exists(output_dir)) { + Error err = da->make_dir_recursive(output_dir); ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); } - DotNetSolution solution(API_SOLUTION_NAME); + Error proj_err; - if (!solution.set_path(p_output_dir)) - return ERR_FILE_NOT_FOUND; + // Generate GodotSharp source files - Error proj_err; + String core_proj_dir = output_dir.plus_file(CORE_API_ASSEMBLY_NAME); + Vector<String> core_compile_items; - proj_err = generate_cs_core_project(p_output_dir, solution); + proj_err = generate_cs_core_project(core_proj_dir, core_compile_items); if (proj_err != OK) { ERR_PRINT("Generation of the Core API C# project failed"); return proj_err; } - proj_err = generate_cs_editor_project(p_output_dir, solution); + // Generate GodotSharpEditor source files + + String editor_proj_dir = output_dir.plus_file(EDITOR_API_ASSEMBLY_NAME); + Vector<String> editor_compile_items; + + proj_err = generate_cs_editor_project(editor_proj_dir, editor_compile_items); if (proj_err != OK) { ERR_PRINT("Generation of the Editor API C# project failed"); return proj_err; } - Error sln_error = solution.save(); - if (sln_error != OK) { - ERR_PRINT("Failed to save API solution"); - return sln_error; + // Generate solution + + if (!CSharpProject::generate_api_solution(output_dir, + core_proj_dir, core_compile_items, editor_proj_dir, editor_compile_items)) { + return ERR_CANT_CREATE; } + _log("The solution for the Godot API was generated successfully\n"); + return OK; } @@ -1311,8 +1289,9 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str output.append(MEMBER_BEGIN "private static Godot.Object singleton;\n"); output.append(MEMBER_BEGIN "public static Godot.Object Singleton\n" INDENT2 "{\n" INDENT3 "get\n" INDENT3 "{\n" INDENT4 "if (singleton == null)\n" INDENT5 - "singleton = Engine.GetSingleton(" BINDINGS_NATIVE_NAME_FIELD ");\n" INDENT4 - "return singleton;\n" INDENT3 "}\n" INDENT2 "}\n"); + "singleton = Engine.GetSingleton(typeof("); + output.append(itype.proxy_name); + output.append(").Name);\n" INDENT4 "return singleton;\n" INDENT3 "}\n" INDENT2 "}\n"); output.append(MEMBER_BEGIN "private const string " BINDINGS_NATIVE_NAME_FIELD " = \""); output.append(itype.name); @@ -1883,7 +1862,7 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) { output.append("\n#endif // MONO_GLUE_ENABLED\n"); - Error save_err = _save_file(path_join(p_output_dir, "mono_glue.gen.cpp"), output); + Error save_err = _save_file(path::join(p_output_dir, "mono_glue.gen.cpp"), output); if (save_err != OK) return save_err; @@ -2213,7 +2192,7 @@ void BindingsGenerator::_populate_object_type_interfaces() { itype.base_name = ClassDB::get_parent_class(type_cname); itype.is_singleton = Engine::get_singleton()->has_singleton(itype.proxy_name); - itype.is_instantiable = ClassDB::can_instance(type_cname) && !itype.is_singleton; + itype.is_instantiable = class_info->creation_func && !itype.is_singleton; itype.is_reference = ClassDB::is_parent_class(type_cname, name_cache.type_Reference); itype.memory_own = itype.is_reference; @@ -2347,6 +2326,13 @@ void BindingsGenerator::_populate_object_type_interfaces() { imethod.return_type.is_enum = true; } else if (return_info.class_name != StringName()) { imethod.return_type.cname = return_info.class_name; + if (!imethod.is_virtual && ClassDB::is_parent_class(return_info.class_name, name_cache.type_Reference) && return_info.hint != PROPERTY_HINT_RESOURCE_TYPE) { + /* clang-format off */ + ERR_PRINTS("Return type is reference but hint is not " _STR(PROPERTY_HINT_RESOURCE_TYPE) "." + " Are you returning a reference type by pointer? Method: " + itype.name + "." + imethod.name); + /* clang-format on */ + ERR_FAIL(); + } } else if (return_info.hint == PROPERTY_HINT_RESOURCE_TYPE) { imethod.return_type.cname = return_info.hint_string; } else if (return_info.type == Variant::NIL && return_info.usage & PROPERTY_USAGE_NIL_IS_VARIANT) { @@ -3018,36 +3004,49 @@ void BindingsGenerator::_initialize() { void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) { const int NUM_OPTIONS = 2; - String mono_glue_option = "--generate-mono-glue"; - String cs_api_option = "--generate-cs-api"; + String generate_all_glue_option = "--generate-mono-glue"; + String generate_cs_glue_option = "--generate-mono-cs-glue"; + String generate_cpp_glue_option = "--generate-mono-cpp-glue"; - String mono_glue_path; - String cs_api_path; + String glue_dir_path; + String cs_dir_path; + String cpp_dir_path; int options_left = NUM_OPTIONS; const List<String>::Element *elem = p_cmdline_args.front(); while (elem && options_left) { - if (elem->get() == mono_glue_option) { + if (elem->get() == generate_all_glue_option) { + const List<String>::Element *path_elem = elem->next(); + + if (path_elem) { + glue_dir_path = path_elem->get(); + elem = elem->next(); + } else { + ERR_PRINTS(generate_all_glue_option + ": No output directory specified (expected path to {GODOT_ROOT}/modules/mono/glue)"); + } + + --options_left; + } else if (elem->get() == generate_cs_glue_option) { const List<String>::Element *path_elem = elem->next(); if (path_elem) { - mono_glue_path = path_elem->get(); + cs_dir_path = path_elem->get(); elem = elem->next(); } else { - ERR_PRINTS(mono_glue_option + ": No output directory specified"); + ERR_PRINTS(generate_cs_glue_option + ": No output directory specified"); } --options_left; - } else if (elem->get() == cs_api_option) { + } else if (elem->get() == generate_cpp_glue_option) { const List<String>::Element *path_elem = elem->next(); if (path_elem) { - cs_api_path = path_elem->get(); + cpp_dir_path = path_elem->get(); elem = elem->next(); } else { - ERR_PRINTS(cs_api_option + ": No output directory specified"); + ERR_PRINTS(generate_cpp_glue_option + ": No output directory specified"); } --options_left; @@ -3056,18 +3055,26 @@ void BindingsGenerator::handle_cmdline_args(const List<String> &p_cmdline_args) elem = elem->next(); } - if (mono_glue_path.length() || cs_api_path.length()) { + if (glue_dir_path.length() || cs_dir_path.length() || cpp_dir_path.length()) { BindingsGenerator bindings_generator; bindings_generator.set_log_print_enabled(true); - if (mono_glue_path.length()) { - if (bindings_generator.generate_glue(mono_glue_path) != OK) - ERR_PRINTS(mono_glue_option + ": Failed to generate mono glue"); + if (glue_dir_path.length()) { + if (bindings_generator.generate_glue(glue_dir_path) != OK) + ERR_PRINTS(generate_all_glue_option + ": Failed to generate the C++ glue"); + + if (bindings_generator.generate_cs_api(glue_dir_path.plus_file("Managed/Generated")) != OK) + ERR_PRINTS(generate_all_glue_option + ": Failed to generate the C# API"); + } + + if (cs_dir_path.length()) { + if (bindings_generator.generate_cs_api(cs_dir_path) != OK) + ERR_PRINTS(generate_cs_glue_option + ": Failed to generate the C# API"); } - if (cs_api_path.length()) { - if (bindings_generator.generate_cs_api(cs_api_path) != OK) - ERR_PRINTS(cs_api_option + ": Failed to generate the C# API"); + if (cpp_dir_path.length()) { + if (bindings_generator.generate_glue(cpp_dir_path) != OK) + ERR_PRINTS(generate_cpp_glue_option + ": Failed to generate the C++ glue"); } // Exit once done diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h index ffc73a7e3e..8be51a6c55 100644 --- a/modules/mono/editor/bindings_generator.h +++ b/modules/mono/editor/bindings_generator.h @@ -33,7 +33,6 @@ #include "core/class_db.h" #include "core/string_builder.h" -#include "dotnet_solution.h" #include "editor/doc/doc_data.h" #include "editor/editor_help.h" @@ -614,12 +613,13 @@ class BindingsGenerator { void _initialize(); public: - Error generate_cs_core_project(const String &p_solution_dir, DotNetSolution &r_solution); - Error generate_cs_editor_project(const String &p_solution_dir, DotNetSolution &r_solution); + Error generate_cs_core_project(const String &p_proj_dir, Vector<String> &r_compile_files); + Error generate_cs_editor_project(const String &p_proj_dir, Vector<String> &r_compile_items); Error generate_cs_api(const String &p_output_dir); Error generate_glue(const String &p_output_dir); - void set_log_print_enabled(bool p_enabled) { log_print_enabled = p_enabled; } + _FORCE_INLINE_ bool is_log_print_enabled() { return log_print_enabled; } + _FORCE_INLINE_ void set_log_print_enabled(bool p_enabled) { log_print_enabled = p_enabled; } static uint32_t get_version(); diff --git a/modules/mono/editor/csharp_project.cpp b/modules/mono/editor/csharp_project.cpp index fe79286556..d88b08c646 100644 --- a/modules/mono/editor/csharp_project.cpp +++ b/modules/mono/editor/csharp_project.cpp @@ -44,66 +44,54 @@ namespace CSharpProject { -String generate_core_api_project(const String &p_dir, const Vector<String> &p_files) { - - _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) - - GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Project", "ProjectGenerator"); - - Variant dir = p_dir; - Variant compile_items = p_files; - const Variant *args[2] = { &dir, &compile_items }; +bool generate_api_solution_impl(const String &p_solution_dir, const String &p_core_proj_dir, const Vector<String> &p_core_compile_items, + const String &p_editor_proj_dir, const Vector<String> &p_editor_compile_items, + GDMonoAssembly *p_tools_project_editor_assembly) { + + GDMonoClass *klass = p_tools_project_editor_assembly->get_class("GodotTools.ProjectEditor", "ApiSolutionGenerator"); + + Variant solution_dir = p_solution_dir; + Variant core_proj_dir = p_core_proj_dir; + Variant core_compile_items = p_core_compile_items; + Variant editor_proj_dir = p_editor_proj_dir; + Variant editor_compile_items = p_editor_compile_items; + const Variant *args[5] = { &solution_dir, &core_proj_dir, &core_compile_items, &editor_proj_dir, &editor_compile_items }; MonoException *exc = NULL; - MonoObject *ret = klass->get_method("GenCoreApiProject", 2)->invoke(NULL, args, &exc); + klass->get_method("GenerateApiSolution", 5)->invoke(NULL, args, &exc); if (exc) { GDMonoUtils::debug_print_unhandled_exception(exc); - ERR_FAIL_V(String()); + ERR_FAIL_V(false); } - return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : String(); + return true; } -String generate_editor_api_project(const String &p_dir, const String &p_core_proj_path, const Vector<String> &p_files) { - - _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) - - GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Project", "ProjectGenerator"); - - Variant dir = p_dir; - Variant core_proj_path = p_core_proj_path; - Variant compile_items = p_files; - const Variant *args[3] = { &dir, &core_proj_path, &compile_items }; - MonoException *exc = NULL; - MonoObject *ret = klass->get_method("GenEditorApiProject", 3)->invoke(NULL, args, &exc); - - if (exc) { - GDMonoUtils::debug_print_unhandled_exception(exc); - ERR_FAIL_V(String()); - } - - return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : String(); -} +bool generate_api_solution(const String &p_solution_dir, const String &p_core_proj_dir, const Vector<String> &p_core_compile_items, + const String &p_editor_proj_dir, const Vector<String> &p_editor_compile_items) { -String generate_game_project(const String &p_dir, const String &p_name, const Vector<String> &p_files) { + if (GDMono::get_singleton()->get_tools_project_editor_assembly()) { + return generate_api_solution_impl(p_solution_dir, p_core_proj_dir, p_core_compile_items, + p_editor_proj_dir, p_editor_compile_items, + GDMono::get_singleton()->get_tools_project_editor_assembly()); + } else { + MonoDomain *temp_domain = GDMonoUtils::create_domain("GodotEngine.ApiSolutionGenerationDomain"); + CRASH_COND(temp_domain == NULL); + _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(temp_domain); - _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) + _GDMONO_SCOPE_DOMAIN_(temp_domain); - GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Project", "ProjectGenerator"); + GDMonoAssembly *tools_project_editor_assembly = NULL; - Variant dir = p_dir; - Variant name = p_name; - Variant compile_items = p_files; - const Variant *args[3] = { &dir, &name, &compile_items }; - MonoException *exc = NULL; - MonoObject *ret = klass->get_method("GenGameProject", 3)->invoke(NULL, args, &exc); + if (!GDMono::get_singleton()->load_assembly("GodotTools.ProjectEditor", &tools_project_editor_assembly)) { + ERR_EXPLAIN("Failed to load assembly: 'GodotTools.ProjectEditor'"); + ERR_FAIL_V(false); + } - if (exc) { - GDMonoUtils::debug_print_unhandled_exception(exc); - ERR_FAIL_V(String()); + return generate_api_solution_impl(p_solution_dir, p_core_proj_dir, p_core_compile_items, + p_editor_proj_dir, p_editor_compile_items, + tools_project_editor_assembly); } - - return ret ? GDMonoMarshal::mono_string_to_godot((MonoString *)ret) : String(); } void add_item(const String &p_project_path, const String &p_item_type, const String &p_include) { @@ -111,9 +99,9 @@ void add_item(const String &p_project_path, const String &p_item_type, const Str if (!GLOBAL_DEF("mono/project/auto_update_project", true)) return; - _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) + GDMonoAssembly *tools_project_editor_assembly = GDMono::get_singleton()->get_tools_project_editor_assembly(); - GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Project", "ProjectUtils"); + GDMonoClass *klass = tools_project_editor_assembly->get_class("GodotTools.ProjectEditor", "ProjectUtils"); Variant project_path = p_project_path; Variant item_type = p_item_type; @@ -128,126 +116,4 @@ void add_item(const String &p_project_path, const String &p_item_type, const Str } } -Error generate_scripts_metadata(const String &p_project_path, const String &p_output_path) { - - _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) - - if (FileAccess::exists(p_output_path)) { - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - Error rm_err = da->remove(p_output_path); - - ERR_EXPLAIN("Failed to remove old scripts metadata file"); - ERR_FAIL_COND_V(rm_err != OK, rm_err); - } - - GDMonoClass *project_utils = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Project", "ProjectUtils"); - - void *args[2] = { - GDMonoMarshal::mono_string_from_godot(p_project_path), - GDMonoMarshal::mono_string_from_godot("Compile") - }; - - MonoException *exc = NULL; - MonoArray *ret = (MonoArray *)project_utils->get_method("GetIncludeFiles", 2)->invoke_raw(NULL, args, &exc); - - if (exc) { - GDMonoUtils::debug_print_unhandled_exception(exc); - ERR_FAIL_V(FAILED); - } - - PoolStringArray project_files = GDMonoMarshal::mono_array_to_PoolStringArray(ret); - PoolStringArray::Read r = project_files.read(); - - Dictionary old_dict = CSharpLanguage::get_singleton()->get_scripts_metadata_or_nothing(); - Dictionary new_dict; - - for (int i = 0; i < project_files.size(); i++) { - const String &project_file = ("res://" + r[i]).simplify_path(); - - uint64_t modified_time = FileAccess::get_modified_time(project_file); - - const Variant *old_file_var = old_dict.getptr(project_file); - if (old_file_var) { - Dictionary old_file_dict = old_file_var->operator Dictionary(); - - if (old_file_dict["modified_time"].operator uint64_t() == modified_time) { - // No changes so no need to parse again - new_dict[project_file] = old_file_dict; - continue; - } - } - - ScriptClassParser scp; - Error err = scp.parse_file(project_file); - if (err != OK) { - ERR_PRINTS("Parse error: " + scp.get_error()); - ERR_EXPLAIN("Failed to determine namespace and class for script: " + project_file); - ERR_FAIL_V(err); - } - - Vector<ScriptClassParser::ClassDecl> classes = scp.get_classes(); - - bool found = false; - Dictionary class_dict; - - String search_name = project_file.get_file().get_basename(); - - for (int j = 0; j < classes.size(); j++) { - const ScriptClassParser::ClassDecl &class_decl = classes[j]; - - if (class_decl.base.size() == 0) - continue; // Does not inherit nor implement anything, so it can't be a script class - - String class_cmp; - - if (class_decl.nested) { - class_cmp = class_decl.name.get_slice(".", class_decl.name.get_slice_count(".") - 1); - } else { - class_cmp = class_decl.name; - } - - if (class_cmp != search_name) - continue; - - class_dict["namespace"] = class_decl.namespace_; - class_dict["class_name"] = class_decl.name; - class_dict["nested"] = class_decl.nested; - - found = true; - break; - } - - if (found) { - Dictionary file_dict; - file_dict["modified_time"] = modified_time; - file_dict["class"] = class_dict; - new_dict[project_file] = file_dict; - } - } - - if (new_dict.size()) { - String json = JSON::print(new_dict, "", false); - - String base_dir = p_output_path.get_base_dir(); - - if (!DirAccess::exists(base_dir)) { - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - - Error err = da->make_dir_recursive(base_dir); - ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); - } - - Error ferr; - FileAccess *f = FileAccess::open(p_output_path, FileAccess::WRITE, &ferr); - ERR_EXPLAIN("Cannot open file for writing: " + p_output_path); - ERR_FAIL_COND_V(ferr != OK, ferr); - f->store_string(json); - f->flush(); - f->close(); - memdelete(f); - } - - return OK; -} - } // namespace CSharpProject diff --git a/modules/mono/editor/csharp_project.h b/modules/mono/editor/csharp_project.h index b08c9090c7..b42762cea2 100644 --- a/modules/mono/editor/csharp_project.h +++ b/modules/mono/editor/csharp_project.h @@ -35,14 +35,11 @@ namespace CSharpProject { -String generate_core_api_project(const String &p_dir, const Vector<String> &p_files = Vector<String>()); -String generate_editor_api_project(const String &p_dir, const String &p_core_proj_path, const Vector<String> &p_files = Vector<String>()); -String generate_game_project(const String &p_dir, const String &p_name, const Vector<String> &p_files = Vector<String>()); +bool generate_api_solution(const String &p_solution_dir, const String &p_core_proj_dir, const Vector<String> &p_core_compile_items, + const String &p_editor_proj_dir, const Vector<String> &p_editor_compile_items); void add_item(const String &p_project_path, const String &p_item_type, const String &p_include); -Error generate_scripts_metadata(const String &p_project_path, const String &p_output_path); - } // namespace CSharpProject #endif // CSHARP_PROJECT_H diff --git a/modules/mono/editor/dotnet_solution.cpp b/modules/mono/editor/dotnet_solution.cpp deleted file mode 100644 index 324752cafc..0000000000 --- a/modules/mono/editor/dotnet_solution.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/*************************************************************************/ -/* dotnet_solution.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 "dotnet_solution.h" - -#include "core/os/dir_access.h" -#include "core/os/file_access.h" - -#include "../utils/path_utils.h" -#include "../utils/string_utils.h" -#include "csharp_project.h" - -#define SOLUTION_TEMPLATE \ - "Microsoft Visual Studio Solution File, Format Version 12.00\n" \ - "# Visual Studio 2012\n" \ - "%0\n" \ - "Global\n" \ - "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" \ - "%1\n" \ - "\tEndGlobalSection\n" \ - "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n" \ - "%2\n" \ - "\tEndGlobalSection\n" \ - "EndGlobal\n" - -#define PROJECT_DECLARATION "Project(\"{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}\") = \"%0\", \"%1\", \"{%2}\"\nEndProject" - -#define SOLUTION_PLATFORMS_CONFIG "\t%0|Any CPU = %0|Any CPU" - -#define PROJECT_PLATFORMS_CONFIG \ - "\t\t{%0}.%1|Any CPU.ActiveCfg = %1|Any CPU\n" \ - "\t\t{%0}.%1|Any CPU.Build.0 = %1|Any CPU" - -void DotNetSolution::add_new_project(const String &p_name, const ProjectInfo &p_project_info) { - projects[p_name] = p_project_info; -} - -bool DotNetSolution::has_project(const String &p_name) const { - return projects.find(p_name) != NULL; -} - -const DotNetSolution::ProjectInfo &DotNetSolution::get_project_info(const String &p_name) const { - return projects[p_name]; -} - -bool DotNetSolution::remove_project(const String &p_name) { - return projects.erase(p_name); -} - -Error DotNetSolution::save() { - bool dir_exists = DirAccess::exists(path); - ERR_EXPLAIN("The directory does not exist."); - ERR_FAIL_COND_V(!dir_exists, ERR_FILE_NOT_FOUND); - - String projs_decl; - String sln_platform_cfg; - String proj_platform_cfg; - - for (Map<String, ProjectInfo>::Element *E = projects.front(); E; E = E->next()) { - const String &name = E->key(); - const ProjectInfo &proj_info = E->value(); - - bool is_front = E == projects.front(); - - if (!is_front) - projs_decl += "\n"; - - projs_decl += sformat(PROJECT_DECLARATION, name, proj_info.relpath.replace("/", "\\"), proj_info.guid); - - for (int i = 0; i < proj_info.configs.size(); i++) { - const String &config = proj_info.configs[i]; - - if (i != 0 || !is_front) { - sln_platform_cfg += "\n"; - proj_platform_cfg += "\n"; - } - - sln_platform_cfg += sformat(SOLUTION_PLATFORMS_CONFIG, config); - proj_platform_cfg += sformat(PROJECT_PLATFORMS_CONFIG, proj_info.guid, config); - } - } - - String content = sformat(SOLUTION_TEMPLATE, projs_decl, sln_platform_cfg, proj_platform_cfg); - - FileAccess *file = FileAccess::open(path_join(path, name + ".sln"), FileAccess::WRITE); - ERR_FAIL_NULL_V(file, ERR_FILE_CANT_WRITE); - file->store_string(content); - file->close(); - memdelete(file); - - return OK; -} - -bool DotNetSolution::set_path(const String &p_existing_path) { - if (p_existing_path.is_abs_path()) { - path = p_existing_path; - } else { - String abspath; - if (!rel_path_to_abs(p_existing_path, abspath)) - return false; - path = abspath; - } - - return true; -} - -String DotNetSolution::get_path() { - return path; -} - -DotNetSolution::DotNetSolution(const String &p_name) { - name = p_name; -} diff --git a/modules/mono/editor/editor_internal_calls.cpp b/modules/mono/editor/editor_internal_calls.cpp new file mode 100644 index 0000000000..0014aaca70 --- /dev/null +++ b/modules/mono/editor/editor_internal_calls.cpp @@ -0,0 +1,427 @@ +/*************************************************************************/ +/* editor_internal_calls.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor_internal_calls.h" + +#include "core/os/os.h" +#include "core/version.h" +#include "editor/editor_node.h" +#include "editor/plugins/script_editor_plugin.h" +#include "editor/script_editor_debugger.h" +#include "main/main.h" + +#include "../csharp_script.h" +#include "../glue/cs_glue_version.gen.h" +#include "../godotsharp_dirs.h" +#include "../mono_gd/gd_mono_marshal.h" +#include "../utils/osx_utils.h" +#include "bindings_generator.h" +#include "godotsharp_export.h" +#include "script_class_parser.h" + +MonoString *godot_icall_GodotSharpDirs_ResDataDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_res_data_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_ResMetadataDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_res_metadata_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_ResAssembliesBaseDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_res_assemblies_base_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_ResAssembliesDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_res_assemblies_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_ResConfigDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_res_config_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_ResTempDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_res_temp_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_ResTempAssembliesBaseDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_res_temp_assemblies_base_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_ResTempAssembliesDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_res_temp_assemblies_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_MonoUserDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_mono_user_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_MonoLogsDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_mono_logs_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_MonoSolutionsDir() { +#ifdef TOOLS_ENABLED + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_mono_solutions_dir()); +#else + return NULL; +#endif +} + +MonoString *godot_icall_GodotSharpDirs_BuildLogsDirs() { +#ifdef TOOLS_ENABLED + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_build_logs_dir()); +#else + return NULL; +#endif +} + +MonoString *godot_icall_GodotSharpDirs_ProjectSlnPath() { +#ifdef TOOLS_ENABLED + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_project_sln_path()); +#else + return NULL; +#endif +} + +MonoString *godot_icall_GodotSharpDirs_ProjectCsProjPath() { +#ifdef TOOLS_ENABLED + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_project_csproj_path()); +#else + return NULL; +#endif +} + +MonoString *godot_icall_GodotSharpDirs_DataEditorToolsDir() { +#ifdef TOOLS_ENABLED + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_data_editor_tools_dir()); +#else + return NULL; +#endif +} + +MonoString *godot_icall_GodotSharpDirs_DataEditorPrebuiltApiDir() { +#ifdef TOOLS_ENABLED + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_data_editor_prebuilt_api_dir()); +#else + return NULL; +#endif +} + +MonoString *godot_icall_GodotSharpDirs_DataMonoEtcDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_data_mono_etc_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_DataMonoLibDir() { + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_data_mono_lib_dir()); +} + +MonoString *godot_icall_GodotSharpDirs_DataMonoBinDir() { +#ifdef WINDOWS_ENABLED + return GDMonoMarshal::mono_string_from_godot(GodotSharpDirs::get_data_mono_bin_dir()); +#else + return NULL; +#endif +} + +void godot_icall_EditorProgress_Create(MonoString *p_task, MonoString *p_label, int32_t p_amount, MonoBoolean p_can_cancel) { + String task = GDMonoMarshal::mono_string_to_godot(p_task); + String label = GDMonoMarshal::mono_string_to_godot(p_label); + EditorNode::progress_add_task(task, label, p_amount, (bool)p_can_cancel); +} + +void godot_icall_EditorProgress_Dispose(MonoString *p_task) { + String task = GDMonoMarshal::mono_string_to_godot(p_task); + EditorNode::progress_end_task(task); +} + +MonoBoolean godot_icall_EditorProgress_Step(MonoString *p_task, MonoString *p_state, int32_t p_step, MonoBoolean p_force_refresh) { + String task = GDMonoMarshal::mono_string_to_godot(p_task); + String state = GDMonoMarshal::mono_string_to_godot(p_state); + return EditorNode::progress_task_step(task, state, p_step, (bool)p_force_refresh); +} + +BindingsGenerator *godot_icall_BindingsGenerator_Ctor() { + return memnew(BindingsGenerator); +} + +void godot_icall_BindingsGenerator_Dtor(BindingsGenerator *p_handle) { + memdelete(p_handle); +} + +MonoBoolean godot_icall_BindingsGenerator_LogPrintEnabled(BindingsGenerator *p_handle) { + return p_handle->is_log_print_enabled(); +} + +void godot_icall_BindingsGenerator_SetLogPrintEnabled(BindingsGenerator p_handle, MonoBoolean p_enabled) { + p_handle.set_log_print_enabled(p_enabled); +} + +int32_t godot_icall_BindingsGenerator_GenerateCsApi(BindingsGenerator *p_handle, MonoString *p_output_dir) { + String output_dir = GDMonoMarshal::mono_string_to_godot(p_output_dir); + return p_handle->generate_cs_api(output_dir); +} + +uint32_t godot_icall_BindingsGenerator_Version() { + return BindingsGenerator::get_version(); +} + +uint32_t godot_icall_BindingsGenerator_CsGlueVersion() { + return CS_GLUE_VERSION; +} + +int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObject *p_classes) { + String filepath = GDMonoMarshal::mono_string_to_godot(p_filepath); + + ScriptClassParser scp; + Error err = scp.parse_file(filepath); + if (err == OK) { + Array classes = GDMonoMarshal::mono_object_to_variant(p_classes); + const Vector<ScriptClassParser::ClassDecl> &class_decls = scp.get_classes(); + + for (int i = 0; i < class_decls.size(); i++) { + const ScriptClassParser::ClassDecl &classDecl = class_decls[i]; + + Dictionary classDeclDict; + classDeclDict["name"] = classDecl.name; + classDeclDict["namespace"] = classDecl.namespace_; + classDeclDict["nested"] = classDecl.nested; + classDeclDict["base_count"] = classDecl.base.size(); + classes.push_back(classDeclDict); + } + } + return err; +} + +uint32_t godot_icall_GodotSharpExport_GetExportedAssemblyDependencies(MonoString *p_project_dll_name, MonoString *p_project_dll_src_path, + MonoString *p_build_config, MonoString *p_custom_lib_dir, MonoObject *r_dependencies) { + String project_dll_name = GDMonoMarshal::mono_string_to_godot(p_project_dll_name); + String project_dll_src_path = GDMonoMarshal::mono_string_to_godot(p_project_dll_src_path); + String build_config = GDMonoMarshal::mono_string_to_godot(p_build_config); + String custom_lib_dir = GDMonoMarshal::mono_string_to_godot(p_custom_lib_dir); + Dictionary dependencies = GDMonoMarshal::mono_object_to_variant(r_dependencies); + + return GodotSharpExport::get_exported_assembly_dependencies(project_dll_name, project_dll_src_path, build_config, custom_lib_dir, dependencies); +} + +float godot_icall_Globals_EditorScale() { + return EDSCALE; +} + +MonoObject *godot_icall_Globals_GlobalDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) { + String setting = GDMonoMarshal::mono_string_to_godot(p_setting); + Variant default_value = GDMonoMarshal::mono_object_to_variant(p_default_value); + Variant result = _GLOBAL_DEF(setting, default_value, (bool)p_restart_if_changed); + return GDMonoMarshal::variant_to_mono_object(result); +} + +MonoObject *godot_icall_Globals_EditorDef(MonoString *p_setting, MonoObject *p_default_value, MonoBoolean p_restart_if_changed) { + String setting = GDMonoMarshal::mono_string_to_godot(p_setting); + Variant default_value = GDMonoMarshal::mono_object_to_variant(p_default_value); + Variant result = _EDITOR_DEF(setting, default_value, (bool)p_restart_if_changed); + return GDMonoMarshal::variant_to_mono_object(result); +} + +MonoString *godot_icall_Globals_TTR(MonoString *p_text) { + String text = GDMonoMarshal::mono_string_to_godot(p_text); + return GDMonoMarshal::mono_string_from_godot(TTR(text)); +} + +MonoString *godot_icall_Internal_UpdateApiAssembliesFromPrebuilt() { + String error_str = GDMono::get_singleton()->update_api_assemblies_from_prebuilt(); + return GDMonoMarshal::mono_string_from_godot(error_str); +} + +MonoString *godot_icall_Internal_FullTemplatesDir() { + String full_templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG); + return GDMonoMarshal::mono_string_from_godot(full_templates_dir); +} + +MonoString *godot_icall_Internal_SimplifyGodotPath(MonoString *p_path) { + String path = GDMonoMarshal::mono_string_to_godot(p_path); + return GDMonoMarshal::mono_string_from_godot(path.simplify_path()); +} + +MonoBoolean godot_icall_Internal_IsOsxAppBundleInstalled(MonoString *p_bundle_id) { +#ifdef OSX_ENABLED + String bundle_id = GDMonoMarshal::mono_string_to_godot(p_bundle_id); + return (MonoBoolean)osx_is_app_bundle_installed; +#else + (void)p_bundle_id; // UNUSED + return (MonoBoolean) false; +#endif +} + +MonoBoolean godot_icall_Internal_GodotIs32Bits() { + return sizeof(void *) == 4; +} + +MonoBoolean godot_icall_Internal_GodotIsRealTDouble() { +#ifdef REAL_T_IS_DOUBLE + return (MonoBoolean) true; +#else + return (MonoBoolean) false; +#endif +} + +void godot_icall_Internal_GodotMainIteration() { + Main::iteration(); +} + +uint64_t godot_icall_Internal_GetCoreApiHash() { + return ClassDB::get_api_hash(ClassDB::API_CORE); +} + +uint64_t godot_icall_Internal_GetEditorApiHash() { + return ClassDB::get_api_hash(ClassDB::API_EDITOR); +} + +MonoBoolean godot_icall_Internal_IsAssembliesReloadingNeeded() { +#ifdef GD_MONO_HOT_RELOAD + return (MonoBoolean)CSharpLanguage::get_singleton()->is_assembly_reloading_needed(); +#else + return (MonoBoolean) false; +#endif +} + +void godot_icall_Internal_ReloadAssemblies(MonoBoolean p_soft_reload) { +#ifdef GD_MONO_HOT_RELOAD + _GodotSharp::get_singleton()->call_deferred("_reload_assemblies", (bool)p_soft_reload); +#endif +} + +void godot_icall_Internal_ScriptEditorDebuggerReloadScripts() { + ScriptEditor::get_singleton()->get_debugger()->reload_scripts(); +} + +MonoBoolean godot_icall_Internal_ScriptEditorEdit(MonoObject *p_resource, int32_t p_line, int32_t p_col, MonoBoolean p_grab_focus) { + Ref<Resource> resource = GDMonoMarshal::mono_object_to_variant(p_resource); + return (MonoBoolean)ScriptEditor::get_singleton()->edit(resource, p_line, p_col, (bool)p_grab_focus); +} + +void godot_icall_Internal_EditorNodeShowScriptScreen() { + EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT); +} + +MonoObject *godot_icall_Internal_GetScriptsMetadataOrNothing(MonoReflectionType *p_dict_reftype) { + Dictionary maybe_metadata = CSharpLanguage::get_singleton()->get_scripts_metadata_or_nothing(); + + MonoType *dict_type = mono_reflection_type_get_type(p_dict_reftype); + + uint32_t type_encoding = mono_type_get_type(dict_type); + MonoClass *type_class_raw = mono_class_from_mono_type(dict_type); + GDMonoClass *type_class = GDMono::get_singleton()->get_class(type_class_raw); + + return GDMonoMarshal::variant_to_mono_object(maybe_metadata, ManagedType(type_encoding, type_class)); +} + +MonoString *godot_icall_Internal_MonoWindowsInstallRoot() { +#ifdef WINDOWS_ENABLED + String install_root_dir = GDMono::get_singleton()->get_mono_reg_info().install_root_dir; + return GDMonoMarshal::mono_string_from_godot(install_root_dir); +#else + return NULL; +#endif +} + +MonoString *godot_icall_Utils_OS_GetPlatformName() { + String os_name = OS::get_singleton()->get_name(); + return GDMonoMarshal::mono_string_from_godot(os_name); +} + +void register_editor_internal_calls() { + + // GodotSharpDirs + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResDataDir", (void *)godot_icall_GodotSharpDirs_ResDataDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResMetadataDir", (void *)godot_icall_GodotSharpDirs_ResMetadataDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResAssembliesBaseDir", (void *)godot_icall_GodotSharpDirs_ResAssembliesBaseDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResAssembliesDir", (void *)godot_icall_GodotSharpDirs_ResAssembliesDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResConfigDir", (void *)godot_icall_GodotSharpDirs_ResConfigDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempDir", (void *)godot_icall_GodotSharpDirs_ResTempDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempAssembliesBaseDir", (void *)godot_icall_GodotSharpDirs_ResTempAssembliesBaseDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempAssembliesDir", (void *)godot_icall_GodotSharpDirs_ResTempAssembliesDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoUserDir", (void *)godot_icall_GodotSharpDirs_MonoUserDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoLogsDir", (void *)godot_icall_GodotSharpDirs_MonoLogsDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoSolutionsDir", (void *)godot_icall_GodotSharpDirs_MonoSolutionsDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_BuildLogsDirs", (void *)godot_icall_GodotSharpDirs_BuildLogsDirs); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ProjectSlnPath", (void *)godot_icall_GodotSharpDirs_ProjectSlnPath); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ProjectCsProjPath", (void *)godot_icall_GodotSharpDirs_ProjectCsProjPath); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataEditorToolsDir", (void *)godot_icall_GodotSharpDirs_DataEditorToolsDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataEditorPrebuiltApiDir", (void *)godot_icall_GodotSharpDirs_DataEditorPrebuiltApiDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoEtcDir", (void *)godot_icall_GodotSharpDirs_DataMonoEtcDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoLibDir", (void *)godot_icall_GodotSharpDirs_DataMonoLibDir); + mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoBinDir", (void *)godot_icall_GodotSharpDirs_DataMonoBinDir); + + // EditorProgress + mono_add_internal_call("GodotTools.Internals.EditorProgress::internal_Create", (void *)godot_icall_EditorProgress_Create); + mono_add_internal_call("GodotTools.Internals.EditorProgress::internal_Dispose", (void *)godot_icall_EditorProgress_Dispose); + mono_add_internal_call("GodotTools.Internals.EditorProgress::internal_Step", (void *)godot_icall_EditorProgress_Step); + + // BiningsGenerator + mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_Ctor", (void *)godot_icall_BindingsGenerator_Ctor); + mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_Dtor", (void *)godot_icall_BindingsGenerator_Dtor); + mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_LogPrintEnabled", (void *)godot_icall_BindingsGenerator_LogPrintEnabled); + mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_SetLogPrintEnabled", (void *)godot_icall_BindingsGenerator_SetLogPrintEnabled); + mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_GenerateCsApi", (void *)godot_icall_BindingsGenerator_GenerateCsApi); + mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_Version", (void *)godot_icall_BindingsGenerator_Version); + mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_CsGlueVersion", (void *)godot_icall_BindingsGenerator_CsGlueVersion); + + // ScriptClassParser + mono_add_internal_call("GodotTools.Internals.ScriptClassParser::internal_ParseFile", (void *)godot_icall_ScriptClassParser_ParseFile); + + // GodotSharpExport + mono_add_internal_call("GodotTools.GodotSharpExport::internal_GetExportedAssemblyDependencies", (void *)godot_icall_GodotSharpExport_GetExportedAssemblyDependencies); + + // Internals + mono_add_internal_call("GodotTools.Internals.Internal::internal_UpdateApiAssembliesFromPrebuilt", (void *)godot_icall_Internal_UpdateApiAssembliesFromPrebuilt); + mono_add_internal_call("GodotTools.Internals.Internal::internal_FullTemplatesDir", (void *)godot_icall_Internal_FullTemplatesDir); + mono_add_internal_call("GodotTools.Internals.Internal::internal_SimplifyGodotPath", (void *)godot_icall_Internal_SimplifyGodotPath); + mono_add_internal_call("GodotTools.Internals.Internal::internal_IsOsxAppBundleInstalled", (void *)godot_icall_Internal_IsOsxAppBundleInstalled); + mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotIs32Bits", (void *)godot_icall_Internal_GodotIs32Bits); + mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotIsRealTDouble", (void *)godot_icall_Internal_GodotIsRealTDouble); + mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotMainIteration", (void *)godot_icall_Internal_GodotMainIteration); + mono_add_internal_call("GodotTools.Internals.Internal::internal_GetCoreApiHash", (void *)godot_icall_Internal_GetCoreApiHash); + mono_add_internal_call("GodotTools.Internals.Internal::internal_GetEditorApiHash", (void *)godot_icall_Internal_GetEditorApiHash); + mono_add_internal_call("GodotTools.Internals.Internal::internal_IsAssembliesReloadingNeeded", (void *)godot_icall_Internal_IsAssembliesReloadingNeeded); + mono_add_internal_call("GodotTools.Internals.Internal::internal_ReloadAssemblies", (void *)godot_icall_Internal_ReloadAssemblies); + mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorDebuggerReloadScripts", (void *)godot_icall_Internal_ScriptEditorDebuggerReloadScripts); + mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorEdit", (void *)godot_icall_Internal_ScriptEditorEdit); + mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorNodeShowScriptScreen", (void *)godot_icall_Internal_EditorNodeShowScriptScreen); + mono_add_internal_call("GodotTools.Internals.Internal::internal_GetScriptsMetadataOrNothing", (void *)godot_icall_Internal_GetScriptsMetadataOrNothing); + mono_add_internal_call("GodotTools.Internals.Internal::internal_MonoWindowsInstallRoot", (void *)godot_icall_Internal_MonoWindowsInstallRoot); + + // Globals + mono_add_internal_call("GodotTools.Internals.Globals::internal_EditorScale", (void *)godot_icall_Globals_EditorScale); + mono_add_internal_call("GodotTools.Internals.Globals::internal_GlobalDef", (void *)godot_icall_Globals_GlobalDef); + mono_add_internal_call("GodotTools.Internals.Globals::internal_EditorDef", (void *)godot_icall_Globals_EditorDef); + mono_add_internal_call("GodotTools.Internals.Globals::internal_TTR", (void *)godot_icall_Globals_TTR); + + // Utils.OS + mono_add_internal_call("GodotTools.Utils.OS::GetPlatformName", (void *)godot_icall_Utils_OS_GetPlatformName); +} diff --git a/modules/mono/editor/monodevelop_instance.h b/modules/mono/editor/editor_internal_calls.h index 3b3af9607b..1682da66e5 100644 --- a/modules/mono/editor/monodevelop_instance.h +++ b/modules/mono/editor/editor_internal_calls.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* monodevelop_instance.h */ +/* editor_internal_calls.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,29 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef MONODEVELOP_INSTANCE_H -#define MONODEVELOP_INSTANCE_H +#ifndef EDITOR_INTERNAL_CALL_H +#define EDITOR_INTERNAL_CALL_H -#include "core/reference.h" +void register_editor_internal_calls(); -#include "../mono_gc_handle.h" -#include "../mono_gd/gd_mono_method.h" - -class MonoDevelopInstance { - - Ref<MonoGCHandle> gc_handle; - GDMonoMethod *execute_method; - -public: - enum EditorId { - MONODEVELOP = 0, - VISUALSTUDIO_FOR_MAC = 1 - }; - - void execute(const Vector<String> &p_files); - void execute(const String &p_file); - - MonoDevelopInstance(const String &p_solution, EditorId p_editor_id); -}; - -#endif // MONODEVELOP_INSTANCE_H +#endif // EDITOR_INTERNAL_CALL_H diff --git a/modules/mono/editor/godotsharp_builds.cpp b/modules/mono/editor/godotsharp_builds.cpp deleted file mode 100644 index a962d6df27..0000000000 --- a/modules/mono/editor/godotsharp_builds.cpp +++ /dev/null @@ -1,632 +0,0 @@ -/*************************************************************************/ -/* godotsharp_builds.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 "godotsharp_builds.h" - -#include "core/os/os.h" -#include "core/vector.h" -#include "main/main.h" - -#include "../glue/cs_glue_version.gen.h" -#include "../godotsharp_dirs.h" -#include "../mono_gd/gd_mono_class.h" -#include "../mono_gd/gd_mono_marshal.h" -#include "../utils/path_utils.h" -#include "bindings_generator.h" -#include "csharp_project.h" -#include "godotsharp_editor.h" - -#define PROP_NAME_MSBUILD_MONO "MSBuild (Mono)" -#define PROP_NAME_MSBUILD_VS "MSBuild (VS Build Tools)" -#define PROP_NAME_XBUILD "xbuild (Deprecated)" - -void godot_icall_BuildInstance_ExitCallback(MonoString *p_solution, MonoString *p_config, int p_exit_code) { - - String solution = GDMonoMarshal::mono_string_to_godot(p_solution); - String config = GDMonoMarshal::mono_string_to_godot(p_config); - GodotSharpBuilds::get_singleton()->build_exit_callback(MonoBuildInfo(solution, config), p_exit_code); -} - -static Vector<const char *> _get_msbuild_hint_dirs() { - Vector<const char *> ret; -#ifdef OSX_ENABLED - ret.push_back("/Library/Frameworks/Mono.framework/Versions/Current/bin/"); - ret.push_back("/usr/local/var/homebrew/linked/mono/bin/"); -#endif - ret.push_back("/opt/novell/mono/bin/"); - return ret; -} - -#ifdef UNIX_ENABLED -String _find_build_engine_on_unix(const String &p_name) { - String ret = path_which(p_name); - - if (ret.length()) - return ret; - - String ret_fallback = path_which(p_name + ".exe"); - if (ret_fallback.length()) - return ret_fallback; - - static Vector<const char *> locations = _get_msbuild_hint_dirs(); - - for (int i = 0; i < locations.size(); i++) { - String hint_path = locations[i] + p_name; - - if (FileAccess::exists(hint_path)) { - return hint_path; - } - } - - return String(); -} -#endif - -MonoString *godot_icall_BuildInstance_get_MSBuildPath() { - - GodotSharpBuilds::BuildTool build_tool = GodotSharpBuilds::BuildTool(int(EditorSettings::get_singleton()->get("mono/builds/build_tool"))); - -#if defined(WINDOWS_ENABLED) - switch (build_tool) { - case GodotSharpBuilds::MSBUILD_VS: { - static String msbuild_tools_path; - - if (msbuild_tools_path.empty() || !FileAccess::exists(msbuild_tools_path)) { - // Try to search it again if it wasn't found last time or if it was removed from its location - msbuild_tools_path = MonoRegUtils::find_msbuild_tools_path(); - - if (msbuild_tools_path.empty()) { - ERR_PRINTS("Cannot find executable for '" PROP_NAME_MSBUILD_VS "'. Tried with path: " + msbuild_tools_path); - return NULL; - } - } - - if (!msbuild_tools_path.ends_with("\\")) - msbuild_tools_path += "\\"; - - return GDMonoMarshal::mono_string_from_godot(msbuild_tools_path + "MSBuild.exe"); - } break; - case GodotSharpBuilds::MSBUILD_MONO: { - String msbuild_path = GDMono::get_singleton()->get_mono_reg_info().bin_dir.plus_file("msbuild.bat"); - - if (!FileAccess::exists(msbuild_path)) { - ERR_PRINTS("Cannot find executable for '" PROP_NAME_MSBUILD_MONO "'. Tried with path: " + msbuild_path); - return NULL; - } - - return GDMonoMarshal::mono_string_from_godot(msbuild_path); - } break; - case GodotSharpBuilds::XBUILD: { - String xbuild_path = GDMono::get_singleton()->get_mono_reg_info().bin_dir.plus_file("xbuild.bat"); - - if (!FileAccess::exists(xbuild_path)) { - ERR_PRINTS("Cannot find executable for '" PROP_NAME_XBUILD "'. Tried with path: " + xbuild_path); - return NULL; - } - - return GDMonoMarshal::mono_string_from_godot(xbuild_path); - } break; - default: - ERR_EXPLAIN("You don't deserve to live"); - CRASH_NOW(); - } -#elif defined(UNIX_ENABLED) - static String msbuild_path; - static String xbuild_path; - - if (build_tool == GodotSharpBuilds::XBUILD) { - if (xbuild_path.empty() || !FileAccess::exists(xbuild_path)) { - // Try to search it again if it wasn't found last time or if it was removed from its location - xbuild_path = _find_build_engine_on_unix("msbuild"); - } - - if (xbuild_path.empty()) { - ERR_PRINT("Cannot find binary for '" PROP_NAME_XBUILD "'"); - return NULL; - } - } else { - if (msbuild_path.empty() || !FileAccess::exists(msbuild_path)) { - // Try to search it again if it wasn't found last time or if it was removed from its location - msbuild_path = _find_build_engine_on_unix("msbuild"); - } - - if (msbuild_path.empty()) { - ERR_PRINT("Cannot find binary for '" PROP_NAME_MSBUILD_MONO "'"); - return NULL; - } - } - - return GDMonoMarshal::mono_string_from_godot(build_tool != GodotSharpBuilds::XBUILD ? msbuild_path : xbuild_path); -#else - (void)build_tool; // UNUSED - - ERR_EXPLAIN("Not implemented on this platform"); - ERR_FAIL_V(NULL); -#endif -} - -MonoString *godot_icall_BuildInstance_get_MonoWindowsBinDir() { - -#if defined(WINDOWS_ENABLED) - const MonoRegInfo &mono_reg_info = GDMono::get_singleton()->get_mono_reg_info(); - if (mono_reg_info.bin_dir.length()) { - return GDMonoMarshal::mono_string_from_godot(mono_reg_info.bin_dir); - } - - ERR_EXPLAIN("Cannot find Mono's binaries directory in the registry"); - ERR_FAIL_V(NULL); -#else - return NULL; -#endif -} - -MonoBoolean godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows() { - -#if defined(WINDOWS_ENABLED) - return GodotSharpBuilds::BuildTool(int(EditorSettings::get_singleton()->get("mono/builds/build_tool"))) == GodotSharpBuilds::MSBUILD_MONO; -#else - return false; -#endif -} - -MonoBoolean godot_icall_BuildInstance_get_PrintBuildOutput() { - - return (bool)EDITOR_GET("mono/builds/print_build_output"); -} - -void GodotSharpBuilds::register_internal_calls() { - - static bool registered = false; - ERR_FAIL_COND(registered); - registered = true; - - mono_add_internal_call("GodotSharpTools.Build.BuildSystem::godot_icall_BuildInstance_ExitCallback", (void *)godot_icall_BuildInstance_ExitCallback); - mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_MSBuildPath", (void *)godot_icall_BuildInstance_get_MSBuildPath); - mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_MonoWindowsBinDir", (void *)godot_icall_BuildInstance_get_MonoWindowsBinDir); - mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows", (void *)godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows); - mono_add_internal_call("GodotSharpTools.Build.BuildInstance::godot_icall_BuildInstance_get_PrintBuildOutput", (void *)godot_icall_BuildInstance_get_PrintBuildOutput); -} - -void GodotSharpBuilds::show_build_error_dialog(const String &p_message) { - - GodotSharpEditor::get_singleton()->show_error_dialog(p_message, "Build error"); - MonoBottomPanel::get_singleton()->show_build_tab(); -} - -bool GodotSharpBuilds::build_api_sln(const String &p_api_sln_dir, const String &p_config) { - - String api_sln_file = p_api_sln_dir.plus_file(API_SOLUTION_NAME ".sln"); - - String core_api_assembly_dir = p_api_sln_dir.plus_file(CORE_API_ASSEMBLY_NAME).plus_file("bin").plus_file(p_config); - String core_api_assembly_file = core_api_assembly_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); - - String editor_api_assembly_dir = p_api_sln_dir.plus_file(EDITOR_API_ASSEMBLY_NAME).plus_file("bin").plus_file(p_config); - String editor_api_assembly_file = editor_api_assembly_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); - - if (!FileAccess::exists(core_api_assembly_file) || !FileAccess::exists(editor_api_assembly_file)) { - MonoBuildInfo api_build_info(api_sln_file, p_config); - // TODO Replace this global NoWarn with '#pragma warning' directives on generated files, - // once we start to actively document manually maintained C# classes - api_build_info.custom_props.push_back("NoWarn=1591"); // Ignore missing documentation warnings - - if (!GodotSharpBuilds::get_singleton()->build(api_build_info)) { - show_build_error_dialog("Failed to build " API_SOLUTION_NAME " solution."); - return false; - } - } - - return true; -} - -bool GodotSharpBuilds::copy_api_assembly(const String &p_src_dir, const String &p_dst_dir, const String &p_assembly_name, APIAssembly::Type p_api_type) { - - // Create destination directory if needed - if (!DirAccess::exists(p_dst_dir)) { - DirAccess *da = DirAccess::create_for_path(p_dst_dir); - Error err = da->make_dir_recursive(p_dst_dir); - memdelete(da); - - if (err != OK) { - show_build_error_dialog("Failed to create destination directory for the API assemblies. Error: " + itos(err)); - return false; - } - } - - String assembly_file = p_assembly_name + ".dll"; - String assembly_src = p_src_dir.plus_file(assembly_file); - String assembly_dst = p_dst_dir.plus_file(assembly_file); - - if (!FileAccess::exists(assembly_dst) || - FileAccess::get_modified_time(assembly_src) > FileAccess::get_modified_time(assembly_dst) || - GDMono::get_singleton()->metadata_is_api_assembly_invalidated(p_api_type)) { - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - - String xml_file = p_assembly_name + ".xml"; - if (da->copy(p_src_dir.plus_file(xml_file), p_dst_dir.plus_file(xml_file)) != OK) - WARN_PRINTS("Failed to copy " + xml_file); - - String pdb_file = p_assembly_name + ".pdb"; - if (da->copy(p_src_dir.plus_file(pdb_file), p_dst_dir.plus_file(pdb_file)) != OK) - WARN_PRINTS("Failed to copy " + pdb_file); - - Error err = da->copy(assembly_src, assembly_dst); - - if (err != OK) { - show_build_error_dialog("Failed to copy " + assembly_file); - return false; - } - - GDMono::get_singleton()->metadata_set_api_assembly_invalidated(p_api_type, false); - } - - return true; -} - -String GodotSharpBuilds::_api_folder_name(APIAssembly::Type p_api_type) { - - uint64_t api_hash = p_api_type == APIAssembly::API_CORE ? - GDMono::get_singleton()->get_api_core_hash() : - GDMono::get_singleton()->get_api_editor_hash(); - return String::num_uint64(api_hash) + - "_" + String::num_uint64(BindingsGenerator::get_version()) + - "_" + String::num_uint64(CS_GLUE_VERSION); -} - -bool GodotSharpBuilds::make_api_assembly(APIAssembly::Type p_api_type) { - - String api_name = p_api_type == APIAssembly::API_CORE ? CORE_API_ASSEMBLY_NAME : EDITOR_API_ASSEMBLY_NAME; - - String editor_prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir(); - String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir(); - - if (FileAccess::exists(editor_prebuilt_api_dir.plus_file(api_name + ".dll"))) { - EditorProgress pr("mono_copy_prebuilt_api_assembly", "Copying prebuilt " + api_name + " assembly...", 1); - pr.step("Copying " + api_name + " assembly", 0); - return GodotSharpBuilds::copy_api_assembly(editor_prebuilt_api_dir, res_assemblies_dir, api_name, p_api_type); - } - - String api_build_config = "Release"; - - EditorProgress pr("mono_build_release_" API_SOLUTION_NAME, "Building " API_SOLUTION_NAME " solution...", 3); - - pr.step("Generating " API_SOLUTION_NAME " solution", 0); - - String api_sln_dir = GodotSharpDirs::get_mono_solutions_dir() - .plus_file(_api_folder_name(APIAssembly::API_CORE)); - - String api_sln_file = api_sln_dir.plus_file(API_SOLUTION_NAME ".sln"); - - if (!DirAccess::exists(api_sln_dir) || !FileAccess::exists(api_sln_file)) { - BindingsGenerator bindings_generator; - - if (!OS::get_singleton()->is_stdout_verbose()) { - bindings_generator.set_log_print_enabled(false); - } - - Error err = bindings_generator.generate_cs_api(api_sln_dir); - if (err != OK) { - show_build_error_dialog("Failed to generate " API_SOLUTION_NAME " solution. Error: " + itos(err)); - return false; - } - } - - pr.step("Building " API_SOLUTION_NAME " solution", 1); - - if (!GodotSharpBuilds::build_api_sln(api_sln_dir, api_build_config)) - return false; - - pr.step("Copying " + api_name + " assembly", 2); - - // Copy the built assembly to the assemblies directory - String api_assembly_dir = api_sln_dir.plus_file(api_name).plus_file("bin").plus_file(api_build_config); - if (!GodotSharpBuilds::copy_api_assembly(api_assembly_dir, res_assemblies_dir, api_name, p_api_type)) - return false; - - return true; -} - -bool GodotSharpBuilds::build_project_blocking(const String &p_config, const Vector<String> &p_godot_defines) { - - if (!FileAccess::exists(GodotSharpDirs::get_project_sln_path())) - return true; // No solution to build - - if (!GodotSharpBuilds::make_api_assembly(APIAssembly::API_CORE)) - return false; - - if (!GodotSharpBuilds::make_api_assembly(APIAssembly::API_EDITOR)) - return false; - - EditorProgress pr("mono_project_debug_build", "Building project solution...", 1); - pr.step("Building project solution", 0); - - MonoBuildInfo build_info(GodotSharpDirs::get_project_sln_path(), p_config); - - // Add Godot defines -#ifdef WINDOWS_ENABLED - String constants = "GodotDefineConstants=\""; -#else - String constants = "GodotDefineConstants=\\\""; -#endif - - for (int i = 0; i < p_godot_defines.size(); i++) { - constants += "GODOT_" + p_godot_defines[i].to_upper().replace("-", "_").replace(" ", "_").replace(";", "_") + ";"; - } - -#ifdef REAL_T_IS_DOUBLE - constants += "GODOT_REAL_T_IS_DOUBLE;"; -#endif - -#ifdef WINDOWS_ENABLED - constants += "\""; -#else - constants += "\\\""; -#endif - build_info.custom_props.push_back(constants); - - if (!GodotSharpBuilds::get_singleton()->build(build_info)) { - GodotSharpBuilds::show_build_error_dialog("Failed to build project solution"); - return false; - } - - return true; -} - -bool GodotSharpBuilds::editor_build_callback() { - - if (!FileAccess::exists(GodotSharpDirs::get_project_sln_path())) - return true; // No solution to build - - String scripts_metadata_path_editor = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata.editor"); - String scripts_metadata_path_player = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata.editor_player"); - - Error metadata_err = CSharpProject::generate_scripts_metadata(GodotSharpDirs::get_project_csproj_path(), scripts_metadata_path_editor); - ERR_FAIL_COND_V(metadata_err != OK, false); - - if (FileAccess::exists(scripts_metadata_path_editor)) { - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - Error copy_err = da->copy(scripts_metadata_path_editor, scripts_metadata_path_player); - - ERR_EXPLAIN("Failed to copy scripts metadata file"); - ERR_FAIL_COND_V(copy_err != OK, false); - } - - Vector<String> godot_defines; - godot_defines.push_back(OS::get_singleton()->get_name()); - godot_defines.push_back(sizeof(void *) == 4 ? "32" : "64"); - return build_project_blocking("Tools", godot_defines); -} - -GodotSharpBuilds *GodotSharpBuilds::singleton = NULL; - -void GodotSharpBuilds::build_exit_callback(const MonoBuildInfo &p_build_info, int p_exit_code) { - - BuildProcess *match = builds.getptr(p_build_info); - ERR_FAIL_NULL(match); - - BuildProcess &bp = *match; - bp.on_exit(p_exit_code); -} - -void GodotSharpBuilds::restart_build(MonoBuildTab *p_build_tab) { -} - -void GodotSharpBuilds::stop_build(MonoBuildTab *p_build_tab) { -} - -bool GodotSharpBuilds::build(const MonoBuildInfo &p_build_info) { - - BuildProcess *match = builds.getptr(p_build_info); - - if (match) { - BuildProcess &bp = *match; - bp.start(true); - return bp.exit_code == 0; - } else { - BuildProcess bp = BuildProcess(p_build_info); - bp.start(true); - builds.set(p_build_info, bp); - return bp.exit_code == 0; - } -} - -bool GodotSharpBuilds::build_async(const MonoBuildInfo &p_build_info, GodotSharpBuild_ExitCallback p_callback) { - - BuildProcess *match = builds.getptr(p_build_info); - - if (match) { - BuildProcess &bp = *match; - bp.start(); - return !bp.exited; // failed to start - } else { - BuildProcess bp = BuildProcess(p_build_info, p_callback); - bp.start(); - builds.set(p_build_info, bp); - return !bp.exited; // failed to start - } -} - -GodotSharpBuilds::GodotSharpBuilds() { - - singleton = this; - - EditorNode::get_singleton()->add_build_callback(&GodotSharpBuilds::editor_build_callback); - - // Build tool settings - EditorSettings *ed_settings = EditorSettings::get_singleton(); - -#ifdef WINDOWS_ENABLED - EDITOR_DEF("mono/builds/build_tool", MSBUILD_VS); -#else - EDITOR_DEF("mono/builds/build_tool", MSBUILD_MONO); -#endif - - ed_settings->add_property_hint(PropertyInfo(Variant::INT, "mono/builds/build_tool", PROPERTY_HINT_ENUM, - PROP_NAME_MSBUILD_MONO -#ifdef WINDOWS_ENABLED - "," PROP_NAME_MSBUILD_VS -#endif - "," PROP_NAME_XBUILD)); - - EDITOR_DEF("mono/builds/print_build_output", false); -} - -GodotSharpBuilds::~GodotSharpBuilds() { - - singleton = NULL; -} - -void GodotSharpBuilds::BuildProcess::on_exit(int p_exit_code) { - - exited = true; - exit_code = p_exit_code; - build_tab->on_build_exit(p_exit_code == 0 ? MonoBuildTab::RESULT_SUCCESS : MonoBuildTab::RESULT_ERROR); - build_instance.unref(); - - if (exit_callback) - exit_callback(exit_code); -} - -void GodotSharpBuilds::BuildProcess::start(bool p_blocking) { - - _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) - - exit_code = -1; - - String log_dirpath = build_info.get_log_dirpath(); - - if (build_tab) { - build_tab->on_build_start(); - } else { - build_tab = memnew(MonoBuildTab(build_info, log_dirpath)); - MonoBottomPanel::get_singleton()->add_build_tab(build_tab); - } - - if (p_blocking) { - // Required in order to update the build tasks list - Main::iteration(); - } - - if (!exited) { - exited = true; - String message = "Tried to start build process, but it is already running"; - build_tab->on_build_exec_failed(message); - ERR_EXPLAIN(message); - ERR_FAIL(); - } - - exited = false; - - // Remove old issues file - - String issues_file = get_msbuild_issues_filename(); - DirAccessRef d = DirAccess::create_for_path(log_dirpath); - if (d->file_exists(issues_file)) { - Error err = d->remove(issues_file); - if (err != OK) { - exited = true; - String file_path = ProjectSettings::get_singleton()->localize_path(log_dirpath).plus_file(issues_file); - String message = "Cannot remove issues file: " + file_path; - build_tab->on_build_exec_failed(message); - ERR_EXPLAIN(message); - ERR_FAIL(); - } - } - - GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Build", "BuildInstance"); - - MonoObject *mono_object = mono_object_new(mono_domain_get(), klass->get_mono_ptr()); - - // Construct - - Variant solution = build_info.solution; - Variant config = build_info.configuration; - - const Variant *ctor_args[2] = { &solution, &config }; - - MonoException *exc = NULL; - GDMonoMethod *ctor = klass->get_method(".ctor", 2); - ctor->invoke(mono_object, ctor_args, &exc); - - if (exc) { - exited = true; - GDMonoUtils::debug_unhandled_exception(exc); - String message = "The build constructor threw an exception.\n" + GDMonoUtils::get_exception_name_and_message(exc); - build_tab->on_build_exec_failed(message); - ERR_EXPLAIN(message); - ERR_FAIL(); - } - - // Call Build - - String logger_assembly_path = GDMono::get_singleton()->get_editor_tools_assembly()->get_path(); - Variant logger_assembly = ProjectSettings::get_singleton()->globalize_path(logger_assembly_path); - Variant logger_output_dir = log_dirpath; - Variant custom_props = build_info.custom_props; - - const Variant *args[3] = { &logger_assembly, &logger_output_dir, &custom_props }; - - exc = NULL; - GDMonoMethod *build_method = klass->get_method(p_blocking ? "Build" : "BuildAsync", 3); - build_method->invoke(mono_object, args, &exc); - - if (exc) { - exited = true; - GDMonoUtils::debug_unhandled_exception(exc); - String message = "The build method threw an exception.\n" + GDMonoUtils::get_exception_name_and_message(exc); - build_tab->on_build_exec_failed(message); - ERR_EXPLAIN(message); - ERR_FAIL(); - } - - // Build returned - - if (p_blocking) { - exited = true; - exit_code = klass->get_field("exitCode")->get_int_value(mono_object); - - if (exit_code != 0) { - String log_filepath = build_info.get_log_dirpath().plus_file(get_msbuild_log_filename()); - print_verbose("MSBuild exited with code: " + itos(exit_code) + ". Log file: " + log_filepath); - } - - build_tab->on_build_exit(exit_code == 0 ? MonoBuildTab::RESULT_SUCCESS : MonoBuildTab::RESULT_ERROR); - } else { - build_instance = MonoGCHandle::create_strong(mono_object); - exited = false; - } -} - -GodotSharpBuilds::BuildProcess::BuildProcess(const MonoBuildInfo &p_build_info, GodotSharpBuild_ExitCallback p_callback) : - build_info(p_build_info), - build_tab(NULL), - exit_callback(p_callback), - exited(true), - exit_code(-1) { -} diff --git a/modules/mono/editor/godotsharp_builds.h b/modules/mono/editor/godotsharp_builds.h deleted file mode 100644 index 2e9050e12e..0000000000 --- a/modules/mono/editor/godotsharp_builds.h +++ /dev/null @@ -1,103 +0,0 @@ -/*************************************************************************/ -/* godotsharp_builds.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 GODOTSHARP_BUILDS_H -#define GODOTSHARP_BUILDS_H - -#include "../mono_gd/gd_mono.h" -#include "mono_bottom_panel.h" -#include "mono_build_info.h" - -typedef void (*GodotSharpBuild_ExitCallback)(int); - -class GodotSharpBuilds { - -private: - struct BuildProcess { - Ref<MonoGCHandle> build_instance; - MonoBuildInfo build_info; - MonoBuildTab *build_tab; - GodotSharpBuild_ExitCallback exit_callback; - bool exited; - int exit_code; - - void on_exit(int p_exit_code); - void start(bool p_blocking = false); - - BuildProcess() {} - BuildProcess(const MonoBuildInfo &p_build_info, GodotSharpBuild_ExitCallback p_callback = NULL); - }; - - HashMap<MonoBuildInfo, BuildProcess, MonoBuildInfo::Hasher> builds; - - static String _api_folder_name(APIAssembly::Type p_api_type); - - static GodotSharpBuilds *singleton; - -public: - enum BuildTool { - MSBUILD_MONO, -#ifdef WINDOWS_ENABLED - MSBUILD_VS, -#endif - XBUILD // Deprecated - }; - - _FORCE_INLINE_ static GodotSharpBuilds *get_singleton() { return singleton; } - - static void register_internal_calls(); - - static void show_build_error_dialog(const String &p_message); - - static const char *get_msbuild_issues_filename() { return "msbuild_issues.csv"; } - static const char *get_msbuild_log_filename() { return "msbuild_log.txt"; } - - void build_exit_callback(const MonoBuildInfo &p_build_info, int p_exit_code); - - void restart_build(MonoBuildTab *p_build_tab); - void stop_build(MonoBuildTab *p_build_tab); - - bool build(const MonoBuildInfo &p_build_info); - bool build_async(const MonoBuildInfo &p_build_info, GodotSharpBuild_ExitCallback p_callback = NULL); - - static bool build_api_sln(const String &p_api_sln_dir, const String &p_config); - static bool copy_api_assembly(const String &p_src_dir, const String &p_dst_dir, const String &p_assembly_name, APIAssembly::Type p_api_type); - - static bool make_api_assembly(APIAssembly::Type p_api_type); - - static bool build_project_blocking(const String &p_config, const Vector<String> &p_godot_defines); - - static bool editor_build_callback(); - - GodotSharpBuilds(); - ~GodotSharpBuilds(); -}; - -#endif // GODOTSHARP_BUILDS_H diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp deleted file mode 100644 index 9d42528927..0000000000 --- a/modules/mono/editor/godotsharp_editor.cpp +++ /dev/null @@ -1,581 +0,0 @@ -/*************************************************************************/ -/* godotsharp_editor.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 "godotsharp_editor.h" - -#include "core/message_queue.h" -#include "core/os/os.h" -#include "core/project_settings.h" -#include "scene/gui/control.h" -#include "scene/main/node.h" - -#include "../csharp_script.h" -#include "../godotsharp_dirs.h" -#include "../mono_gd/gd_mono.h" -#include "../mono_gd/gd_mono_marshal.h" -#include "../utils/path_utils.h" -#include "bindings_generator.h" -#include "csharp_project.h" -#include "dotnet_solution.h" -#include "godotsharp_export.h" - -#ifdef OSX_ENABLED -#include "../utils/osx_utils.h" -#endif - -#ifdef WINDOWS_ENABLED -#include "../utils/mono_reg_utils.h" -#endif - -GodotSharpEditor *GodotSharpEditor::singleton = NULL; - -bool GodotSharpEditor::_create_project_solution() { - - EditorProgress pr("create_csharp_solution", TTR("Generating solution..."), 2); - - pr.step(TTR("Generating C# project...")); - - String path = OS::get_singleton()->get_resource_dir(); - String name = ProjectSettings::get_singleton()->get("application/config/name"); - if (name.empty()) { - name = "UnnamedProject"; - } - - String guid = CSharpProject::generate_game_project(path, name); - - if (guid.length()) { - - DotNetSolution solution(name); - - if (!solution.set_path(path)) { - show_error_dialog(TTR("Failed to create solution.")); - return false; - } - - DotNetSolution::ProjectInfo proj_info; - proj_info.guid = guid; - proj_info.relpath = name + ".csproj"; - proj_info.configs.push_back("Debug"); - proj_info.configs.push_back("Release"); - proj_info.configs.push_back("Tools"); - - solution.add_new_project(name, proj_info); - - Error sln_error = solution.save(); - - if (sln_error != OK) { - show_error_dialog(TTR("Failed to save solution.")); - return false; - } - - if (!GodotSharpBuilds::make_api_assembly(APIAssembly::API_CORE)) - return false; - - if (!GodotSharpBuilds::make_api_assembly(APIAssembly::API_EDITOR)) - return false; - - pr.step(TTR("Done")); - - // Here, after all calls to progress_task_step - call_deferred("_remove_create_sln_menu_option"); - - } else { - show_error_dialog(TTR("Failed to create C# project.")); - } - - return true; -} - -void GodotSharpEditor::_make_api_solutions_if_needed() { - // I'm sick entirely of ProgressDialog - - static int attempts_left = 100; - - if (MessageQueue::get_singleton()->is_flushing() || !SceneTree::get_singleton()) { - ERR_FAIL_COND(attempts_left == 0); // You've got to be kidding - - if (SceneTree::get_singleton()) { - SceneTree::get_singleton()->connect("idle_frame", this, "_make_api_solutions_if_needed", Vector<Variant>()); - } else { - call_deferred("_make_api_solutions_if_needed"); - } - - attempts_left--; - return; - } - - // Recursion guard needed because signals don't play well with ProgressDialog either, but unlike - // the message queue, with signals the collateral damage should be minimal in the worst case. - static bool recursion_guard = false; - if (!recursion_guard) { - recursion_guard = true; - - // Oneshot signals don't play well with ProgressDialog either, so we do it this way instead - SceneTree::get_singleton()->disconnect("idle_frame", this, "_make_api_solutions_if_needed"); - - _make_api_solutions_if_needed_impl(); - - recursion_guard = false; - } -} - -void GodotSharpEditor::_make_api_solutions_if_needed_impl() { - // If the project has a solution and C# project make sure the API assemblies are present and up to date - String res_assemblies_dir = GodotSharpDirs::get_res_assemblies_dir(); - - if (!FileAccess::exists(res_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll")) || - GDMono::get_singleton()->metadata_is_api_assembly_invalidated(APIAssembly::API_CORE)) { - if (!GodotSharpBuilds::make_api_assembly(APIAssembly::API_CORE)) - return; - } - - if (!FileAccess::exists(res_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll")) || - GDMono::get_singleton()->metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR)) { - if (!GodotSharpBuilds::make_api_assembly(APIAssembly::API_EDITOR)) - return; // Redundant? I don't think so - } -} - -void GodotSharpEditor::_remove_create_sln_menu_option() { - - menu_popup->remove_item(menu_popup->get_item_index(MENU_CREATE_SLN)); - - bottom_panel_btn->show(); -} - -void GodotSharpEditor::_show_about_dialog() { - - bool show_on_start = EDITOR_GET("mono/editor/show_info_on_start"); - about_dialog_checkbox->set_pressed(show_on_start); - about_dialog->popup_centered_minsize(); -} - -void GodotSharpEditor::_toggle_about_dialog_on_start(bool p_enabled) { - - bool show_on_start = EDITOR_GET("mono/editor/show_info_on_start"); - if (show_on_start != p_enabled) { - EditorSettings::get_singleton()->set_setting("mono/editor/show_info_on_start", p_enabled); - } -} - -void GodotSharpEditor::_build_solution_pressed() { - - if (!FileAccess::exists(GodotSharpDirs::get_project_sln_path())) { - if (!_create_project_solution()) - return; // Failed to create solution - } - - MonoBottomPanel::get_singleton()->call("_build_project_pressed"); -} - -void GodotSharpEditor::_menu_option_pressed(int p_id) { - - switch (p_id) { - case MENU_CREATE_SLN: { - - _create_project_solution(); - } break; - case MENU_ABOUT_CSHARP: { - - _show_about_dialog(); - } break; - default: - ERR_FAIL(); - } -} - -void GodotSharpEditor::_notification(int p_notification) { - - switch (p_notification) { - - case NOTIFICATION_READY: { - - bool show_info_dialog = EDITOR_GET("mono/editor/show_info_on_start"); - if (show_info_dialog) { - about_dialog->set_exclusive(true); - _show_about_dialog(); - // Once shown a first time, it can be seen again via the Mono menu - it doesn't have to be exclusive then. - about_dialog->set_exclusive(false); - } - } - } -} - -void GodotSharpEditor::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_build_solution_pressed"), &GodotSharpEditor::_build_solution_pressed); - ClassDB::bind_method(D_METHOD("_create_project_solution"), &GodotSharpEditor::_create_project_solution); - ClassDB::bind_method(D_METHOD("_make_api_solutions_if_needed"), &GodotSharpEditor::_make_api_solutions_if_needed); - ClassDB::bind_method(D_METHOD("_remove_create_sln_menu_option"), &GodotSharpEditor::_remove_create_sln_menu_option); - ClassDB::bind_method(D_METHOD("_toggle_about_dialog_on_start"), &GodotSharpEditor::_toggle_about_dialog_on_start); - ClassDB::bind_method(D_METHOD("_menu_option_pressed", "id"), &GodotSharpEditor::_menu_option_pressed); -} - -MonoBoolean godot_icall_MonoDevelopInstance_IsApplicationBundleInstalled(MonoString *p_bundle_id) { -#ifdef OSX_ENABLED - return (MonoBoolean)osx_is_app_bundle_installed(GDMonoMarshal::mono_string_to_godot(p_bundle_id)); -#else - (void)p_bundle_id; // UNUSED - ERR_FAIL_V(false); -#endif -} - -MonoString *godot_icall_Utils_OS_GetPlatformName() { - return GDMonoMarshal::mono_string_from_godot(OS::get_singleton()->get_name()); -} - -void GodotSharpEditor::register_internal_calls() { - - static bool registered = false; - ERR_FAIL_COND(registered); - registered = true; - - mono_add_internal_call("GodotSharpTools.Editor.MonoDevelopInstance::IsApplicationBundleInstalled", (void *)godot_icall_MonoDevelopInstance_IsApplicationBundleInstalled); - mono_add_internal_call("GodotSharpTools.Utils.OS::GetPlatformName", (void *)godot_icall_Utils_OS_GetPlatformName); - - GodotSharpBuilds::register_internal_calls(); - GodotSharpExport::register_internal_calls(); -} - -void GodotSharpEditor::show_error_dialog(const String &p_message, const String &p_title) { - - error_dialog->set_title(p_title); - error_dialog->set_text(p_message); - error_dialog->popup_centered_minsize(); -} - -Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col) { - - ExternalEditor editor = ExternalEditor(int(EditorSettings::get_singleton()->get("mono/editor/external_editor"))); - - switch (editor) { - case EDITOR_VSCODE: { - static String vscode_path; - - if (vscode_path.empty() || !FileAccess::exists(vscode_path)) { - // Try to search it again if it wasn't found last time or if it was removed from its location - bool found = false; - - // TODO: Use initializer lists once C++11 is allowed - - static Vector<String> vscode_names; - if (vscode_names.empty()) { - vscode_names.push_back("code"); - vscode_names.push_back("code-oss"); - vscode_names.push_back("vscode"); - vscode_names.push_back("vscode-oss"); - vscode_names.push_back("visual-studio-code"); - vscode_names.push_back("visual-studio-code-oss"); - } - for (int i = 0; i < vscode_names.size(); i++) { - vscode_path = path_which(vscode_names[i]); - if (!vscode_path.empty()) { - found = true; - break; - } - } - - if (!found) - vscode_path.clear(); // Not found, clear so next time the empty() check is enough - } - - List<String> args; - -#ifdef OSX_ENABLED - // The package path is '/Applications/Visual Studio Code.app' - static const String vscode_bundle_id = "com.microsoft.VSCode"; - static bool osx_app_bundle_installed = osx_is_app_bundle_installed(vscode_bundle_id); - - if (osx_app_bundle_installed) { - args.push_back("-b"); - args.push_back(vscode_bundle_id); - - // The reusing of existing windows made by the 'open' command might not choose a wubdiw that is - // editing our folder. It's better to ask for a new window and let VSCode do the window management. - args.push_back("-n"); - - // The open process must wait until the application finishes (which is instant in VSCode's case) - args.push_back("--wait-apps"); - - args.push_back("--args"); - } -#endif - - args.push_back(ProjectSettings::get_singleton()->get_resource_path()); - - String script_path = ProjectSettings::get_singleton()->globalize_path(p_script->get_path()); - - if (p_line >= 0) { - args.push_back("-g"); - args.push_back(script_path + ":" + itos(p_line + 1) + ":" + itos(p_col)); - } else { - args.push_back(script_path); - } - -#ifdef OSX_ENABLED - ERR_EXPLAIN("Cannot find code editor: VSCode"); - ERR_FAIL_COND_V(!osx_app_bundle_installed && vscode_path.empty(), ERR_FILE_NOT_FOUND); - - String command = osx_app_bundle_installed ? "/usr/bin/open" : vscode_path; -#else - ERR_EXPLAIN("Cannot find code editor: VSCode"); - ERR_FAIL_COND_V(vscode_path.empty(), ERR_FILE_NOT_FOUND); - - String command = vscode_path; -#endif - - Error err = OS::get_singleton()->execute(command, args, false); - - if (err != OK) { - ERR_PRINT("Error when trying to execute code editor: VSCode"); - return err; - } - } break; -#ifdef OSX_ENABLED - case EDITOR_VISUALSTUDIO_MAC: - // [[fallthrough]]; -#endif - case EDITOR_MONODEVELOP: { -#ifdef OSX_ENABLED - bool is_visualstudio = editor == EDITOR_VISUALSTUDIO_MAC; - - MonoDevelopInstance **instance = is_visualstudio ? - &visualstudio_mac_instance : - &monodevelop_instance; - - MonoDevelopInstance::EditorId editor_id = is_visualstudio ? - MonoDevelopInstance::VISUALSTUDIO_FOR_MAC : - MonoDevelopInstance::MONODEVELOP; -#else - MonoDevelopInstance **instance = &monodevelop_instance; - MonoDevelopInstance::EditorId editor_id = MonoDevelopInstance::MONODEVELOP; -#endif - - if (!*instance) - *instance = memnew(MonoDevelopInstance(GodotSharpDirs::get_project_sln_path(), editor_id)); - - String script_path = ProjectSettings::get_singleton()->globalize_path(p_script->get_path()); - - if (p_line >= 0) { - script_path += ";" + itos(p_line + 1) + ";" + itos(p_col); - } - - (*instance)->execute(script_path); - } break; - default: - return ERR_UNAVAILABLE; - } - - return OK; -} - -bool GodotSharpEditor::overrides_external_editor() { - - return ExternalEditor(int(EditorSettings::get_singleton()->get("mono/editor/external_editor"))) != EDITOR_NONE; -} - -GodotSharpEditor::GodotSharpEditor(EditorNode *p_editor) { - - singleton = this; - - monodevelop_instance = NULL; -#ifdef OSX_ENABLED - visualstudio_mac_instance = NULL; -#endif - - editor = p_editor; - - error_dialog = memnew(AcceptDialog); - editor->get_gui_base()->add_child(error_dialog); - - bottom_panel_btn = editor->add_bottom_panel_item(TTR("Mono"), memnew(MonoBottomPanel(editor))); - - godotsharp_builds = memnew(GodotSharpBuilds); - - editor->add_child(memnew(MonoReloadNode)); - - menu_popup = memnew(PopupMenu); - menu_popup->hide(); - menu_popup->set_as_toplevel(true); - menu_popup->set_pass_on_modal_close_click(false); - - editor->add_tool_submenu_item("Mono", menu_popup); - - // TODO: Remove or edit this info dialog once Mono support is no longer in alpha - { - menu_popup->add_item(TTR("About C# support"), MENU_ABOUT_CSHARP); - about_dialog = memnew(AcceptDialog); - editor->get_gui_base()->add_child(about_dialog); - about_dialog->set_title("Important: C# support is not feature-complete"); - - // We don't use set_text() as the default AcceptDialog Label doesn't play well with the TextureRect and CheckBox - // we'll add. Instead we add containers and a new autowrapped Label inside. - - // Main VBoxContainer (icon + label on top, checkbox at bottom) - VBoxContainer *about_vbc = memnew(VBoxContainer); - about_dialog->add_child(about_vbc); - - // HBoxContainer for icon + label - HBoxContainer *about_hbc = memnew(HBoxContainer); - about_vbc->add_child(about_hbc); - - TextureRect *about_icon = memnew(TextureRect); - about_hbc->add_child(about_icon); - Ref<Texture> about_icon_tex = about_icon->get_icon("NodeWarning", "EditorIcons"); - about_icon->set_texture(about_icon_tex); - - Label *about_label = memnew(Label); - about_hbc->add_child(about_label); - about_label->set_custom_minimum_size(Size2(600, 150) * EDSCALE); - about_label->set_v_size_flags(Control::SIZE_EXPAND_FILL); - about_label->set_autowrap(true); - String about_text = - String("C# support in Godot Engine is in late alpha stage and, while already usable, ") + - "it is not meant for use in production.\n\n" + - "Projects can be exported to Linux, macOS and Windows, but not yet to mobile or web platforms. " + - "Bugs and usability issues will be addressed gradually over future releases, " + - "potentially including compatibility breaking changes as new features are implemented for a better overall C# experience.\n\n" + - "If you experience issues with this Mono build, please report them on Godot's issue tracker with details about your system, MSBuild version, IDE, etc.:\n\n" + - " https://github.com/godotengine/godot/issues\n\n" + - "Your critical feedback at this stage will play a great role in shaping the C# support in future releases, so thank you!"; - about_label->set_text(about_text); - - EDITOR_DEF("mono/editor/show_info_on_start", true); - - // CheckBox in main container - about_dialog_checkbox = memnew(CheckBox); - about_vbc->add_child(about_dialog_checkbox); - about_dialog_checkbox->set_text("Show this warning when starting the editor"); - about_dialog_checkbox->connect("toggled", this, "_toggle_about_dialog_on_start"); - } - - String sln_path = GodotSharpDirs::get_project_sln_path(); - String csproj_path = GodotSharpDirs::get_project_csproj_path(); - - if (FileAccess::exists(sln_path) && FileAccess::exists(csproj_path)) { - // Defer this task because EditorProgress calls Main::iterarion() and the main loop is not yet initialized. - call_deferred("_make_api_solutions_if_needed"); - } else { - bottom_panel_btn->hide(); - menu_popup->add_item(TTR("Create C# solution"), MENU_CREATE_SLN); - } - - menu_popup->connect("id_pressed", this, "_menu_option_pressed"); - - ToolButton *build_button = memnew(ToolButton); - build_button->set_text("Build"); - build_button->set_tooltip("Build solution"); - build_button->set_focus_mode(Control::FOCUS_NONE); - build_button->connect("pressed", this, "_build_solution_pressed"); - editor->get_menu_hb()->add_child(build_button); - - // External editor settings - EditorSettings *ed_settings = EditorSettings::get_singleton(); - EDITOR_DEF("mono/editor/external_editor", EDITOR_NONE); - - String settings_hint_str = "Disabled"; - -#if defined(WINDOWS_ENABLED) - settings_hint_str += ",MonoDevelop,Visual Studio Code"; -#elif defined(OSX_ENABLED) - settings_hint_str += ",Visual Studio,MonoDevelop,Visual Studio Code"; -#elif defined(UNIX_ENABLED) - settings_hint_str += ",MonoDevelop,Visual Studio Code"; -#endif - - ed_settings->add_property_hint(PropertyInfo(Variant::INT, "mono/editor/external_editor", PROPERTY_HINT_ENUM, settings_hint_str)); - - // Export plugin - Ref<GodotSharpExport> godotsharp_export; - godotsharp_export.instance(); - EditorExport::get_singleton()->add_export_plugin(godotsharp_export); -} - -GodotSharpEditor::~GodotSharpEditor() { - - singleton = NULL; - - memdelete(godotsharp_builds); - - if (monodevelop_instance) { - memdelete(monodevelop_instance); - monodevelop_instance = NULL; - } -} - -MonoReloadNode *MonoReloadNode::singleton = NULL; - -void MonoReloadNode::_reload_timer_timeout() { - - if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) { - CSharpLanguage::get_singleton()->reload_assemblies(false); - } -} - -void MonoReloadNode::restart_reload_timer() { - - reload_timer->stop(); - reload_timer->start(); -} - -void MonoReloadNode::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_reload_timer_timeout"), &MonoReloadNode::_reload_timer_timeout); -} - -void MonoReloadNode::_notification(int p_what) { - switch (p_what) { - case MainLoop::NOTIFICATION_WM_FOCUS_IN: { - restart_reload_timer(); - if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) { - CSharpLanguage::get_singleton()->reload_assemblies(false); - } - } break; - default: { - } break; - }; -} - -MonoReloadNode::MonoReloadNode() { - - singleton = this; - - reload_timer = memnew(Timer); - add_child(reload_timer); - reload_timer->set_one_shot(false); - reload_timer->set_wait_time(EDITOR_DEF("mono/assembly_watch_interval_sec", 0.5)); - reload_timer->connect("timeout", this, "_reload_timer_timeout"); - reload_timer->start(); -} - -MonoReloadNode::~MonoReloadNode() { - - singleton = NULL; -} diff --git a/modules/mono/editor/godotsharp_editor.h b/modules/mono/editor/godotsharp_editor.h deleted file mode 100644 index d5bd8ba126..0000000000 --- a/modules/mono/editor/godotsharp_editor.h +++ /dev/null @@ -1,134 +0,0 @@ -/*************************************************************************/ -/* godotsharp_editor.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 GODOTSHARP_EDITOR_H -#define GODOTSHARP_EDITOR_H - -#include "godotsharp_builds.h" -#include "monodevelop_instance.h" - -class GodotSharpEditor : public Node { - GDCLASS(GodotSharpEditor, Node); - - EditorNode *editor; - - MenuButton *menu_button; - PopupMenu *menu_popup; - - AcceptDialog *error_dialog; - AcceptDialog *about_dialog; - CheckBox *about_dialog_checkbox; - - ToolButton *bottom_panel_btn; - - GodotSharpBuilds *godotsharp_builds; - - MonoDevelopInstance *monodevelop_instance; -#ifdef OSX_ENABLED - MonoDevelopInstance *visualstudio_mac_instance; -#endif - - bool _create_project_solution(); - void _make_api_solutions_if_needed(); - void _make_api_solutions_if_needed_impl(); - - void _remove_create_sln_menu_option(); - void _show_about_dialog(); - void _toggle_about_dialog_on_start(bool p_enabled); - - void _menu_option_pressed(int p_id); - - void _build_solution_pressed(); - - static GodotSharpEditor *singleton; - -protected: - void _notification(int p_notification); - static void _bind_methods(); - -public: - enum MenuOptions { - MENU_CREATE_SLN, - MENU_ABOUT_CSHARP, - }; - - enum ExternalEditor { - EDITOR_NONE, -#if defined(WINDOWS_ENABLED) - //EDITOR_VISUALSTUDIO, // TODO - EDITOR_MONODEVELOP, - EDITOR_VSCODE -#elif defined(OSX_ENABLED) - EDITOR_VISUALSTUDIO_MAC, - EDITOR_MONODEVELOP, - EDITOR_VSCODE -#elif defined(UNIX_ENABLED) - EDITOR_MONODEVELOP, - EDITOR_VSCODE -#endif - }; - - _FORCE_INLINE_ static GodotSharpEditor *get_singleton() { return singleton; } - - static void register_internal_calls(); - - void show_error_dialog(const String &p_message, const String &p_title = "Error"); - - Error open_in_external_editor(const Ref<Script> &p_script, int p_line, int p_col); - bool overrides_external_editor(); - - GodotSharpEditor(EditorNode *p_editor); - ~GodotSharpEditor(); -}; - -class MonoReloadNode : public Node { - GDCLASS(MonoReloadNode, Node); - - Timer *reload_timer; - - void _reload_timer_timeout(); - - static MonoReloadNode *singleton; - -protected: - static void _bind_methods(); - - void _notification(int p_what); - -public: - _FORCE_INLINE_ static MonoReloadNode *get_singleton() { return singleton; } - - void restart_reload_timer(); - - MonoReloadNode(); - ~MonoReloadNode(); -}; - -#endif // GODOTSHARP_EDITOR_H diff --git a/modules/mono/editor/godotsharp_export.cpp b/modules/mono/editor/godotsharp_export.cpp index 126178125f..020bb70a08 100644 --- a/modules/mono/editor/godotsharp_export.cpp +++ b/modules/mono/editor/godotsharp_export.cpp @@ -30,179 +30,28 @@ #include "godotsharp_export.h" -#include "core/version.h" +#include <mono/metadata/image.h> -#include "../csharp_script.h" -#include "../godotsharp_defs.h" -#include "../godotsharp_dirs.h" -#include "../mono_gd/gd_mono_class.h" -#include "../mono_gd/gd_mono_marshal.h" -#include "csharp_project.h" -#include "godotsharp_builds.h" +#include "../mono_gd/gd_mono.h" +#include "../mono_gd/gd_mono_assembly.h" -static MonoString *godot_icall_GodotSharpExport_GetTemplatesDir() { - String current_version = VERSION_FULL_CONFIG; - String templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(current_version); - return GDMonoMarshal::mono_string_from_godot(ProjectSettings::get_singleton()->globalize_path(templates_dir)); -} - -static MonoString *godot_icall_GodotSharpExport_GetDataDirName() { - String appname = ProjectSettings::get_singleton()->get("application/config/name"); - String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); - return GDMonoMarshal::mono_string_from_godot("data_" + appname_safe); -} - -void GodotSharpExport::register_internal_calls() { - static bool registered = false; - ERR_FAIL_COND(registered); - registered = true; - - mono_add_internal_call("GodotSharpTools.Editor.GodotSharpExport::GetTemplatesDir", (void *)godot_icall_GodotSharpExport_GetTemplatesDir); - mono_add_internal_call("GodotSharpTools.Editor.GodotSharpExport::GetDataDirName", (void *)godot_icall_GodotSharpExport_GetDataDirName); -} - -void GodotSharpExport::_export_file(const String &p_path, const String &p_type, const Set<String> &) { - - if (p_type != CSharpLanguage::get_singleton()->get_type()) - return; - - ERR_FAIL_COND(p_path.get_extension() != CSharpLanguage::get_singleton()->get_extension()); - - // TODO what if the source file is not part of the game's C# project - - if (!GLOBAL_GET("mono/export/include_scripts_content")) { - // We don't want to include the source code on exported games - add_file(p_path, Vector<uint8_t>(), false); - skip(); - } -} - -void GodotSharpExport::_export_begin(const Set<String> &p_features, bool p_debug, const String &p_path, int p_flags) { - - // TODO right now there is no way to stop the export process with an error - - ERR_FAIL_COND(!GDMono::get_singleton()->is_runtime_initialized()); - ERR_FAIL_NULL(TOOLS_DOMAIN); - ERR_FAIL_NULL(GDMono::get_singleton()->get_editor_tools_assembly()); - - if (FileAccess::exists(GodotSharpDirs::get_project_sln_path())) { - String build_config = p_debug ? "Debug" : "Release"; - - String scripts_metadata_path = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata." + String(p_debug ? "debug" : "release")); - Error metadata_err = CSharpProject::generate_scripts_metadata(GodotSharpDirs::get_project_csproj_path(), scripts_metadata_path); - ERR_FAIL_COND(metadata_err != OK); - - ERR_FAIL_COND(!_add_file(scripts_metadata_path, scripts_metadata_path)); - - // Turn export features into defines - Vector<String> godot_defines; - for (Set<String>::Element *E = p_features.front(); E; E = E->next()) { - godot_defines.push_back(E->get()); - } - ERR_FAIL_COND(!GodotSharpBuilds::build_project_blocking(build_config, godot_defines)); - - // Add dependency assemblies - - Map<String, String> dependencies; - - String project_dll_name = ProjectSettings::get_singleton()->get("application/config/name"); - if (project_dll_name.empty()) { - project_dll_name = "UnnamedProject"; - } - - String project_dll_src_dir = GodotSharpDirs::get_res_temp_assemblies_base_dir().plus_file(build_config); - String project_dll_src_path = project_dll_src_dir.plus_file(project_dll_name + ".dll"); - dependencies.insert(project_dll_name, project_dll_src_path); - - { - MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.ProjectExportDomain"); - ERR_FAIL_NULL(export_domain); - _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain); - - _GDMONO_SCOPE_DOMAIN_(export_domain); +String get_assemblyref_name(MonoImage *p_image, int index) { + const MonoTableInfo *table_info = mono_image_get_table_info(p_image, MONO_TABLE_ASSEMBLYREF); - GDMonoAssembly *scripts_assembly = NULL; - bool load_success = GDMono::get_singleton()->load_assembly_from(project_dll_name, - project_dll_src_path, &scripts_assembly, /* refonly: */ true); + uint32_t cols[MONO_ASSEMBLYREF_SIZE]; - ERR_EXPLAIN("Cannot load assembly (refonly): " + project_dll_name); - ERR_FAIL_COND(!load_success); + mono_metadata_decode_row(table_info, index, cols, MONO_ASSEMBLYREF_SIZE); - Vector<String> search_dirs; - String templates_dir = EditorSettings::get_singleton()->get_templates_dir().plus_file(VERSION_FULL_CONFIG); - String android_bcl_dir = templates_dir.plus_file("android-bcl"); - - String custom_lib_dir; - - if (p_features.find("Android") && DirAccess::exists(android_bcl_dir)) { - custom_lib_dir = android_bcl_dir; - } - - GDMonoAssembly::fill_search_dirs(search_dirs, build_config, custom_lib_dir); - - Error depend_error = _get_assembly_dependencies(scripts_assembly, search_dirs, dependencies); - ERR_FAIL_COND(depend_error != OK); - } - - for (Map<String, String>::Element *E = dependencies.front(); E; E = E->next()) { - String depend_src_path = E->value(); - String depend_dst_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(depend_src_path.get_file()); - ERR_FAIL_COND(!_add_file(depend_src_path, depend_dst_path)); - } - } - - // Mono specific export template extras (data dir) - - GDMonoClass *export_class = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Editor", "GodotSharpExport"); - ERR_FAIL_NULL(export_class); - GDMonoMethod *export_begin_method = export_class->get_method("_ExportBegin", 4); - ERR_FAIL_NULL(export_begin_method); - - MonoArray *features = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(String), p_features.size()); - int i = 0; - for (const Set<String>::Element *E = p_features.front(); E; E = E->next()) { - MonoString *boxed = GDMonoMarshal::mono_string_from_godot(E->get()); - mono_array_setref(features, i, boxed); - i++; - } - - MonoBoolean debug = p_debug; - MonoString *path = GDMonoMarshal::mono_string_from_godot(p_path); - uint32_t flags = p_flags; - void *args[4] = { features, &debug, path, &flags }; - MonoException *exc = NULL; - export_begin_method->invoke_raw(NULL, args, &exc); - - if (exc) { - GDMonoUtils::debug_print_unhandled_exception(exc); - ERR_FAIL(); - } -} - -bool GodotSharpExport::_add_file(const String &p_src_path, const String &p_dst_path, bool p_remap) { - - FileAccessRef f = FileAccess::open(p_src_path, FileAccess::READ); - ERR_FAIL_COND_V(!f, false); - - Vector<uint8_t> data; - data.resize(f->get_len()); - f->get_buffer(data.ptrw(), data.size()); - - add_file(p_dst_path, data, p_remap); - - return true; + return String::utf8(mono_metadata_string_heap(p_image, cols[MONO_ASSEMBLYREF_NAME])); } -Error GodotSharpExport::_get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Map<String, String> &r_dependencies) { - +Error GodotSharpExport::get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies) { MonoImage *image = p_assembly->get_image(); for (int i = 0; i < mono_image_get_table_rows(image, MONO_TABLE_ASSEMBLYREF); i++) { - MonoAssemblyName *ref_aname = aname_prealloc; - mono_assembly_get_assemblyref(image, i, ref_aname); - String ref_name = mono_assembly_name_get_name(ref_aname); + String ref_name = get_assemblyref_name(image, i); - if (r_dependencies.find(ref_name)) + if (r_dependencies.has(ref_name)) continue; GDMonoAssembly *ref_assembly = NULL; @@ -241,9 +90,9 @@ Error GodotSharpExport::_get_assembly_dependencies(GDMonoAssembly *p_assembly, c ERR_FAIL_V(ERR_CANT_RESOLVE); } - r_dependencies.insert(ref_name, ref_assembly->get_path()); + r_dependencies[ref_name] = ref_assembly->get_path(); - Error err = _get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies); + Error err = get_assembly_dependencies(ref_assembly, p_search_dirs, r_dependencies); if (err != OK) { ERR_EXPLAIN("Cannot load one of the dependencies for the assembly: " + ref_name); ERR_FAIL_V(err); @@ -253,14 +102,22 @@ Error GodotSharpExport::_get_assembly_dependencies(GDMonoAssembly *p_assembly, c return OK; } -GodotSharpExport::GodotSharpExport() { - // MonoAssemblyName is an incomplete type (internal to mono), so we can't allocate it ourselves. - // There isn't any api to allocate an empty one either, so we need to do it this way. - aname_prealloc = mono_assembly_name_new("whatever"); - mono_assembly_name_free(aname_prealloc); // "it does not frees the object itself, only the name members" (typo included) -} +Error GodotSharpExport::get_exported_assembly_dependencies(const String &p_project_dll_name, const String &p_project_dll_src_path, const String &p_build_config, const String &p_custom_lib_dir, Dictionary &r_dependencies) { + MonoDomain *export_domain = GDMonoUtils::create_domain("GodotEngine.ProjectExportDomain"); + ERR_FAIL_NULL_V(export_domain, FAILED); + _GDMONO_SCOPE_EXIT_DOMAIN_UNLOAD_(export_domain); + + _GDMONO_SCOPE_DOMAIN_(export_domain); + + GDMonoAssembly *scripts_assembly = NULL; + bool load_success = GDMono::get_singleton()->load_assembly_from(p_project_dll_name, + p_project_dll_src_path, &scripts_assembly, /* refonly: */ true); + + ERR_EXPLAIN("Cannot load assembly (refonly): " + p_project_dll_name); + ERR_FAIL_COND_V(!load_success, ERR_CANT_RESOLVE); + + Vector<String> search_dirs; + GDMonoAssembly::fill_search_dirs(search_dirs, p_build_config, p_custom_lib_dir); -GodotSharpExport::~GodotSharpExport() { - if (aname_prealloc) - mono_free(aname_prealloc); + return get_assembly_dependencies(scripts_assembly, search_dirs, r_dependencies); } diff --git a/modules/mono/editor/godotsharp_export.h b/modules/mono/editor/godotsharp_export.h index 4dc8ea75d5..8d121a6bc3 100644 --- a/modules/mono/editor/godotsharp_export.h +++ b/modules/mono/editor/godotsharp_export.h @@ -31,29 +31,19 @@ #ifndef GODOTSHARP_EXPORT_H #define GODOTSHARP_EXPORT_H -#include <mono/metadata/image.h> - -#include "editor/editor_export.h" +#include "core/dictionary.h" +#include "core/error_list.h" +#include "core/ustring.h" #include "../mono_gd/gd_mono_header.h" -class GodotSharpExport : public EditorExportPlugin { - - MonoAssemblyName *aname_prealloc; - - bool _add_file(const String &p_src_path, const String &p_dst_path, bool p_remap = false); - - Error _get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Map<String, String> &r_dependencies); - -protected: - virtual void _export_file(const String &p_path, const String &p_type, const Set<String> &p_features); - virtual void _export_begin(const Set<String> &p_features, bool p_debug, const String &p_path, int p_flags); +namespace GodotSharpExport { -public: - static void register_internal_calls(); +Error get_exported_assembly_dependencies(const String &p_project_dll_name, + const String &p_project_dll_src_path, const String &p_build_config, + const String &p_custom_lib_dir, Dictionary &r_dependencies); +Error get_assembly_dependencies(GDMonoAssembly *p_assembly, const Vector<String> &p_search_dirs, Dictionary &r_dependencies); - GodotSharpExport(); - ~GodotSharpExport(); -}; +} // namespace GodotSharpExport #endif // GODOTSHARP_EXPORT_H diff --git a/modules/mono/editor/mono_bottom_panel.cpp b/modules/mono/editor/mono_bottom_panel.cpp deleted file mode 100644 index 5d9e39b6c2..0000000000 --- a/modules/mono/editor/mono_bottom_panel.cpp +++ /dev/null @@ -1,528 +0,0 @@ -/*************************************************************************/ -/* mono_bottom_panel.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 "mono_bottom_panel.h" - -#include "editor/plugins/script_editor_plugin.h" -#include "editor/script_editor_debugger.h" - -#include "../csharp_script.h" -#include "../godotsharp_dirs.h" -#include "csharp_project.h" -#include "godotsharp_editor.h" - -MonoBottomPanel *MonoBottomPanel::singleton = NULL; - -void MonoBottomPanel::_update_build_tabs_list() { - - build_tabs_list->clear(); - - int current_tab = build_tabs->get_current_tab(); - - bool no_current_tab = current_tab < 0 || current_tab >= build_tabs->get_tab_count(); - - for (int i = 0; i < build_tabs->get_child_count(); i++) { - - MonoBuildTab *tab = Object::cast_to<MonoBuildTab>(build_tabs->get_child(i)); - - if (tab) { - String item_name = tab->build_info.solution.get_file().get_basename(); - item_name += " [" + tab->build_info.configuration + "]"; - - build_tabs_list->add_item(item_name, tab->get_icon_texture()); - - String item_tooltip = "Solution: " + tab->build_info.solution; - item_tooltip += "\nConfiguration: " + tab->build_info.configuration; - item_tooltip += "\nStatus: "; - - if (tab->build_exited) { - item_tooltip += tab->build_result == MonoBuildTab::RESULT_SUCCESS ? "Succeeded" : "Errored"; - } else { - item_tooltip += "Running"; - } - - if (!tab->build_exited || tab->build_result == MonoBuildTab::RESULT_ERROR) { - item_tooltip += "\nErrors: " + itos(tab->error_count); - } - - item_tooltip += "\nWarnings: " + itos(tab->warning_count); - - build_tabs_list->set_item_tooltip(i, item_tooltip); - - if (no_current_tab || current_tab == i) { - build_tabs_list->select(i); - _build_tabs_item_selected(i); - } - } - } -} - -void MonoBottomPanel::add_build_tab(MonoBuildTab *p_build_tab) { - - build_tabs->add_child(p_build_tab); - raise_build_tab(p_build_tab); -} - -void MonoBottomPanel::raise_build_tab(MonoBuildTab *p_build_tab) { - - ERR_FAIL_COND(p_build_tab->get_parent() != build_tabs); - build_tabs->move_child(p_build_tab, 0); - _update_build_tabs_list(); -} - -void MonoBottomPanel::show_build_tab() { - - for (int i = 0; i < panel_tabs->get_tab_count(); i++) { - if (panel_tabs->get_tab_control(i) == panel_builds_tab) { - panel_tabs->set_current_tab(i); - editor->make_bottom_panel_item_visible(this); - return; - } - } - - ERR_PRINT("Builds tab not found"); -} - -void MonoBottomPanel::_build_tabs_item_selected(int p_idx) { - - ERR_FAIL_INDEX(p_idx, build_tabs->get_tab_count()); - - build_tabs->set_current_tab(p_idx); - if (!build_tabs->is_visible()) - build_tabs->set_visible(true); - - warnings_btn->set_visible(true); - errors_btn->set_visible(true); - view_log_btn->set_visible(true); -} - -void MonoBottomPanel::_build_tabs_nothing_selected() { - - if (build_tabs->get_tab_count() != 0) { // just in case - build_tabs->set_visible(false); - - // This callback is called when clicking on the empty space of the list. - // ItemList won't deselect the items automatically, so we must do it ourselves. - build_tabs_list->unselect_all(); - } - - warnings_btn->set_visible(false); - errors_btn->set_visible(false); - view_log_btn->set_visible(false); -} - -void MonoBottomPanel::_warnings_toggled(bool p_pressed) { - - int current_tab = build_tabs->get_current_tab(); - ERR_FAIL_INDEX(current_tab, build_tabs->get_tab_count()); - MonoBuildTab *build_tab = Object::cast_to<MonoBuildTab>(build_tabs->get_child(current_tab)); - build_tab->warnings_visible = p_pressed; - build_tab->_update_issues_list(); -} - -void MonoBottomPanel::_errors_toggled(bool p_pressed) { - - int current_tab = build_tabs->get_current_tab(); - ERR_FAIL_INDEX(current_tab, build_tabs->get_tab_count()); - MonoBuildTab *build_tab = Object::cast_to<MonoBuildTab>(build_tabs->get_child(current_tab)); - build_tab->errors_visible = p_pressed; - build_tab->_update_issues_list(); -} - -void MonoBottomPanel::_build_project_pressed() { - - if (!FileAccess::exists(GodotSharpDirs::get_project_sln_path())) - return; // No solution to build - - String scripts_metadata_path_editor = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata.editor"); - String scripts_metadata_path_player = GodotSharpDirs::get_res_metadata_dir().plus_file("scripts_metadata.editor_player"); - - Error metadata_err = CSharpProject::generate_scripts_metadata(GodotSharpDirs::get_project_csproj_path(), scripts_metadata_path_editor); - ERR_FAIL_COND(metadata_err != OK); - - if (FileAccess::exists(scripts_metadata_path_editor)) { - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES); - Error copy_err = da->copy(scripts_metadata_path_editor, scripts_metadata_path_player); - - ERR_EXPLAIN("Failed to copy scripts metadata file"); - ERR_FAIL_COND(copy_err != OK); - } - - Vector<String> godot_defines; - godot_defines.push_back(OS::get_singleton()->get_name()); - godot_defines.push_back((sizeof(void *) == 4 ? "32" : "64")); - bool build_success = GodotSharpBuilds::get_singleton()->build_project_blocking("Tools", godot_defines); - - if (build_success) { - // Notify running game for hot-reload - ScriptEditor::get_singleton()->get_debugger()->reload_scripts(); - - // Hot-reload in the editor - MonoReloadNode::get_singleton()->restart_reload_timer(); - - if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) { - CSharpLanguage::get_singleton()->reload_assemblies(false); - } - } -} - -void MonoBottomPanel::_view_log_pressed() { - - if (build_tabs_list->is_anything_selected()) { - Vector<int> selected_items = build_tabs_list->get_selected_items(); - CRASH_COND(selected_items.size() != 1); - int selected_item = selected_items[0]; - - MonoBuildTab *build_tab = Object::cast_to<MonoBuildTab>(build_tabs->get_tab_control(selected_item)); - ERR_FAIL_NULL(build_tab); - - String log_dirpath = build_tab->get_build_info().get_log_dirpath(); - - OS::get_singleton()->shell_open(log_dirpath.plus_file(GodotSharpBuilds::get_msbuild_log_filename())); - } -} - -void MonoBottomPanel::_notification(int p_what) { - - switch (p_what) { - - case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: { - panel_tabs->add_style_override("panel", editor->get_gui_base()->get_stylebox("DebuggerPanel", "EditorStyles")); - panel_tabs->add_style_override("tab_fg", editor->get_gui_base()->get_stylebox("DebuggerTabFG", "EditorStyles")); - panel_tabs->add_style_override("tab_bg", editor->get_gui_base()->get_stylebox("DebuggerTabBG", "EditorStyles")); - } break; - } -} - -void MonoBottomPanel::_bind_methods() { - - ClassDB::bind_method(D_METHOD("_build_project_pressed"), &MonoBottomPanel::_build_project_pressed); - ClassDB::bind_method(D_METHOD("_view_log_pressed"), &MonoBottomPanel::_view_log_pressed); - ClassDB::bind_method(D_METHOD("_warnings_toggled", "pressed"), &MonoBottomPanel::_warnings_toggled); - ClassDB::bind_method(D_METHOD("_errors_toggled", "pressed"), &MonoBottomPanel::_errors_toggled); - ClassDB::bind_method(D_METHOD("_build_tabs_item_selected", "idx"), &MonoBottomPanel::_build_tabs_item_selected); - ClassDB::bind_method(D_METHOD("_build_tabs_nothing_selected"), &MonoBottomPanel::_build_tabs_nothing_selected); -} - -MonoBottomPanel::MonoBottomPanel(EditorNode *p_editor) { - - singleton = this; - - editor = p_editor; - - set_v_size_flags(SIZE_EXPAND_FILL); - set_anchors_and_margins_preset(Control::PRESET_WIDE); - - panel_tabs = memnew(TabContainer); - panel_tabs->set_tab_align(TabContainer::ALIGN_LEFT); - panel_tabs->add_style_override("panel", editor->get_gui_base()->get_stylebox("DebuggerPanel", "EditorStyles")); - panel_tabs->add_style_override("tab_fg", editor->get_gui_base()->get_stylebox("DebuggerTabFG", "EditorStyles")); - panel_tabs->add_style_override("tab_bg", editor->get_gui_base()->get_stylebox("DebuggerTabBG", "EditorStyles")); - panel_tabs->set_custom_minimum_size(Size2(0, 228) * EDSCALE); - panel_tabs->set_v_size_flags(SIZE_EXPAND_FILL); - add_child(panel_tabs); - - { // Builds - panel_builds_tab = memnew(VBoxContainer); - panel_builds_tab->set_name(TTR("Builds")); - panel_builds_tab->set_h_size_flags(SIZE_EXPAND_FILL); - panel_tabs->add_child(panel_builds_tab); - - HBoxContainer *toolbar_hbc = memnew(HBoxContainer); - toolbar_hbc->set_h_size_flags(SIZE_EXPAND_FILL); - panel_builds_tab->add_child(toolbar_hbc); - - Button *build_project_btn = memnew(Button); - build_project_btn->set_text(TTR("Build Project")); - build_project_btn->set_focus_mode(FOCUS_NONE); - build_project_btn->connect("pressed", this, "_build_project_pressed"); - toolbar_hbc->add_child(build_project_btn); - - toolbar_hbc->add_spacer(); - - warnings_btn = memnew(ToolButton); - warnings_btn->set_text(TTR("Warnings")); - warnings_btn->set_toggle_mode(true); - warnings_btn->set_pressed(true); - warnings_btn->set_visible(false); - warnings_btn->set_focus_mode(FOCUS_NONE); - warnings_btn->connect("toggled", this, "_warnings_toggled"); - toolbar_hbc->add_child(warnings_btn); - - errors_btn = memnew(ToolButton); - errors_btn->set_text(TTR("Errors")); - errors_btn->set_toggle_mode(true); - errors_btn->set_pressed(true); - errors_btn->set_visible(false); - errors_btn->set_focus_mode(FOCUS_NONE); - errors_btn->connect("toggled", this, "_errors_toggled"); - toolbar_hbc->add_child(errors_btn); - - toolbar_hbc->add_spacer(); - - view_log_btn = memnew(Button); - view_log_btn->set_text(TTR("View log")); - view_log_btn->set_focus_mode(FOCUS_NONE); - view_log_btn->set_visible(false); - view_log_btn->connect("pressed", this, "_view_log_pressed"); - toolbar_hbc->add_child(view_log_btn); - - HSplitContainer *hsc = memnew(HSplitContainer); - hsc->set_h_size_flags(SIZE_EXPAND_FILL); - hsc->set_v_size_flags(SIZE_EXPAND_FILL); - panel_builds_tab->add_child(hsc); - - build_tabs_list = memnew(ItemList); - build_tabs_list->set_h_size_flags(SIZE_EXPAND_FILL); - build_tabs_list->connect("item_selected", this, "_build_tabs_item_selected"); - build_tabs_list->connect("nothing_selected", this, "_build_tabs_nothing_selected"); - hsc->add_child(build_tabs_list); - - build_tabs = memnew(TabContainer); - build_tabs->set_tab_align(TabContainer::ALIGN_LEFT); - build_tabs->set_h_size_flags(SIZE_EXPAND_FILL); - build_tabs->set_tabs_visible(false); - hsc->add_child(build_tabs); - } -} - -MonoBottomPanel::~MonoBottomPanel() { - - singleton = NULL; -} - -void MonoBuildTab::_load_issues_from_file(const String &p_csv_file) { - - FileAccessRef f = FileAccess::open(p_csv_file, FileAccess::READ); - - if (!f) - return; - - while (!f->eof_reached()) { - Vector<String> csv_line = f->get_csv_line(); - - if (csv_line.size() == 1 && csv_line[0].empty()) - return; - - ERR_CONTINUE(csv_line.size() != 7); - - BuildIssue issue; - issue.warning = csv_line[0] == "warning"; - issue.file = csv_line[1]; - issue.line = csv_line[2].to_int(); - issue.column = csv_line[3].to_int(); - issue.code = csv_line[4]; - issue.message = csv_line[5]; - issue.project_file = csv_line[6]; - - if (issue.warning) - warning_count += 1; - else - error_count += 1; - - issues.push_back(issue); - } -} - -void MonoBuildTab::_update_issues_list() { - - issues_list->clear(); - - Ref<Texture> warning_icon = get_icon("Warning", "EditorIcons"); - Ref<Texture> error_icon = get_icon("Error", "EditorIcons"); - - for (int i = 0; i < issues.size(); i++) { - - const BuildIssue &issue = issues[i]; - - if (!(issue.warning ? warnings_visible : errors_visible)) - continue; - - String tooltip; - tooltip += String("Message: ") + issue.message; - - if (issue.code.length()) { - tooltip += String("\nCode: ") + issue.code; - } - - tooltip += String("\nType: ") + (issue.warning ? "warning" : "error"); - - String text; - - if (issue.file.length()) { - String sline = String::num_int64(issue.line); - String scolumn = String::num_int64(issue.column); - - text += issue.file + "("; - text += sline + ","; - text += scolumn + "): "; - - tooltip += "\nFile: " + issue.file; - tooltip += "\nLine: " + sline; - tooltip += "\nColumn: " + scolumn; - } - - if (issue.project_file.length()) { - tooltip += "\nProject: " + issue.project_file; - } - - text += issue.message; - - int line_break_idx = text.find("\n"); - issues_list->add_item(line_break_idx == -1 ? text : text.substr(0, line_break_idx), - issue.warning ? warning_icon : error_icon); - int index = issues_list->get_item_count() - 1; - issues_list->set_item_tooltip(index, tooltip); - issues_list->set_item_metadata(index, i); - } -} - -Ref<Texture> MonoBuildTab::get_icon_texture() const { - - if (build_exited) { - if (build_result == RESULT_ERROR) { - return get_icon("StatusError", "EditorIcons"); - } else { - return get_icon("StatusSuccess", "EditorIcons"); - } - } else { - return get_icon("Stop", "EditorIcons"); - } -} - -MonoBuildInfo MonoBuildTab::get_build_info() { - - return build_info; -} - -void MonoBuildTab::on_build_start() { - - build_exited = false; - - issues.clear(); - warning_count = 0; - error_count = 0; - _update_issues_list(); - - MonoBottomPanel::get_singleton()->raise_build_tab(this); -} - -void MonoBuildTab::on_build_exit(BuildResult result) { - - build_exited = true; - build_result = result; - - _load_issues_from_file(logs_dir.plus_file(GodotSharpBuilds::get_msbuild_issues_filename())); - _update_issues_list(); - - MonoBottomPanel::get_singleton()->raise_build_tab(this); -} - -void MonoBuildTab::on_build_exec_failed(const String &p_cause) { - - build_exited = true; - build_result = RESULT_ERROR; - - issues_list->clear(); - - BuildIssue issue; - issue.message = p_cause; - issue.warning = false; - - error_count += 1; - issues.push_back(issue); - - _update_issues_list(); - - MonoBottomPanel::get_singleton()->raise_build_tab(this); -} - -void MonoBuildTab::restart_build() { - - ERR_FAIL_COND(!build_exited); - GodotSharpBuilds::get_singleton()->restart_build(this); -} - -void MonoBuildTab::stop_build() { - - ERR_FAIL_COND(build_exited); - GodotSharpBuilds::get_singleton()->stop_build(this); -} - -void MonoBuildTab::_issue_activated(int p_idx) { - - ERR_FAIL_INDEX(p_idx, issues_list->get_item_count()); - - // Get correct issue idx from issue list - int issue_idx = this->issues_list->get_item_metadata(p_idx); - - ERR_FAIL_INDEX(issue_idx, issues.size()); - - const BuildIssue &issue = issues[issue_idx]; - - if (issue.project_file.empty() && issue.file.empty()) - return; - - String project_dir = issue.project_file.length() ? issue.project_file.get_base_dir() : build_info.solution.get_base_dir(); - - String file = project_dir.simplify_path().plus_file(issue.file.simplify_path()); - - if (!FileAccess::exists(file)) - return; - - file = ProjectSettings::get_singleton()->localize_path(file); - - if (file.begins_with("res://")) { - Ref<Script> script = ResourceLoader::load(file, CSharpLanguage::get_singleton()->get_type()); - - if (script.is_valid() && ScriptEditor::get_singleton()->edit(script, issue.line, issue.column)) { - EditorNode::get_singleton()->call("_editor_select", EditorNode::EDITOR_SCRIPT); - } - } -} - -void MonoBuildTab::_bind_methods() { - - ClassDB::bind_method("_issue_activated", &MonoBuildTab::_issue_activated); -} - -MonoBuildTab::MonoBuildTab(const MonoBuildInfo &p_build_info, const String &p_logs_dir) : - build_exited(false), - issues_list(memnew(ItemList)), - error_count(0), - warning_count(0), - errors_visible(true), - warnings_visible(true), - logs_dir(p_logs_dir), - build_info(p_build_info) { - issues_list->set_v_size_flags(SIZE_EXPAND_FILL); - issues_list->connect("item_activated", this, "_issue_activated"); - add_child(issues_list); -} diff --git a/modules/mono/editor/mono_bottom_panel.h b/modules/mono/editor/mono_bottom_panel.h deleted file mode 100644 index 9b362e51df..0000000000 --- a/modules/mono/editor/mono_bottom_panel.h +++ /dev/null @@ -1,150 +0,0 @@ -/*************************************************************************/ -/* mono_bottom_panel.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 MONO_BOTTOM_PANEL_H -#define MONO_BOTTOM_PANEL_H - -#include "editor/editor_node.h" -#include "scene/gui/control.h" - -#include "mono_build_info.h" - -class MonoBuildTab; - -class MonoBottomPanel : public VBoxContainer { - - GDCLASS(MonoBottomPanel, VBoxContainer); - - EditorNode *editor; - - TabContainer *panel_tabs; - - VBoxContainer *panel_builds_tab; - - ItemList *build_tabs_list; - TabContainer *build_tabs; - - ToolButton *warnings_btn; - ToolButton *errors_btn; - Button *view_log_btn; - - void _update_build_tabs_list(); - - void _build_tabs_item_selected(int p_idx); - void _build_tabs_nothing_selected(); - - void _warnings_toggled(bool p_pressed); - void _errors_toggled(bool p_pressed); - - void _build_project_pressed(); - void _view_log_pressed(); - - static MonoBottomPanel *singleton; - -protected: - void _notification(int p_what); - - static void _bind_methods(); - -public: - _FORCE_INLINE_ static MonoBottomPanel *get_singleton() { return singleton; } - - void add_build_tab(MonoBuildTab *p_build_tab); - void raise_build_tab(MonoBuildTab *p_build_tab); - - void show_build_tab(); - - MonoBottomPanel(EditorNode *p_editor = NULL); - ~MonoBottomPanel(); -}; - -class MonoBuildTab : public VBoxContainer { - - GDCLASS(MonoBuildTab, VBoxContainer); - -public: - enum BuildResult { - RESULT_ERROR, - RESULT_SUCCESS - }; - - struct BuildIssue { - bool warning; - String file; - int line; - int column; - String code; - String message; - String project_file; - }; - -private: - friend class MonoBottomPanel; - - bool build_exited; - BuildResult build_result; - - Vector<BuildIssue> issues; - ItemList *issues_list; - - int error_count; - int warning_count; - - bool errors_visible; - bool warnings_visible; - - String logs_dir; - - MonoBuildInfo build_info; - - void _load_issues_from_file(const String &p_csv_file); - void _update_issues_list(); - - void _issue_activated(int p_idx); - -protected: - static void _bind_methods(); - -public: - Ref<Texture> get_icon_texture() const; - - MonoBuildInfo get_build_info(); - - void on_build_start(); - void on_build_exit(BuildResult result); - void on_build_exec_failed(const String &p_cause); - - void restart_build(); - void stop_build(); - - MonoBuildTab(const MonoBuildInfo &p_build_info, const String &p_logs_dir); -}; - -#endif // MONO_BOTTOM_PANEL_H diff --git a/modules/mono/editor/mono_build_info.cpp b/modules/mono/editor/mono_build_info.cpp deleted file mode 100644 index b386c06435..0000000000 --- a/modules/mono/editor/mono_build_info.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/*************************************************************************/ -/* mono_build_info.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 "mono_build_info.h" - -#include "../godotsharp_dirs.h" -#include "../mono_gd/gd_mono_utils.h" - -uint32_t MonoBuildInfo::Hasher::hash(const MonoBuildInfo &p_key) { - - uint32_t hash = 0; - - GDMonoUtils::hash_combine(hash, p_key.solution.hash()); - GDMonoUtils::hash_combine(hash, p_key.configuration.hash()); - - return hash; -} - -bool MonoBuildInfo::operator==(const MonoBuildInfo &p_b) const { - - return p_b.solution == solution && p_b.configuration == configuration; -} - -String MonoBuildInfo::get_log_dirpath() { - - return GodotSharpDirs::get_build_logs_dir().plus_file(solution.md5_text() + "_" + configuration); -} - -MonoBuildInfo::MonoBuildInfo() {} - -MonoBuildInfo::MonoBuildInfo(const String &p_solution, const String &p_config) { - - solution = p_solution; - configuration = p_config; -} diff --git a/modules/mono/glue/Managed/.gitignore b/modules/mono/glue/Managed/.gitignore new file mode 100644 index 0000000000..146421cac8 --- /dev/null +++ b/modules/mono/glue/Managed/.gitignore @@ -0,0 +1,2 @@ +# Generated Godot API solution folder +Generated diff --git a/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs b/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs index 2398e10135..1bf6d5199a 100644 --- a/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs +++ b/modules/mono/glue/Managed/Files/Attributes/RPCAttributes.cs @@ -2,27 +2,27 @@ using System; namespace Godot { - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class RemoteAttribute : Attribute {} - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class SyncAttribute : Attribute {} - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class MasterAttribute : Attribute {} - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class PuppetAttribute : Attribute {} - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class SlaveAttribute : Attribute {} - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class RemoteSyncAttribute : Attribute {} - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class MasterSyncAttribute : Attribute {} - [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field)] + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Property)] public class PuppetSyncAttribute : Attribute {} } diff --git a/modules/mono/glue/Managed/Files/Interfaces/ISerializationListener.cs b/modules/mono/glue/Managed/Files/Interfaces/ISerializationListener.cs new file mode 100644 index 0000000000..c3fa2f3e82 --- /dev/null +++ b/modules/mono/glue/Managed/Files/Interfaces/ISerializationListener.cs @@ -0,0 +1,8 @@ +namespace Godot +{ + public interface ISerializationListener + { + void OnBeforeSerialize(); + void OnAfterDeserialize(); + } +} diff --git a/modules/mono/glue/Managed/Files/StringExtensions.cs b/modules/mono/glue/Managed/Files/StringExtensions.cs index c194facd0b..b43034fbb5 100644 --- a/modules/mono/glue/Managed/Files/StringExtensions.cs +++ b/modules/mono/glue/Managed/Files/StringExtensions.cs @@ -299,14 +299,14 @@ namespace Godot if (basepos != -1) { var end = basepos + 3; - rs = instance.Substring(end, instance.Length); + rs = instance.Substring(end); @base = instance.Substring(0, end); } else { if (instance.BeginsWith("/")) { - rs = instance.Substring(1, instance.Length); + rs = instance.Substring(1); @base = "/"; } else @@ -333,7 +333,7 @@ namespace Godot if (sep == -1) return instance; - return instance.Substring(sep + 1, instance.Length); + return instance.Substring(sep + 1); } // <summary> @@ -911,7 +911,8 @@ namespace Godot // </summary> public static string Substr(this string instance, int from, int len) { - return instance.Substring(from, len); + int max = instance.Length - from; + return instance.Substring(from, len > max ? max : len); } // <summary> diff --git a/modules/mono/glue/base_object_glue.cpp b/modules/mono/glue/base_object_glue.cpp index 75b2dfce9a..6d85f55b97 100644 --- a/modules/mono/glue/base_object_glue.cpp +++ b/modules/mono/glue/base_object_glue.cpp @@ -219,7 +219,18 @@ MonoBoolean godot_icall_DynamicGodotObject_SetMember(Object *p_ptr, MonoString * } MonoString *godot_icall_Object_ToString(Object *p_ptr) { - return GDMonoMarshal::mono_string_from_godot(Variant(p_ptr).operator String()); +#ifdef DEBUG_ENABLED + // Cannot happen in C#; would get an ObjectDisposedException instead. + CRASH_COND(p_ptr == NULL); + + if (ScriptDebugger::get_singleton() && !Object::cast_to<Reference>(p_ptr)) { // Only if debugging! + // Cannot happen either in C#; the handle is nullified when the object is destroyed + CRASH_COND(!ObjectDB::instance_validate(p_ptr)); + } +#endif + + String result = "[" + p_ptr->get_class() + ":" + itos(p_ptr->get_instance_id()) + "]"; + return GDMonoMarshal::mono_string_from_godot(result); } void godot_register_object_icalls() { diff --git a/modules/mono/glue/collections_glue.cpp b/modules/mono/glue/collections_glue.cpp index 47239f1260..e67c8b9ad9 100644 --- a/modules/mono/glue/collections_glue.cpp +++ b/modules/mono/glue/collections_glue.cpp @@ -46,7 +46,7 @@ void godot_icall_Array_Dtor(Array *ptr) { } MonoObject *godot_icall_Array_At(Array *ptr, int index) { - if (index < 0 || index > ptr->size()) { + if (index < 0 || index >= ptr->size()) { GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range()); return NULL; } @@ -54,7 +54,7 @@ MonoObject *godot_icall_Array_At(Array *ptr, int index) { } MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_encoding, GDMonoClass *type_class) { - if (index < 0 || index > ptr->size()) { + if (index < 0 || index >= ptr->size()) { GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range()); return NULL; } @@ -62,7 +62,7 @@ MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_en } void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value) { - if (index < 0 || index > ptr->size()) { + if (index < 0 || index >= ptr->size()) { GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range()); return; } @@ -124,7 +124,7 @@ MonoBoolean godot_icall_Array_Remove(Array *ptr, MonoObject *item) { } void godot_icall_Array_RemoveAt(Array *ptr, int index) { - if (index < 0 || index > ptr->size()) { + if (index < 0 || index >= ptr->size()) { GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range()); return; } diff --git a/modules/mono/glue/string_glue.cpp b/modules/mono/glue/string_glue.cpp index a5c72160d7..e9373fb486 100644 --- a/modules/mono/glue/string_glue.cpp +++ b/modules/mono/glue/string_glue.cpp @@ -68,12 +68,12 @@ MonoString *godot_icall_String_sha256_text(MonoString *p_str) { } void godot_register_string_icalls() { - mono_add_internal_call("Godot.String::godot_icall_String_md5_buffer", (void *)godot_icall_String_md5_buffer); - mono_add_internal_call("Godot.String::godot_icall_String_md5_text", (void *)godot_icall_String_md5_text); - mono_add_internal_call("Godot.String::godot_icall_String_rfind", (void *)godot_icall_String_rfind); - mono_add_internal_call("Godot.String::godot_icall_String_rfindn", (void *)godot_icall_String_rfindn); - mono_add_internal_call("Godot.String::godot_icall_String_sha256_buffer", (void *)godot_icall_String_sha256_buffer); - mono_add_internal_call("Godot.String::godot_icall_String_sha256_text", (void *)godot_icall_String_sha256_text); + mono_add_internal_call("Godot.StringExtensions::godot_icall_String_md5_buffer", (void *)godot_icall_String_md5_buffer); + mono_add_internal_call("Godot.StringExtensions::godot_icall_String_md5_text", (void *)godot_icall_String_md5_text); + mono_add_internal_call("Godot.StringExtensions::godot_icall_String_rfind", (void *)godot_icall_String_rfind); + mono_add_internal_call("Godot.StringExtensions::godot_icall_String_rfindn", (void *)godot_icall_String_rfindn); + mono_add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_buffer", (void *)godot_icall_String_sha256_buffer); + mono_add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_text", (void *)godot_icall_String_sha256_text); } #endif // MONO_GLUE_ENABLED diff --git a/modules/mono/godotsharp_defs.h b/modules/mono/godotsharp_defs.h index 0d3b96d789..4ad4088514 100644 --- a/modules/mono/godotsharp_defs.h +++ b/modules/mono/godotsharp_defs.h @@ -39,7 +39,8 @@ #define API_SOLUTION_NAME "GodotSharp" #define CORE_API_ASSEMBLY_NAME "GodotSharp" #define EDITOR_API_ASSEMBLY_NAME "GodotSharpEditor" -#define EDITOR_TOOLS_ASSEMBLY_NAME "GodotSharpTools" +#define TOOLS_ASSEMBLY_NAME "GodotTools" +#define TOOLS_PROJECT_EDITOR_ASSEMBLY_NAME "GodotTools.ProjectEditor" #define BINDINGS_CLASS_NATIVECALLS "NativeCalls" #define BINDINGS_CLASS_NATIVECALLS_EDITOR "EditorNativeCalls" diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp index 09a1fc6fbc..4b2525c692 100644 --- a/modules/mono/godotsharp_dirs.cpp +++ b/modules/mono/godotsharp_dirs.cpp @@ -39,6 +39,10 @@ #include "editor/editor_settings.h" #endif +#ifdef __ANDROID__ +#include "utils/android_utils.h" +#endif + namespace GodotSharpDirs { String _get_expected_build_config() { @@ -55,6 +59,20 @@ String _get_expected_build_config() { #endif } +String _get_expected_api_build_config() { +#ifdef TOOLS_ENABLED + return "Debug"; +#else + +#ifdef DEBUG_ENABLED + return "Debug"; +#else + return "Release"; +#endif + +#endif +} + String _get_mono_user_dir() { #ifdef TOOLS_ENABLED if (EditorSettings::get_singleton()) { @@ -84,6 +102,7 @@ class _GodotSharpDirs { public: String res_data_dir; String res_metadata_dir; + String res_assemblies_base_dir; String res_assemblies_dir; String res_config_dir; String res_temp_dir; @@ -114,7 +133,8 @@ private: _GodotSharpDirs() { res_data_dir = "res://.mono"; res_metadata_dir = res_data_dir.plus_file("metadata"); - res_assemblies_dir = res_data_dir.plus_file("assemblies"); + res_assemblies_base_dir = res_data_dir.plus_file("assemblies"); + res_assemblies_dir = res_assemblies_base_dir.plus_file(_get_expected_api_build_config()); res_config_dir = res_data_dir.plus_file("etc").plus_file("mono"); // TODO use paths from csproj @@ -129,15 +149,16 @@ private: mono_solutions_dir = mono_user_dir.plus_file("solutions"); build_logs_dir = mono_user_dir.plus_file("build_logs"); - String name = ProjectSettings::get_singleton()->get("application/config/name"); - if (name.empty()) { - name = "UnnamedProject"; + String appname = ProjectSettings::get_singleton()->get("application/config/name"); + String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); + if (appname_safe.empty()) { + appname_safe = "UnnamedProject"; } String base_path = ProjectSettings::get_singleton()->globalize_path("res://"); - sln_filepath = base_path.plus_file(name + ".sln"); - csproj_filepath = base_path.plus_file(name + ".csproj"); + sln_filepath = base_path.plus_file(appname_safe + ".sln"); + csproj_filepath = base_path.plus_file(appname_safe + ".csproj"); #endif String exe_dir = OS::get_singleton()->get_executable_path().get_base_dir(); @@ -150,7 +171,12 @@ private: String data_mono_root_dir = data_dir_root.plus_file("Mono"); data_mono_etc_dir = data_mono_root_dir.plus_file("etc"); + +#if __ANDROID__ + data_mono_lib_dir = GDMonoUtils::Android::get_app_native_lib_dir(); +#else data_mono_lib_dir = data_mono_root_dir.plus_file("lib"); +#endif #ifdef WINDOWS_ENABLED data_mono_bin_dir = data_mono_root_dir.plus_file("bin"); @@ -173,15 +199,21 @@ private: #else - String appname = OS::get_singleton()->get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name")); - String data_dir_root = exe_dir.plus_file("data_" + appname); + String appname = ProjectSettings::get_singleton()->get("application/config/name"); + String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); + String data_dir_root = exe_dir.plus_file("data_" + appname_safe); if (!DirAccess::exists(data_dir_root)) { data_dir_root = exe_dir.plus_file("data_Godot"); } String data_mono_root_dir = data_dir_root.plus_file("Mono"); data_mono_etc_dir = data_mono_root_dir.plus_file("etc"); + +#if __ANDROID__ + data_mono_lib_dir = GDMonoUtils::Android::get_app_native_lib_dir(); +#else data_mono_lib_dir = data_mono_root_dir.plus_file("lib"); +#endif #ifdef WINDOWS_ENABLED data_mono_bin_dir = data_mono_root_dir.plus_file("bin"); @@ -215,6 +247,10 @@ String get_res_metadata_dir() { return _GodotSharpDirs::get_singleton().res_metadata_dir; } +String get_res_assemblies_base_dir() { + return _GodotSharpDirs::get_singleton().res_assemblies_base_dir; +} + String get_res_assemblies_dir() { return _GodotSharpDirs::get_singleton().res_assemblies_dir; } diff --git a/modules/mono/godotsharp_dirs.h b/modules/mono/godotsharp_dirs.h index 556df959e2..ff51888d1c 100644 --- a/modules/mono/godotsharp_dirs.h +++ b/modules/mono/godotsharp_dirs.h @@ -37,6 +37,7 @@ namespace GodotSharpDirs { String get_res_data_dir(); String get_res_metadata_dir(); +String get_res_assemblies_base_dir(); String get_res_assemblies_dir(); String get_res_config_dir(); String get_res_temp_dir(); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 7699e0d0cd..096ad0f5e3 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -52,13 +52,12 @@ #include "gd_mono_utils.h" #ifdef TOOLS_ENABLED -#include "../editor/godotsharp_editor.h" #include "main/main.h" #endif -#define OUT_OF_SYNC_ERR_MESSAGE(m_assembly_name) "The assembly '" m_assembly_name "' is out of sync. " \ - "This error is expected if you just upgraded to a newer Godot version. " \ - "Building the project will update the assembly to the correct version." +#ifdef ANDROID_ENABLED +#include "android_mono_config.gen.h" +#endif GDMono *GDMono::singleton = NULL; @@ -95,7 +94,7 @@ void gdmono_profiler_init() { #ifdef DEBUG_ENABLED -static bool _wait_for_debugger_msecs(uint32_t p_msecs) { +bool _wait_for_debugger_msecs(uint32_t p_msecs) { do { if (mono_is_debugger_attached()) @@ -125,16 +124,17 @@ void gdmono_debug_init() { bool da_suspend = GLOBAL_DEF("mono/debugger_agent/wait_for_debugger", false); int da_timeout = GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000); + CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8(); + #ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() || ProjectSettings::get_singleton()->get_resource_path().empty() || Main::is_project_manager()) { - return; + if (da_args.size() == 0) + return; } #endif - CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8(); - if (da_args.length() == 0) { da_args = String("--debugger-agent=transport=dt_socket,address=127.0.0.1:" + itos(da_port) + ",embedding=1,server=y,suspend=" + (da_suspend ? "y,timeout=" + itos(da_timeout) : "n")) @@ -203,6 +203,10 @@ void GDMono::initialize() { print_verbose("Mono: Initializing module..."); + char *runtime_build_info = mono_get_runtime_build_info(); + print_verbose("Mono JIT compiler version " + String(runtime_build_info)); + mono_free(runtime_build_info); + #ifdef DEBUG_METHODS_ENABLED _initialize_and_check_api_hashes(); #endif @@ -233,9 +237,9 @@ void GDMono::initialize() { locations.push_back("/usr/local/var/homebrew/linked/mono/"); for (int i = 0; i < locations.size(); i++) { - String hint_assembly_rootdir = path_join(locations[i], "lib"); - String hint_mscorlib_path = path_join(hint_assembly_rootdir, "mono", "4.5", "mscorlib.dll"); - String hint_config_dir = path_join(locations[i], "etc"); + String hint_assembly_rootdir = path::join(locations[i], "lib"); + String hint_mscorlib_path = path::join(hint_assembly_rootdir, "mono", "4.5", "mscorlib.dll"); + String hint_config_dir = path::join(locations[i], "etc"); if (FileAccess::exists(hint_mscorlib_path) && DirAccess::exists(hint_config_dir)) { assembly_rootdir = hint_assembly_rootdir; @@ -287,31 +291,18 @@ void GDMono::initialize() { gdmono_debug_init(); #endif +#ifdef ANDROID_ENABLED + mono_config_parse_memory(get_godot_android_mono_config().utf8().get_data()); +#else mono_config_parse(NULL); +#endif mono_install_unhandled_exception_hook(&unhandled_exception_hook, NULL); #ifndef TOOLS_ENABLED - if (!DirAccess::exists("res://.mono")) { - // 'res://.mono/' is missing so there is nothing to load. We don't need to initialize mono, but - // we still do so unless mscorlib is missing (which is the case for projects that don't use C#). - - String mscorlib_fname("mscorlib.dll"); - - Vector<String> search_dirs; - GDMonoAssembly::fill_search_dirs(search_dirs); - - bool found = false; - for (int i = 0; i < search_dirs.size(); i++) { - if (FileAccess::exists(search_dirs[i].plus_file(mscorlib_fname))) { - found = true; - break; - } - } - - if (!found) - return; // mscorlib is missing, do not initialize mono - } + // Export templates only load the Mono runtime if the project uses it + if (!DirAccess::exists("res://.mono")) + return; #endif root_domain = mono_jit_init_version("GodotEngine.RootDomain", "v4.0.30319"); @@ -331,18 +322,6 @@ void GDMono::initialize() { ERR_EXPLAIN("Mono: Failed to load mscorlib assembly"); ERR_FAIL_COND(!_load_corlib_assembly()); -#ifdef TOOLS_ENABLED - // The tools domain must be loaded here, before the scripts domain. - // Otherwise domain unload on the scripts domain will hang indefinitely. - - ERR_EXPLAIN("Mono: Failed to load tools domain"); - ERR_FAIL_COND(_load_tools_domain() != OK); - - // TODO move to editor init callback, and do it lazily when required before editor init (e.g.: bindings generation) - ERR_EXPLAIN("Mono: Failed to load Editor Tools assembly"); - ERR_FAIL_COND(!_load_editor_tools_assembly()); -#endif - ERR_EXPLAIN("Mono: Failed to load scripts domain"); ERR_FAIL_COND(_load_scripts_domain() != OK); @@ -354,56 +333,48 @@ void GDMono::initialize() { _register_internal_calls(); - // The following assemblies are not required at initialization -#ifdef MONO_GLUE_ENABLED - if (_load_api_assemblies()) { - // Everything is fine with the api assemblies, load the project assembly - _load_project_assembly(); - } else { - if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)) -#ifdef TOOLS_ENABLED - || (editor_api_assembly && editor_api_assembly_out_of_sync) + print_verbose("Mono: INITIALIZED"); +} + +void GDMono::initialize_load_assemblies() { + +#ifndef MONO_GLUE_ENABLED + ERR_EXPLAIN("Mono: This binary was built with `mono_glue=no`; cannot load assemblies"); + CRASH_NOW(); #endif - ) { -#ifdef TOOLS_ENABLED - // The assembly was successfully loaded, but the full api could not be cached. - // This is most likely an outdated assembly loaded because of an invalid version in the - // metadata, so we invalidate the version in the metadata and unload the script domain. - - if (core_api_assembly_out_of_sync) { - ERR_PRINT(OUT_OF_SYNC_ERR_MESSAGE(CORE_API_ASSEMBLY_NAME)); - metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); - } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { - ERR_PRINT("The loaded assembly '" CORE_API_ASSEMBLY_NAME "' is in sync, but the cache update failed"); - metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); - } - if (editor_api_assembly_out_of_sync) { - ERR_PRINT(OUT_OF_SYNC_ERR_MESSAGE(EDITOR_API_ASSEMBLY_NAME)); - metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true); - } + // Load assemblies. The API and tools assemblies are required, + // the application is aborted if these assemblies cannot be loaded. - print_line("Mono: Proceeding to unload scripts domain because of invalid API assemblies."); + _load_api_assemblies(); - Error err = _unload_scripts_domain(); - if (err != OK) { - WARN_PRINT("Mono: Failed to unload scripts domain"); - } -#else - ERR_PRINT("The loaded API assembly is invalid"); - CRASH_NOW(); -#endif // TOOLS_ENABLED - } +#if defined(TOOLS_ENABLED) + if (!_load_tools_assemblies()) { + ERR_EXPLAIN("Mono: Failed to load GodotTools assemblies"); + CRASH_NOW(); } -#else - print_verbose("Mono: Glue disabled, ignoring script assemblies."); -#endif // MONO_GLUE_ENABLED +#endif - print_verbose("Mono: INITIALIZED"); + // Load the project's main assembly. This doesn't necessarily need to succeed. + // The game may not be using .NET at all, or if the project does use .NET and + // we're running in the editor, it may just happen to be it wasn't built yet. + if (!_load_project_assembly()) { + if (OS::get_singleton()->is_stdout_verbose()) + print_error("Mono: Failed to load project assembly"); + } +} + +bool GDMono::_are_api_assemblies_out_of_sync() { + bool out_of_sync = core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated); +#ifdef TOOLS_ENABLED + if (!out_of_sync) + out_of_sync = editor_api_assembly && editor_api_assembly_out_of_sync; +#endif + return out_of_sync; } -#ifdef MONO_GLUE_ENABLED namespace GodotSharpBindings { +#ifdef MONO_GLUE_ENABLED uint64_t get_core_api_hash(); #ifdef TOOLS_ENABLED @@ -412,17 +383,33 @@ uint64_t get_editor_api_hash(); uint32_t get_bindings_version(); void register_generated_icalls(); -} // namespace GodotSharpBindings -#endif -void GDMono::_register_internal_calls() { -#ifdef MONO_GLUE_ENABLED - GodotSharpBindings::register_generated_icalls(); -#endif +#else +uint64_t get_core_api_hash() { + CRASH_NOW(); + GD_UNREACHABLE(); +} #ifdef TOOLS_ENABLED - GodotSharpEditor::register_internal_calls(); +uint64_t get_editor_api_hash() { + CRASH_NOW(); + GD_UNREACHABLE(); +} #endif +uint32_t get_bindings_version() { + CRASH_NOW(); + GD_UNREACHABLE(); +} + +void register_generated_icalls() { + /* Fine, just do nothing */ +} + +#endif // MONO_GLUE_ENABLED +} // namespace GodotSharpBindings + +void GDMono::_register_internal_calls() { + GodotSharpBindings::register_generated_icalls(); } void GDMono::_initialize_and_check_api_hashes() { @@ -561,29 +548,109 @@ bool GDMono::_load_corlib_assembly() { return success; } -bool GDMono::_load_core_api_assembly() { +#ifdef TOOLS_ENABLED +bool GDMono::copy_prebuilt_api_assembly(APIAssembly::Type p_api_type) { - if (core_api_assembly) - return true; + bool &api_assembly_out_of_sync = (p_api_type == APIAssembly::API_CORE) ? + GDMono::get_singleton()->core_api_assembly_out_of_sync : + GDMono::get_singleton()->editor_api_assembly_out_of_sync; -#ifdef TOOLS_ENABLED - if (metadata_is_api_assembly_invalidated(APIAssembly::API_CORE)) { - print_verbose("Mono: Skipping loading of Core API assembly because it was invalidated"); - return false; + String src_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug"); + String dst_dir = GodotSharpDirs::get_res_assemblies_dir(); + + String assembly_name = p_api_type == APIAssembly::API_CORE ? CORE_API_ASSEMBLY_NAME : EDITOR_API_ASSEMBLY_NAME; + + // Create destination directory if needed + if (!DirAccess::exists(dst_dir)) { + DirAccess *da = DirAccess::create_for_path(dst_dir); + Error err = da->make_dir_recursive(dst_dir); + memdelete(da); + + if (err != OK) { + ERR_PRINTS("Failed to create destination directory for the API assemblies. Error: " + itos(err)); + return false; + } + } + + String assembly_file = assembly_name + ".dll"; + String assembly_src = src_dir.plus_file(assembly_file); + String assembly_dst = dst_dir.plus_file(assembly_file); + + if (!FileAccess::exists(assembly_dst) || api_assembly_out_of_sync) { + DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + + String xml_file = assembly_name + ".xml"; + if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) + WARN_PRINTS("Failed to copy " + xml_file); + + String pdb_file = assembly_name + ".pdb"; + if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) + WARN_PRINTS("Failed to copy " + pdb_file); + + Error err = da->copy(assembly_src, assembly_dst); + + if (err != OK) { + ERR_PRINTS("Failed to copy " + assembly_file); + return false; + } + + api_assembly_out_of_sync = false; } + + return true; +} + +String GDMono::update_api_assemblies_from_prebuilt() { + +#define FAIL_REASON(m_out_of_sync, m_prebuilt_exist) \ + ( \ + (m_out_of_sync ? \ + String("The assembly is invalidated") : \ + String("The assembly was not found")) + \ + (m_prebuilt_exist ? \ + String(" and the prebuilt assemblies are missing") : \ + String(" and we failed to copy the prebuilt assemblies"))) + + bool api_assembly_out_of_sync = core_api_assembly_out_of_sync || editor_api_assembly_out_of_sync; + + String core_assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(CORE_API_ASSEMBLY_NAME ".dll"); + String editor_assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); + + if (!api_assembly_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) + return String(); // No update needed + + String prebuilt_api_dir = GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug"); + String prebuilt_core_dll_path = prebuilt_api_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); + String prebuilt_editor_dll_path = prebuilt_api_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); + + if (!FileAccess::exists(prebuilt_core_dll_path) || !FileAccess::exists(prebuilt_editor_dll_path)) + return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exist: */ false); + + // Copy the prebuilt Api + if (!copy_prebuilt_api_assembly(APIAssembly::API_CORE) || !copy_prebuilt_api_assembly(APIAssembly::API_EDITOR)) + return FAIL_REASON(api_assembly_out_of_sync, /* prebuilt_exist: */ true); + + return String(); // Updated successfully + +#undef FAIL_REASON +} #endif - String assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(CORE_API_ASSEMBLY_NAME ".dll"); +bool GDMono::_load_core_api_assembly() { - if (!FileAccess::exists(assembly_path)) - return false; + if (core_api_assembly) + return true; - bool success = load_assembly_from(CORE_API_ASSEMBLY_NAME, - assembly_path, - &core_api_assembly); +#ifdef TOOLS_ENABLED + // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date + String assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(CORE_API_ASSEMBLY_NAME ".dll"); + bool success = FileAccess::exists(assembly_path) && + load_assembly_from(CORE_API_ASSEMBLY_NAME, assembly_path, &core_api_assembly); +#else + bool success = load_assembly(CORE_API_ASSEMBLY_NAME, &core_api_assembly); +#endif if (success) { -#ifdef MONO_GLUE_ENABLED APIAssembly::Version api_assembly_ver = APIAssembly::Version::get_from_loaded_assembly(core_api_assembly, APIAssembly::API_CORE); core_api_assembly_out_of_sync = GodotSharpBindings::get_core_api_hash() != api_assembly_ver.godot_api_hash || GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || @@ -593,9 +660,8 @@ bool GDMono::_load_core_api_assembly() { _install_trace_listener(); } -#else - GDMonoUtils::update_godot_api_cache(); -#endif + } else { + core_api_assembly_out_of_sync = false; } return success; @@ -607,68 +673,25 @@ bool GDMono::_load_editor_api_assembly() { if (editor_api_assembly) return true; - if (metadata_is_api_assembly_invalidated(APIAssembly::API_EDITOR)) { - print_verbose("Mono: Skipping loading of Editor API assembly because it was invalidated"); - return false; - } - + // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date String assembly_path = GodotSharpDirs::get_res_assemblies_dir().plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); - - if (!FileAccess::exists(assembly_path)) - return false; - - bool success = load_assembly_from(EDITOR_API_ASSEMBLY_NAME, - assembly_path, - &editor_api_assembly); + bool success = FileAccess::exists(assembly_path) && + load_assembly_from(EDITOR_API_ASSEMBLY_NAME, assembly_path, &editor_api_assembly); if (success) { -#ifdef MONO_GLUE_ENABLED APIAssembly::Version api_assembly_ver = APIAssembly::Version::get_from_loaded_assembly(editor_api_assembly, APIAssembly::API_EDITOR); editor_api_assembly_out_of_sync = GodotSharpBindings::get_editor_api_hash() != api_assembly_ver.godot_api_hash || GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || CS_GLUE_VERSION != api_assembly_ver.cs_glue_version; -#endif - } - - return success; -} -#endif - -#ifdef TOOLS_ENABLED -bool GDMono::_load_editor_tools_assembly() { - - if (editor_tools_assembly) - return true; - - _GDMONO_SCOPE_DOMAIN_(tools_domain) - - return load_assembly(EDITOR_TOOLS_ASSEMBLY_NAME, &editor_tools_assembly); -} -#endif - -bool GDMono::_load_project_assembly() { - - if (project_assembly) - return true; - - String name = ProjectSettings::get_singleton()->get("application/config/name"); - if (name.empty()) { - name = "UnnamedProject"; - } - - bool success = load_assembly(name, &project_assembly); - - if (success) { - mono_assembly_set_main(project_assembly->get_assembly()); } else { - if (OS::get_singleton()->is_stdout_verbose()) - print_error("Mono: Failed to load project assembly"); + editor_api_assembly_out_of_sync = false; } return success; } +#endif -bool GDMono::_load_api_assemblies() { +bool GDMono::_try_load_api_assemblies() { if (!_load_core_api_assembly()) { if (OS::get_singleton()->is_stdout_verbose()) @@ -693,86 +716,106 @@ bool GDMono::_load_api_assemblies() { return true; } -void GDMono::_install_trace_listener() { - -#ifdef DEBUG_ENABLED - // Install the trace listener now before the project assembly is loaded - typedef void (*DebuggingUtils_InstallTraceListener)(MonoObject **); - MonoException *exc = NULL; - GDMonoClass *debug_utils = core_api_assembly->get_class(BINDINGS_NAMESPACE, "DebuggingUtils"); - DebuggingUtils_InstallTraceListener install_func = - (DebuggingUtils_InstallTraceListener)debug_utils->get_method_thunk("InstallTraceListener"); - install_func((MonoObject **)&exc); - if (exc) { - ERR_PRINT("Failed to install System.Diagnostics.Trace listener"); - GDMonoUtils::debug_print_unhandled_exception(exc); - } -#endif -} +void GDMono::_load_api_assemblies() { -#ifdef TOOLS_ENABLED -String GDMono::_get_api_assembly_metadata_path() { + if (!_try_load_api_assemblies()) { + // The API assemblies are out of sync. Fine, try one more time, but this time + // update them from the prebuilt assemblies directory before trying to load them. - return GodotSharpDirs::get_res_metadata_dir().plus_file("api_assemblies.cfg"); -} + // 1. Unload the scripts domain + if (_unload_scripts_domain() != OK) { + ERR_EXPLAIN("Mono: Failed to unload scripts domain"); + CRASH_NOW(); + } -void GDMono::metadata_set_api_assembly_invalidated(APIAssembly::Type p_api_type, bool p_invalidated) { + // 2. Update the API assemblies + String update_error = update_api_assemblies_from_prebuilt(); + if (!update_error.empty()) { + ERR_EXPLAIN(update_error); + CRASH_NOW(); + } - String section = APIAssembly::to_string(p_api_type); - String path = _get_api_assembly_metadata_path(); + // 3. Load the scripts domain again + if (_load_scripts_domain() != OK) { + ERR_EXPLAIN("Mono: Failed to load scripts domain"); + CRASH_NOW(); + } - Ref<ConfigFile> metadata; - metadata.instance(); - metadata->load(path); + // 4. Try loading the updated assemblies + if (!_try_load_api_assemblies()) { + // welp... too bad - metadata->set_value(section, "invalidated", p_invalidated); + if (_are_api_assemblies_out_of_sync()) { + if (core_api_assembly_out_of_sync) { + ERR_PRINT("The assembly '" CORE_API_ASSEMBLY_NAME "' is out of sync"); + } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { + ERR_PRINT("The loaded assembly '" CORE_API_ASSEMBLY_NAME "' is in sync, but the cache update failed"); + } - String assembly_path = GodotSharpDirs::get_res_assemblies_dir() - .plus_file(p_api_type == APIAssembly::API_CORE ? - CORE_API_ASSEMBLY_NAME ".dll" : - EDITOR_API_ASSEMBLY_NAME ".dll"); +#ifdef TOOLS_ENABLED + if (editor_api_assembly_out_of_sync) { + ERR_PRINT("The assembly '" EDITOR_API_ASSEMBLY_NAME "' is out of sync"); + } +#endif - ERR_FAIL_COND(!FileAccess::exists(assembly_path)); + CRASH_NOW(); + } else { + ERR_EXPLAIN("Failed to load one of the API assemblies"); + CRASH_NOW(); + } + } + } +} - uint64_t modified_time = FileAccess::get_modified_time(assembly_path); +#ifdef TOOLS_ENABLED +bool GDMono::_load_tools_assemblies() { - metadata->set_value(section, "invalidated_asm_modified_time", String::num_uint64(modified_time)); + if (tools_assembly && tools_project_editor_assembly) + return true; - String dir = path.get_base_dir(); - if (!DirAccess::exists(dir)) { - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - ERR_FAIL_COND(!da); - Error err = da->make_dir_recursive(ProjectSettings::get_singleton()->globalize_path(dir)); - ERR_FAIL_COND(err != OK); - } + bool success = load_assembly(TOOLS_ASSEMBLY_NAME, &tools_assembly) && + load_assembly(TOOLS_PROJECT_EDITOR_ASSEMBLY_NAME, &tools_project_editor_assembly); - Error save_err = metadata->save(path); - ERR_FAIL_COND(save_err != OK); + return success; } +#endif -bool GDMono::metadata_is_api_assembly_invalidated(APIAssembly::Type p_api_type) { +bool GDMono::_load_project_assembly() { - String section = APIAssembly::to_string(p_api_type); + if (project_assembly) + return true; - Ref<ConfigFile> metadata; - metadata.instance(); - metadata->load(_get_api_assembly_metadata_path()); + String appname = ProjectSettings::get_singleton()->get("application/config/name"); + String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); + if (appname_safe.empty()) { + appname_safe = "UnnamedProject"; + } - String assembly_path = GodotSharpDirs::get_res_assemblies_dir() - .plus_file(p_api_type == APIAssembly::API_CORE ? - CORE_API_ASSEMBLY_NAME ".dll" : - EDITOR_API_ASSEMBLY_NAME ".dll"); + bool success = load_assembly(appname_safe, &project_assembly); - if (!FileAccess::exists(assembly_path)) - return false; + if (success) { + mono_assembly_set_main(project_assembly->get_assembly()); + } - uint64_t modified_time = FileAccess::get_modified_time(assembly_path); + return success; +} - uint64_t stored_modified_time = metadata->get_value(section, "invalidated_asm_modified_time", 0); +void GDMono::_install_trace_listener() { - return metadata->get_value(section, "invalidated", false) && modified_time <= stored_modified_time; -} +#ifdef DEBUG_ENABLED + // Install the trace listener now before the project assembly is loaded + typedef void (*DebuggingUtils_InstallTraceListener)(MonoObject **); + MonoException *exc = NULL; + GDMonoClass *debug_utils = core_api_assembly->get_class(BINDINGS_NAMESPACE, "DebuggingUtils"); + DebuggingUtils_InstallTraceListener install_func = + (DebuggingUtils_InstallTraceListener)debug_utils->get_method_thunk("InstallTraceListener"); + install_func((MonoObject **)&exc); + if (exc) { + ERR_PRINT("Failed to install System.Diagnostics.Trace listener"); + GDMonoUtils::debug_print_unhandled_exception(exc); + } #endif +} Error GDMono::_load_scripts_domain() { @@ -817,11 +860,8 @@ Error GDMono::_unload_scripts_domain() { project_assembly = NULL; #ifdef TOOLS_ENABLED editor_api_assembly = NULL; -#endif - - core_api_assembly_out_of_sync = false; -#ifdef TOOLS_ENABLED - editor_api_assembly_out_of_sync = false; + tools_assembly = NULL; + tools_project_editor_assembly = NULL; #endif MonoDomain *domain = scripts_domain; @@ -839,22 +879,6 @@ Error GDMono::_unload_scripts_domain() { return OK; } -#ifdef TOOLS_ENABLED -Error GDMono::_load_tools_domain() { - - ERR_FAIL_COND_V(tools_domain != NULL, ERR_BUG); - - print_verbose("Mono: Loading tools domain..."); - - tools_domain = GDMonoUtils::create_domain("GodotEngine.ToolsDomain"); - - ERR_EXPLAIN("Mono: Could not create tools app domain"); - ERR_FAIL_NULL_V(tools_domain, ERR_CANT_CREATE); - - return OK; -} -#endif - #ifdef GD_MONO_HOT_RELOAD Error GDMono::reload_scripts_domain() { @@ -876,52 +900,25 @@ Error GDMono::reload_scripts_domain() { return err; } -#ifdef MONO_GLUE_ENABLED - if (!_load_api_assemblies()) { - if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)) -#ifdef TOOLS_ENABLED - || (editor_api_assembly && editor_api_assembly_out_of_sync) -#endif - ) { -#ifdef TOOLS_ENABLED - // The assembly was successfully loaded, but the full api could not be cached. - // This is most likely an outdated assembly loaded because of an invalid version in the - // metadata, so we invalidate the version in the metadata and unload the script domain. - - if (core_api_assembly_out_of_sync) { - ERR_PRINT(OUT_OF_SYNC_ERR_MESSAGE(CORE_API_ASSEMBLY_NAME)); - metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); - } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { - ERR_PRINT("The loaded Core API assembly is in sync, but the cache update failed"); - metadata_set_api_assembly_invalidated(APIAssembly::API_CORE, true); - } + // Load assemblies. The API and tools assemblies are required, + // the application is aborted if these assemblies cannot be loaded. - if (editor_api_assembly_out_of_sync) { - ERR_PRINT(OUT_OF_SYNC_ERR_MESSAGE(EDITOR_API_ASSEMBLY_NAME)); - metadata_set_api_assembly_invalidated(APIAssembly::API_EDITOR, true); - } - - err = _unload_scripts_domain(); - if (err != OK) { - WARN_PRINT("Mono: Failed to unload scripts domain"); - } + _load_api_assemblies(); - return ERR_CANT_RESOLVE; -#else - ERR_PRINT("The loaded API assembly is invalid"); - CRASH_NOW(); -#endif - } else { - return ERR_CANT_OPEN; - } +#if defined(TOOLS_ENABLED) + if (!_load_tools_assemblies()) { + ERR_EXPLAIN("Mono: Failed to load GodotTools assemblies"); + CRASH_NOW(); } +#endif + // Load the project's main assembly. Here, during hot-reloading, we do + // consider failing to load the project's main assembly to be an error. + // However, unlike the API and tools assemblies, the application can continue working. if (!_load_project_assembly()) { + print_error("Mono: Failed to load project assembly"); return ERR_CANT_OPEN; } -#else - print_verbose("Mono: Glue disabled, ignoring script assemblies."); -#endif // MONO_GLUE_ENABLED return OK; } @@ -930,7 +927,7 @@ Error GDMono::reload_scripts_domain() { Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) { CRASH_COND(p_domain == NULL); - CRASH_COND(p_domain == SCRIPTS_DOMAIN); // Should use _unload_scripts_domain() instead + CRASH_COND(p_domain == GDMono::get_singleton()->get_scripts_domain()); // Should use _unload_scripts_domain() instead String domain_name = mono_domain_get_friendly_name(p_domain); @@ -947,18 +944,12 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) { _domain_assemblies_cleanup(mono_domain_get_id(p_domain)); -#ifdef TOOLS_ENABLED - if (p_domain == tools_domain) { - editor_tools_assembly = NULL; - } -#endif - MonoException *exc = NULL; mono_domain_try_unload(p_domain, (MonoObject **)&exc); if (exc) { ERR_PRINTS("Exception thrown when unloading domain `" + domain_name + "`"); - GDMonoUtils::debug_unhandled_exception(exc); + GDMonoUtils::debug_print_unhandled_exception(exc); return FAILED; } @@ -989,6 +980,22 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) { return NULL; } +GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &p_name) { + + uint32_t domain_id = mono_domain_get_id(mono_domain_get()); + HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id]; + + const String *k = NULL; + while ((k = domain_assemblies.next(k))) { + GDMonoAssembly *assembly = domain_assemblies.get(*k); + GDMonoClass *klass = assembly->get_class(p_namespace, p_name); + if (klass) + return klass; + } + + return NULL; +} + void GDMono::_domain_assemblies_cleanup(uint32_t p_domain_id) { HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id]; @@ -1029,9 +1036,6 @@ GDMono::GDMono() { root_domain = NULL; scripts_domain = NULL; -#ifdef TOOLS_ENABLED - tools_domain = NULL; -#endif core_api_assembly_out_of_sync = false; #ifdef TOOLS_ENABLED @@ -1043,7 +1047,8 @@ GDMono::GDMono() { project_assembly = NULL; #ifdef TOOLS_ENABLED editor_api_assembly = NULL; - editor_tools_assembly = NULL; + tools_assembly = NULL; + tools_project_editor_assembly = NULL; #endif api_core_hash = 0; @@ -1055,16 +1060,6 @@ GDMono::GDMono() { GDMono::~GDMono() { if (is_runtime_initialized()) { - -#ifdef TOOLS_ENABLED - if (tools_domain) { - Error err = finalize_and_unload_domain(tools_domain); - if (err != OK) { - ERR_PRINT("Mono: Failed to unload tools domain"); - } - } -#endif - if (scripts_domain) { Error err = _unload_scripts_domain(); if (err != OK) { @@ -1119,14 +1114,14 @@ int32_t _GodotSharp::get_domain_id() { int32_t _GodotSharp::get_scripts_domain_id() { - MonoDomain *domain = SCRIPTS_DOMAIN; + MonoDomain *domain = GDMono::get_singleton()->get_scripts_domain(); CRASH_COND(!domain); // User must check if scripts domain is loaded before calling this method return mono_domain_get_id(domain); } bool _GodotSharp::is_scripts_domain_loaded() { - return GDMono::get_singleton()->is_runtime_initialized() && SCRIPTS_DOMAIN != NULL; + return GDMono::get_singleton()->is_runtime_initialized() && GDMono::get_singleton()->get_scripts_domain() != NULL; } bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) { @@ -1148,7 +1143,7 @@ bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) { if (!p_domain) return true; - if (p_domain == SCRIPTS_DOMAIN && GDMono::get_singleton()->is_finalizing_scripts_domain()) + if (p_domain == GDMono::get_singleton()->get_scripts_domain() && GDMono::get_singleton()->is_finalizing_scripts_domain()) return true; return mono_domain_is_unloading(p_domain); } @@ -1163,6 +1158,12 @@ bool _GodotSharp::is_runtime_initialized() { return GDMono::get_singleton()->is_runtime_initialized(); } +void _GodotSharp::_reload_assemblies(bool p_soft_reload) { +#ifdef GD_MONO_HOT_RELOAD + CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload); +#endif +} + void _GodotSharp::_bind_methods() { ClassDB::bind_method(D_METHOD("attach_thread"), &_GodotSharp::attach_thread); @@ -1175,6 +1176,7 @@ void _GodotSharp::_bind_methods() { ClassDB::bind_method(D_METHOD("is_runtime_shutting_down"), &_GodotSharp::is_runtime_shutting_down); ClassDB::bind_method(D_METHOD("is_runtime_initialized"), &_GodotSharp::is_runtime_initialized); + ClassDB::bind_method(D_METHOD("_reload_assemblies"), &_GodotSharp::_reload_assemblies); } _GodotSharp::_GodotSharp() { diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 95340edcca..deebe5fd50 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -78,11 +78,6 @@ struct Version { String to_string(Type p_type); } // namespace APIAssembly -#define SCRIPTS_DOMAIN GDMono::get_singleton()->get_scripts_domain() -#ifdef TOOLS_ENABLED -#define TOOLS_DOMAIN GDMono::get_singleton()->get_tools_domain() -#endif - class GDMono { bool runtime_initialized; @@ -90,9 +85,6 @@ class GDMono { MonoDomain *root_domain; MonoDomain *scripts_domain; -#ifdef TOOLS_ENABLED - MonoDomain *tools_domain; -#endif bool core_api_assembly_out_of_sync; #ifdef TOOLS_ENABLED @@ -104,26 +96,26 @@ class GDMono { GDMonoAssembly *project_assembly; #ifdef TOOLS_ENABLED GDMonoAssembly *editor_api_assembly; - GDMonoAssembly *editor_tools_assembly; + GDMonoAssembly *tools_assembly; + GDMonoAssembly *tools_project_editor_assembly; #endif HashMap<uint32_t, HashMap<String, GDMonoAssembly *> > assemblies; void _domain_assemblies_cleanup(uint32_t p_domain_id); + bool _are_api_assemblies_out_of_sync(); + bool _load_corlib_assembly(); bool _load_core_api_assembly(); #ifdef TOOLS_ENABLED bool _load_editor_api_assembly(); - bool _load_editor_tools_assembly(); + bool _load_tools_assemblies(); #endif bool _load_project_assembly(); - bool _load_api_assemblies(); - -#ifdef TOOLS_ENABLED - String _get_api_assembly_metadata_path(); -#endif + bool _try_load_api_assemblies(); + void _load_api_assemblies(); void _install_trace_listener(); @@ -132,10 +124,6 @@ class GDMono { Error _load_scripts_domain(); Error _unload_scripts_domain(); -#ifdef TOOLS_ENABLED - Error _load_tools_domain(); -#endif - uint64_t api_core_hash; #ifdef TOOLS_ENABLED uint64_t api_editor_hash; @@ -168,8 +156,8 @@ public: #endif #ifdef TOOLS_ENABLED - void metadata_set_api_assembly_invalidated(APIAssembly::Type p_api_type, bool p_invalidated); - bool metadata_is_api_assembly_invalidated(APIAssembly::Type p_api_type); + bool copy_prebuilt_api_assembly(APIAssembly::Type p_api_type); + String update_api_assemblies_from_prebuilt(); #endif static GDMono *get_singleton() { return singleton; } @@ -185,16 +173,14 @@ public: _FORCE_INLINE_ bool is_finalizing_scripts_domain() { return finalizing_scripts_domain; } _FORCE_INLINE_ MonoDomain *get_scripts_domain() { return scripts_domain; } -#ifdef TOOLS_ENABLED - _FORCE_INLINE_ MonoDomain *get_tools_domain() { return tools_domain; } -#endif _FORCE_INLINE_ GDMonoAssembly *get_corlib_assembly() const { return corlib_assembly; } _FORCE_INLINE_ GDMonoAssembly *get_core_api_assembly() const { return core_api_assembly; } _FORCE_INLINE_ GDMonoAssembly *get_project_assembly() const { return project_assembly; } #ifdef TOOLS_ENABLED _FORCE_INLINE_ GDMonoAssembly *get_editor_api_assembly() const { return editor_api_assembly; } - _FORCE_INLINE_ GDMonoAssembly *get_editor_tools_assembly() const { return editor_tools_assembly; } + _FORCE_INLINE_ GDMonoAssembly *get_tools_assembly() const { return tools_assembly; } + _FORCE_INLINE_ GDMonoAssembly *get_tools_project_editor_assembly() const { return tools_project_editor_assembly; } #endif #if defined(WINDOWS_ENABLED) && defined(TOOLS_ENABLED) @@ -202,6 +188,7 @@ public: #endif GDMonoClass *get_class(MonoClass *p_raw_class); + GDMonoClass *get_class(const StringName &p_namespace, const StringName &p_name); #ifdef GD_MONO_HOT_RELOAD Error reload_scripts_domain(); @@ -214,6 +201,7 @@ public: Error finalize_and_unload_domain(MonoDomain *p_domain); void initialize(); + void initialize_load_assemblies(); GDMono(); ~GDMono(); @@ -276,6 +264,8 @@ class _GodotSharp : public Object { List<NodePath *> np_delete_queue; List<RID *> rid_delete_queue; + void _reload_assemblies(bool p_soft_reload); + protected: static _GodotSharp *singleton; static void _bind_methods(); diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index f1f0015ac9..761c7f6fcb 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -67,11 +67,22 @@ void GDMonoAssembly::fill_search_dirs(Vector<String> &r_search_dirs, const Strin r_search_dirs.push_back(GodotSharpDirs::get_res_temp_assemblies_dir()); } - r_search_dirs.push_back(GodotSharpDirs::get_res_assemblies_dir()); + if (p_custom_config.empty()) { + r_search_dirs.push_back(GodotSharpDirs::get_res_assemblies_dir()); + } else { + String api_config = p_custom_config == "Release" ? "Release" : "Debug"; + r_search_dirs.push_back(GodotSharpDirs::get_res_assemblies_base_dir().plus_file(api_config)); + } + + r_search_dirs.push_back(GodotSharpDirs::get_res_assemblies_base_dir()); r_search_dirs.push_back(OS::get_singleton()->get_resource_dir()); r_search_dirs.push_back(OS::get_singleton()->get_executable_path().get_base_dir()); + #ifdef TOOLS_ENABLED r_search_dirs.push_back(GodotSharpDirs::get_data_editor_tools_dir()); + + // For GodotTools to find the api assemblies + r_search_dirs.push_back(GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file("Debug")); #endif } @@ -270,7 +281,18 @@ Error GDMonoAssembly::load(bool p_refonly) { Vector<uint8_t> data = FileAccess::get_file_as_array(path); ERR_FAIL_COND_V(data.empty(), ERR_FILE_CANT_READ); - String image_filename = ProjectSettings::get_singleton()->globalize_path(path); + String image_filename; + +#ifdef ANDROID_ENABLED + if (path.begins_with("res://")) { + image_filename = path.substr(6, path.length()); + } else { + image_filename = ProjectSettings::get_singleton()->globalize_path(path); + } +#else + // FIXME: globalize_path does not work on exported games + image_filename = ProjectSettings::get_singleton()->globalize_path(path); +#endif MonoImageOpenStatus status = MONO_IMAGE_OK; diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index 4342f46109..1c10d3c8eb 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -41,7 +41,7 @@ String GDMonoClass::get_full_name(MonoClass *p_mono_class) { MonoException *exc = NULL; MonoString *str = GDMonoUtils::object_to_string((MonoObject *)type_obj, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return GDMonoMarshal::mono_string_to_godot(str); } @@ -74,16 +74,13 @@ bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const { } GDMonoClass *GDMonoClass::get_parent_class() { + MonoClass *parent_mono_class = mono_class_get_parent(mono_class); + return parent_mono_class ? GDMono::get_singleton()->get_class(parent_mono_class) : NULL; +} - if (assembly) { - MonoClass *parent_mono_class = mono_class_get_parent(mono_class); - - if (parent_mono_class) { - return GDMono::get_singleton()->get_class(parent_mono_class); - } - } - - return NULL; +GDMonoClass *GDMonoClass::get_nesting_class() { + MonoClass *nesting_type = mono_class_get_nesting_type(mono_class); + return nesting_type ? GDMono::get_singleton()->get_class(nesting_type) : NULL; } #ifdef TOOLS_ENABLED diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h index 249422b844..40e1574927 100644 --- a/modules/mono/mono_gd/gd_mono_class.h +++ b/modules/mono/mono_gd/gd_mono_class.h @@ -121,6 +121,7 @@ public: _FORCE_INLINE_ const GDMonoAssembly *get_assembly() const { return assembly; } GDMonoClass *get_parent_class(); + GDMonoClass *get_nesting_class(); #ifdef TOOLS_ENABLED Vector<MonoClassField *> get_enum_fields(); diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 2e79f87625..3999658f93 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -315,7 +315,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ // The order in which we check the following interfaces is very important (dictionaries and generics first) - MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type_class->get_mono_type()); + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); MonoReflectionType *key_reftype, *value_reftype; if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) { @@ -340,9 +340,15 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ } if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); - mono_field_set_value(p_object, mono_field, managed); - break; + if (GDMonoUtils::tools_godot_api_check()) { + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); + mono_field_set_value(p_object, mono_field, managed); + break; + } else { + MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array()); + mono_field_set_value(p_object, mono_field, managed); + break; + } } ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + type_class->get_name()); @@ -450,7 +456,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ } break; case MONO_TYPE_GENERICINST: { - MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type.type_class->get_mono_type()); + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type()); if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Dictionary(), type.type_class); @@ -489,9 +495,15 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ } if (type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); - mono_field_set_value(p_object, mono_field, managed); - break; + if (GDMonoUtils::tools_godot_api_check()) { + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator Array(), CACHED_CLASS(Array)); + mono_field_set_value(p_object, mono_field, managed); + break; + } else { + MonoObject *managed = (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_value.operator Array()); + mono_field_set_value(p_object, mono_field, managed); + break; + } } } break; diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index cb28efb4e5..a84332d4cd 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -74,15 +74,14 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { script_binding.type_name = NATIVE_GDMONOCLASS_NAME(klass); script_binding.wrapper_class = klass; script_binding.gchandle = MonoGCHandle::create_strong(managed); + script_binding.owner = unmanaged; - Reference *kref = Object::cast_to<Reference>(unmanaged); - if (kref) { + if (ref) { // Unsafe refcount increment. The managed instance also counts as a reference. // This way if the unmanaged world has no references to our owner // but the managed instance is alive, the refcount will be 1 instead of 0. // See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr) - - kref->reference(); + ref->reference(); } // The object was just created, no script instance binding should have been attached diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 87157ed233..42102ed835 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -159,7 +159,7 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { // The order in which we check the following interfaces is very important (dictionaries and generics first) - MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type_class->get_mono_type()); + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) { return Variant::DICTIONARY; @@ -179,7 +179,7 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { } break; case MONO_TYPE_GENERICINST: { - MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, p_type.type_class->get_mono_type()); + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { return Variant::DICTIONARY; @@ -217,7 +217,7 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) { bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type) { switch (p_array_type.type_encoding) { case MONO_TYPE_GENERICINST: { - MonoReflectionType *array_reftype = mono_type_get_object(SCRIPTS_DOMAIN, p_array_type.type_class->get_mono_type()); + MonoReflectionType *array_reftype = mono_type_get_object(mono_domain_get(), p_array_type.type_class->get_mono_type()); if (GDMonoUtils::Marshal::type_is_generic_array(array_reftype)) { MonoReflectionType *elem_reftype; @@ -244,7 +244,7 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_ bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type) { switch (p_dictionary_type.type_encoding) { case MONO_TYPE_GENERICINST: { - MonoReflectionType *dict_reftype = mono_type_get_object(SCRIPTS_DOMAIN, p_dictionary_type.type_class->get_mono_type()); + MonoReflectionType *dict_reftype = mono_type_get_object(mono_domain_get(), p_dictionary_type.type_class->get_mono_type()); if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype)) { MonoReflectionType *key_reftype; @@ -539,7 +539,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty // The order in which we check the following interfaces is very important (dictionaries and generics first) - MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type_class->get_mono_type()); + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); MonoReflectionType *key_reftype, *value_reftype; if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype, &key_reftype, &value_reftype)) { @@ -558,7 +558,11 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty } if (type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); + if (GDMonoUtils::tools_godot_api_check()) { + return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); + } else { + return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array()); + } } } break; case MONO_TYPE_OBJECT: { @@ -652,7 +656,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty } break; case MONO_TYPE_GENERICINST: { - MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, p_type.type_class->get_mono_type()); + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), p_type.type_class->get_mono_type()); if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { return GDMonoUtils::create_managed_from(p_var->operator Dictionary(), p_type.type_class); @@ -681,7 +685,11 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty } if (p_type.type_class->implements_interface(CACHED_CLASS(System_Collections_IEnumerable))) { - return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); + if (GDMonoUtils::tools_godot_api_check()) { + return GDMonoUtils::create_managed_from(p_var->operator Array(), CACHED_CLASS(Array)); + } else { + return (MonoObject *)GDMonoMarshal::Array_to_mono_array(p_var->operator Array()); + } } } break; } break; @@ -831,20 +839,20 @@ Variant mono_object_to_variant(MonoObject *p_obj) { if (CACHED_CLASS(Array) == type_class) { MonoException *exc = NULL; Array *ptr = invoke_method_thunk(CACHED_METHOD_THUNK(Array, GetPtr), p_obj, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return ptr ? Variant(*ptr) : Variant(); } if (CACHED_CLASS(Dictionary) == type_class) { MonoException *exc = NULL; Dictionary *ptr = invoke_method_thunk(CACHED_METHOD_THUNK(Dictionary, GetPtr), p_obj, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return ptr ? Variant(*ptr) : Variant(); } // The order in which we check the following interfaces is very important (dictionaries and generics first) - MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type_class->get_mono_type()); + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type_class->get_mono_type()); if (GDMonoUtils::Marshal::generic_idictionary_is_assignable_from(reftype)) { return GDMonoUtils::Marshal::generic_idictionary_to_dictionary(p_obj); @@ -864,19 +872,19 @@ Variant mono_object_to_variant(MonoObject *p_obj) { } break; case MONO_TYPE_GENERICINST: { - MonoReflectionType *reftype = mono_type_get_object(SCRIPTS_DOMAIN, type.type_class->get_mono_type()); + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), type.type_class->get_mono_type()); if (GDMonoUtils::Marshal::type_is_generic_dictionary(reftype)) { MonoException *exc = NULL; MonoObject *ret = type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return *unbox<Dictionary *>(ret); } if (GDMonoUtils::Marshal::type_is_generic_array(reftype)) { MonoException *exc = NULL; MonoObject *ret = type.type_class->get_method("GetPtr")->invoke(p_obj, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return *unbox<Array *>(ret); } diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 1b32f1126e..5987fa8ebb 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -125,6 +125,7 @@ void MonoCache::clear_godot_api_cache() { class_Array = NULL; class_Dictionary = NULL; class_MarshalUtils = NULL; + class_ISerializationListener = NULL; #ifdef DEBUG_ENABLED class_DebuggingUtils = NULL; @@ -242,6 +243,7 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(Array, GODOT_API_NS_CLAS(BINDINGS_NAMESPACE_COLLECTIONS, Array)); CACHE_CLASS_AND_CHECK(Dictionary, GODOT_API_NS_CLAS(BINDINGS_NAMESPACE_COLLECTIONS, Dictionary)); CACHE_CLASS_AND_CHECK(MarshalUtils, GODOT_API_CLASS(MarshalUtils)); + CACHE_CLASS_AND_CHECK(ISerializationListener, GODOT_API_CLASS(ISerializationListener)); #ifdef DEBUG_ENABLED CACHE_CLASS_AND_CHECK(DebuggingUtils, GODOT_API_CLASS(DebuggingUtils)); @@ -302,7 +304,7 @@ void update_godot_api_cache() { #endif // TODO Move to CSharpLanguage::init() and do handle disposal - MonoObject *task_scheduler = mono_object_new(SCRIPTS_DOMAIN, GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr()); + MonoObject *task_scheduler = mono_object_new(mono_domain_get(), GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr()); GDMonoUtils::runtime_object_init(task_scheduler, GODOT_API_CLASS(GodotTaskScheduler)); mono_cache.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler); @@ -371,7 +373,6 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { // This way if the unmanaged world has no references to our owner // but the managed instance is alive, the refcount will be 1 instead of 0. // See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr) - ref->reference(); } @@ -384,7 +385,7 @@ void set_main_thread(MonoThread *p_thread) { void attach_current_thread() { ERR_FAIL_COND(!GDMono::get_singleton()->is_runtime_initialized()); - MonoThread *mono_thread = mono_thread_attach(SCRIPTS_DOMAIN); + MonoThread *mono_thread = mono_thread_attach(mono_domain_get()); ERR_FAIL_NULL(mono_thread); } @@ -448,17 +449,12 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class) { } MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringName &p_native, Object *p_object) { - String object_type = p_object->get_class_name(); - - if (object_type[0] == '_') - object_type = object_type.substr(1, object_type.length()); - - if (!ClassDB::is_parent_class(object_type, p_native)) { + if (!ClassDB::is_parent_class(p_object->get_class_name(), p_native)) { ERR_EXPLAIN("Type inherits from native type '" + p_native + "', so it can't be instanced in object of type: '" + p_object->get_class() + "'"); ERR_FAIL_V(NULL); } - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, p_class->get_mono_ptr()); + MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); ERR_FAIL_NULL_V(mono_object, NULL); CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, p_object); @@ -470,7 +466,7 @@ MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringNa } MonoObject *create_managed_from(const NodePath &p_from) { - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(NodePath)); + MonoObject *mono_object = mono_object_new(mono_domain_get(), CACHED_CLASS_RAW(NodePath)); ERR_FAIL_NULL_V(mono_object, NULL); // Construct @@ -482,7 +478,7 @@ MonoObject *create_managed_from(const NodePath &p_from) { } MonoObject *create_managed_from(const RID &p_from) { - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(RID)); + MonoObject *mono_object = mono_object_new(mono_domain_get(), CACHED_CLASS_RAW(RID)); ERR_FAIL_NULL_V(mono_object, NULL); // Construct @@ -494,7 +490,7 @@ MonoObject *create_managed_from(const RID &p_from) { } MonoObject *create_managed_from(const Array &p_from, GDMonoClass *p_class) { - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, p_class->get_mono_ptr()); + MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); ERR_FAIL_NULL_V(mono_object, NULL); // Search constructor that takes a pointer as parameter @@ -518,13 +514,13 @@ MonoObject *create_managed_from(const Array &p_from, GDMonoClass *p_class) { MonoException *exc = NULL; GDMonoUtils::runtime_invoke(m, mono_object, args, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return mono_object; } MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class) { - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, p_class->get_mono_ptr()); + MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); ERR_FAIL_NULL_V(mono_object, NULL); // Search constructor that takes a pointer as parameter @@ -548,7 +544,7 @@ MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class) MonoException *exc = NULL; GDMonoUtils::runtime_invoke(m, mono_object, args, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return mono_object; } @@ -667,7 +663,10 @@ void print_unhandled_exception(MonoException *p_exc) { } void set_pending_exception(MonoException *p_exc) { -#ifdef HAS_PENDING_EXCEPTIONS +#ifdef NO_PENDING_EXCEPTIONS + debug_unhandled_exception(p_exc); + GD_UNREACHABLE(); +#else if (get_runtime_invoke_count() == 0) { debug_unhandled_exception(p_exc); GD_UNREACHABLE(); @@ -677,9 +676,6 @@ void set_pending_exception(MonoException *p_exc) { ERR_PRINTS("Exception thrown from managed code, but it could not be set as pending:"); GDMonoUtils::debug_print_unhandled_exception(p_exc); } -#else - debug_unhandled_exception(p_exc); - GD_UNREACHABLE(); #endif } @@ -755,113 +751,137 @@ void dispose(MonoObject *p_mono_object, MonoException **r_exc) { namespace Marshal { -MonoBoolean type_is_generic_array(MonoReflectionType *p_reftype) { +#ifdef MONO_GLUE_ENABLED +#ifdef TOOLS_ENABLED +#define NO_GLUE_RET(m_ret) \ + { \ + if (!mono_cache.godot_api_cache_updated) return m_ret; \ + } +#else +#define NO_GLUE_RET(m_ret) \ + {} +#endif +#else +#define NO_GLUE_RET(m_ret) \ + { return m_ret; } +#endif + +bool type_is_generic_array(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); TypeIsGenericArray thunk = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericArray); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } -MonoBoolean type_is_generic_dictionary(MonoReflectionType *p_reftype) { +bool type_is_generic_dictionary(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); TypeIsGenericDictionary thunk = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericDictionary); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) { ArrayGetElementType thunk = CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType); MonoException *exc = NULL; invoke_method_thunk(thunk, p_array_reftype, r_elem_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); } void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { DictionaryGetKeyValueTypes thunk = CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes); MonoException *exc = NULL; invoke_method_thunk(thunk, p_dict_reftype, r_key_reftype, r_value_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); } -MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype) { +bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); GenericIEnumerableIsAssignableFromType thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } -MonoBoolean generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype) { +bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); GenericIDictionaryIsAssignableFromType thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } -MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) { +bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) { + NO_GLUE_RET(false); GenericIEnumerableIsAssignableFromType_with_info thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, r_elem_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } -MonoBoolean generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { +bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { + NO_GLUE_RET(false); GenericIDictionaryIsAssignableFromType_with_info thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, r_key_reftype, r_value_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } Array enumerable_to_array(MonoObject *p_enumerable) { + NO_GLUE_RET(Array()); Array result; EnumerableToArray thunk = CACHED_METHOD_THUNK(MarshalUtils, EnumerableToArray); MonoException *exc = NULL; invoke_method_thunk(thunk, p_enumerable, &result, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return result; } Dictionary idictionary_to_dictionary(MonoObject *p_idictionary) { + NO_GLUE_RET(Dictionary()); Dictionary result; IDictionaryToDictionary thunk = CACHED_METHOD_THUNK(MarshalUtils, IDictionaryToDictionary); MonoException *exc = NULL; invoke_method_thunk(thunk, p_idictionary, &result, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return result; } Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary) { + NO_GLUE_RET(Dictionary()); Dictionary result; GenericIDictionaryToDictionary thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryToDictionary); MonoException *exc = NULL; invoke_method_thunk(thunk, p_generic_idictionary, &result, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return result; } GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype) { + NO_GLUE_RET(NULL); MakeGenericArrayType thunk = CACHED_METHOD_THUNK(MarshalUtils, MakeGenericArrayType); MonoException *exc = NULL; MonoReflectionType *reftype = invoke_method_thunk(thunk, p_elem_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return GDMono::get_singleton()->get_class(mono_class_from_mono_type(mono_reflection_type_get_type(reftype))); } GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) { + NO_GLUE_RET(NULL); MakeGenericDictionaryType thunk = CACHED_METHOD_THUNK(MarshalUtils, MakeGenericDictionaryType); MonoException *exc = NULL; MonoReflectionType *reftype = invoke_method_thunk(thunk, p_key_reftype, p_value_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return GDMono::get_singleton()->get_class(mono_class_from_mono_type(mono_reflection_type_get_type(reftype))); } } // namespace Marshal -// namespace Marshal - } // namespace GDMonoUtils diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 00e1ffdd31..f535fbb6d0 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -41,7 +41,7 @@ #include "core/object.h" #include "core/reference.h" -#define UNLIKELY_UNHANDLED_EXCEPTION(m_exc) \ +#define UNHANDLED_EXCEPTION(m_exc) \ if (unlikely(m_exc != NULL)) { \ GDMonoUtils::debug_unhandled_exception(m_exc); \ GD_UNREACHABLE(); \ @@ -78,16 +78,16 @@ typedef void (*GenericIDictionaryToDictionary)(MonoObject *, Dictionary *, MonoE namespace Marshal { -MonoBoolean type_is_generic_array(MonoReflectionType *p_reftype); -MonoBoolean type_is_generic_dictionary(MonoReflectionType *p_reftype); +bool type_is_generic_array(MonoReflectionType *p_reftype); +bool type_is_generic_dictionary(MonoReflectionType *p_reftype); void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype); void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype); -MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype); -MonoBoolean generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype); -MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype); -MonoBoolean generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype); +bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype); +bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype); +bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype); +bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype); GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype); GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype); @@ -157,6 +157,7 @@ struct MonoCache { GDMonoClass *class_Array; GDMonoClass *class_Dictionary; GDMonoClass *class_MarshalUtils; + GDMonoClass *class_ISerializationListener; #ifdef DEBUG_ENABLED GDMonoClass *class_DebuggingUtils; @@ -235,10 +236,19 @@ void update_godot_api_cache(); inline void clear_corlib_cache() { mono_cache.clear_corlib_cache(); } + inline void clear_godot_api_cache() { mono_cache.clear_godot_api_cache(); } +_FORCE_INLINE_ bool tools_godot_api_check() { +#ifdef TOOLS_ENABLED + return mono_cache.godot_api_cache_updated; +#else + return true; // Assume it's updated if this was called, otherwise it's a bug +#endif +} + _FORCE_INLINE_ void hash_combine(uint32_t &p_hash, const uint32_t &p_with_hash) { p_hash ^= p_with_hash + 0x9e3779b9 + (p_hash << 6) + (p_hash >> 2); } diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp index 0e1739b754..54d73c971f 100644 --- a/modules/mono/signal_awaiter_utils.cpp +++ b/modules/mono/signal_awaiter_utils.cpp @@ -91,7 +91,7 @@ Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argc set_completed(true); int signal_argc = p_argcount - 1; - MonoArray *signal_args = mono_array_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(MonoObject), signal_argc); + MonoArray *signal_args = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), signal_argc); for (int i = 0; i < signal_argc; i++) { MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_args[i]); diff --git a/modules/mono/editor/monodevelop_instance.cpp b/modules/mono/utils/android_utils.cpp index 3caa56d1d0..7dd67e3b8e 100644 --- a/modules/mono/editor/monodevelop_instance.cpp +++ b/modules/mono/utils/android_utils.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* monodevelop_instance.cpp */ +/* android_utils.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,58 +28,41 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "monodevelop_instance.h" +#include "android_utils.h" -#include "../mono_gd/gd_mono.h" -#include "../mono_gd/gd_mono_class.h" +#ifdef __ANDROID__ -void MonoDevelopInstance::execute(const Vector<String> &p_files) { +#include "platform/android/thread_jandroid.h" - _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) +namespace GDMonoUtils { +namespace Android { - ERR_FAIL_NULL(execute_method); - ERR_FAIL_COND(gc_handle.is_null()); +String get_app_native_lib_dir() { + JNIEnv *env = ThreadAndroid::get_env(); - MonoException *exc = NULL; + jclass activityThreadClass = env->FindClass("android/app/ActivityThread"); + jmethodID currentActivityThread = env->GetStaticMethodID(activityThreadClass, "currentActivityThread", "()Landroid/app/ActivityThread;"); + jobject activityThread = env->CallStaticObjectMethod(activityThreadClass, currentActivityThread); + jmethodID getApplication = env->GetMethodID(activityThreadClass, "getApplication", "()Landroid/app/Application;"); + jobject ctx = env->CallObjectMethod(activityThread, getApplication); - Variant files = p_files; - const Variant *args[1] = { &files }; - execute_method->invoke(gc_handle->get_target(), args, &exc); + jmethodID getApplicationInfo = env->GetMethodID(env->GetObjectClass(ctx), "getApplicationInfo", "()Landroid/content/pm/ApplicationInfo;"); + jobject applicationInfo = env->CallObjectMethod(ctx, getApplicationInfo); + jfieldID nativeLibraryDirField = env->GetFieldID(env->GetObjectClass(applicationInfo), "nativeLibraryDir", "Ljava/lang/String;"); + jstring nativeLibraryDir = (jstring)env->GetObjectField(applicationInfo, nativeLibraryDirField); - if (exc) { - GDMonoUtils::debug_print_unhandled_exception(exc); - ERR_FAIL(); - } -} + String result; -void MonoDevelopInstance::execute(const String &p_file) { + const char *const nativeLibraryDir_utf8 = env->GetStringUTFChars(nativeLibraryDir, NULL); + if (nativeLibraryDir_utf8) { + result.parse_utf8(nativeLibraryDir_utf8); + env->ReleaseStringUTFChars(nativeLibraryDir, nativeLibraryDir_utf8); + } - Vector<String> files; - files.push_back(p_file); - execute(files); + return result; } -MonoDevelopInstance::MonoDevelopInstance(const String &p_solution, EditorId p_editor_id) { - - _GDMONO_SCOPE_DOMAIN_(TOOLS_DOMAIN) - - GDMonoClass *klass = GDMono::get_singleton()->get_editor_tools_assembly()->get_class("GodotSharpTools.Editor", "MonoDevelopInstance"); - - MonoObject *obj = mono_object_new(TOOLS_DOMAIN, klass->get_mono_ptr()); +} // namespace Android +} // namespace GDMonoUtils - GDMonoMethod *ctor = klass->get_method(".ctor", 2); - MonoException *exc = NULL; - - Variant solution = p_solution; - Variant editor_id = p_editor_id; - const Variant *args[2] = { &solution, &editor_id }; - ctor->invoke(obj, args, &exc); - - if (exc) { - GDMonoUtils::debug_print_unhandled_exception(exc); - ERR_FAIL(); - } - - gc_handle = MonoGCHandle::create_strong(obj); - execute_method = klass->get_method("Execute", 1); -} +#endif // __ANDROID__ diff --git a/modules/mono/editor/mono_build_info.h b/modules/mono/utils/android_utils.h index b0ae2ed52e..f911c3fdfe 100644 --- a/modules/mono/editor/mono_build_info.h +++ b/modules/mono/utils/android_utils.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* mono_build_info.h */ +/* android_utils.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,28 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef MONO_BUILD_INFO_H -#define MONO_BUILD_INFO_H +#ifndef ANDROID_UTILS_H +#define ANDROID_UTILS_H -#include "core/ustring.h" -#include "core/vector.h" - -struct MonoBuildInfo { +#ifdef __ANDROID__ - struct Hasher { - static uint32_t hash(const MonoBuildInfo &p_key); - }; +#include "core/ustring.h" - String solution; - String configuration; - Vector<String> custom_props; +namespace GDMonoUtils { +namespace Android { - bool operator==(const MonoBuildInfo &p_b) const; +String get_app_native_lib_dir(); - String get_log_dirpath(); +} // namespace Android +} // namespace GDMonoUtils - MonoBuildInfo(); - MonoBuildInfo(const String &p_solution, const String &p_config); -}; +#endif // __ANDROID__ -#endif // MONO_BUILD_INFO_H +#endif // ANDROID_UTILS_H diff --git a/modules/mono/utils/path_utils.cpp b/modules/mono/utils/path_utils.cpp index 6e431f51e7..20863b1afe 100644 --- a/modules/mono/utils/path_utils.cpp +++ b/modules/mono/utils/path_utils.cpp @@ -36,16 +36,21 @@ #include "core/project_settings.h" #ifdef WINDOWS_ENABLED +#include <windows.h> + #define ENV_PATH_SEP ";" #else -#define ENV_PATH_SEP ":" #include <limits.h> +#include <unistd.h> + +#define ENV_PATH_SEP ":" #endif #include <stdlib.h> -String path_which(const String &p_name) { +namespace path { +String find_executable(const String &p_name) { #ifdef WINDOWS_ENABLED Vector<String> exts = OS::get_singleton()->get_environment("PATHEXT").split(ENV_PATH_SEP, false); #endif @@ -55,7 +60,7 @@ String path_which(const String &p_name) { return String(); for (int i = 0; i < env_path.size(); i++) { - String p = path_join(env_path[i], p_name); + String p = path::join(env_path[i], p_name); #ifdef WINDOWS_ENABLED for (int j = 0; j < exts.size(); j++) { @@ -73,42 +78,96 @@ String path_which(const String &p_name) { return String(); } -void fix_path(const String &p_path, String &r_out) { - r_out = p_path.replace("\\", "/"); +String cwd() { +#ifdef WINDOWS_ENABLED + const DWORD expected_size = ::GetCurrentDirectoryW(0, NULL); + + String buffer; + buffer.resize((int)expected_size); + if (::GetCurrentDirectoryW(expected_size, buffer.ptrw()) == 0) + return "."; + + return buffer.simplify_path(); +#else + char buffer[PATH_MAX]; + if (::getcwd(buffer, sizeof(buffer)) == NULL) + return "."; + + String result; + if (result.parse_utf8(buffer)) + return "."; - while (true) { // in case of using 2 or more slash - String compare = r_out.replace("//", "/"); - if (r_out == compare) - break; - else - r_out = compare; + return result.simplify_path(); +#endif +} + +String abspath(const String &p_path) { + if (p_path.is_abs_path()) { + return p_path.simplify_path(); + } else { + return path::join(path::cwd(), p_path).simplify_path(); } } -bool rel_path_to_abs(const String &p_existing_path, String &r_abs_path) { +String realpath(const String &p_path) { #ifdef WINDOWS_ENABLED - CharType ret[_MAX_PATH]; - if (::_wfullpath(ret, p_existing_path.c_str(), _MAX_PATH)) { - String abspath = String(ret).replace("\\", "/"); - int pos = abspath.find(":/"); - if (pos != -1) { - r_abs_path = abspath.substr(pos - 1, abspath.length()); - } else { - r_abs_path = abspath; - } - return true; - } -#else - char *resolved_path = ::realpath(p_existing_path.utf8().get_data(), NULL); - if (resolved_path) { - String retstr; - bool success = !retstr.parse_utf8(resolved_path); - ::free(resolved_path); - if (success) { - r_abs_path = retstr; - return true; - } + // Open file without read/write access + HANDLE hFile = ::CreateFileW(p_path.c_str(), 0, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (hFile == INVALID_HANDLE_VALUE) + return p_path; + + const DWORD expected_size = ::GetFinalPathNameByHandleW(hFile, NULL, 0, FILE_NAME_NORMALIZED); + + if (expected_size == 0) { + ::CloseHandle(hFile); + return p_path; } + + String buffer; + buffer.resize((int)expected_size); + ::GetFinalPathNameByHandleW(hFile, buffer.ptrw(), expected_size, FILE_NAME_NORMALIZED); + + ::CloseHandle(hFile); + return buffer.simplify_path(); +#elif UNIX_ENABLED + char *resolved_path = ::realpath(p_path.utf8().get_data(), NULL); + + if (!resolved_path) + return p_path; + + String result; + bool parse_ok = result.parse_utf8(resolved_path); + ::free(resolved_path); + + if (parse_ok) + return p_path; + + return result.simplify_path(); #endif - return false; } + +String join(const String &p_a, const String &p_b) { + if (p_a.empty()) + return p_b; + + const CharType a_last = p_a[p_a.length() - 1]; + if ((a_last == '/' || a_last == '\\') || + (p_b.size() > 0 && (p_b[0] == '/' || p_b[0] == '\\'))) { + return p_a + p_b; + } + + return p_a + "/" + p_b; +} + +String join(const String &p_a, const String &p_b, const String &p_c) { + return path::join(path::join(p_a, p_b), p_c); +} + +String join(const String &p_a, const String &p_b, const String &p_c, const String &p_d) { + return path::join(path::join(path::join(p_a, p_b), p_c), p_d); +} + +} // namespace path diff --git a/modules/mono/utils/path_utils.h b/modules/mono/utils/path_utils.h index 69edf4deb7..ca25bc09f7 100644 --- a/modules/mono/utils/path_utils.h +++ b/modules/mono/utils/path_utils.h @@ -31,24 +31,32 @@ #ifndef PATH_UTILS_H #define PATH_UTILS_H +#include "core/string_builder.h" #include "core/ustring.h" -_FORCE_INLINE_ String path_join(const String &e1, const String &e2) { - return e1.plus_file(e2); -} +namespace path { -_FORCE_INLINE_ String path_join(const String &e1, const String &e2, const String &e3) { - return e1.plus_file(e2).plus_file(e3); -} +String join(const String &p_a, const String &p_b); +String join(const String &p_a, const String &p_b, const String &p_c); +String join(const String &p_a, const String &p_b, const String &p_c, const String &p_d); -_FORCE_INLINE_ String path_join(const String &e1, const String &e2, const String &e3, const String &e4) { - return e1.plus_file(e2).plus_file(e3).plus_file(e4); -} +String find_executable(const String &p_name); -String path_which(const String &p_name); +/// Returns a normalized absolute path to the current working directory +String cwd(); -void fix_path(const String &p_path, String &r_out); +/** + * Obtains a normalized absolute path to p_path. Symbolic links are + * not resolved. The path p_path might not exist in the file system. + */ +String abspath(const String &p_path); -bool rel_path_to_abs(const String &p_existing_path, String &r_abs_path); +/** + * Obtains a normalized path to p_path with symbolic links resolved. + * The resulting path might be either a relative or an absolute path. + */ +String realpath(const String &p_path); + +} // namespace path #endif // PATH_UTILS_H diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp index 877122985d..2b014c2a45 100644 --- a/modules/mono/utils/string_utils.cpp +++ b/modules/mono/utils/string_utils.cpp @@ -44,7 +44,7 @@ int sfind(const String &p_text, int p_from) { int src_len = 2; int len = p_text.length(); - if (src_len == 0 || len == 0) + if (len == 0) return -1; const CharType *src = p_text.c_str(); diff --git a/modules/opensimplex/doc_classes/NoiseTexture.xml b/modules/opensimplex/doc_classes/NoiseTexture.xml index 4826b6cd2a..4b59a380f5 100644 --- a/modules/opensimplex/doc_classes/NoiseTexture.xml +++ b/modules/opensimplex/doc_classes/NoiseTexture.xml @@ -20,7 +20,7 @@ <member name="height" type="int" setter="set_height" getter="get_height" default="512"> Height of the generated texture. </member> - <member name="noise" type="OpenSimplexNoise" setter="set_noise" getter="get_noise" default="null"> + <member name="noise" type="OpenSimplexNoise" setter="set_noise" getter="get_noise"> The [OpenSimplexNoise] instance used to generate the noise. </member> <member name="seamless" type="bool" setter="set_seamless" getter="get_seamless" default="false"> diff --git a/modules/opus/SCsub b/modules/opus/SCsub index a4a431bab7..1db5b0987e 100644 --- a/modules/opus/SCsub +++ b/modules/opus/SCsub @@ -139,7 +139,7 @@ if env['builtin_opus']: opus_sources_silk = [] if env["platform"] in ["android", "iphone", "javascript"]: - env_opus.Append(CPPFLAGS=["-DFIXED_POINT"]) + env_opus.Append(CPPDEFINES=["FIXED_POINT"]) opus_sources_silk = [ "silk/fixed/LTP_analysis_filter_FIX.c", "silk/fixed/LTP_scale_ctrl_FIX.c", @@ -208,7 +208,7 @@ if env['builtin_opus']: if env['builtin_libogg']: env_opus.Prepend(CPPPATH=["#thirdparty/libogg"]) - env_opus.Append(CPPFLAGS=["-DHAVE_CONFIG_H"]) + env_opus.Append(CPPDEFINES=["HAVE_CONFIG_H"]) thirdparty_include_paths = [ "", @@ -222,14 +222,14 @@ if env['builtin_opus']: if env["platform"] == "android": if ("android_arch" in env and env["android_arch"] == "armv7"): - env_opus.Append(CPPFLAGS=["-DOPUS_ARM_OPT"]) + env_opus.Append(CPPDEFINES=["OPUS_ARM_OPT"]) elif ("android_arch" in env and env["android_arch"] == "arm64v8"): - env_opus.Append(CPPFLAGS=["-DOPUS_ARM64_OPT"]) + env_opus.Append(CPPDEFINES=["OPUS_ARM64_OPT"]) elif env["platform"] == "iphone": if ("arch" in env and env["arch"] == "arm"): - env_opus.Append(CPPFLAGS=["-DOPUS_ARM_OPT"]) + env_opus.Append(CPPDEFINES=["OPUS_ARM_OPT"]) elif ("arch" in env and env["arch"] == "arm64"): - env_opus.Append(CPPFLAGS=["-DOPUS_ARM64_OPT"]) + env_opus.Append(CPPDEFINES=["OPUS_ARM64_OPT"]) env_thirdparty = env_opus.Clone() env_thirdparty.disable_warnings() diff --git a/modules/opus/audio_stream_opus.cpp b/modules/opus/audio_stream_opus.cpp index 70d0f770d8..615081d818 100644 --- a/modules/opus/audio_stream_opus.cpp +++ b/modules/opus/audio_stream_opus.cpp @@ -280,7 +280,7 @@ int AudioStreamPlaybackOpus::mix(int16_t *p_buffer, int p_frames) { int todo = p_frames; - if (todo == 0 || todo < MIN_MIX) { + if (todo < MIN_MIX) { break; } diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp index 8f6ffcc83f..8b1f21d95d 100644 --- a/modules/pvr/texture_loader_pvr.cpp +++ b/modules/pvr/texture_loader_pvr.cpp @@ -153,7 +153,7 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path, ERR_FAIL_V(RES()); } - w = PoolVector<uint8_t>::Write(); + w.release(); int tex_flags = Texture::FLAG_FILTER | Texture::FLAG_REPEAT; @@ -655,8 +655,8 @@ static void _pvrtc_decompress(Image *p_img) { decompress_pvrtc((PVRTCBlock *)r.ptr(), _2bit, p_img->get_width(), p_img->get_height(), 0, (unsigned char *)w.ptr()); - w = PoolVector<uint8_t>::Write(); - r = PoolVector<uint8_t>::Read(); + w.release(); + r.release(); bool make_mipmaps = p_img->has_mipmaps(); p_img->create(p_img->get_width(), p_img->get_height(), false, Image::FORMAT_RGBA8, newdata); diff --git a/modules/recast/register_types.cpp b/modules/recast/register_types.cpp index 247d7f6144..44129fbb61 100644 --- a/modules/recast/register_types.cpp +++ b/modules/recast/register_types.cpp @@ -40,7 +40,14 @@ void register_recast_types() { #ifdef TOOLS_ENABLED EditorPlugins::add_by_type<NavigationMeshEditorPlugin>(); _nav_mesh_generator = memnew(EditorNavigationMeshGenerator); + + ClassDB::APIType prev_api = ClassDB::get_current_api(); + ClassDB::set_current_api(ClassDB::API_EDITOR); + ClassDB::register_class<EditorNavigationMeshGenerator>(); + + ClassDB::set_current_api(prev_api); + Engine::get_singleton()->add_singleton(Engine::Singleton("NavigationMeshGenerator", EditorNavigationMeshGenerator::get_singleton())); #endif } diff --git a/modules/regex/SCsub b/modules/regex/SCsub index 65f354ffa7..1be5af02a5 100644 --- a/modules/regex/SCsub +++ b/modules/regex/SCsub @@ -9,10 +9,10 @@ if env['builtin_pcre2']: jit_blacklist = ['javascript', 'uwp'] thirdparty_dir = '#thirdparty/pcre2/src/' - thirdparty_flags = ['-DPCRE2_STATIC', '-DHAVE_CONFIG_H'] + thirdparty_flags = ['PCRE2_STATIC', 'HAVE_CONFIG_H'] if 'platform' in env and env['platform'] not in jit_blacklist: - thirdparty_flags.append('-DSUPPORT_JIT') + thirdparty_flags.append('SUPPORT_JIT') thirdparty_sources = [ "pcre2_auto_possess.c", @@ -33,6 +33,7 @@ if env['builtin_pcre2']: "pcre2_newline.c", "pcre2_ord2utf.c", "pcre2_pattern_info.c", + "pcre2_script_run.c", "pcre2_serialize.c", "pcre2_string_utils.c", "pcre2_study.c", @@ -47,17 +48,17 @@ if env['builtin_pcre2']: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_regex.Prepend(CPPPATH=[thirdparty_dir]) - env_regex.Append(CPPFLAGS=thirdparty_flags) + env_regex.Append(CPPDEFINES=thirdparty_flags) def pcre2_builtin(width): env_pcre2 = env_regex.Clone() env_pcre2.disable_warnings() env_pcre2["OBJSUFFIX"] = "_" + width + env_pcre2["OBJSUFFIX"] env_pcre2.add_source_files(env.modules_sources, thirdparty_sources) - env_pcre2.Append(CPPFLAGS=["-DPCRE2_CODE_UNIT_WIDTH=" + width]) + env_pcre2.Append(CPPDEFINES=[("PCRE2_CODE_UNIT_WIDTH", width)]) pcre2_builtin("16") pcre2_builtin("32") -env_regex.Append(CPPFLAGS=["-DPCRE2_CODE_UNIT_WIDTH=0"]) +env_regex.Append(CPPDEFINES=[("PCRE2_CODE_UNIT_WIDTH", 0)]) env_regex.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/regex/doc_classes/RegExMatch.xml b/modules/regex/doc_classes/RegExMatch.xml index e279607d13..6dec9fc516 100644 --- a/modules/regex/doc_classes/RegExMatch.xml +++ b/modules/regex/doc_classes/RegExMatch.xml @@ -48,9 +48,7 @@ </method> </methods> <members> - <member name="names" type="Dictionary" setter="" getter="get_names" default="{ - -}"> + <member name="names" type="Dictionary" setter="" getter="get_names" default="{}"> A dictionary of named groups and its corresponding group number. Only groups with that were matched are included. If multiple groups have the same name, that name would refer to the first matching one. </member> <member name="strings" type="Array" setter="" getter="get_strings" default="[ ]"> diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp index 4f38357aa1..64f4c169cb 100644 --- a/modules/squish/image_compress_squish.cpp +++ b/modules/squish/image_compress_squish.cpp @@ -198,8 +198,8 @@ void image_compress_squish(Image *p_image, float p_lossy_quality, Image::Compres h = MAX(h / 2, 1); } - rb = PoolVector<uint8_t>::Read(); - wb = PoolVector<uint8_t>::Write(); + rb.release(); + wb.release(); p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data); } diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp index b5f4718c72..0922471500 100644 --- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp @@ -188,7 +188,7 @@ void AudioStreamOGGVorbis::set_data(const PoolVector<uint8_t> &p_data) { ogg_stream = stb_vorbis_open_memory((const unsigned char *)src_datar.ptr(), src_data_len, &error, &ogg_alloc); if (!ogg_stream && error == VORBIS_outofmem) { - w = PoolVector<char>::Write(); + w.release(); alloc_try *= 2; } else { diff --git a/modules/svg/SCsub b/modules/svg/SCsub index 90bfe22abb..9324c1634b 100644 --- a/modules/svg/SCsub +++ b/modules/svg/SCsub @@ -16,7 +16,7 @@ env_svg.Prepend(CPPPATH=[thirdparty_dir]) # FIXME: Needed in editor/editor_themes.cpp for now, but ideally there # shouldn't be a dependency on modules/ and its own 3rd party deps. env.Prepend(CPPPATH=[thirdparty_dir]) -env.Append(CPPFLAGS=["-DSVG_ENABLED"]) +env.Append(CPPDEFINES=["SVG_ENABLED"]) env_thirdparty = env_svg.Clone() env_thirdparty.disable_warnings() diff --git a/modules/svg/image_loader_svg.cpp b/modules/svg/image_loader_svg.cpp index e36844a1bc..b0cd648734 100644 --- a/modules/svg/image_loader_svg.cpp +++ b/modules/svg/image_loader_svg.cpp @@ -123,7 +123,7 @@ Error ImageLoaderSVG::_create_image(Ref<Image> p_image, const PoolVector<uint8_t rasterizer.rasterize(svg_image, 0, 0, p_scale * upscale, (unsigned char *)dw.ptr(), w, h, w * 4); - dw = PoolVector<uint8_t>::Write(); + dw.release(); p_image->create(w, h, false, Image::FORMAT_RGBA8, dst_image); if (upsample) p_image->shrink_x2(); diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp index a3c0f5ded7..6ee408d472 100644 --- a/modules/tga/image_loader_tga.cpp +++ b/modules/tga/image_loader_tga.cpp @@ -199,7 +199,7 @@ Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buff } } - image_data_w = PoolVector<uint8_t>::Write(); + image_data_w.release(); p_image->create(width, height, 0, Image::FORMAT_RGBA8, image_data); diff --git a/modules/theora/SCsub b/modules/theora/SCsub index 785eca4c41..ff65d2f8ec 100644 --- a/modules/theora/SCsub +++ b/modules/theora/SCsub @@ -66,7 +66,7 @@ if env['builtin_libtheora']: thirdparty_sources += thirdparty_sources_x86_vc if (env["x86_libtheora_opt_gcc"] or env["x86_libtheora_opt_vc"]): - env_theora.Append(CPPFLAGS=["-DOC_X86_ASM"]) + env_theora.Append(CPPDEFINES=["OC_X86_ASM"]) thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp index a9340b1498..74a584821a 100644 --- a/modules/tinyexr/image_loader_tinyexr.cpp +++ b/modules/tinyexr/image_loader_tinyexr.cpp @@ -235,7 +235,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f p_image->create(exr_image.width, exr_image.height, false, format, imgdata); - w = PoolVector<uint8_t>::Write(); + w.release(); FreeEXRHeader(&exr_header); FreeEXRImage(&exr_image); diff --git a/modules/upnp/SCsub b/modules/upnp/SCsub index ec1d7f44d5..3f56a69594 100644 --- a/modules/upnp/SCsub +++ b/modules/upnp/SCsub @@ -26,8 +26,8 @@ if env['builtin_miniupnpc']: thirdparty_sources = [thirdparty_dir + "miniupnpc/" + file for file in thirdparty_sources] env_upnp.Prepend(CPPPATH=[thirdparty_dir]) - env_upnp.Append(CPPFLAGS=["-DMINIUPNP_STATICLIB"]) - env_upnp.Append(CPPFLAGS=["-DMINIUPNPC_SET_SOCKET_TIMEOUT"]) + env_upnp.Append(CPPDEFINES=["MINIUPNP_STATICLIB"]) + env_upnp.Append(CPPDEFINES=["MINIUPNPC_SET_SOCKET_TIMEOUT"]) env_thirdparty = env_upnp.Clone() env_thirdparty.disable_warnings() diff --git a/modules/vhacd/SCsub b/modules/vhacd/SCsub index 161aed2eb9..e581fb7bb2 100644 --- a/modules/vhacd/SCsub +++ b/modules/vhacd/SCsub @@ -10,22 +10,21 @@ env_vhacd = env_modules.Clone() thirdparty_dir = "#thirdparty/vhacd/" thirdparty_sources = [ -"src/vhacdManifoldMesh.cpp", -"src/FloatMath.cpp", -"src/vhacdMesh.cpp", -"src/vhacdICHull.cpp", -"src/vhacdVolume.cpp", -"src/VHACD-ASYNC.cpp", -"src/btAlignedAllocator.cpp", -"src/vhacdRaycastMesh.cpp", -"src/VHACD.cpp", -"src/btConvexHullComputer.cpp" + "src/vhacdManifoldMesh.cpp", + "src/FloatMath.cpp", + "src/vhacdMesh.cpp", + "src/vhacdICHull.cpp", + "src/vhacdVolume.cpp", + "src/VHACD-ASYNC.cpp", + "src/btAlignedAllocator.cpp", + "src/vhacdRaycastMesh.cpp", + "src/VHACD.cpp", + "src/btConvexHullComputer.cpp" ] thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_vhacd.Prepend(CPPPATH=[thirdparty_dir + "/inc"]) -env_vhacd.Append(CPPFLAGS=["-DGODOT_ENET"]) # upstream uses c++11 if not env.msvc: diff --git a/modules/visual_script/doc_classes/VisualScriptPreload.xml b/modules/visual_script/doc_classes/VisualScriptPreload.xml index 05ed0ad1e5..b3b39691c9 100644 --- a/modules/visual_script/doc_classes/VisualScriptPreload.xml +++ b/modules/visual_script/doc_classes/VisualScriptPreload.xml @@ -15,7 +15,7 @@ <methods> </methods> <members> - <member name="resource" type="Resource" setter="set_preload" getter="get_preload" default="null"> + <member name="resource" type="Resource" setter="set_preload" getter="get_preload"> The [Resource] to load. </member> </members> diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index df5bb9ca2e..b816e37936 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -1487,7 +1487,7 @@ Variant VisualScriptInstance::_call_internal(const StringName &p_method, void *p Variant **output_args = (Variant **)(input_args + max_input_args); int flow_max = f->flow_stack_size; int *flow_stack = flow_max ? (int *)(output_args + max_output_args) : (int *)NULL; - int *pass_stack = flow_stack + flow_max; + int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)NULL; String error_str; @@ -1905,7 +1905,7 @@ Variant VisualScriptInstance::call(const StringName &p_method, const Variant **p Variant **output_args = (Variant **)(input_args + max_input_args); int flow_max = f->flow_stack_size; int *flow_stack = flow_max ? (int *)(output_args + max_output_args) : (int *)NULL; - int *pass_stack = flow_stack + flow_max; + int *pass_stack = flow_stack ? (int *)(flow_stack + flow_max) : (int *)NULL; for (int i = 0; i < f->node_count; i++) { sequence_bits[i] = false; //all starts as false diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp index 4579644d49..31d5e4665a 100644 --- a/modules/visual_script/visual_script_editor.cpp +++ b/modules/visual_script/visual_script_editor.cpp @@ -341,74 +341,74 @@ static Color _color_from_type(Variant::Type p_type, bool dark_theme = true) { Color color; if (dark_theme) switch (p_type) { - case Variant::NIL: color = Color::html("#69ecbd"); break; - - case Variant::BOOL: color = Color::html("#8da6f0"); break; - case Variant::INT: color = Color::html("#7dc6ef"); break; - case Variant::REAL: color = Color::html("#61daf4"); break; - case Variant::STRING: color = Color::html("#6ba7ec"); break; - - case Variant::VECTOR2: color = Color::html("#bd91f1"); break; - case Variant::RECT2: color = Color::html("#f191a5"); break; - case Variant::VECTOR3: color = Color::html("#d67dee"); break; - case Variant::TRANSFORM2D: color = Color::html("#c4ec69"); break; - case Variant::PLANE: color = Color::html("#f77070"); break; - case Variant::QUAT: color = Color::html("#ec69a3"); break; - case Variant::AABB: color = Color::html("#ee7991"); break; - case Variant::BASIS: color = Color::html("#e3ec69"); break; - case Variant::TRANSFORM: color = Color::html("#f6a86e"); break; - - case Variant::COLOR: color = Color::html("#9dff70"); break; - case Variant::NODE_PATH: color = Color::html("#6993ec"); break; - case Variant::_RID: color = Color::html("#69ec9a"); break; - case Variant::OBJECT: color = Color::html("#79f3e8"); break; - case Variant::DICTIONARY: color = Color::html("#77edb1"); break; - - case Variant::ARRAY: color = Color::html("#e0e0e0"); break; - case Variant::POOL_BYTE_ARRAY: color = Color::html("#aaf4c8"); break; - case Variant::POOL_INT_ARRAY: color = Color::html("#afdcf5"); break; - case Variant::POOL_REAL_ARRAY: color = Color::html("#97e7f8"); break; - case Variant::POOL_STRING_ARRAY: color = Color::html("#9dc4f2"); break; - case Variant::POOL_VECTOR2_ARRAY: color = Color::html("#d1b3f5"); break; - case Variant::POOL_VECTOR3_ARRAY: color = Color::html("#df9bf2"); break; - case Variant::POOL_COLOR_ARRAY: color = Color::html("#e9ff97"); break; + case Variant::NIL: color = Color(0.41, 0.93, 0.74); break; + + case Variant::BOOL: color = Color(0.55, 0.65, 0.94); break; + case Variant::INT: color = Color(0.49, 0.78, 0.94); break; + case Variant::REAL: color = Color(0.38, 0.85, 0.96); break; + case Variant::STRING: color = Color(0.42, 0.65, 0.93); break; + + case Variant::VECTOR2: color = Color(0.74, 0.57, 0.95); break; + case Variant::RECT2: color = Color(0.95, 0.57, 0.65); break; + case Variant::VECTOR3: color = Color(0.84, 0.49, 0.93); break; + case Variant::TRANSFORM2D: color = Color(0.77, 0.93, 0.41); break; + case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break; + case Variant::QUAT: color = Color(0.93, 0.41, 0.64); break; + case Variant::AABB: color = Color(0.93, 0.47, 0.57); break; + case Variant::BASIS: color = Color(0.89, 0.93, 0.41); break; + case Variant::TRANSFORM: color = Color(0.96, 0.66, 0.43); break; + + case Variant::COLOR: color = Color(0.62, 1.0, 0.44); break; + case Variant::NODE_PATH: color = Color(0.41, 0.58, 0.93); break; + case Variant::_RID: color = Color(0.41, 0.93, 0.6); break; + case Variant::OBJECT: color = Color(0.47, 0.95, 0.91); break; + case Variant::DICTIONARY: color = Color(0.47, 0.93, 0.69); break; + + case Variant::ARRAY: color = Color(0.88, 0.88, 0.88); break; + case Variant::POOL_BYTE_ARRAY: color = Color(0.67, 0.96, 0.78); break; + case Variant::POOL_INT_ARRAY: color = Color(0.69, 0.86, 0.96); break; + case Variant::POOL_REAL_ARRAY: color = Color(0.59, 0.91, 0.97); break; + case Variant::POOL_STRING_ARRAY: color = Color(0.62, 0.77, 0.95); break; + case Variant::POOL_VECTOR2_ARRAY: color = Color(0.82, 0.7, 0.96); break; + case Variant::POOL_VECTOR3_ARRAY: color = Color(0.87, 0.61, 0.95); break; + case Variant::POOL_COLOR_ARRAY: color = Color(0.91, 1.0, 0.59); break; default: color.set_hsv(p_type / float(Variant::VARIANT_MAX), 0.7, 0.7); } else switch (p_type) { - case Variant::NIL: color = Color::html("#25e3a0"); break; - - case Variant::BOOL: color = Color::html("#6d8eeb"); break; - case Variant::INT: color = Color::html("#4fb2e9"); break; - case Variant::REAL: color = Color::html("#27ccf0"); break; - case Variant::STRING: color = Color::html("#4690e7"); break; - - case Variant::VECTOR2: color = Color::html("#ad76ee"); break; - case Variant::RECT2: color = Color::html("#ee758e"); break; - case Variant::VECTOR3: color = Color::html("#dc6aed"); break; - case Variant::TRANSFORM2D: color = Color::html("#96ce1a"); break; - case Variant::PLANE: color = Color::html("#f77070"); break; - case Variant::QUAT: color = Color::html("#ec69a3"); break; - case Variant::AABB: color = Color::html("#ee7991"); break; - case Variant::BASIS: color = Color::html("#b2bb19"); break; - case Variant::TRANSFORM: color = Color::html("#f49047"); break; - - case Variant::COLOR: color = Color::html("#3cbf00"); break; - case Variant::NODE_PATH: color = Color::html("#6993ec"); break; - case Variant::_RID: color = Color::html("#2ce573"); break; - case Variant::OBJECT: color = Color::html("#12d5c3"); break; - case Variant::DICTIONARY: color = Color::html("#57e99f"); break; - - case Variant::ARRAY: color = Color::html("#737373"); break; - case Variant::POOL_BYTE_ARRAY: color = Color::html("#61ea98"); break; - case Variant::POOL_INT_ARRAY: color = Color::html("#61baeb"); break; - case Variant::POOL_REAL_ARRAY: color = Color::html("#40d3f2"); break; - case Variant::POOL_STRING_ARRAY: color = Color::html("#609fea"); break; - case Variant::POOL_VECTOR2_ARRAY: color = Color::html("#9d5dea"); break; - case Variant::POOL_VECTOR3_ARRAY: color = Color::html("#ca5aea"); break; - case Variant::POOL_COLOR_ARRAY: color = Color::html("#92ba00"); break; + case Variant::NIL: color = Color(0.15, 0.89, 0.63); break; + + case Variant::BOOL: color = Color(0.43, 0.56, 0.92); break; + case Variant::INT: color = Color(0.31, 0.7, 0.91); break; + case Variant::REAL: color = Color(0.15, 0.8, 0.94); break; + case Variant::STRING: color = Color(0.27, 0.56, 0.91); break; + + case Variant::VECTOR2: color = Color(0.68, 0.46, 0.93); break; + case Variant::RECT2: color = Color(0.93, 0.46, 0.56); break; + case Variant::VECTOR3: color = Color(0.86, 0.42, 0.93); break; + case Variant::TRANSFORM2D: color = Color(0.59, 0.81, 0.1); break; + case Variant::PLANE: color = Color(0.97, 0.44, 0.44); break; + case Variant::QUAT: color = Color(0.93, 0.41, 0.64); break; + case Variant::AABB: color = Color(0.93, 0.47, 0.57); break; + case Variant::BASIS: color = Color(0.7, 0.73, 0.1); break; + case Variant::TRANSFORM: color = Color(0.96, 0.56, 0.28); break; + + case Variant::COLOR: color = Color(0.24, 0.75, 0.0); break; + case Variant::NODE_PATH: color = Color(0.41, 0.58, 0.93); break; + case Variant::_RID: color = Color(0.17, 0.9, 0.45); break; + case Variant::OBJECT: color = Color(0.07, 0.84, 0.76); break; + case Variant::DICTIONARY: color = Color(0.34, 0.91, 0.62); break; + + case Variant::ARRAY: color = Color(0.45, 0.45, 0.45); break; + case Variant::POOL_BYTE_ARRAY: color = Color(0.38, 0.92, 0.6); break; + case Variant::POOL_INT_ARRAY: color = Color(0.38, 0.73, 0.92); break; + case Variant::POOL_REAL_ARRAY: color = Color(0.25, 0.83, 0.95); break; + case Variant::POOL_STRING_ARRAY: color = Color(0.38, 0.62, 0.92); break; + case Variant::POOL_VECTOR2_ARRAY: color = Color(0.62, 0.36, 0.92); break; + case Variant::POOL_VECTOR3_ARRAY: color = Color(0.79, 0.35, 0.92); break; + case Variant::POOL_COLOR_ARRAY: color = Color(0.57, 0.73, 0.0); break; default: color.set_hsv(p_type / float(Variant::VARIANT_MAX), 0.3, 0.3); @@ -3054,19 +3054,19 @@ void VisualScriptEditor::_notification(int p_what) { List<Pair<String, Color> > colors; if (dark_theme) { - colors.push_back(Pair<String, Color>("flow_control", Color::html("#f4f4f4"))); - colors.push_back(Pair<String, Color>("functions", Color::html("#f58581"))); - colors.push_back(Pair<String, Color>("data", Color::html("#80f6cf"))); - colors.push_back(Pair<String, Color>("operators", Color::html("#ab97df"))); - colors.push_back(Pair<String, Color>("custom", Color::html("#80bbf6"))); - colors.push_back(Pair<String, Color>("constants", Color::html("#f680b0"))); + colors.push_back(Pair<String, Color>("flow_control", Color(0.96, 0.96, 0.96))); + colors.push_back(Pair<String, Color>("functions", Color(0.96, 0.52, 0.51))); + colors.push_back(Pair<String, Color>("data", Color(0.5, 0.96, 0.81))); + colors.push_back(Pair<String, Color>("operators", Color(0.67, 0.59, 0.87))); + colors.push_back(Pair<String, Color>("custom", Color(0.5, 0.73, 0.96))); + colors.push_back(Pair<String, Color>("constants", Color(0.96, 0.5, 0.69))); } else { - colors.push_back(Pair<String, Color>("flow_control", Color::html("#424242"))); - colors.push_back(Pair<String, Color>("functions", Color::html("#f26661"))); - colors.push_back(Pair<String, Color>("data", Color::html("#13bb83"))); - colors.push_back(Pair<String, Color>("operators", Color::html("#8265d0"))); - colors.push_back(Pair<String, Color>("custom", Color::html("#4ea0f2"))); - colors.push_back(Pair<String, Color>("constants", Color::html("#f02f7d"))); + colors.push_back(Pair<String, Color>("flow_control", Color(0.26, 0.26, 0.26))); + colors.push_back(Pair<String, Color>("functions", Color(0.95, 0.4, 0.38))); + colors.push_back(Pair<String, Color>("data", Color(0.07, 0.73, 0.51))); + colors.push_back(Pair<String, Color>("operators", Color(0.51, 0.4, 0.82))); + colors.push_back(Pair<String, Color>("custom", Color(0.31, 0.63, 0.95))); + colors.push_back(Pair<String, Color>("constants", Color(0.94, 0.18, 0.49))); } for (List<Pair<String, Color> >::Element *E = colors.front(); E; E = E->next()) { diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp index f8cb6cfa3c..0413bbf303 100644 --- a/modules/visual_script/visual_script_func_nodes.cpp +++ b/modules/visual_script/visual_script_func_nodes.cpp @@ -570,7 +570,6 @@ void VisualScriptFunctionCall::_validate_property(PropertyInfo &property) const Node *bnode = _get_base_node(); if (bnode) { property.hint_string = bnode->get_path(); //convert to loong string - } else { } } } @@ -1035,8 +1034,6 @@ PropertyInfo VisualScriptPropertySet::get_input_value_port_info(int p_idx) const pi.name = (call_mode == CALL_MODE_INSTANCE ? String("instance") : Variant::get_type_name(basic_type).to_lower()); _adjust_input_index(pi); return pi; - } else { - p_idx--; } } @@ -1352,7 +1349,6 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const { Node *bnode = _get_base_node(); if (bnode) { property.hint_string = bnode->get_path(); //convert to loong string - } else { } } } @@ -1794,8 +1790,6 @@ PropertyInfo VisualScriptPropertyGet::get_input_value_port_info(int p_idx) const pi.type = (call_mode == CALL_MODE_INSTANCE ? Variant::OBJECT : basic_type); pi.name = (call_mode == CALL_MODE_INSTANCE ? String("instance") : Variant::get_type_name(basic_type).to_lower()); return pi; - } else { - p_idx--; } } return PropertyInfo(); @@ -2073,7 +2067,6 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const { Node *bnode = _get_base_node(); if (bnode) { property.hint_string = bnode->get_path(); //convert to loong string - } else { } } } diff --git a/modules/visual_script/visual_script_yield_nodes.cpp b/modules/visual_script/visual_script_yield_nodes.cpp index 962560cc96..ebd0f0b3cb 100644 --- a/modules/visual_script/visual_script_yield_nodes.cpp +++ b/modules/visual_script/visual_script_yield_nodes.cpp @@ -431,7 +431,6 @@ void VisualScriptYieldSignal::_validate_property(PropertyInfo &property) const { Node *bnode = _get_base_node(); if (bnode) { property.hint_string = bnode->get_path(); //convert to loong string - } else { } } } diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp index e652abbe6a..2f4a45f108 100644 --- a/modules/vorbis/audio_stream_ogg_vorbis.cpp +++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp @@ -103,7 +103,7 @@ int AudioStreamPlaybackOGGVorbis::mix(int16_t *p_buffer, int p_frames) { int todo = p_frames; - if (todo == 0 || todo < MIN_MIX) { + if (todo < MIN_MIX) { break; } diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub index c76585013c..14fa6c1268 100644 --- a/modules/webm/libvpx/SCsub +++ b/modules/webm/libvpx/SCsub @@ -323,7 +323,7 @@ if webm_cpu_x86: elif cpu_bits == '64': env_libvpx["ASCPU"] = 'X86_64' - env_libvpx.Append(CPPFLAGS=['-DWEBM_X86ASM']) + env_libvpx.Append(CPPDEFINES=['WEBM_X86ASM']) webm_simd_optimizations = True @@ -337,7 +337,7 @@ if webm_cpu_arm: env_libvpx["ASFLAGS"] = '' env_libvpx["ASCOM"] = '$AS $ASFLAGS -o $TARGET $SOURCES' - env_libvpx.Append(CPPFLAGS=['-DWEBM_ARMASM']) + env_libvpx.Append(CPPDEFINES=['WEBM_ARMASM']) webm_simd_optimizations = True diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp index 928a0dcbd3..630c15f140 100644 --- a/modules/webp/image_loader_webp.cpp +++ b/modules/webp/image_loader_webp.cpp @@ -71,7 +71,7 @@ static PoolVector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_q w[3] = 'P'; copymem(&w[4], dst_buff, dst_size); free(dst_buff); - w = PoolVector<uint8_t>::Write(); + w.release(); return dst; } @@ -110,7 +110,7 @@ static Ref<Image> _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) { //ERR_EXPLAIN("Error decoding webp! - "+p_file); ERR_FAIL_COND_V(errdec, Ref<Image>()); - dst_w = PoolVector<uint8_t>::Write(); + dst_w.release(); Ref<Image> img = memnew(Image(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image)); return img; @@ -137,7 +137,7 @@ Error webp_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p } else { errdec = WebPDecodeRGBInto(p_buffer, p_buffer_len, dst_w.ptr(), datasize, 3 * features.width) == NULL; } - dst_w = PoolVector<uint8_t>::Write(); + dst_w.release(); //ERR_EXPLAIN("Error decoding webp!"); ERR_FAIL_COND_V(errdec, ERR_FILE_CORRUPT); @@ -171,8 +171,6 @@ Error ImageLoaderWEBP::load_image(Ref<Image> p_image, FileAccess *f, bool p_forc Error err = webp_load_image_from_buffer(p_image.ptr(), w.ptr(), src_image_len); - w = PoolVector<uint8_t>::Write(); - return err; } diff --git a/modules/websocket/SCsub b/modules/websocket/SCsub index d9e60eb6f1..033169411f 100644 --- a/modules/websocket/SCsub +++ b/modules/websocket/SCsub @@ -5,89 +5,26 @@ Import('env_modules') # Thirdparty source files -env_lws = env_modules.Clone() - -if env['builtin_libwebsockets'] and not env["platform"] == "javascript": # already builtin for javascript - thirdparty_dir = "#thirdparty/libwebsockets/" - helper_dir = "win32helpers/" - thirdparty_sources = [ - - "core/alloc.c", - "core/context.c", - "core/libwebsockets.c", - "core/output.c", - "core/pollfd.c", - "core/service.c", - - "event-libs/poll/poll.c", - - "misc/base64-decode.c", - "misc/lejp.c", - "misc/sha-1.c", - - "roles/h1/ops-h1.c", - "roles/http/header.c", - "roles/http/client/client.c", - "roles/http/client/client-handshake.c", - "roles/http/server/fops-zip.c", - "roles/http/server/lejp-conf.c", - "roles/http/server/parsers.c", - "roles/http/server/server.c", - "roles/listen/ops-listen.c", - "roles/pipe/ops-pipe.c", - "roles/raw/ops-raw.c", - - "roles/ws/client-ws.c", - "roles/ws/client-parser-ws.c", - "roles/ws/ops-ws.c", - "roles/ws/server-ws.c", - - "tls/tls.c", - "tls/tls-client.c", - "tls/tls-server.c", - - "tls/mbedtls/wrapper/library/ssl_cert.c", - "tls/mbedtls/wrapper/library/ssl_pkey.c", - "tls/mbedtls/wrapper/library/ssl_stack.c", - "tls/mbedtls/wrapper/library/ssl_methods.c", - "tls/mbedtls/wrapper/library/ssl_lib.c", - "tls/mbedtls/wrapper/library/ssl_x509.c", - "tls/mbedtls/wrapper/platform/ssl_port.c", - "tls/mbedtls/wrapper/platform/ssl_pm.c", - "tls/mbedtls/lws-genhash.c", - "tls/mbedtls/mbedtls-client.c", - "tls/mbedtls/lws-genrsa.c", - "tls/mbedtls/ssl.c", - "tls/mbedtls/mbedtls-server.c" +env_ws = env_modules.Clone() + +if env['builtin_wslay'] and not env["platform"] == "javascript": # already builtin for javascript + wslay_dir = "#thirdparty/wslay/" + wslay_sources = [ + "wslay_net.c", + "wslay_event.c", + "wslay_queue.c", + "wslay_stack.c", + "wslay_frame.c", ] - - if env["platform"] == "android": # Builtin getifaddrs - thirdparty_sources += ["misc/getifaddrs.c"] - - if env["platform"] == "windows" or env["platform"] == "uwp": # Winsock - thirdparty_sources += ["plat/lws-plat-win.c", helper_dir + "getopt.c", helper_dir + "getopt_long.c", helper_dir + "gettimeofday.c"] - else: # Unix socket - thirdparty_sources += ["plat/lws-plat-unix.c"] - - thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] - - env_lws.Prepend(CPPPATH=[thirdparty_dir]) - - if env['builtin_mbedtls']: - mbedtls_includes = "#thirdparty/mbedtls/include" - env_lws.Prepend(CPPPATH=[mbedtls_includes]) - - wrapper_includes = ["#thirdparty/libwebsockets/tls/mbedtls/wrapper/include/" + inc for inc in ["internal", "openssl", "platform", ""]] - env_lws.Prepend(CPPPATH=wrapper_includes) - + wslay_sources = [wslay_dir + s for s in wslay_sources] + env_ws.Prepend(CPPPATH=[wslay_dir + "includes/"]) + env_ws.Append(CPPDEFINES=["HAVE_CONFIG_H"]) if env["platform"] == "windows" or env["platform"] == "uwp": - env_lws.Prepend(CPPPATH=[thirdparty_dir + helper_dir]) - - if env["platform"] == "uwp": - env_lws.Append(CPPFLAGS=["/DLWS_MINGW_SUPPORT"]) - - env_thirdparty = env_lws.Clone() - env_thirdparty.disable_warnings() - env_thirdparty.add_source_files(env.modules_sources, thirdparty_sources) - -env_lws.add_source_files(env.modules_sources, "*.cpp") + env_ws.Append(CPPDEFINES=["HAVE_WINSOCK2_H"]) + else: + env_ws.Append(CPPDEFINES=["HAVE_NETINET_IN_H"]) + env_wslay = env_ws.Clone() + env_wslay.disable_warnings() + env_wslay.add_source_files(env.modules_sources, wslay_sources) + +env_ws.add_source_files(env.modules_sources, "*.cpp") diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml index 0d425ad1dd..c3baf9de83 100644 --- a/modules/websocket/doc_classes/WebSocketClient.xml +++ b/modules/websocket/doc_classes/WebSocketClient.xml @@ -22,7 +22,7 @@ <argument index="2" name="gd_mp_api" type="bool" default="false"> </argument> <description> - Connects to the given URL requesting one of the given [code]protocols[/code] as sub-protocol. + Connects to the given URL requesting one of the given [code]protocols[/code] as sub-protocol. If the list empty (default), no sub-protocol will be requested. If [code]true[/code] is passed as [code]gd_mp_api[/code], the client will behave like a network peer for the [MultiplayerAPI], connections to non-Godot servers will not work, and [signal data_received] will not be emitted. If [code]false[/code] is passed instead (default), you must call [PacketPeer] functions ([code]put_packet[/code], [code]get_packet[/code], etc.) on the [WebSocketPeer] returned via [code]get_peer(1)[/code] and not on this object directly (e.g. [code]get_peer(1).put_packet(data)[/code]). </description> diff --git a/modules/websocket/doc_classes/WebSocketServer.xml b/modules/websocket/doc_classes/WebSocketServer.xml index 1af5e403e6..63318e5874 100644 --- a/modules/websocket/doc_classes/WebSocketServer.xml +++ b/modules/websocket/doc_classes/WebSocketServer.xml @@ -69,7 +69,7 @@ </argument> <description> Starts listening on the given port. - You can specify the desired subprotocols via the "protocols" array. If the list empty (default), "binary" will be used. + You can specify the desired subprotocols via the "protocols" array. If the list empty (default), no sub-protocol will be requested. If [code]true[/code] is passed as [code]gd_mp_api[/code], the server will behave like a network peer for the [MultiplayerAPI], connections from non-Godot clients will not work, and [signal data_received] will not be emitted. If [code]false[/code] is passed instead (default), you must call [PacketPeer] functions ([code]put_packet[/code], [code]get_packet[/code], etc.), on the [WebSocketPeer] returned via [code]get_peer(id)[/code] to communicate with the peer with given [code]id[/code] (e.g. [code]get_peer(id).get_available_packet_count[/code]). </description> diff --git a/modules/websocket/lws_client.cpp b/modules/websocket/lws_client.cpp deleted file mode 100644 index f139a4ef66..0000000000 --- a/modules/websocket/lws_client.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/*************************************************************************/ -/* lws_client.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 JAVASCRIPT_ENABLED - -#include "lws_client.h" -#include "core/io/ip.h" -#include "core/project_settings.h" -#if defined(LWS_OPENSSL_SUPPORT) -#include "core/io/stream_peer_ssl.h" -#include "tls/mbedtls/wrapper/include/openssl/ssl.h" -#endif - -Error LWSClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) { - - ERR_FAIL_COND_V(context != NULL, FAILED); - - IP_Address addr; - - if (!p_host.is_valid_ip_address()) { - addr = IP::get_singleton()->resolve_hostname(p_host); - } else { - addr = p_host; - } - - ERR_FAIL_COND_V(!addr.is_valid(), ERR_INVALID_PARAMETER); - - // Prepare protocols - _lws_make_protocols(this, &LWSClient::_lws_gd_callback, p_protocols, &_lws_ref); - - // Init lws client - struct lws_context_creation_info info; - struct lws_client_connect_info i; - - memset(&i, 0, sizeof i); - memset(&info, 0, sizeof info); - - info.port = CONTEXT_PORT_NO_LISTEN; - info.protocols = _lws_ref->lws_structs; - info.gid = -1; - info.uid = -1; - //info.ws_ping_pong_interval = 5; - info.user = _lws_ref; -#if defined(LWS_OPENSSL_SUPPORT) - info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; -#endif - context = lws_create_context(&info); - - if (context == NULL) { - _lws_free_ref(_lws_ref); - _lws_ref = NULL; - ERR_EXPLAIN("Unable to create lws context"); - ERR_FAIL_V(FAILED); - } - - i.context = context; - if (p_protocols.size() > 0) - i.protocol = _lws_ref->lws_names; - else - i.protocol = NULL; - - if (p_ssl) { - i.ssl_connection = LCCSCF_USE_SSL; - if (!verify_ssl) - i.ssl_connection |= LCCSCF_ALLOW_SELFSIGNED; - } else { - i.ssl_connection = 0; - } - - // These CharStrings needs to survive till we call lws_client_connect_via_info - CharString addr_ch = ((String)addr).ascii(); - CharString host_ch = p_host.utf8(); - CharString path_ch = p_path.utf8(); - i.address = addr_ch.get_data(); - i.host = host_ch.get_data(); - i.path = path_ch.get_data(); - i.port = p_port; - - lws_client_connect_via_info(&i); - - return OK; -}; - -int LWSClient::get_max_packet_size() const { - return (1 << _out_buf_size) - PROTO_SIZE; -} - -void LWSClient::poll() { - - _lws_poll(); -} - -int LWSClient::_handle_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { - - Ref<LWSPeer> peer = static_cast<Ref<LWSPeer> >(_peer); - LWSPeer::PeerData *peer_data = (LWSPeer::PeerData *)user; - - switch (reason) { -#if defined(LWS_OPENSSL_SUPPORT) - case LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS: { - PoolByteArray arr = StreamPeerSSL::get_project_cert_array(); - if (arr.size() > 0) - SSL_CTX_add_client_CA((SSL_CTX *)user, d2i_X509(NULL, &arr.read()[0], arr.size())); - else if (verify_ssl) - WARN_PRINTS("No CA cert specified in project settings, SSL will not work"); - } break; -#endif - case LWS_CALLBACK_CLIENT_ESTABLISHED: - peer->set_wsi(wsi, _in_buf_size, _in_pkt_size, _out_buf_size, _out_pkt_size); - peer_data->peer_id = 0; - peer_data->force_close = false; - peer_data->clean_close = false; - _on_connect(lws_get_protocol(wsi)->name); - break; - - case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - _on_error(); - destroy_context(); - return -1; // We should close the connection (would probably happen anyway) - - case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: { - int code; - String reason2 = peer->get_close_reason(in, len, code); - peer_data->clean_close = true; - _on_close_request(code, reason2); - return 0; - } - - case LWS_CALLBACK_CLIENT_CLOSED: - peer->close(); - destroy_context(); - _on_disconnect(peer_data->clean_close); - return 0; // We can end here - - case LWS_CALLBACK_CLIENT_RECEIVE: - peer->read_wsi(in, len); - if (peer->get_available_packet_count() > 0) - _on_peer_packet(); - break; - - case LWS_CALLBACK_CLIENT_WRITEABLE: - if (peer_data->force_close) { - peer->send_close_status(wsi); - return -1; - } - - peer->write_wsi(); - break; - - default: - break; - } - - return 0; -} - -Ref<WebSocketPeer> LWSClient::get_peer(int p_peer_id) const { - - return _peer; -} - -NetworkedMultiplayerPeer::ConnectionStatus LWSClient::get_connection_status() const { - - if (context == NULL) - return CONNECTION_DISCONNECTED; - - if (_peer->is_connected_to_host()) - return CONNECTION_CONNECTED; - - return CONNECTION_CONNECTING; -} - -void LWSClient::disconnect_from_host(int p_code, String p_reason) { - - if (context == NULL) - return; - - _peer->close(p_code, p_reason); -}; - -IP_Address LWSClient::get_connected_host() const { - - return IP_Address(); -}; - -uint16_t LWSClient::get_connected_port() const { - - return 1025; -}; - -Error LWSClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) { - ERR_EXPLAIN("Buffers sizes can only be set before listening or connecting"); - ERR_FAIL_COND_V(context != NULL, FAILED); - - _in_buf_size = nearest_shift(p_in_buffer - 1) + 10; - _in_pkt_size = nearest_shift(p_in_packets - 1); - _out_buf_size = nearest_shift(p_out_buffer - 1) + 10; - _out_pkt_size = nearest_shift(p_out_packets - 1); - return OK; -} - -LWSClient::LWSClient() { - _in_buf_size = nearest_shift((int)GLOBAL_GET(WSC_IN_BUF) - 1) + 10; - _in_pkt_size = nearest_shift((int)GLOBAL_GET(WSC_IN_PKT) - 1); - _out_buf_size = nearest_shift((int)GLOBAL_GET(WSC_OUT_BUF) - 1) + 10; - _out_pkt_size = nearest_shift((int)GLOBAL_GET(WSC_OUT_PKT) - 1); - - context = NULL; - _lws_ref = NULL; - _peer = Ref<LWSPeer>(memnew(LWSPeer)); -}; - -LWSClient::~LWSClient() { - - invalidate_lws_ref(); // We do not want any more callback - disconnect_from_host(); - destroy_context(); - _peer = Ref<LWSPeer>(); -}; - -#endif // JAVASCRIPT_ENABLED diff --git a/modules/websocket/lws_helper.cpp b/modules/websocket/lws_helper.cpp deleted file mode 100644 index a652779960..0000000000 --- a/modules/websocket/lws_helper.cpp +++ /dev/null @@ -1,157 +0,0 @@ -/*************************************************************************/ -/* lws_helper.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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(JAVASCRIPT_ENABLED) - -#include "lws_helper.h" - -_LWSRef *_lws_create_ref(void *obj) { - - _LWSRef *out = (_LWSRef *)memalloc(sizeof(_LWSRef)); - out->is_destroying = false; - out->free_context = false; - out->is_polling = false; - out->obj = obj; - out->is_valid = true; - out->lws_structs = NULL; - out->lws_names = NULL; - return out; -} - -void _lws_free_ref(_LWSRef *ref) { - // Free strings and structs - memfree(ref->lws_structs); - memfree(ref->lws_names); - // Free ref - memfree(ref); -} - -bool _lws_destroy(struct lws_context *context, _LWSRef *ref) { - if (context == NULL || ref->is_destroying) - return false; - - if (ref->is_polling) { - ref->free_context = true; - return false; - } - - ref->is_destroying = true; - lws_context_destroy(context); - _lws_free_ref(ref); - return true; -} - -bool _lws_poll(struct lws_context *context, _LWSRef *ref) { - - ERR_FAIL_COND_V(context == NULL, false); - ERR_FAIL_COND_V(ref == NULL, false); - - ref->is_polling = true; - lws_service(context, 0); - ref->is_polling = false; - - if (!ref->free_context) - return false; // Nothing to do - - bool is_valid = ref->is_valid; // Might have been destroyed by poll - - _lws_destroy(context, ref); // Will destroy context and ref - - return is_valid; // If the object should NULL its context and ref -} - -/* - * Prepare the protocol_structs to be fed to context. - * Also prepare the protocol string used by the client. - */ -void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback, PoolVector<String> p_names, _LWSRef **r_lws_ref) { - // The input strings might go away after this call, we need to copy them. - // We will clear them when destroying the context. - int i; - int len = p_names.size(); - size_t data_size = sizeof(struct LWSPeer::PeerData); - PoolVector<String>::Read pnr = p_names.read(); - - // This is a reference connecting the object with lws keep track of status, mallocs, etc. - // Must survive as long the context. - // Must be freed manually when context creation fails. - _LWSRef *ref = _lws_create_ref(p_obj); - - // LWS protocol structs. - ref->lws_structs = (struct lws_protocols *)memalloc(sizeof(struct lws_protocols) * (len + 2)); - memset(ref->lws_structs, 0, sizeof(struct lws_protocols) * (len + 2)); - - CharString strings = p_names.join(",").ascii(); - int str_len = strings.length(); - - // Joined string of protocols, double the size: comma separated first, NULL separated last - ref->lws_names = (char *)memalloc((str_len + 1) * 2); // Plus the terminator - - char *names_ptr = ref->lws_names; - struct lws_protocols *structs_ptr = ref->lws_structs; - - // Comma separated protocols string to be used in client Sec-WebSocket-Protocol header - if (str_len > 0) - copymem(names_ptr, strings.get_data(), str_len); - names_ptr[str_len] = '\0'; // NULL terminator - - // NULL terminated protocol strings to be used in protocol structs - if (str_len > 0) - copymem(&names_ptr[str_len + 1], strings.get_data(), str_len); - names_ptr[(str_len * 2) + 1] = '\0'; // NULL terminator - int pos = str_len + 1; - - // The first protocol is the default for any http request (before upgrade). - // It is also used as the websocket protocol when no subprotocol is specified. - structs_ptr[0].name = "default"; - structs_ptr[0].callback = p_callback; - structs_ptr[0].per_session_data_size = data_size; - structs_ptr[0].rx_buffer_size = LWS_BUF_SIZE; - structs_ptr[0].tx_packet_size = LWS_PACKET_SIZE; - // Add user defined protocols - for (i = 0; i < len; i++) { - structs_ptr[i + 1].name = (const char *)&names_ptr[pos]; - structs_ptr[i + 1].callback = p_callback; - structs_ptr[i + 1].per_session_data_size = data_size; - structs_ptr[i + 1].rx_buffer_size = LWS_BUF_SIZE; - structs_ptr[i + 1].tx_packet_size = LWS_PACKET_SIZE; - pos += pnr[i].ascii().length() + 1; - names_ptr[pos - 1] = '\0'; - } - // Add protocols terminator - structs_ptr[len + 1].name = NULL; - structs_ptr[len + 1].callback = NULL; - structs_ptr[len + 1].per_session_data_size = 0; - structs_ptr[len + 1].rx_buffer_size = 0; - - *r_lws_ref = ref; -} - -#endif diff --git a/modules/websocket/lws_helper.h b/modules/websocket/lws_helper.h deleted file mode 100644 index 265dc4e6ad..0000000000 --- a/modules/websocket/lws_helper.h +++ /dev/null @@ -1,111 +0,0 @@ -/*************************************************************************/ -/* lws_helper.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 LWS_HELPER_H -#define LWS_HELPER_H - -#define LWS_BUF_SIZE 65536 -#define LWS_PACKET_SIZE LWS_BUF_SIZE - -#include "core/io/stream_peer.h" -#include "core/os/os.h" -#include "core/reference.h" -#include "core/ring_buffer.h" -#include "lws_peer.h" - -struct _LWSRef { - bool free_context; - bool is_polling; - bool is_valid; - bool is_destroying; - void *obj; - struct lws_protocols *lws_structs; - char *lws_names; -}; - -_LWSRef *_lws_create_ref(void *obj); -void _lws_free_ref(_LWSRef *ref); -bool _lws_destroy(struct lws_context *context, _LWSRef *ref); -bool _lws_poll(struct lws_context *context, _LWSRef *ref); -void _lws_make_protocols(void *p_obj, lws_callback_function *p_callback, PoolVector<String> p_names, _LWSRef **r_lws_ref); - -/* clang-format off */ -#define LWS_HELPER(CNAME) \ -protected: \ - struct _LWSRef *_lws_ref; \ - struct lws_context *context; \ - bool _keep_servicing; \ - \ - static int _lws_gd_callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { \ - \ - if (wsi == NULL) { \ - return 0; \ - } \ - \ - struct _LWSRef *ref = (struct _LWSRef *)lws_context_user(lws_get_context(wsi)); \ - if (!ref->is_valid) \ - return 0; \ - CNAME *helper = (CNAME *)ref->obj; \ - helper->_keep_servicing = true; \ - return helper->_handle_cb(wsi, reason, user, in, len); \ - } \ - \ - void invalidate_lws_ref() { \ - if (_lws_ref != NULL) \ - _lws_ref->is_valid = false; \ - } \ - \ - void destroy_context() { \ - if (_lws_destroy(context, _lws_ref)) { \ - context = NULL; \ - _lws_ref = NULL; \ - } \ - } \ - \ -public: \ - virtual int _handle_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); \ - \ - void _lws_poll() { \ - ERR_FAIL_COND(context == NULL); \ - do { \ - _keep_servicing = false; \ - if (::_lws_poll(context, _lws_ref)) { \ - context = NULL; \ - _lws_ref = NULL; \ - break; \ - } \ - } while (_keep_servicing); \ - } \ - \ -protected: - -/* clang-format on */ - -#endif // LWS_HELPER_H diff --git a/modules/websocket/lws_peer.cpp b/modules/websocket/lws_peer.cpp deleted file mode 100644 index a7c85450fa..0000000000 --- a/modules/websocket/lws_peer.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/*************************************************************************/ -/* lws_peer.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 JAVASCRIPT_ENABLED - -#include "lws_peer.h" - -#include "core/io/ip.h" - -// Needed for socket_helpers on Android at least. UNIXes has it, just include if not windows -#if !defined(WINDOWS_ENABLED) -#include <netinet/in.h> -#include <sys/socket.h> -#endif - -#include "drivers/unix/net_socket_posix.h" - -void LWSPeer::set_wsi(struct lws *p_wsi, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size, unsigned int p_out_pkt_size) { - ERR_FAIL_COND(wsi != NULL); - - _in_buffer.resize(p_in_pkt_size, p_in_buf_size); - _out_buffer.resize(p_out_pkt_size, p_out_buf_size); - _packet_buffer.resize((1 << MAX(p_in_buf_size, p_out_buf_size)) + LWS_PRE); - wsi = p_wsi; -}; - -void LWSPeer::set_write_mode(WriteMode p_mode) { - write_mode = p_mode; -} - -LWSPeer::WriteMode LWSPeer::get_write_mode() const { - return write_mode; -} - -Error LWSPeer::read_wsi(void *in, size_t len) { - - ERR_FAIL_COND_V(!is_connected_to_host(), FAILED); - - if (lws_is_first_fragment(wsi)) - _in_size = 0; - else if (_in_size == -1) // Trash this frame - return ERR_FILE_CORRUPT; - - Error err = _in_buffer.write_packet((const uint8_t *)in, len, NULL); - - if (err != OK) { - _in_buffer.discard_payload(_in_size); - _in_size = -1; - ERR_FAIL_V(err); - } - - _in_size += len; - - if (lws_is_final_fragment(wsi)) { - uint8_t is_string = lws_frame_is_binary(wsi) ? 0 : 1; - err = _in_buffer.write_packet(NULL, _in_size, &is_string); - if (err != OK) { - _in_buffer.discard_payload(_in_size); - _in_size = -1; - ERR_FAIL_V(err); - } - } - - return OK; -} - -Error LWSPeer::write_wsi() { - - ERR_FAIL_COND_V(!is_connected_to_host(), FAILED); - - PoolVector<uint8_t> tmp; - int count = _out_buffer.packets_left(); - - if (count == 0) - return OK; - - int read = 0; - uint8_t is_string = 0; - PoolVector<uint8_t>::Write rw = _packet_buffer.write(); - _out_buffer.read_packet(&(rw[LWS_PRE]), _packet_buffer.size() - LWS_PRE, &is_string, read); - - enum lws_write_protocol mode = is_string ? LWS_WRITE_TEXT : LWS_WRITE_BINARY; - lws_write(wsi, &(rw[LWS_PRE]), read, mode); - - if (count > 1) - lws_callback_on_writable(wsi); // we want to write more! - - return OK; -} - -Error LWSPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { - - ERR_FAIL_COND_V(!is_connected_to_host(), FAILED); - - uint8_t is_string = write_mode == WRITE_MODE_TEXT; - _out_buffer.write_packet(p_buffer, p_buffer_size, &is_string); - lws_callback_on_writable(wsi); // notify that we want to write - return OK; -}; - -Error LWSPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { - - r_buffer_size = 0; - - ERR_FAIL_COND_V(!is_connected_to_host(), FAILED); - - if (_in_buffer.packets_left() == 0) - return ERR_UNAVAILABLE; - - int read = 0; - PoolVector<uint8_t>::Write rw = _packet_buffer.write(); - _in_buffer.read_packet(rw.ptr(), _packet_buffer.size(), &_is_string, read); - - *r_buffer = rw.ptr(); - r_buffer_size = read; - - return OK; -}; - -int LWSPeer::get_available_packet_count() const { - - if (!is_connected_to_host()) - return 0; - - return _in_buffer.packets_left(); -}; - -bool LWSPeer::was_string_packet() const { - - return _is_string; -}; - -bool LWSPeer::is_connected_to_host() const { - - return wsi != NULL; -}; - -String LWSPeer::get_close_reason(void *in, size_t len, int &r_code) { - String s; - r_code = 0; - if (len < 2) // From docs this should not happen - return s; - - const uint8_t *b = (const uint8_t *)in; - r_code = b[0] << 8 | b[1]; - - if (len > 2) { - const char *utf8 = (const char *)&b[2]; - s.parse_utf8(utf8, len - 2); - } - return s; -} - -void LWSPeer::send_close_status(struct lws *p_wsi) { - if (close_code == -1) - return; - - int len = close_reason.size(); - ERR_FAIL_COND(len > 123); // Maximum allowed reason size in bytes - - lws_close_status code = (lws_close_status)close_code; - unsigned char *reason = len > 0 ? (unsigned char *)close_reason.utf8().ptrw() : NULL; - - lws_close_reason(p_wsi, code, reason, len); - - close_code = -1; - close_reason = ""; -} - -void LWSPeer::close(int p_code, String p_reason) { - if (wsi != NULL) { - close_code = p_code; - close_reason = p_reason; - PeerData *data = ((PeerData *)lws_wsi_user(wsi)); - data->force_close = true; - data->clean_close = true; - lws_callback_on_writable(wsi); // Notify that we want to disconnect - } else { - close_code = -1; - close_reason = ""; - } - wsi = NULL; - _in_buffer.clear(); - _out_buffer.clear(); - _in_size = 0; - _is_string = 0; - _packet_buffer.resize(0); -}; - -IP_Address LWSPeer::get_connected_host() const { - - ERR_FAIL_COND_V(!is_connected_to_host(), IP_Address()); - - IP_Address ip; - uint16_t port = 0; - - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - - int fd = lws_get_socket_fd(wsi); - ERR_FAIL_COND_V(fd == -1, IP_Address()); - - int ret = getpeername(fd, (struct sockaddr *)&addr, &len); - ERR_FAIL_COND_V(ret != 0, IP_Address()); - - NetSocketPosix::_set_ip_port(&addr, ip, port); - - return ip; -}; - -uint16_t LWSPeer::get_connected_port() const { - - ERR_FAIL_COND_V(!is_connected_to_host(), 0); - - IP_Address ip; - uint16_t port = 0; - - struct sockaddr_storage addr; - socklen_t len = sizeof(addr); - - int fd = lws_get_socket_fd(wsi); - ERR_FAIL_COND_V(fd == -1, 0); - - int ret = getpeername(fd, (struct sockaddr *)&addr, &len); - ERR_FAIL_COND_V(ret != 0, 0); - - NetSocketPosix::_set_ip_port(&addr, ip, port); - - return port; -}; - -LWSPeer::LWSPeer() { - wsi = NULL; - write_mode = WRITE_MODE_BINARY; - close(); -}; - -LWSPeer::~LWSPeer() { - - close(); -}; - -#endif // JAVASCRIPT_ENABLED diff --git a/modules/websocket/lws_server.cpp b/modules/websocket/lws_server.cpp deleted file mode 100644 index 482c02dc60..0000000000 --- a/modules/websocket/lws_server.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/*************************************************************************/ -/* lws_server.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 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 JAVASCRIPT_ENABLED - -#include "lws_server.h" -#include "core/os/os.h" -#include "core/project_settings.h" - -Error LWSServer::listen(int p_port, PoolVector<String> p_protocols, bool gd_mp_api) { - - ERR_FAIL_COND_V(context != NULL, FAILED); - - _is_multiplayer = gd_mp_api; - - struct lws_context_creation_info info; - memset(&info, 0, sizeof info); - - // Prepare lws protocol structs - _lws_make_protocols(this, &LWSServer::_lws_gd_callback, p_protocols, &_lws_ref); - - info.port = p_port; - info.user = _lws_ref; - info.protocols = _lws_ref->lws_structs; - info.gid = -1; - info.uid = -1; - //info.ws_ping_pong_interval = 5; - - context = lws_create_context(&info); - - if (context == NULL) { - _lws_free_ref(_lws_ref); - _lws_ref = NULL; - ERR_EXPLAIN("Unable to create LWS context"); - ERR_FAIL_V(FAILED); - } - - return OK; -} - -bool LWSServer::is_listening() const { - return context != NULL; -} - -int LWSServer::get_max_packet_size() const { - return (1 << _out_buf_size) - PROTO_SIZE; -} - -int LWSServer::_handle_cb(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { - - LWSPeer::PeerData *peer_data = (LWSPeer::PeerData *)user; - - switch (reason) { - case LWS_CALLBACK_HTTP: - // no http for now - // closing immediately returning -1; - return -1; - - case LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION: - // check header here? - break; - - case LWS_CALLBACK_ESTABLISHED: { - int32_t id = _gen_unique_id(); - - Ref<LWSPeer> peer = Ref<LWSPeer>(memnew(LWSPeer)); - peer->set_wsi(wsi, _in_buf_size, _in_pkt_size, _out_buf_size, _out_pkt_size); - _peer_map[id] = peer; - - peer_data->peer_id = id; - peer_data->force_close = false; - peer_data->clean_close = false; - _on_connect(id, lws_get_protocol(wsi)->name); - break; - } - - case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: { - if (peer_data == NULL) - return 0; - - int32_t id = peer_data->peer_id; - if (_peer_map.has(id)) { - int code; - Ref<LWSPeer> peer = _peer_map[id]; - String reason2 = peer->get_close_reason(in, len, code); - peer_data->clean_close = true; - _on_close_request(id, code, reason2); - } - return 0; - } - - case LWS_CALLBACK_CLOSED: { - if (peer_data == NULL) - return 0; - int32_t id = peer_data->peer_id; - bool clean = peer_data->clean_close; - if (_peer_map.has(id)) { - _peer_map[id]->close(); - _peer_map.erase(id); - } - _on_disconnect(id, clean); - return 0; // we can end here - } - - case LWS_CALLBACK_RECEIVE: { - int32_t id = peer_data->peer_id; - if (_peer_map.has(id)) { - static_cast<Ref<LWSPeer> >(_peer_map[id])->read_wsi(in, len); - if (_peer_map[id]->get_available_packet_count() > 0) - _on_peer_packet(id); - } - break; - } - - case LWS_CALLBACK_SERVER_WRITEABLE: { - int id = peer_data->peer_id; - if (peer_data->force_close) { - if (_peer_map.has(id)) { - Ref<LWSPeer> peer = _peer_map[id]; - peer->send_close_status(wsi); - } - return -1; - } - - if (_peer_map.has(id)) - static_cast<Ref<LWSPeer> >(_peer_map[id])->write_wsi(); - break; - } - - default: - break; - } - - return 0; -} - -void LWSServer::stop() { - if (context == NULL) - return; - - _peer_map.clear(); - destroy_context(); - context = NULL; -} - -bool LWSServer::has_peer(int p_id) const { - return _peer_map.has(p_id); -} - -Ref<WebSocketPeer> LWSServer::get_peer(int p_id) const { - ERR_FAIL_COND_V(!has_peer(p_id), NULL); - return _peer_map[p_id]; -} - -IP_Address LWSServer::get_peer_address(int p_peer_id) const { - ERR_FAIL_COND_V(!has_peer(p_peer_id), IP_Address()); - - return _peer_map[p_peer_id]->get_connected_host(); -} - -int LWSServer::get_peer_port(int p_peer_id) const { - ERR_FAIL_COND_V(!has_peer(p_peer_id), 0); - - return _peer_map[p_peer_id]->get_connected_port(); -} - -void LWSServer::disconnect_peer(int p_peer_id, int p_code, String p_reason) { - ERR_FAIL_COND(!has_peer(p_peer_id)); - - get_peer(p_peer_id)->close(p_code, p_reason); -} - -Error LWSServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) { - ERR_EXPLAIN("Buffers sizes can only be set before listening or connecting"); - ERR_FAIL_COND_V(context != NULL, FAILED); - - _in_buf_size = nearest_shift(p_in_buffer - 1) + 10; - _in_pkt_size = nearest_shift(p_in_packets - 1); - _out_buf_size = nearest_shift(p_out_buffer - 1) + 10; - _out_pkt_size = nearest_shift(p_out_packets - 1); - return OK; -} - -LWSServer::LWSServer() { - _in_buf_size = nearest_shift((int)GLOBAL_GET(WSS_IN_BUF) - 1) + 10; - _in_pkt_size = nearest_shift((int)GLOBAL_GET(WSS_IN_PKT) - 1); - _out_buf_size = nearest_shift((int)GLOBAL_GET(WSS_OUT_BUF) - 1) + 10; - _out_pkt_size = nearest_shift((int)GLOBAL_GET(WSS_OUT_PKT) - 1); - context = NULL; - _lws_ref = NULL; -} - -LWSServer::~LWSServer() { - invalidate_lws_ref(); // we do not want any more callbacks - stop(); -} - -#endif // JAVASCRIPT_ENABLED diff --git a/modules/websocket/register_types.cpp b/modules/websocket/register_types.cpp index 39bf3de982..1c808f0d5c 100644 --- a/modules/websocket/register_types.cpp +++ b/modules/websocket/register_types.cpp @@ -37,9 +37,8 @@ #include "emws_peer.h" #include "emws_server.h" #else -#include "lws_client.h" -#include "lws_peer.h" -#include "lws_server.h" +#include "wsl_client.h" +#include "wsl_server.h" #endif void register_websocket_types() { @@ -64,9 +63,9 @@ void register_websocket_types() { EMWSClient::make_default(); EMWSServer::make_default(); #else - LWSPeer::make_default(); - LWSClient::make_default(); - LWSServer::make_default(); + WSLPeer::make_default(); + WSLClient::make_default(); + WSLServer::make_default(); #endif ClassDB::register_virtual_class<WebSocketMultiplayerPeer>(); diff --git a/modules/websocket/websocket_multiplayer_peer.cpp b/modules/websocket/websocket_multiplayer_peer.cpp index 23cbf916eb..e24cb850ec 100644 --- a/modules/websocket/websocket_multiplayer_peer.cpp +++ b/modules/websocket/websocket_multiplayer_peer.cpp @@ -191,7 +191,7 @@ void WebSocketMultiplayerPeer::_send_sys(Ref<WebSocketPeer> p_peer, uint8_t p_ty p_peer->put_packet(&(message.read()[0]), message.size()); } -PoolVector<uint8_t> WebSocketMultiplayerPeer::_make_pkt(uint32_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size) { +PoolVector<uint8_t> WebSocketMultiplayerPeer::_make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size) { PoolVector<uint8_t> out; out.resize(PROTO_SIZE + p_data_size); diff --git a/modules/websocket/websocket_multiplayer_peer.h b/modules/websocket/websocket_multiplayer_peer.h index 7fd97a6595..e3ab0784ab 100644 --- a/modules/websocket/websocket_multiplayer_peer.h +++ b/modules/websocket/websocket_multiplayer_peer.h @@ -41,7 +41,7 @@ class WebSocketMultiplayerPeer : public NetworkedMultiplayerPeer { GDCLASS(WebSocketMultiplayerPeer, NetworkedMultiplayerPeer); private: - PoolVector<uint8_t> _make_pkt(uint32_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size); + PoolVector<uint8_t> _make_pkt(uint8_t p_type, int32_t p_from, int32_t p_to, const uint8_t *p_data, uint32_t p_data_size); void _store_pkt(int32_t p_source, int32_t p_dest, const uint8_t *p_data, uint32_t p_data_size); Error _server_relay(int32_t p_from, int32_t p_to, const uint8_t *p_buffer, uint32_t p_buffer_size); diff --git a/modules/websocket/wsl_client.cpp b/modules/websocket/wsl_client.cpp new file mode 100644 index 0000000000..86374e8f80 --- /dev/null +++ b/modules/websocket/wsl_client.cpp @@ -0,0 +1,363 @@ +/*************************************************************************/ +/* wsl_client.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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 JAVASCRIPT_ENABLED + +#include "wsl_client.h" +#include "core/io/ip.h" +#include "core/project_settings.h" + +void WSLClient::_do_handshake() { + if (_requested < _request.size() - 1) { + int sent = 0; + Error err = _connection->put_partial_data(((const uint8_t *)_request.get_data() + _requested), _request.size() - _requested - 1, sent); + // Sending handshake failed + if (err != OK) { + disconnect_from_host(); + _on_error(); + return; + } + _requested += sent; + + } else { + int read = 0; + while (true) { + if (_resp_pos >= WSL_MAX_HEADER_SIZE) { + // Header is too big + disconnect_from_host(); + _on_error(); + ERR_EXPLAIN("Response headers too big"); + ERR_FAIL(); + } + Error err = _connection->get_partial_data(&_resp_buf[_resp_pos], 1, read); + if (err == ERR_FILE_EOF) { + // We got a disconnect. + disconnect_from_host(); + _on_error(); + return; + } else if (err != OK) { + // Got some error. + disconnect_from_host(); + _on_error(); + return; + } else if (read != 1) { + // Busy, wait next poll. + break; + } + // Check "\r\n\r\n" header terminator + char *r = (char *)_resp_buf; + int l = _resp_pos; + if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') { + r[l - 3] = '\0'; + String protocol; + // Response is over, verify headers and create peer. + if (!_verify_headers(protocol)) { + disconnect_from_host(); + _on_error(); + ERR_EXPLAIN("Invalid response headers"); + ERR_FAIL(); + } + // Create peer. + WSLPeer::PeerData *data = memnew(struct WSLPeer::PeerData); + data->obj = this; + data->conn = _connection; + data->is_server = false; + data->id = 1; + _peer->make_context(data, _in_buf_size, _in_pkt_size, _out_buf_size, _out_pkt_size); + _on_connect(protocol); + break; + } + _resp_pos += 1; + } + } +} + +bool WSLClient::_verify_headers(String &r_protocol) { + String s = (char *)_resp_buf; + Vector<String> psa = s.split("\r\n"); + int len = psa.size(); + if (len < 4) { + ERR_EXPLAIN("Not enough response headers."); + ERR_FAIL_V(false); + } + + Vector<String> req = psa[0].split(" ", false); + if (req.size() < 2) { + ERR_EXPLAIN("Invalid protocol or status code."); + ERR_FAIL_V(false); + } + // Wrong protocol + if (req[0] != "HTTP/1.1" || req[1] != "101") { + ERR_EXPLAIN("Invalid protocol or status code."); + ERR_FAIL_V(false); + } + + Map<String, String> headers; + for (int i = 1; i < len; i++) { + Vector<String> header = psa[i].split(":", false, 1); + if (header.size() != 2) { + ERR_EXPLAIN("Invalid header -> " + psa[i]); + ERR_FAIL_V(false); + } + String name = header[0].to_lower(); + String value = header[1].strip_edges(); + if (headers.has(name)) + headers[name] += "," + value; + else + headers[name] = value; + } + +#define _WLS_EXPLAIN(NAME, VALUE) \ + ERR_EXPLAIN("Missing or invalid header '" + String(NAME) + "'. Expected value '" + VALUE + "'"); +#define _WLS_CHECK(NAME, VALUE) \ + _WLS_EXPLAIN(NAME, VALUE); \ + ERR_FAIL_COND_V(!headers.has(NAME) || headers[NAME].to_lower() != VALUE, false); +#define _WLS_CHECK_NC(NAME, VALUE) \ + _WLS_EXPLAIN(NAME, VALUE); \ + ERR_FAIL_COND_V(!headers.has(NAME) || headers[NAME] != VALUE, false); + _WLS_CHECK("connection", "upgrade"); + _WLS_CHECK("upgrade", "websocket"); + _WLS_CHECK_NC("sec-websocket-accept", WSLPeer::compute_key_response(_key)); + if (_protocols.size() == 0) { + // We didn't request a custom protocol + ERR_FAIL_COND_V(headers.has("sec-websocket-protocol"), false); + } else { + ERR_FAIL_COND_V(!headers.has("sec-websocket-protocol"), false); + r_protocol = headers["sec-websocket-protocol"]; + bool valid = false; + for (int i = 0; i < _protocols.size(); i++) { + if (_protocols[i] != r_protocol) + continue; + valid = true; + break; + } + if (!valid) + return false; + } +#undef _WLS_CHECK_NC +#undef _WLS_CHECK +#undef _WLS_EXPLAIN + + return true; +} + +Error WSLClient::connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocols) { + + ERR_FAIL_COND_V(_connection.is_valid(), ERR_ALREADY_IN_USE); + + _peer = Ref<WSLPeer>(memnew(WSLPeer)); + IP_Address addr; + + if (!p_host.is_valid_ip_address()) { + addr = IP::get_singleton()->resolve_hostname(p_host); + } else { + addr = p_host; + } + + ERR_FAIL_COND_V(!addr.is_valid(), ERR_INVALID_PARAMETER); + + String port = ""; + if ((p_port != 80 && !p_ssl) || (p_port != 443 && p_ssl)) { + port = ":" + itos(p_port); + } + + Error err = _tcp->connect_to_host(addr, p_port); + if (err != OK) { + _on_error(); + _tcp->disconnect_from_host(); + return err; + } + _connection = _tcp; + _use_ssl = p_ssl; + _host = p_host; + _protocols = p_protocols; + + _key = WSLPeer::generate_key(); + // TODO custom extra headers (allow overriding this too?) + String request = "GET " + p_path + " HTTP/1.1\r\n"; + request += "Host: " + p_host + port + "\r\n"; + request += "Upgrade: websocket\r\n"; + request += "Connection: Upgrade\r\n"; + request += "Sec-WebSocket-Key: " + _key + "\r\n"; + request += "Sec-WebSocket-Version: 13\r\n"; + if (p_protocols.size() > 0) { + request += "Sec-WebSocket-Protocol: "; + for (int i = 0; i < p_protocols.size(); i++) { + if (i != 0) + request += ","; + request += p_protocols[i]; + } + request += "\r\n"; + } + request += "\r\n"; + _request = request.utf8(); + + return OK; +} + +int WSLClient::get_max_packet_size() const { + return (1 << _out_buf_size) - PROTO_SIZE; +} + +void WSLClient::poll() { + if (_peer->is_connected_to_host()) { + _peer->poll(); + if (!_peer->is_connected_to_host()) { + _on_disconnect(_peer->close_code != -1); + disconnect_from_host(); + } + return; + } + + if (_connection.is_null()) + return; // Not connected. + + switch (_tcp->get_status()) { + case StreamPeerTCP::STATUS_NONE: + // Clean close + _on_error(); + disconnect_from_host(); + break; + case StreamPeerTCP::STATUS_CONNECTED: { + Ref<StreamPeerSSL> ssl; + if (_use_ssl) { + if (_connection == _tcp) { + // Start SSL handshake + ssl = Ref<StreamPeerSSL>(StreamPeerSSL::create()); + ERR_EXPLAIN("SSL is not available in this build"); + ERR_FAIL_COND(ssl.is_null()); + ssl->set_blocking_handshake_enabled(false); + if (ssl->connect_to_stream(_tcp, verify_ssl, _host) != OK) { + _on_error(); + disconnect_from_host(); + return; + } + _connection = ssl; + } else { + ssl = static_cast<Ref<StreamPeerSSL> >(_connection); + ERR_FAIL_COND(ssl.is_null()); // Bug? + ssl->poll(); + } + if (ssl->get_status() == StreamPeerSSL::STATUS_HANDSHAKING) + return; // Need more polling. + else if (ssl->get_status() != StreamPeerSSL::STATUS_CONNECTED) { + _on_error(); + disconnect_from_host(); + return; // Error. + } + } + // Do websocket handshake. + _do_handshake(); + } break; + case StreamPeerTCP::STATUS_ERROR: + _on_error(); + disconnect_from_host(); + break; + case StreamPeerTCP::STATUS_CONNECTING: + break; // Wait for connection + } +} + +Ref<WebSocketPeer> WSLClient::get_peer(int p_peer_id) const { + + ERR_FAIL_COND_V(p_peer_id != 1, NULL); + + return _peer; +} + +NetworkedMultiplayerPeer::ConnectionStatus WSLClient::get_connection_status() const { + + if (_peer->is_connected_to_host()) + return CONNECTION_CONNECTED; + + if (_tcp->is_connected_to_host()) + return CONNECTION_CONNECTING; + + return CONNECTION_DISCONNECTED; +} + +void WSLClient::disconnect_from_host(int p_code, String p_reason) { + + _peer->close(p_code, p_reason); + _connection = Ref<StreamPeer>(NULL); + _tcp = Ref<StreamPeerTCP>(memnew(StreamPeerTCP)); + + _key = ""; + _host = ""; + _protocols.resize(0); + _use_ssl = false; + + _request = ""; + _requested = 0; + + memset(_resp_buf, 0, sizeof(_resp_buf)); + _resp_pos = 0; +} + +IP_Address WSLClient::get_connected_host() const { + + return IP_Address(); +} + +uint16_t WSLClient::get_connected_port() const { + + return 1025; +} + +Error WSLClient::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) { + ERR_EXPLAIN("Buffers sizes can only be set before listening or connecting"); + ERR_FAIL_COND_V(_connection.is_valid(), FAILED); + + _in_buf_size = nearest_shift(p_in_buffer - 1) + 10; + _in_pkt_size = nearest_shift(p_in_packets - 1); + _out_buf_size = nearest_shift(p_out_buffer - 1) + 10; + _out_pkt_size = nearest_shift(p_out_packets - 1); + return OK; +} + +WSLClient::WSLClient() { + _in_buf_size = nearest_shift((int)GLOBAL_GET(WSC_IN_BUF) - 1) + 10; + _in_pkt_size = nearest_shift((int)GLOBAL_GET(WSC_IN_PKT) - 1); + _out_buf_size = nearest_shift((int)GLOBAL_GET(WSC_OUT_BUF) - 1) + 10; + _out_pkt_size = nearest_shift((int)GLOBAL_GET(WSC_OUT_PKT) - 1); + + _peer.instance(); + _tcp.instance(); + disconnect_from_host(); +} + +WSLClient::~WSLClient() { + + _peer->close_now(); + _peer->invalidate(); + disconnect_from_host(); +} + +#endif // JAVASCRIPT_ENABLED diff --git a/modules/websocket/lws_client.h b/modules/websocket/wsl_client.h index df4aabec7f..57dfd635b7 100644 --- a/modules/websocket/lws_client.h +++ b/modules/websocket/wsl_client.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* lws_client.h */ +/* wsl_client.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,21 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef LWSCLIENT_H -#define LWSCLIENT_H +#ifndef WSLCLIENT_H +#define WSLCLIENT_H #ifndef JAVASCRIPT_ENABLED #include "core/error_list.h" -#include "lws_helper.h" -#include "lws_peer.h" +#include "core/io/stream_peer_ssl.h" +#include "core/io/stream_peer_tcp.h" #include "websocket_client.h" +#include "wsl_peer.h" +#include "wslay/wslay.h" -class LWSClient : public WebSocketClient { +class WSLClient : public WebSocketClient { - GDCIIMPL(LWSClient, WebSocketClient); - - LWS_HELPER(LWSClient); + GDCIIMPL(WSLClient, WebSocketClient); private: int _in_buf_size; @@ -50,6 +50,26 @@ private: int _out_buf_size; int _out_pkt_size; + Ref<WSLPeer> _peer; + Ref<StreamPeerTCP> _tcp; + Ref<StreamPeer> _connection; + + CharString _request; + int _requested; + + uint8_t _resp_buf[WSL_MAX_HEADER_SIZE]; + int _resp_pos; + + String _response; + + String _key; + String _host; + PoolVector<String> _protocols; + bool _use_ssl; + + void _do_handshake(); + bool _verify_headers(String &r_protocol); + public: Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets); Error connect_to_host(String p_host, String p_path, uint16_t p_port, bool p_ssl, PoolVector<String> p_protocol = PoolVector<String>()); @@ -61,10 +81,10 @@ public: virtual ConnectionStatus get_connection_status() const; virtual void poll(); - LWSClient(); - ~LWSClient(); + WSLClient(); + ~WSLClient(); }; #endif // JAVASCRIPT_ENABLED -#endif // LWSCLIENT_H +#endif // WSLCLIENT_H diff --git a/modules/websocket/wsl_peer.cpp b/modules/websocket/wsl_peer.cpp new file mode 100644 index 0000000000..b11bd2b70f --- /dev/null +++ b/modules/websocket/wsl_peer.cpp @@ -0,0 +1,339 @@ +/*************************************************************************/ +/* lws_peer.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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 JAVASCRIPT_ENABLED + +#include "wsl_peer.h" + +#include "wsl_client.h" +#include "wsl_server.h" + +#include "core/math/crypto_core.h" +#include "core/math/random_number_generator.h" +#include "core/os/os.h" + +String WSLPeer::generate_key() { + // Random key + RandomNumberGenerator rng; + rng.set_seed(OS::get_singleton()->get_unix_time()); + PoolVector<uint8_t> bkey; + int len = 16; // 16 bytes, as per RFC + bkey.resize(len); + PoolVector<uint8_t>::Write w = bkey.write(); + for (int i = 0; i < len; i++) { + w[i] = (uint8_t)rng.randi_range(0, 255); + } + return CryptoCore::b64_encode_str(&w[0], len); +} + +String WSLPeer::compute_key_response(String p_key) { + String key = p_key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; // Magic UUID as per RFC + Vector<uint8_t> sha = key.sha1_buffer(); + return CryptoCore::b64_encode_str(sha.ptr(), sha.size()); +} + +void WSLPeer::_wsl_destroy(struct PeerData **p_data) { + if (!p_data || !(*p_data)) + return; + struct PeerData *data = *p_data; + if (data->polling) { + data->destroy = true; + return; + } + wslay_event_context_free(data->ctx); + memdelete(data); + *p_data = NULL; +} + +bool WSLPeer::_wsl_poll(struct PeerData *p_data) { + p_data->polling = true; + int err = 0; + if ((err = wslay_event_recv(p_data->ctx)) != 0 || (err = wslay_event_send(p_data->ctx)) != 0) { + print_verbose("Websocket (wslay) poll error: " + itos(err)); + p_data->destroy = true; + } + p_data->polling = false; + + if (p_data->destroy || (wslay_event_get_close_sent(p_data->ctx) && wslay_event_get_close_received(p_data->ctx))) { + bool valid = p_data->valid; + _wsl_destroy(&p_data); + return valid; + } + return false; +} + +ssize_t wsl_recv_callback(wslay_event_context_ptr ctx, uint8_t *data, size_t len, int flags, void *user_data) { + struct WSLPeer::PeerData *peer_data = (struct WSLPeer::PeerData *)user_data; + if (!peer_data->valid) { + wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); + return -1; + } + Ref<StreamPeer> conn = peer_data->conn; + int read = 0; + Error err = conn->get_partial_data(data, len, read); + if (err != OK) { + print_verbose("Websocket get data error: " + itos(err) + ", read (should be 0!): " + itos(read)); + wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); + return -1; + } + if (read == 0) { + wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK); + return -1; + } + return read; +} + +ssize_t wsl_send_callback(wslay_event_context_ptr ctx, const uint8_t *data, size_t len, int flags, void *user_data) { + struct WSLPeer::PeerData *peer_data = (struct WSLPeer::PeerData *)user_data; + if (!peer_data->valid) { + wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); + return -1; + } + Ref<StreamPeer> conn = peer_data->conn; + int sent = 0; + Error err = conn->put_partial_data(data, len, sent); + if (err != OK) { + wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE); + return -1; + } + if (sent == 0) { + wslay_event_set_error(ctx, WSLAY_ERR_WOULDBLOCK); + return -1; + } + return sent; +} + +int wsl_genmask_callback(wslay_event_context_ptr ctx, uint8_t *buf, size_t len, void *user_data) { + RandomNumberGenerator rng; + // TODO maybe use crypto in the future? + rng.set_seed(OS::get_singleton()->get_unix_time()); + for (unsigned int i = 0; i < len; i++) { + buf[i] = (uint8_t)rng.randi_range(0, 255); + } + return 0; +} + +void wsl_msg_recv_callback(wslay_event_context_ptr ctx, const struct wslay_event_on_msg_recv_arg *arg, void *user_data) { + struct WSLPeer::PeerData *peer_data = (struct WSLPeer::PeerData *)user_data; + if (!peer_data->valid) { + return; + } + WSLPeer *peer = (WSLPeer *)peer_data->peer; + + if (peer->parse_message(arg) != OK) + return; + + if (peer_data->is_server) { + WSLServer *helper = (WSLServer *)peer_data->obj; + helper->_on_peer_packet(peer_data->id); + } else { + WSLClient *helper = (WSLClient *)peer_data->obj; + helper->_on_peer_packet(); + } +} + +wslay_event_callbacks wsl_callbacks = { + wsl_recv_callback, + wsl_send_callback, + wsl_genmask_callback, + NULL, /* on_frame_recv_start_callback */ + NULL, /* on_frame_recv_callback */ + NULL, /* on_frame_recv_end_callback */ + wsl_msg_recv_callback +}; + +Error WSLPeer::parse_message(const wslay_event_on_msg_recv_arg *arg) { + uint8_t is_string = 0; + if (arg->opcode == WSLAY_TEXT_FRAME) { + is_string = 1; + } else if (arg->opcode == WSLAY_CONNECTION_CLOSE) { + close_code = arg->status_code; + size_t len = arg->msg_length; + close_reason = ""; + if (len > 2 /* first 2 bytes = close code */) { + close_reason.parse_utf8((char *)arg->msg + 2, len - 2); + } + if (!wslay_event_get_close_sent(_data->ctx)) { + if (_data->is_server) { + WSLServer *helper = (WSLServer *)_data->obj; + helper->_on_close_request(_data->id, close_code, close_reason); + } else { + WSLClient *helper = (WSLClient *)_data->obj; + helper->_on_close_request(close_code, close_reason); + } + } + return ERR_FILE_EOF; + } else if (arg->opcode != WSLAY_BINARY_FRAME) { + // Ping or pong + return ERR_SKIP; + } + _in_buffer.write_packet(arg->msg, arg->msg_length, &is_string); + return OK; +} + +void WSLPeer::make_context(PeerData *p_data, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size, unsigned int p_out_pkt_size) { + ERR_FAIL_COND(_data != NULL); + ERR_FAIL_COND(p_data == NULL); + + _in_buffer.resize(p_in_pkt_size, p_in_buf_size); + _packet_buffer.resize((1 << MAX(p_in_buf_size, p_out_buf_size))); + + _data = p_data; + _data->peer = this; + _data->valid = true; + _connection = Ref<StreamPeer>(_data->conn); + + if (_data->is_server) + wslay_event_context_server_init(&(_data->ctx), &wsl_callbacks, _data); + else + wslay_event_context_client_init(&(_data->ctx), &wsl_callbacks, _data); + wslay_event_config_set_max_recv_msg_length(_data->ctx, (1 << p_in_buf_size)); +} + +void WSLPeer::set_write_mode(WriteMode p_mode) { + write_mode = p_mode; +} + +WSLPeer::WriteMode WSLPeer::get_write_mode() const { + return write_mode; +} + +void WSLPeer::poll() { + if (!_data) + return; + + if (_wsl_poll(_data)) { + _data = NULL; + } +} + +Error WSLPeer::put_packet(const uint8_t *p_buffer, int p_buffer_size) { + + ERR_FAIL_COND_V(!is_connected_to_host(), FAILED); + + struct wslay_event_msg msg; // Should I use fragmented? + msg.opcode = write_mode == WRITE_MODE_TEXT ? WSLAY_TEXT_FRAME : WSLAY_BINARY_FRAME; + msg.msg = p_buffer; + msg.msg_length = p_buffer_size; + + wslay_event_queue_msg(_data->ctx, &msg); + return OK; +} + +Error WSLPeer::get_packet(const uint8_t **r_buffer, int &r_buffer_size) { + + r_buffer_size = 0; + + ERR_FAIL_COND_V(!is_connected_to_host(), FAILED); + + if (_in_buffer.packets_left() == 0) + return ERR_UNAVAILABLE; + + int read = 0; + PoolVector<uint8_t>::Write rw = _packet_buffer.write(); + _in_buffer.read_packet(rw.ptr(), _packet_buffer.size(), &_is_string, read); + + *r_buffer = rw.ptr(); + r_buffer_size = read; + + return OK; +} + +int WSLPeer::get_available_packet_count() const { + + if (!is_connected_to_host()) + return 0; + + return _in_buffer.packets_left(); +} + +bool WSLPeer::was_string_packet() const { + + return _is_string; +} + +bool WSLPeer::is_connected_to_host() const { + + return _data != NULL; +} + +void WSLPeer::close_now() { + close(1000, ""); + _wsl_destroy(&_data); +} + +void WSLPeer::close(int p_code, String p_reason) { + if (_data && !wslay_event_get_close_sent(_data->ctx)) { + CharString cs = p_reason.utf8(); + wslay_event_queue_close(_data->ctx, p_code, (uint8_t *)cs.ptr(), cs.size()); + wslay_event_send(_data->ctx); + } + + _in_buffer.clear(); + _packet_buffer.resize(0); +} + +IP_Address WSLPeer::get_connected_host() const { + + ERR_FAIL_COND_V(!is_connected_to_host(), IP_Address()); + + IP_Address ip; + return ip; +} + +uint16_t WSLPeer::get_connected_port() const { + + ERR_FAIL_COND_V(!is_connected_to_host(), 0); + + uint16_t port = 0; + return port; +} + +void WSLPeer::invalidate() { + if (_data) + _data->valid = false; +} + +WSLPeer::WSLPeer() { + _data = NULL; + _is_string = 0; + close_code = -1; + write_mode = WRITE_MODE_BINARY; +} + +WSLPeer::~WSLPeer() { + + close(); + invalidate(); + _wsl_destroy(&_data); + _data = NULL; +} + +#endif // JAVASCRIPT_ENABLED diff --git a/modules/websocket/lws_peer.h b/modules/websocket/wsl_peer.h index 6771c13094..d51b304fe1 100644 --- a/modules/websocket/lws_peer.h +++ b/modules/websocket/wsl_peer.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* lws_peer.h */ +/* wsl_peer.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,50 +28,76 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef LWSPEER_H -#define LWSPEER_H +#ifndef WSLPEER_H +#define WSLPEER_H #ifndef JAVASCRIPT_ENABLED #include "core/error_list.h" #include "core/io/packet_peer.h" #include "core/ring_buffer.h" -#include "libwebsockets.h" -#include "lws_config.h" #include "packet_buffer.h" #include "websocket_peer.h" +#include "wslay/wslay.h" -class LWSPeer : public WebSocketPeer { +#define WSL_MAX_HEADER_SIZE 4096 - GDCIIMPL(LWSPeer, WebSocketPeer); +class WSLPeer : public WebSocketPeer { + + GDCIIMPL(WSLPeer, WebSocketPeer); + +public: + struct PeerData { + bool polling; + bool destroy; + bool valid; + bool is_server; + void *obj; + void *peer; + Ref<StreamPeer> conn; + int id; + wslay_event_context_ptr ctx; + + PeerData() { + polling = false; + destroy = false; + valid = false; + is_server = false; + id = 1; + ctx = NULL; + obj = NULL; + peer = NULL; + } + }; + + static String compute_key_response(String p_key); + static String generate_key(); private: - int _in_size; + static bool _wsl_poll(struct PeerData *p_data); + static void _wsl_destroy(struct PeerData **p_data); + + Ref<StreamPeer> _connection; + struct PeerData *_data; uint8_t _is_string; // Our packet info is just a boolean (is_string), using uint8_t for it. PacketBuffer<uint8_t> _in_buffer; - PacketBuffer<uint8_t> _out_buffer; PoolVector<uint8_t> _packet_buffer; - struct lws *wsi; WriteMode write_mode; +public: int close_code; String close_reason; - -public: - struct PeerData { - uint32_t peer_id; - bool force_close; - bool clean_close; - }; + void poll(); // Used by client and server. virtual int get_available_packet_count() const; virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size); virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size); virtual int get_max_packet_size() const { return _packet_buffer.size(); }; + virtual void close_now(); virtual void close(int p_code = 1000, String p_reason = ""); virtual bool is_connected_to_host() const; virtual IP_Address get_connected_host() const; @@ -81,14 +107,12 @@ public: virtual void set_write_mode(WriteMode p_mode); virtual bool was_string_packet() const; - void set_wsi(struct lws *wsi, unsigned int _in_buf_size, unsigned int _in_pkt_size, unsigned int _out_buf_size, unsigned int _out_pkt_size); - Error read_wsi(void *in, size_t len); - Error write_wsi(); - void send_close_status(struct lws *wsi); - String get_close_reason(void *in, size_t len, int &r_code); + void make_context(PeerData *p_data, unsigned int p_in_buf_size, unsigned int p_in_pkt_size, unsigned int p_out_buf_size, unsigned int p_out_pkt_size); + Error parse_message(const wslay_event_on_msg_recv_arg *arg); + void invalidate(); - LWSPeer(); - ~LWSPeer(); + WSLPeer(); + ~WSLPeer(); }; #endif // JAVASCRIPT_ENABLED diff --git a/modules/websocket/wsl_server.cpp b/modules/websocket/wsl_server.cpp new file mode 100644 index 0000000000..0d09a4d74e --- /dev/null +++ b/modules/websocket/wsl_server.cpp @@ -0,0 +1,302 @@ +/*************************************************************************/ +/* lws_server.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2019 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 JAVASCRIPT_ENABLED + +#include "wsl_server.h" +#include "core/os/os.h" +#include "core/project_settings.h" + +WSLServer::PendingPeer::PendingPeer() { + time = 0; + has_request = false; + response_sent = 0; + req_pos = 0; + memset(req_buf, 0, sizeof(req_buf)); +} + +bool WSLServer::PendingPeer::_parse_request(const PoolStringArray p_protocols) { + Vector<String> psa = String((char *)req_buf).split("\r\n"); + int len = psa.size(); + if (len < 4) { + ERR_EXPLAIN("Not enough response headers."); + ERR_FAIL_V(false); + } + + Vector<String> req = psa[0].split(" ", false); + if (req.size() < 2) { + ERR_EXPLAIN("Invalid protocol or status code."); + ERR_FAIL_V(false); + } + // Wrong protocol + if (req[0] != "GET" || req[2] != "HTTP/1.1") { + ERR_EXPLAIN("Invalid method or HTTP version."); + ERR_FAIL_V(false); + } + + Map<String, String> headers; + for (int i = 1; i < len; i++) { + Vector<String> header = psa[i].split(":", false, 1); + if (header.size() != 2) { + ERR_EXPLAIN("Invalid header -> " + psa[i]); + ERR_FAIL_V(false); + } + String name = header[0].to_lower(); + String value = header[1].strip_edges(); + if (headers.has(name)) + headers[name] += "," + value; + else + headers[name] = value; + } +#define _WLS_CHECK(NAME, VALUE) \ + ERR_EXPLAIN("Missing or invalid header '" + String(NAME) + "'. Expected value '" + VALUE + "'"); \ + ERR_FAIL_COND_V(!headers.has(NAME) || headers[NAME].to_lower() != VALUE, false); +#define _WLS_CHECK_EX(NAME) \ + ERR_EXPLAIN("Missing header '" + String(NAME) + "'."); \ + ERR_FAIL_COND_V(!headers.has(NAME), false); + _WLS_CHECK("upgrade", "websocket"); + _WLS_CHECK("sec-websocket-version", "13"); + _WLS_CHECK_EX("sec-websocket-key"); + _WLS_CHECK_EX("connection"); +#undef _WLS_CHECK_EX +#undef _WLS_CHECK + key = headers["sec-websocket-key"]; + if (headers.has("sec-websocket-protocol")) { + Vector<String> protos = headers["sec-websocket-protocol"].split(","); + for (int i = 0; i < protos.size(); i++) { + // Check if we have the given protocol + for (int j = 0; j < p_protocols.size(); j++) { + if (protos[i] != p_protocols[j]) + continue; + protocol = protos[i]; + break; + } + // Found a protocol + if (protocol != "") + break; + } + if (protocol == "") // Invalid protocol(s) requested + return false; + } else if (p_protocols.size() > 0) // No protocol requested, but we need one + return false; + return true; +} + +Error WSLServer::PendingPeer::do_handshake(PoolStringArray p_protocols) { + if (OS::get_singleton()->get_ticks_msec() - time > WSL_SERVER_TIMEOUT) + return ERR_TIMEOUT; + if (!has_request) { + int read = 0; + while (true) { + if (req_pos >= WSL_MAX_HEADER_SIZE) { + // Header is too big + ERR_EXPLAIN("Response headers too big"); + ERR_FAIL_V(ERR_OUT_OF_MEMORY); + } + Error err = connection->get_partial_data(&req_buf[req_pos], 1, read); + if (err != OK) // Got an error + return FAILED; + else if (read != 1) // Busy, wait next poll + return ERR_BUSY; + char *r = (char *)req_buf; + int l = req_pos; + if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') { + r[l - 3] = '\0'; + if (!_parse_request(p_protocols)) { + return FAILED; + } + String s = "HTTP/1.1 101 Switching Protocols\r\n"; + s += "Upgrade: websocket\r\n"; + s += "Connection: Upgrade\r\n"; + s += "Sec-WebSocket-Accept: " + WSLPeer::compute_key_response(key) + "\r\n"; + if (protocol != "") + s += "Sec-WebSocket-Protocol: " + protocol + "\r\n"; + s += "\r\n"; + response = s.utf8(); + has_request = true; + break; + } + req_pos += 1; + } + } + if (has_request && response_sent < response.size() - 1) { + int sent = 0; + Error err = connection->put_partial_data((const uint8_t *)response.get_data() + response_sent, response.size() - response_sent - 1, sent); + if (err != OK) { + return err; + } + response_sent += sent; + } + if (response_sent < response.size() - 1) + return ERR_BUSY; + return OK; +} + +Error WSLServer::listen(int p_port, PoolVector<String> p_protocols, bool gd_mp_api) { + ERR_FAIL_COND_V(is_listening(), ERR_ALREADY_IN_USE); + + _is_multiplayer = gd_mp_api; + _protocols = p_protocols; + _server->listen(p_port); + + return OK; +} + +void WSLServer::poll() { + + List<int> remove_ids; + for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) { + Ref<WSLPeer> peer = (WSLPeer *)E->get().ptr(); + peer->poll(); + if (!peer->is_connected_to_host()) { + _on_disconnect(E->key(), peer->close_code != -1); + remove_ids.push_back(E->key()); + } + } + for (List<int>::Element *E = remove_ids.front(); E; E = E->next()) { + _peer_map.erase(E->get()); + } + remove_ids.clear(); + + List<Ref<PendingPeer> > remove_peers; + for (List<Ref<PendingPeer> >::Element *E = _pending.front(); E; E = E->next()) { + Ref<PendingPeer> ppeer = E->get(); + Error err = ppeer->do_handshake(_protocols); + if (err == ERR_BUSY) { + continue; + } else if (err != OK) { + remove_peers.push_back(ppeer); + continue; + } + // Creating new peer + int32_t id = _gen_unique_id(); + + WSLPeer::PeerData *data = memnew(struct WSLPeer::PeerData); + data->obj = this; + data->conn = ppeer->connection; + data->is_server = true; + data->id = id; + + Ref<WSLPeer> ws_peer = memnew(WSLPeer); + ws_peer->make_context(data, _in_buf_size, _in_pkt_size, _out_buf_size, _out_pkt_size); + + _peer_map[id] = ws_peer; + remove_peers.push_back(ppeer); + _on_connect(id, ppeer->protocol); + } + for (List<Ref<PendingPeer> >::Element *E = remove_peers.front(); E; E = E->next()) { + _pending.erase(E->get()); + } + remove_peers.clear(); + + if (!_server->is_listening()) + return; + + while (_server->is_connection_available()) { + Ref<StreamPeer> conn = _server->take_connection(); + if (is_refusing_new_connections()) + continue; // Conn will go out-of-scope and be closed. + + Ref<PendingPeer> peer = memnew(PendingPeer); + peer->connection = conn; + peer->time = OS::get_singleton()->get_ticks_msec(); + _pending.push_back(peer); + } +} + +bool WSLServer::is_listening() const { + return _server->is_listening(); +} + +int WSLServer::get_max_packet_size() const { + return (1 << _out_buf_size) - PROTO_SIZE; +} + +void WSLServer::stop() { + _server->stop(); + for (Map<int, Ref<WebSocketPeer> >::Element *E = _peer_map.front(); E; E = E->next()) { + Ref<WSLPeer> peer = (WSLPeer *)E->get().ptr(); + peer->close_now(); + } + _pending.clear(); + _peer_map.clear(); +} + +bool WSLServer::has_peer(int p_id) const { + return _peer_map.has(p_id); +} + +Ref<WebSocketPeer> WSLServer::get_peer(int p_id) const { + ERR_FAIL_COND_V(!has_peer(p_id), NULL); + return _peer_map[p_id]; +} + +IP_Address WSLServer::get_peer_address(int p_peer_id) const { + ERR_FAIL_COND_V(!has_peer(p_peer_id), IP_Address()); + + return _peer_map[p_peer_id]->get_connected_host(); +} + +int WSLServer::get_peer_port(int p_peer_id) const { + ERR_FAIL_COND_V(!has_peer(p_peer_id), 0); + + return _peer_map[p_peer_id]->get_connected_port(); +} + +void WSLServer::disconnect_peer(int p_peer_id, int p_code, String p_reason) { + ERR_FAIL_COND(!has_peer(p_peer_id)); + + get_peer(p_peer_id)->close(p_code, p_reason); +} + +Error WSLServer::set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets) { + ERR_EXPLAIN("Buffers sizes can only be set before listening or connecting"); + ERR_FAIL_COND_V(_server->is_listening(), FAILED); + + _in_buf_size = nearest_shift(p_in_buffer - 1) + 10; + _in_pkt_size = nearest_shift(p_in_packets - 1); + _out_buf_size = nearest_shift(p_out_buffer - 1) + 10; + _out_pkt_size = nearest_shift(p_out_packets - 1); + return OK; +} + +WSLServer::WSLServer() { + _in_buf_size = nearest_shift((int)GLOBAL_GET(WSS_IN_BUF) - 1) + 10; + _in_pkt_size = nearest_shift((int)GLOBAL_GET(WSS_IN_PKT) - 1); + _out_buf_size = nearest_shift((int)GLOBAL_GET(WSS_OUT_BUF) - 1) + 10; + _out_pkt_size = nearest_shift((int)GLOBAL_GET(WSS_OUT_PKT) - 1); + _server.instance(); +} + +WSLServer::~WSLServer() { + stop(); +} + +#endif // JAVASCRIPT_ENABLED diff --git a/modules/websocket/lws_server.h b/modules/websocket/wsl_server.h index b331852d26..2ceb941073 100644 --- a/modules/websocket/lws_server.h +++ b/modules/websocket/wsl_server.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* lws_server.h */ +/* wsl_server.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,29 +28,55 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef LWSSERVER_H -#define LWSSERVER_H +#ifndef WSLSERVER_H +#define WSLSERVER_H #ifndef JAVASCRIPT_ENABLED -#include "core/reference.h" -#include "lws_helper.h" -#include "lws_peer.h" #include "websocket_server.h" +#include "wsl_peer.h" -class LWSServer : public WebSocketServer { +#include "core/io/stream_peer_tcp.h" +#include "core/io/tcp_server.h" - GDCIIMPL(LWSServer, WebSocketServer); +#define WSL_SERVER_TIMEOUT 1000 - LWS_HELPER(LWSServer); +class WSLServer : public WebSocketServer { + + GDCIIMPL(WSLServer, WebSocketServer); private: - Map<int, Ref<LWSPeer> > peer_map; + class PendingPeer : public Reference { + + private: + bool _parse_request(const PoolStringArray p_protocols); + + public: + Ref<StreamPeer> connection; + + int time; + uint8_t req_buf[WSL_MAX_HEADER_SIZE]; + int req_pos; + String key; + String protocol; + bool has_request; + CharString response; + int response_sent; + + PendingPeer(); + + Error do_handshake(const PoolStringArray p_protocols); + }; + int _in_buf_size; int _in_pkt_size; int _out_buf_size; int _out_pkt_size; + List<Ref<PendingPeer> > _pending; + Ref<TCP_Server> _server; + PoolStringArray _protocols; + public: Error set_buffers(int p_in_buffer, int p_in_packets, int p_out_buffer, int p_out_packets); Error listen(int p_port, PoolVector<String> p_protocols = PoolVector<String>(), bool gd_mp_api = false); @@ -62,12 +88,12 @@ public: IP_Address get_peer_address(int p_peer_id) const; int get_peer_port(int p_peer_id) const; void disconnect_peer(int p_peer_id, int p_code = 1000, String p_reason = ""); - virtual void poll() { _lws_poll(); } + virtual void poll(); - LWSServer(); - ~LWSServer(); + WSLServer(); + ~WSLServer(); }; #endif // JAVASCRIPT_ENABLED -#endif // LWSSERVER_H +#endif // WSLSERVER_H diff --git a/modules/xatlas_unwrap/register_types.cpp b/modules/xatlas_unwrap/register_types.cpp index 903b57f017..c18aa04336 100644 --- a/modules/xatlas_unwrap/register_types.cpp +++ b/modules/xatlas_unwrap/register_types.cpp @@ -39,57 +39,37 @@ extern bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const flo bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_vertices, const float *p_normals, int p_vertex_count, const int *p_indices, const int *p_face_materials, int p_index_count, float **r_uv, int **r_vertex, int *r_vertex_count, int **r_index, int *r_index_count, int *r_size_hint_x, int *r_size_hint_y) { //set up input mesh - xatlas::InputMesh input_mesh; - input_mesh.indexData = malloc(sizeof(int) * p_index_count); + xatlas::MeshDecl input_mesh; + input_mesh.indexData = p_indices; input_mesh.indexCount = p_index_count; - input_mesh.indexFormat = xatlas::IndexFormat::Float; //really xatlas? - input_mesh.faceMaterialData = (uint16_t *)malloc(sizeof(uint16_t) * p_index_count); - - for (int i = 0; i < p_index_count; i++) { - int *index = (int *)input_mesh.indexData; - index[i] = p_indices[i]; - } - for (int i = 0; i < p_index_count / 3; i++) { - uint16_t *mat_index = (uint16_t *)input_mesh.faceMaterialData; - mat_index[i] = p_face_materials[i]; - } + input_mesh.indexFormat = xatlas::IndexFormat::UInt32; input_mesh.vertexCount = p_vertex_count; - input_mesh.vertexPositionData = malloc(sizeof(float) * p_vertex_count * 3); + input_mesh.vertexPositionData = p_vertices; input_mesh.vertexPositionStride = sizeof(float) * 3; - input_mesh.vertexNormalData = malloc(sizeof(float) * p_vertex_count * 3); - input_mesh.vertexNormalStride = sizeof(float) * 3; - - //material is a better hint than this i guess? + input_mesh.vertexNormalData = p_normals; + input_mesh.vertexNormalStride = sizeof(uint32_t) * 3; input_mesh.vertexUvData = NULL; input_mesh.vertexUvStride = 0; - for (int i = 0; i < p_vertex_count * 3; i++) { - float *vertex_ptr = (float *)input_mesh.vertexPositionData; - float *normal_ptr = (float *)input_mesh.vertexNormalData; + xatlas::ChartOptions chart_options; + xatlas::PackOptions pack_options; - vertex_ptr[i] = p_vertices[i]; - normal_ptr[i] = p_normals[i]; - } - - xatlas::CharterOptions chart_options; - xatlas::PackerOptions pack_options; - - pack_options.method = xatlas::PackMethod::TexelArea; - pack_options.texelArea = 1.0 / p_texel_size; - pack_options.quality = 3; + pack_options.maxChartSize = 4096; + pack_options.bruteForce = true; + pack_options.texelsPerUnit = 1.0 / p_texel_size; xatlas::Atlas *atlas = xatlas::Create(); - printf("adding mesh..\n"); - xatlas::AddMeshError err = xatlas::AddMesh(atlas, input_mesh); - ERR_EXPLAINC(xatlas::StringForEnum(err.code)); - ERR_FAIL_COND_V(err.code != xatlas::AddMeshErrorCode::Success, false); + printf("Adding mesh..\n"); + xatlas::AddMeshError::Enum err = xatlas::AddMesh(atlas, input_mesh, 1); + ERR_EXPLAINC(xatlas::StringForEnum(err)); + ERR_FAIL_COND_V(err != xatlas::AddMeshError::Enum::Success, false); - printf("generate..\n"); - xatlas::Generate(atlas, chart_options, pack_options); + printf("Generate..\n"); + xatlas::Generate(atlas, chart_options, NULL, pack_options); - *r_size_hint_x = xatlas::GetWidth(atlas); - *r_size_hint_y = xatlas::GetHeight(atlas); + *r_size_hint_x = atlas->width; + *r_size_hint_y = atlas->height; float w = *r_size_hint_x; float h = *r_size_hint_y; @@ -98,39 +78,33 @@ bool xatlas_mesh_lightmap_unwrap_callback(float p_texel_size, const float *p_ver return false; //could not bake } - const xatlas::OutputMesh *const *output_meshes = xatlas::GetOutputMeshes(atlas); - - const xatlas::OutputMesh *output = output_meshes[0]; + const xatlas::Mesh &output = atlas->meshes[0]; - *r_vertex = (int *)malloc(sizeof(int) * output->vertexCount); - *r_uv = (float *)malloc(sizeof(float) * output->vertexCount * 2); - *r_index = (int *)malloc(sizeof(int) * output->indexCount); + *r_vertex = (int *)malloc(sizeof(int) * output.vertexCount); + *r_uv = (float *)malloc(sizeof(float) * output.vertexCount * 2); + *r_index = (int *)malloc(sizeof(int) * output.indexCount); float max_x = 0; float max_y = 0; - for (uint32_t i = 0; i < output->vertexCount; i++) { - (*r_vertex)[i] = output->vertexArray[i].xref; - (*r_uv)[i * 2 + 0] = output->vertexArray[i].uv[0] / w; - (*r_uv)[i * 2 + 1] = output->vertexArray[i].uv[1] / h; - max_x = MAX(max_x, output->vertexArray[i].uv[0]); - max_y = MAX(max_y, output->vertexArray[i].uv[1]); + for (uint32_t i = 0; i < output.vertexCount; i++) { + (*r_vertex)[i] = output.vertexArray[i].xref; + (*r_uv)[i * 2 + 0] = output.vertexArray[i].uv[0] / w; + (*r_uv)[i * 2 + 1] = output.vertexArray[i].uv[1] / h; + max_x = MAX(max_x, output.vertexArray[i].uv[0]); + max_y = MAX(max_y, output.vertexArray[i].uv[1]); } - printf("final texsize: %f,%f - max %f,%f\n", w, h, max_x, max_y); - *r_vertex_count = output->vertexCount; + printf("Final texture size: %f,%f - max %f,%f\n", w, h, max_x, max_y); + *r_vertex_count = output.vertexCount; - for (uint32_t i = 0; i < output->indexCount; i++) { - (*r_index)[i] = output->indexArray[i]; + for (uint32_t i = 0; i < output.indexCount; i++) { + (*r_index)[i] = output.indexArray[i]; } - *r_index_count = output->indexCount; + *r_index_count = output.indexCount; //xatlas::Destroy(atlas); - free((void *)input_mesh.indexData); - free((void *)input_mesh.vertexPositionData); - free((void *)input_mesh.vertexNormalData); - free((void *)input_mesh.faceMaterialData); - printf("done"); + printf("Done\n"); return true; } diff --git a/platform/android/SCsub b/platform/android/SCsub index 1562714d76..cf6752fa54 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -23,8 +23,6 @@ android_files = [ ] env_android = env.Clone() -if env['target'] == "profile": - env_android.Append(CPPFLAGS=['-DPROFILER_ENABLED']) android_objects = [] for x in android_files: diff --git a/platform/android/detect.py b/platform/android/detect.py index eed51c4d30..3f179e3a65 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -144,20 +144,21 @@ def configure(env): if (env["optimize"] == "speed"): #optimize for speed (default) env.Append(LINKFLAGS=['-O2']) env.Append(CCFLAGS=['-O2', '-fomit-frame-pointer']) - env.Append(CPPFLAGS=['-DNDEBUG']) + env.Append(CPPDEFINES=['NDEBUG']) else: #optimize for size env.Append(CCFLAGS=['-Os']) - env.Append(CPPFLAGS=['-DNDEBUG']) + env.Append(CPPDEFINES=['NDEBUG']) env.Append(LINKFLAGS=['-Os']) if (can_vectorize): env.Append(CCFLAGS=['-ftree-vectorize']) if (env["target"] == "release_debug"): - env.Append(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED']) elif (env["target"] == "debug"): env.Append(LINKFLAGS=['-O0']) env.Append(CCFLAGS=['-O0', '-g', '-fno-limit-debug-info']) - env.Append(CPPFLAGS=['-D_DEBUG', '-UNDEBUG', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CPPDEFINES=['_DEBUG', 'DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) + env.Append(CPPFLAGS=['-UNDEBUG']) ## Compiler configuration @@ -215,7 +216,7 @@ def configure(env): else: env.Append(CXXFLAGS=['-fno-rtti', '-fno-exceptions']) # Don't use dynamic_cast, necessary with no-rtti. - env.Append(CPPFLAGS=['-DNO_SAFE_CAST']) + env.Append(CPPDEFINES=['NO_SAFE_CAST']) ndk_version = get_ndk_version(env["ANDROID_NDK_ROOT"]) if ndk_version != None and LooseVersion(ndk_version) >= LooseVersion("15.0.4075724"): @@ -225,13 +226,13 @@ def configure(env): env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include/" + abi_subpath]) env.Append(CPPFLAGS=["-isystem", env["ANDROID_NDK_ROOT"] + "/sources/android/support/include"]) # For unified headers this define has to be set manually - env.Append(CPPFLAGS=["-D__ANDROID_API__=" + str(get_platform(env['ndk_platform']))]) + env.Append(CPPDEFINES=[('__ANDROID_API__', str(get_platform(env['ndk_platform'])))]) else: print("Using NDK deprecated headers") env.Append(CPPFLAGS=["-isystem", lib_sysroot + "/usr/include"]) env.Append(CCFLAGS='-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing'.split()) - env.Append(CPPFLAGS='-DNO_STATVFS -DGLES_ENABLED'.split()) + env.Append(CPPDEFINES=['NO_STATVFS', 'GLES_ENABLED']) env['neon_enabled'] = False if env['android_arch'] == 'x86': @@ -245,18 +246,18 @@ def configure(env): elif env["android_arch"] == "armv7": target_opts = ['-target', 'armv7-none-linux-androideabi'] env.Append(CCFLAGS='-march=armv7-a -mfloat-abi=softfp'.split()) - env.Append(CPPFLAGS='-D__ARM_ARCH_7__ -D__ARM_ARCH_7A__'.split()) + env.Append(CPPDEFINES=['__ARM_ARCH_7__', '__ARM_ARCH_7A__']) if env['android_neon']: env['neon_enabled'] = True env.Append(CCFLAGS=['-mfpu=neon']) - env.Append(CPPFLAGS=['-D__ARM_NEON__']) + env.Append(CPPDEFINES=['__ARM_NEON__']) else: env.Append(CCFLAGS=['-mfpu=vfpv3-d16']) elif env["android_arch"] == "arm64v8": target_opts = ['-target', 'aarch64-none-linux-android'] env.Append(CCFLAGS=['-mfix-cortex-a53-835769']) - env.Append(CPPFLAGS=['-D__ARM_ARCH_8A__']) + env.Append(CPPDEFINES=['__ARM_ARCH_8A__']) env.Append(CCFLAGS=target_opts) env.Append(CCFLAGS=common_opts) @@ -289,7 +290,7 @@ def configure(env): '/toolchains/' + target_subpath + '/prebuilt/' + host_subpath + '/' + abi_subpath + '/lib']) env.Prepend(CPPPATH=['#platform/android']) - env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL']) + env.Append(CPPDEFINES=['ANDROID_ENABLED', 'UNIX_ENABLED', 'NO_FCNTL']) env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'GLESv2', 'android', 'log', 'z', 'dl']) # Return NDK version string in source.properties (adapted from the Chromium project). diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index b37cf642db..1b9d31d752 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -665,6 +665,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { bool screen_support_large = p_preset->get("screen/support_large"); bool screen_support_xlarge = p_preset->get("screen/support_xlarge"); + int xr_mode_index = p_preset->get("graphics/xr_mode"); + Vector<String> perms; const char **aperms = android_perms; @@ -822,6 +824,20 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { encode_uint32(min_gles3 ? 0x00030000 : 0x00020000, &p_manifest.write[iofs + 16]); } + if (tname == "meta-data" && attrname == "name" && string_table[attr_value] == "xr_mode_metadata_name") { + // Update the meta-data 'android:name' attribute based on the selected XR mode. + if (xr_mode_index == 1 /* XRMode.OVR */) { + string_table.write[attr_value] = "com.samsung.android.vr.application.mode"; + } + } + + if (tname == "meta-data" && attrname == "value" && string_table[attr_value] == "xr_mode_metadata_value") { + // Update the meta-data 'android:value' attribute based on the selected XR mode. + if (xr_mode_index == 1 /* XRMode.OVR */) { + string_table.write[attr_value] = "vr_only"; + } + } + iofs += 20; } @@ -1139,6 +1155,7 @@ public: virtual void get_export_options(List<ExportOption> *r_options) { + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), "")); @@ -2071,6 +2088,14 @@ public: } } + int xr_mode_index = p_preset->get("graphics/xr_mode"); + if (xr_mode_index == 1 /* XRMode.OVR */) { + cl.push_back("--xr_mode_ovr"); + } else { + // XRMode.REGULAR is the default. + cl.push_back("--xr_mode_regular"); + } + if (use_32_fb) cl.push_back("--use_depth_32"); diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp index 63bc5f69d1..5b8cf01138 100644 --- a/platform/android/file_access_jandroid.cpp +++ b/platform/android/file_access_jandroid.cpp @@ -62,7 +62,7 @@ Error FileAccessJAndroid::_open(const String &p_path, int p_mode_flags) { JNIEnv *env = ThreadAndroid::get_env(); jstring js = env->NewStringUTF(path.utf8().get_data()); - int res = env->CallIntMethod(io, _file_open, js, p_mode_flags & WRITE ? true : false); + int res = env->CallIntMethod(io, _file_open, js, (p_mode_flags & WRITE) ? true : false); env->DeleteLocalRef(js); OS::get_singleton()->print("fopen: '%s' ret %i\n", path.utf8().get_data(), res); diff --git a/platform/android/java/AndroidManifest.xml b/platform/android/java/AndroidManifest.xml index 9997950137..3152ef12cd 100644 --- a/platform/android/java/AndroidManifest.xml +++ b/platform/android/java/AndroidManifest.xml @@ -13,7 +13,7 @@ <!--glEsVersion is modified by the exporter, changing this value here has no effect--> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> -<!--Adding custom text to manifest is fine, but do it outside the custom user and application BEGIN/ENDregions, as that gets rewritten--> +<!--Adding custom text to manifest is fine, but do it outside the custom user and application BEGIN/END regions, as that gets rewritten--> <!--Custom permissions XML added by add-ons. It's recommended to add them from the export preset, though--> <!--CHUNK_USER_PERMISSIONS_BEGIN--> @@ -25,12 +25,15 @@ <!--The following values are replaced when Godot exports, modifying them here has no effect. Do these changes in the--> <!--export preset. Adding new ones is fine.--> +<!-- XR mode metadata. This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. --> + <meta-data android:name="xr_mode_metadata_name" android:value="xr_mode_metadata_value"/> + <activity android:name="org.godotengine.godot.Godot" android:label="@string/godot_project_name_string" - android:theme="@android:style/Theme.NoTitleBar.Fullscreen" + android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" android:launchMode="singleTask" android:screenOrientation="landscape" - android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize" + android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" android:resizeableActivity="false" tools:ignore="UnusedAttribute"> diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java index 751e885118..6e1841fa8b 100644 --- a/platform/android/java/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -58,7 +58,6 @@ import android.os.Environment; import android.os.Messenger; import android.provider.Settings.Secure; import android.support.v4.content.ContextCompat; -import android.util.Log; import android.view.Display; import android.view.KeyEvent; import android.view.MotionEvent; @@ -115,6 +114,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC private Button mPauseButton; private Button mWiFiSettingsButton; + private XRMode xrMode = XRMode.REGULAR; private boolean use_32_bits = false; private boolean use_immersive = false; private boolean use_debug_opengl = false; @@ -282,7 +282,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC // ...add to FrameLayout layout.addView(edittext); - mView = new GodotView(this, XRMode.PANCAKE, use_gl3, use_32_bits, use_debug_opengl); + mView = new GodotView(this, xrMode, use_gl3, use_32_bits, use_debug_opengl); layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); edittext.setView(mView); io.setEdit(edittext); @@ -488,7 +488,11 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC for (int i = 0; i < command_line.length; i++) { boolean has_extra = i < command_line.length - 1; - if (command_line[i].equals("--use_depth_32")) { + if (command_line[i].equals(XRMode.REGULAR.cmdLineArg)) { + xrMode = XRMode.REGULAR; + } else if (command_line[i].equals(XRMode.OVR.cmdLineArg)) { + xrMode = XRMode.OVR; + } else if (command_line[i].equals("--use_depth_32")) { use_32_bits = true; } else if (command_line[i].equals("--debug_opengl")) { use_debug_opengl = true; diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java index 1c189a1579..fc3e47e69d 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/src/org/godotengine/godot/GodotView.java @@ -40,9 +40,9 @@ import org.godotengine.godot.xr.XRMode; import org.godotengine.godot.xr.ovr.OvrConfigChooser; import org.godotengine.godot.xr.ovr.OvrContextFactory; import org.godotengine.godot.xr.ovr.OvrWindowSurfaceFactory; -import org.godotengine.godot.xr.pancake.PancakeConfigChooser; -import org.godotengine.godot.xr.pancake.PancakeContextFactory; -import org.godotengine.godot.xr.pancake.PancakeFallbackConfigChooser; +import org.godotengine.godot.xr.regular.RegularConfigChooser; +import org.godotengine.godot.xr.regular.RegularContextFactory; +import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser; /** * A simple GLSurfaceView sub-class that demonstrate how to perform @@ -123,7 +123,7 @@ public class GodotView extends GLSurfaceView { setEGLWindowSurfaceFactory(new OvrWindowSurfaceFactory()); break; - case PANCAKE: + case REGULAR: default: /* By default, GLSurfaceView() creates a RGB_565 opaque surface. * If we want a translucent one, we should change the surface's @@ -137,7 +137,7 @@ public class GodotView extends GLSurfaceView { /* Setup the context factory for 2.0 rendering. * See ContextFactory class definition below */ - setEGLContextFactory(new PancakeContextFactory()); + setEGLContextFactory(new RegularContextFactory()); /* We need to choose an EGLConfig that matches the format of * our surface exactly. This is going to be done in our @@ -147,15 +147,15 @@ public class GodotView extends GLSurfaceView { if (GLUtils.use_32) { setEGLConfigChooser(translucent ? - new PancakeFallbackConfigChooser(8, 8, 8, 8, 24, stencil, - new PancakeConfigChooser(8, 8, 8, 8, 16, stencil)) : - new PancakeFallbackConfigChooser(8, 8, 8, 8, 24, stencil, - new PancakeConfigChooser(5, 6, 5, 0, 16, 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 RegularConfigChooser(5, 6, 5, 0, 16, stencil))); } else { setEGLConfigChooser(translucent ? - new PancakeConfigChooser(8, 8, 8, 8, 16, stencil) : - new PancakeConfigChooser(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/src/org/godotengine/godot/xr/XRMode.java b/platform/android/java/src/org/godotengine/godot/xr/XRMode.java index cbc8a1e902..dd5701af7d 100644 --- a/platform/android/java/src/org/godotengine/godot/xr/XRMode.java +++ b/platform/android/java/src/org/godotengine/godot/xr/XRMode.java @@ -34,6 +34,16 @@ package org.godotengine.godot.xr; * Godot available XR modes. */ public enum XRMode { - PANCAKE, // Regular/flatscreen - OVR, // Oculus mobile VR SDK + REGULAR(0, "Regular", "--xr_mode_regular"), // Regular/flatscreen + OVR(1, "Oculus Mobile VR", "--xr_mode_ovr"); + + final int index; + final String label; + public final String cmdLineArg; + + XRMode(int index, String label, String cmdLineArg) { + this.index = index; + this.label = label; + this.cmdLineArg = cmdLineArg; + } } diff --git a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeConfigChooser.java b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java index ac19a09e76..3836967f86 100644 --- a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeConfigChooser.java +++ b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java @@ -1,5 +1,5 @@ /*************************************************************************/ -/* PancakeConfigChooser.java */ +/* RegularConfigChooser.java */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.xr.pancake; +package org.godotengine.godot.xr.regular; import android.opengl.GLSurfaceView; import javax.microedition.khronos.egl.EGL10; @@ -39,9 +39,9 @@ import org.godotengine.godot.utils.GLUtils; /** * Used to select the egl config for pancake games. */ -public class PancakeConfigChooser implements GLSurfaceView.EGLConfigChooser { +public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { - private static final String TAG = PancakeConfigChooser.class.getSimpleName(); + private static final String TAG = RegularConfigChooser.class.getSimpleName(); private int[] mValue = new int[1]; @@ -69,7 +69,7 @@ public class PancakeConfigChooser implements GLSurfaceView.EGLConfigChooser { EGL10.EGL_NONE }; - public PancakeConfigChooser(int r, int g, int b, int a, int depth, int stencil) { + public RegularConfigChooser(int r, int g, int b, int a, int depth, int stencil) { mRedSize = r; mGreenSize = g; mBlueSize = b; diff --git a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeContextFactory.java b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularContextFactory.java index aca6ffdba6..4f1e9a696b 100644 --- a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeContextFactory.java +++ b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularContextFactory.java @@ -1,5 +1,5 @@ /*************************************************************************/ -/* PancakeContextFactory.java */ +/* RegularContextFactory.java */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.xr.pancake; +package org.godotengine.godot.xr.regular; import android.opengl.GLSurfaceView; import android.util.Log; @@ -42,8 +42,8 @@ import org.godotengine.godot.utils.GLUtils; /** * Factory used to setup the opengl context for pancake games. */ -public class PancakeContextFactory implements GLSurfaceView.EGLContextFactory { - private static final String TAG = PancakeContextFactory.class.getSimpleName(); +public class RegularContextFactory implements GLSurfaceView.EGLContextFactory { + private static final String TAG = RegularContextFactory.class.getSimpleName(); private static final int _EGL_CONTEXT_FLAGS_KHR = 0x30FC; private static final int _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR = 0x00000001; diff --git a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeFallbackConfigChooser.java b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java index e19f218916..f5718ef2b3 100644 --- a/platform/android/java/src/org/godotengine/godot/xr/pancake/PancakeFallbackConfigChooser.java +++ b/platform/android/java/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java @@ -1,5 +1,5 @@ /*************************************************************************/ -/* PancakeFallbackConfigChooser.java */ +/* RegularFallbackConfigChooser.java */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,7 +28,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -package org.godotengine.godot.xr.pancake; +package org.godotengine.godot.xr.regular; import android.util.Log; import javax.microedition.khronos.egl.EGL10; @@ -37,13 +37,13 @@ import javax.microedition.khronos.egl.EGLDisplay; import org.godotengine.godot.utils.GLUtils; /* Fallback if 32bit View is not supported*/ -public class PancakeFallbackConfigChooser extends PancakeConfigChooser { +public class RegularFallbackConfigChooser extends RegularConfigChooser { - private static final String TAG = PancakeFallbackConfigChooser.class.getSimpleName(); + private static final String TAG = RegularFallbackConfigChooser.class.getSimpleName(); - private PancakeConfigChooser fallback; + private RegularConfigChooser fallback; - public PancakeFallbackConfigChooser(int r, int g, int b, int a, int depth, int stencil, PancakeConfigChooser fallback) { + public RegularFallbackConfigChooser(int r, int g, int b, int a, int depth, int stencil, RegularConfigChooser fallback) { super(r, g, b, a, depth, stencil); this.fallback = fallback; } diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index 466f79c215..77f077456e 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -289,7 +289,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { PoolVector<int>::Write w = sarr.write(); env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); - w = PoolVector<int>::Write(); + w.release(); return sarr; }; @@ -302,7 +302,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { PoolVector<uint8_t>::Write w = sarr.write(); env->GetByteArrayRegion(arr, 0, fCount, reinterpret_cast<signed char *>(w.ptr())); - w = PoolVector<uint8_t>::Write(); + w.release(); return sarr; }; @@ -514,7 +514,7 @@ public: PoolVector<int>::Write w = sarr.write(); env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); - w = PoolVector<int>::Write(); + w.release(); ret = sarr; env->DeleteLocalRef(arr); } break; @@ -528,7 +528,7 @@ public: PoolVector<float>::Write w = sarr.write(); env->GetFloatArrayRegion(arr, 0, fCount, w.ptr()); - w = PoolVector<float>::Write(); + w.release(); ret = sarr; env->DeleteLocalRef(arr); } break; diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 5a708cdaca..2a3e165069 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -128,8 +128,8 @@ def configure(env): if any(platform.machine() in s for s in list_of_x86): env["x86_libtheora_opt_gcc"] = True - if not env['builtin_libwebsockets']: - env.ParseConfig('pkg-config libwebsockets --cflags --libs') + if not env['builtin_wslay']: + env.ParseConfig('pkg-config libwslay --cflags --libs') if not env['builtin_mbedtls']: # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228 @@ -148,8 +148,7 @@ def configure(env): ## Flags env.Prepend(CPPPATH=['#platform/haiku']) - env.Append(CPPFLAGS=['-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED']) - env.Append(CPPFLAGS=['-DMEDIA_KIT_ENABLED']) - # env.Append(CPPFLAGS=['-DFREETYPE_ENABLED']) - env.Append(CPPFLAGS=['-DPTHREAD_NO_RENAME']) # TODO: enable when we have pthread_setname_np + env.Append(CPPDEFINES=['UNIX_ENABLED', 'OPENGL_ENABLED', 'GLES_ENABLED']) + env.Append(CPPDEFINES=['MEDIA_KIT_ENABLED']) + env.Append(CPPDEFINES=['PTHREAD_NO_RENAME']) # TODO: enable when we have pthread_setname_np env.Append(LIBS=['be', 'game', 'media', 'network', 'bnetapi', 'z', 'GL']) diff --git a/platform/iphone/camera_ios.mm b/platform/iphone/camera_ios.mm index 5a54eaee9b..029ce6debf 100644 --- a/platform/iphone/camera_ios.mm +++ b/platform/iphone/camera_ios.mm @@ -397,6 +397,22 @@ void CameraIOS::update_feeds() { }; 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 diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index b448cbe097..f646b8b1d5 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -43,7 +43,7 @@ def configure(env): ## Build type if (env["target"].startswith("release")): - env.Append(CPPFLAGS=['-DNDEBUG', '-DNS_BLOCK_ASSERTIONS=1']) + env.Append(CPPDEFINES=['NDEBUG', ('NS_BLOCK_ASSERTIONS', 1)]) if (env["optimize"] == "speed"): #optimize for speed (default) env.Append(CCFLAGS=['-O2', '-ftree-vectorize', '-fomit-frame-pointer']) env.Append(LINKFLAGS=['-O2']) @@ -52,11 +52,11 @@ def configure(env): env.Append(LINKFLAGS=['-Os']) if env["target"] == "release_debug": - env.Append(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED']) elif (env["target"] == "debug"): env.Append(CCFLAGS=['-gdwarf-2', '-O0']) - env.Append(CPPFLAGS=['-D_DEBUG', '-DDEBUG=1', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CPPDEFINES=['_DEBUG', ('DEBUG', 1), 'DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) if (env["use_lto"]): env.Append(CCFLAGS=['-flto']) @@ -112,8 +112,8 @@ def configure(env): elif (env["arch"] == "arm64"): detect_darwin_sdk_path('iphone', env) env.Append(CCFLAGS='-fno-objc-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=10.0 -isysroot $IPHONESDK'.split()) - env.Append(CPPFLAGS=['-DNEED_LONG_INT']) - env.Append(CPPFLAGS=['-DLIBYUV_DISABLE_NEON']) + env.Append(CPPDEFINES=['NEED_LONG_INT']) + env.Append(CPPDEFINES=['LIBYUV_DISABLE_NEON']) # Disable exceptions on non-tools (template) builds if not env['tools']: @@ -159,15 +159,15 @@ def configure(env): # Feature options if env['game_center']: - env.Append(CPPFLAGS=['-DGAME_CENTER_ENABLED']) + env.Append(CPPDEFINES=['GAME_CENTER_ENABLED']) env.Append(LINKFLAGS=['-framework', 'GameKit']) if env['store_kit']: - env.Append(CPPFLAGS=['-DSTOREKIT_ENABLED']) + env.Append(CPPDEFINES=['STOREKIT_ENABLED']) env.Append(LINKFLAGS=['-framework', 'StoreKit']) if env['icloud']: - env.Append(CPPFLAGS=['-DICLOUD_ENABLED']) + env.Append(CPPDEFINES=['ICLOUD_ENABLED']) env.Prepend(CPPPATH=['$IPHONESDK/usr/include', '$IPHONESDK/System/Library/Frameworks/OpenGLES.framework/Headers', @@ -177,4 +177,4 @@ def configure(env): env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate' env.Prepend(CPPPATH=['#platform/iphone']) - env.Append(CPPFLAGS=['-DIPHONE_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DCOREAUDIO_ENABLED']) + env.Append(CPPDEFINES=['IPHONE_ENABLED', 'UNIX_ENABLED', 'GLES_ENABLED', 'COREAUDIO_ENABLED']) diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 99ce2e8f87..85a45d62f8 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -268,8 +268,9 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/in_app_purchases"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/push_notifications"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/camera_usage_description"), "Godot would like to use your camera")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photolibrary_usage_description"), "Godot would like to use your photos")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/camera_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the camera"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photolibrary_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need access to the photo library"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/landscape_left"), true)); @@ -398,6 +399,9 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ } else if (lines[i].find("$camera_usage_description") != -1) { String description = p_preset->get("privacy/camera_usage_description"); strnew += lines[i].replace("$camera_usage_description", description) + "\n"; + } else if (lines[i].find("$microphone_usage_description") != -1) { + String description = p_preset->get("privacy/microphone_usage_description"); + strnew += lines[i].replace("$microphone_usage_description", description) + "\n"; } else if (lines[i].find("$photolibrary_usage_description") != -1) { String description = p_preset->get("privacy/photolibrary_usage_description"); strnew += lines[i].replace("$photolibrary_usage_description", description) + "\n"; diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index c6afa02c6d..10680ad1f5 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -69,9 +69,14 @@ def configure(env): exec(f.read(), em_config) except StandardError as e: raise RuntimeError("Emscripten configuration file '%s' is invalid:\n%s" % (em_config_file, e)) - if 'BINARYEN_ROOT' not in em_config and 'EMSCRIPTEN_ROOT' not in em_config: + if 'BINARYEN_ROOT' in em_config and os.path.isdir(os.path.join(em_config.get('BINARYEN_ROOT'), 'emscripten')): + # New style, emscripten path as a subfolder of BINARYEN_ROOT + env.PrependENVPath('PATH', os.path.join(em_config.get('BINARYEN_ROOT'), 'emscripten')) + elif 'EMSCRIPTEN_ROOT' in em_config: + # Old style (but can be there as a result from previous activation, so do last) + env.PrependENVPath('PATH', em_config.get('EMSCRIPTEN_ROOT')) + else: raise RuntimeError("'BINARYEN_ROOT' or 'EMSCRIPTEN_ROOT' missing in Emscripten configuration file '%s'" % em_config_file) - env.PrependENVPath('PATH', em_config.get('BINARYEN_ROOT', em_config.get('EMSCRIPTEN_ROOT'))) env['CC'] = 'emcc' env['CXX'] = 'em++' diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index d96ffc3a55..5363cd4af7 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -448,6 +448,18 @@ void OS_JavaScript::set_cursor_shape(CursorShape p_shape) { void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { if (p_cursor.is_valid()) { + + Map<CursorShape, Vector<Variant> >::Element *cursor_c = cursors_cache.find(p_shape); + + if (cursor_c) { + if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { + set_cursor_shape(p_shape); + return; + } + + cursors_cache.erase(p_shape); + } + Ref<Texture> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; @@ -551,6 +563,11 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s cursors[p_shape] = url; + Vector<Variant> params; + params.push_back(p_cursor); + params.push_back(p_hotspot); + cursors_cache.insert(p_shape, params); + } else if (cursors[p_shape] != "") { /* clang-format off */ EM_ASM({ diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 9635465c0d..10676c49f7 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -52,6 +52,7 @@ class OS_JavaScript : public OS_Unix { Ref<InputEventKey> deferred_key_event; CursorShape cursor_shape; String cursors[CURSOR_MAX]; + Map<CursorShape, Vector<Variant> > cursors_cache; Point2 touches[32]; Point2i last_click_pos; diff --git a/platform/osx/detect.py b/platform/osx/detect.py index 2175797dec..881ed05025 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -56,7 +56,7 @@ def configure(env): env.Prepend(CCFLAGS=['-O2']) else: #optimize for size env.Prepend(CCFLAGS=['-Os']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) if (env["debug_symbols"] == "full"): @@ -64,7 +64,7 @@ def configure(env): elif (env["target"] == "debug"): env.Prepend(CCFLAGS=['-g3']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) ## Architecture @@ -90,7 +90,7 @@ def configure(env): env['AR'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ar" env['RANLIB'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-ranlib" env['AS'] = mpprefix + "/libexec/llvm-" + mpclangver + "/bin/llvm-as" - env.Append(CPPFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define + env.Append(CPPDEFINES=['__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define detect_darwin_sdk_path('osx', env) env.Append(CCFLAGS=['-isysroot', '$MACOS_SDK_PATH']) @@ -112,10 +112,10 @@ def configure(env): env['AR'] = basecmd + "ar" env['RANLIB'] = basecmd + "ranlib" env['AS'] = basecmd + "as" - env.Append(CPPFLAGS=['-D__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define + env.Append(CPPDEFINES=['__MACPORTS__']) #hack to fix libvpx MM256_BROADCASTSI128_SI256 define if (env["CXX"] == "clang++"): - env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) + env.Append(CPPDEFINES=['TYPED_METHOD_BIND']) env["CC"] = "clang" env["LINK"] = "clang++" @@ -127,7 +127,7 @@ def configure(env): ## Flags env.Prepend(CPPPATH=['#platform/osx']) - env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES_ENABLED', '-DAPPLE_STYLE_KEYS', '-DCOREAUDIO_ENABLED', '-DCOREMIDI_ENABLED']) + env.Append(CPPDEFINES=['OSX_ENABLED', 'UNIX_ENABLED', 'GLES_ENABLED', 'APPLE_STYLE_KEYS', 'COREAUDIO_ENABLED', 'COREMIDI_ENABLED']) env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'AVFoundation', '-framework', 'CoreMedia', '-framework', 'CoreVideo']) env.Append(LIBS=['pthread']) diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 1e996608af..a83d5084ed 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -119,6 +119,7 @@ public: CursorShape cursor_shape; NSCursor *cursors[CURSOR_MAX]; + Map<CursorShape, Vector<Variant> > cursors_cache; MouseMode mouse_mode; String title; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 4f84ae9c50..726882438b 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -1770,7 +1770,20 @@ OS::CursorShape OS_OSX::get_cursor_shape() const { } void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + if (p_cursor.is_valid()) { + + Map<CursorShape, Vector<Variant> >::Element *cursor_c = cursors_cache.find(p_shape); + + if (cursor_c) { + if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { + set_cursor_shape(p_shape); + return; + } + + cursors_cache.erase(p_shape); + } + Ref<Texture> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; @@ -1855,6 +1868,11 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c [cursors[p_shape] release]; cursors[p_shape] = cursor; + Vector<Variant> params; + params.push_back(p_cursor); + params.push_back(p_hotspot); + cursors_cache.insert(p_shape, params); + if (p_shape == cursor_shape) { if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { [cursor set]; diff --git a/platform/server/detect.py b/platform/server/detect.py index a325395d6d..185dce8128 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -66,7 +66,7 @@ def configure(env): env.Prepend(CCFLAGS=['-O2']) else: #optimize for size env.Prepend(CCFLAGS=['-Os']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) @@ -75,7 +75,7 @@ def configure(env): elif (env["target"] == "debug"): env.Prepend(CCFLAGS=['-g3']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) env.Append(LINKFLAGS=['-rdynamic']) ## Architecture @@ -95,7 +95,7 @@ def configure(env): env["CC"] = "clang" env["CXX"] = "clang++" env["LINK"] = "clang++" - env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) + env.Append(CPPDEFINES=['TYPED_METHOD_BIND']) env.extra_suffix = ".llvm" + env.extra_suffix @@ -196,8 +196,8 @@ def configure(env): # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228 env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509']) - if not env['builtin_libwebsockets']: - env.ParseConfig('pkg-config libwebsockets --cflags --libs') + if not env['builtin_wslay']: + env.ParseConfig('pkg-config libwslay --cflags --libs') if not env['builtin_miniupnpc']: # No pkgconfig file so far, hardcode default paths. @@ -216,7 +216,7 @@ def configure(env): env.ParseConfig('pkg-config zlib --cflags --libs') env.Prepend(CPPPATH=['#platform/server']) - env.Append(CPPFLAGS=['-DSERVER_ENABLED', '-DUNIX_ENABLED']) + env.Append(CPPDEFINES=['SERVER_ENABLED', 'UNIX_ENABLED']) if (platform.system() == "Darwin"): env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-lz', '-framework', 'IOKit']) diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp index 12e53054bc..87dc6421ac 100644 --- a/platform/server/os_server.cpp +++ b/platform/server/os_server.cpp @@ -88,6 +88,8 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int visual_server = memnew(VisualServerRaster); visual_server->init(); + camera_server = memnew(CameraServer); + AudioDriverManager::initialize(p_audio_driver); input = memnew(InputDefault); @@ -117,6 +119,8 @@ void OS_Server::finalize() { memdelete(input); + memdelete(camera_server); + memdelete(power_manager); ResourceLoader::remove_resource_format_loader(resource_loader_dummy); diff --git a/platform/server/os_server.h b/platform/server/os_server.h index e3488a693d..dbdae6afb1 100644 --- a/platform/server/os_server.h +++ b/platform/server/os_server.h @@ -74,6 +74,7 @@ class OS_Server : public OS_Unix { #endif CrashHandler crash_handler; + CameraServer *camera_server; int video_driver_index; diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py index 00f419f4f0..7da93eafae 100644 --- a/platform/uwp/detect.py +++ b/platform/uwp/detect.py @@ -60,13 +60,13 @@ def configure(env): elif (env["target"] == "release_debug"): env.Append(CCFLAGS=['/O2', '/Zi']) env.Append(CCFLAGS=['/MD']) - env.Append(CPPFLAGS=['/DDEBUG_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED']) env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) elif (env["target"] == "debug"): env.Append(CCFLAGS=['/Zi']) env.Append(CCFLAGS=['/MDd']) - env.Append(CPPFLAGS=['/DDEBUG_ENABLED', '/DDEBUG_MEMORY_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) env.Append(LINKFLAGS=['/DEBUG']) @@ -138,18 +138,18 @@ def configure(env): ## Compile flags env.Prepend(CPPPATH=['#platform/uwp', '#drivers/windows']) - env.Append(CPPFLAGS=['/DUWP_ENABLED', '/DWINDOWS_ENABLED', '/DTYPED_METHOD_BIND']) - env.Append(CPPFLAGS=['/DGLES_ENABLED', '/DGL_GLEXT_PROTOTYPES', '/DEGL_EGLEXT_PROTOTYPES', '/DANGLE_ENABLED']) + env.Append(CPPDEFINES=['UWP_ENABLED', 'WINDOWS_ENABLED', 'TYPED_METHOD_BIND']) + env.Append(CPPDEFINES=['GLES_ENABLED', 'GL_GLEXT_PROTOTYPES', 'EGL_EGLEXT_PROTOTYPES', 'ANGLE_ENABLED']) winver = "0x0602" # Windows 8 is the minimum target for UWP build - env.Append(CPPFLAGS=['/DWINVER=%s' % winver, '/D_WIN32_WINNT=%s' % winver]) + env.Append(CPPDEFINES=[('WINVER', winver), ('_WIN32_WINNT', winver), 'WIN32']) - env.Append(CPPFLAGS=['/D__WRL_NO_DEFAULT_LIB__', '/DWIN32', '/DPNG_ABORT=abort']) + env.Append(CPPDEFINES=['__WRL_NO_DEFAULT_LIB__', ('PNG_ABORT', 'abort')]) env.Append(CPPFLAGS=['/AI', vc_base_path + 'lib/store/references']) env.Append(CPPFLAGS=['/AI', vc_base_path + 'lib/x86/store/references']) env.Append(CCFLAGS='/FS /MP /GS /wd"4453" /wd"28204" /wd"4291" /Zc:wchar_t /Gm- /fp:precise /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo'.split()) - env.Append(CPPFLAGS=['/D_UNICODE', '/DUNICODE', '/D "WINAPI_FAMILY=WINAPI_FAMILY_APP"']) + env.Append(CPPDEFINES=['_UNICODE', 'UNICODE', ('WINAPI_FAMILY', 'WINAPI_FAMILY_APP')]) env.Append(CXXFLAGS=['/ZW']) env.Append(CCFLAGS=['/AI', vc_base_path + '\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR'] + '\\References\\CommonConfiguration\\Neutral']) diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index ec43a4c26f..abb7b391d3 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -32,6 +32,7 @@ #include "core/bind/core_bind.h" #include "core/io/marshalls.h" #include "core/io/zip_io.h" +#include "core/math/crypto_core.h" #include "core/object.h" #include "core/os/file_access.h" #include "core/project_settings.h" @@ -42,8 +43,6 @@ #include "thirdparty/minizip/unzip.h" #include "thirdparty/minizip/zip.h" -#include "thirdparty/misc/base64.h" -#include "thirdparty/misc/sha256.h" #include <zlib.h> @@ -198,15 +197,12 @@ public: String AppxPackager::hash_block(const uint8_t *p_block_data, size_t p_block_len) { - char hash[32]; + unsigned char hash[32]; char base64[45]; - sha256_context ctx; - sha256_init(&ctx); - sha256_hash(&ctx, (uint8_t *)p_block_data, p_block_len); - sha256_done(&ctx, (uint8_t *)hash); - - base64_encode(base64, hash, 32); + CryptoCore::sha256(p_block_data, p_block_len, hash); + size_t len = 0; + CryptoCore::b64_encode((unsigned char *)base64, 45, &len, (unsigned char *)hash, 32); base64[44] = '\0'; return String(base64); diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 4b4b507499..cc9ba720a8 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -274,7 +274,7 @@ def configure_mingw(env): elif (env["target"] == "release_debug"): env.Append(CCFLAGS=['-O2']) - env.Append(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) if (env["debug_symbols"] == "full"): @@ -286,7 +286,7 @@ def configure_mingw(env): elif (env["target"] == "debug"): env.Append(CCFLAGS=['-g3']) - env.Append(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) ## Compiler configuration @@ -328,14 +328,11 @@ def configure_mingw(env): ## Compile flags env.Append(CCFLAGS=['-mwindows']) - env.Append(CPPFLAGS=['-DWINDOWS_ENABLED']) - env.Append(CPPFLAGS=['-DOPENGL_ENABLED']) - env.Append(CPPFLAGS=['-DWASAPI_ENABLED']) - env.Append(CPPFLAGS=['-DWINMIDI_ENABLED']) - env.Append(CPPFLAGS=['-DWINVER=%s' % env['target_win_version'], '-D_WIN32_WINNT=%s' % env['target_win_version']]) + env.Append(CPPDEFINES=['WINDOWS_ENABLED', 'OPENGL_ENABLED', 'WASAPI_ENABLED', 'WINMIDI_ENABLED']) + env.Append(CPPDEFINES=[('WINVER', env['target_win_version']), ('_WIN32_WINNT', env['target_win_version'])]) env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid']) - env.Append(CPPFLAGS=['-DMINGW_ENABLED']) + env.Append(CPPDEFINES=['MINGW_ENABLED']) # resrc env.Append(BUILDERS={'RES': env.Builder(action=build_res_file, suffix='.o', src_suffix='.rc')}) diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 4a72d07adc..827daa2d58 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -34,6 +34,8 @@ #include "editor/editor_settings.h" #include "platform/windows/logo.gen.h" +static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size); + class EditorExportPlatformWindows : public EditorExportPlatformPC { public: @@ -172,6 +174,80 @@ void register_windows_exporter() { platform->set_release_64("windows_64_release.exe"); platform->set_debug_64("windows_64_debug.exe"); platform->set_os_name("Windows"); + platform->set_fixup_embedded_pck_func(&fixup_embedded_pck); EditorExport::get_singleton()->add_export_platform(platform); } + +static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { + + // Patch the header of the "pck" section in the PE file so that it corresponds to the embedded data + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE); + if (!f) { + return ERR_CANT_OPEN; + } + + // Jump to the PE header and check the magic number + { + f->seek(0x3c); + uint32_t pe_pos = f->get_32(); + + f->seek(pe_pos); + uint32_t magic = f->get_32(); + if (magic != 0x00004550) { + f->close(); + return ERR_FILE_CORRUPT; + } + } + + // Process header + + int num_sections; + { + int64_t header_pos = f->get_position(); + + f->seek(header_pos + 2); + num_sections = f->get_16(); + f->seek(header_pos + 16); + uint16_t opt_header_size = f->get_16(); + + // Skip rest of header + optional header to go to the section headers + f->seek(f->get_position() + 2 + opt_header_size); + } + + // Search for the "pck" section + + int64_t section_table_pos = f->get_position(); + + bool found = false; + for (int i = 0; i < num_sections; ++i) { + + int64_t section_header_pos = section_table_pos + i * 40; + f->seek(section_header_pos); + + uint8_t section_name[9]; + f->get_buffer(section_name, 8); + section_name[8] = '\0'; + + if (strcmp((char *)section_name, "pck") == 0) { + // "pck" section found, let's patch! + + // Set virtual size to a little to avoid it taking memory (zero would give issues) + f->seek(section_header_pos + 8); + f->store_32(8); + + f->seek(section_header_pos + 16); + f->store_32(p_embedded_size); + f->seek(section_header_pos + 20); + f->store_32(p_embedded_start); + + found = true; + break; + } + } + + f->close(); + + return found ? OK : ERR_FILE_CORRUPT; +} diff --git a/platform/windows/godot_windows.cpp b/platform/windows/godot_windows.cpp index 0b52682c7c..11bfea6922 100644 --- a/platform/windows/godot_windows.cpp +++ b/platform/windows/godot_windows.cpp @@ -34,6 +34,17 @@ #include <locale.h> #include <stdio.h> +// For export templates, add a section; the exporter will patch it to enclose +// the data appended to the executable (bundled PCK) +#ifndef TOOLS_ENABLED +#if defined _MSC_VER +#pragma section("pck", read) +__declspec(allocate("pck")) static char dummy[8] = { 0 }; +#elif defined __GNUC__ +static const char dummy[8] __attribute__((section("pck"), used)) = { 0 }; +#endif +#endif + PCHAR * CommandLineToArgvA( PCHAR CmdLine, diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index e535f6a148..745f3ce379 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -2367,7 +2367,20 @@ OS::CursorShape OS_Windows::get_cursor_shape() const { } void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + if (p_cursor.is_valid()) { + + Map<CursorShape, Vector<Variant> >::Element *cursor_c = cursors_cache.find(p_shape); + + if (cursor_c) { + if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { + set_cursor_shape(p_shape); + return; + } + + cursors_cache.erase(p_shape); + } + Ref<Texture> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; @@ -2450,6 +2463,11 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap cursors[p_shape] = CreateIconIndirect(&iconinfo); + Vector<Variant> params; + params.push_back(p_cursor); + params.push_back(p_hotspot); + cursors_cache.insert(p_shape, params); + if (p_shape == cursor_shape) { if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { SetCursor(cursors[p_shape]); @@ -2586,7 +2604,7 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, modstr.resize(cmdline.size()); for (int i = 0; i < cmdline.size(); i++) modstr.write[i] = cmdline[i]; - int ret = CreateProcessW(NULL, modstr.ptrw(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS, NULL, NULL, si_w, &pi.pi); + int ret = CreateProcessW(NULL, modstr.ptrw(), NULL, NULL, 0, NORMAL_PRIORITY_CLASS & CREATE_NO_WINDOW, NULL, NULL, si_w, &pi.pi); ERR_FAIL_COND_V(ret == 0, ERR_CANT_FORK); if (p_blocking) { diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index fc8ad1b188..ce55328173 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -155,6 +155,7 @@ class OS_Windows : public OS { HCURSOR cursors[CURSOR_MAX] = { NULL }; CursorShape cursor_shape; + Map<CursorShape, Vector<Variant> > cursors_cache; InputDefault *input; JoypadWindows *joypad; diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index 9718b03164..d70b947fcc 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -145,6 +145,7 @@ Error ContextGL_X11::initialize() { break; } } + XFree(fbc); ERR_FAIL_COND_V(!fbconfig, ERR_UNCONFIGURED); swa.background_pixmap = None; @@ -159,6 +160,7 @@ Error ContextGL_X11::initialize() { vi = glXGetVisualFromFBConfig(x11_display, fbc[0]); fbconfig = fbc[0]; + XFree(fbc); } int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler); diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 9614104750..f3a486df02 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -98,7 +98,7 @@ def configure(env): env.Prepend(CCFLAGS=['-O2']) else: #optimize for size env.Prepend(CCFLAGS=['-Os']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED']) if (env["debug_symbols"] == "yes"): env.Prepend(CCFLAGS=['-g1']) @@ -107,7 +107,7 @@ def configure(env): elif (env["target"] == "debug"): env.Prepend(CCFLAGS=['-g3']) - env.Prepend(CPPFLAGS=['-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CPPDEFINES=['DEBUG_ENABLED', 'DEBUG_MEMORY_ENABLED']) env.Append(LINKFLAGS=['-rdynamic']) ## Architecture @@ -127,7 +127,7 @@ def configure(env): env["CC"] = "clang" env["CXX"] = "clang++" env["LINK"] = "clang++" - env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND']) + env.Append(CPPDEFINES=['TYPED_METHOD_BIND']) env.extra_suffix = ".llvm" + env.extra_suffix if env['use_lld']: @@ -197,7 +197,7 @@ def configure(env): env.ParseConfig('pkg-config xi --cflags --libs') if (env['touch']): - env.Append(CPPFLAGS=['-DTOUCH_ENABLED']) + env.Append(CPPDEFINES=['TOUCH_ENABLED']) # FIXME: Check for existence of the libs before parsing their flags with pkg-config @@ -266,8 +266,8 @@ def configure(env): # mbedTLS does not provide a pkgconfig config yet. See https://github.com/ARMmbed/mbedtls/issues/228 env.Append(LIBS=['mbedtls', 'mbedcrypto', 'mbedx509']) - if not env['builtin_libwebsockets']: - env.ParseConfig('pkg-config libwebsockets --cflags --libs') + if not env['builtin_wslay']: + env.ParseConfig('pkg-config libwslay --cflags --libs') if not env['builtin_miniupnpc']: # No pkgconfig file so far, hardcode default paths. @@ -283,7 +283,7 @@ def configure(env): if (os.system("pkg-config --exists alsa") == 0): # 0 means found print("Enabling ALSA") - env.Append(CPPFLAGS=["-DALSA_ENABLED", "-DALSAMIDI_ENABLED"]) + env.Append(CPPDEFINES=["ALSA_ENABLED", "ALSAMIDI_ENABLED"]) # Don't parse --cflags, we don't need to add /usr/include/alsa to include path env.ParseConfig('pkg-config alsa --libs') else: @@ -292,18 +292,18 @@ def configure(env): if env['pulseaudio']: if (os.system("pkg-config --exists libpulse") == 0): # 0 means found print("Enabling PulseAudio") - env.Append(CPPFLAGS=["-DPULSEAUDIO_ENABLED"]) + env.Append(CPPDEFINES=["PULSEAUDIO_ENABLED"]) env.ParseConfig('pkg-config --cflags --libs libpulse') else: print("PulseAudio development libraries not found, disabling driver") if (platform.system() == "Linux"): - env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"]) + env.Append(CPPDEFINES=["JOYDEV_ENABLED"]) if env['udev']: if (os.system("pkg-config --exists libudev") == 0): # 0 means found print("Enabling udev support") - env.Append(CPPFLAGS=["-DUDEV_ENABLED"]) + env.Append(CPPDEFINES=["UDEV_ENABLED"]) env.ParseConfig('pkg-config libudev --cflags --libs') else: print("libudev development libraries not found, disabling udev support") @@ -313,7 +313,7 @@ def configure(env): env.ParseConfig('pkg-config zlib --cflags --libs') env.Prepend(CPPPATH=['#platform/x11']) - env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES_ENABLED']) + env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED', 'OPENGL_ENABLED', 'GLES_ENABLED']) env.Append(LIBS=['GL', 'pthread']) if (platform.system() == "Linux"): @@ -324,6 +324,9 @@ def configure(env): if env["execinfo"]: env.Append(LIBS=['execinfo']) + + if not env['tools']: + env.Append(LINKFLAGS=['-T', 'platform/x11/pck_embed.ld']) ## Cross-compilation diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp index f7d98c1d68..8767aac517 100644 --- a/platform/x11/export/export.cpp +++ b/platform/x11/export/export.cpp @@ -30,10 +30,13 @@ #include "export.h" +#include "core/os/file_access.h" #include "editor/editor_export.h" #include "platform/x11/logo.gen.h" #include "scene/resources/texture.h" +static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size); + void register_x11_exporter() { Ref<EditorExportPlatformPC> platform; @@ -53,6 +56,115 @@ void register_x11_exporter() { platform->set_debug_64("linux_x11_64_debug"); platform->set_os_name("X11"); platform->set_chmod_flags(0755); + platform->set_fixup_embedded_pck_func(&fixup_embedded_pck); EditorExport::get_singleton()->add_export_platform(platform); } + +static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { + + // Patch the header of the "pck" section in the ELF file so that it corresponds to the embedded data + + FileAccess *f = FileAccess::open(p_path, FileAccess::READ_WRITE); + if (!f) { + return ERR_CANT_OPEN; + } + + // Read and check ELF magic number + { + uint32_t magic = f->get_32(); + if (magic != 0x464c457f) { // 0x7F + "ELF" + f->close(); + return ERR_FILE_CORRUPT; + } + } + + // Read program architecture bits from class field + + int bits = f->get_8() * 32; + + if (bits == 32 && p_embedded_size >= 0x100000000) { + f->close(); + ERR_EXPLAIN("32-bit executables cannot have embedded data >= 4 GiB"); + ERR_FAIL_V(ERR_INVALID_DATA); + } + + // Get info about the section header table + + int64_t section_table_pos; + int64_t section_header_size; + if (bits == 32) { + section_header_size = 40; + f->seek(0x20); + section_table_pos = f->get_32(); + f->seek(0x30); + } else { // 64 + section_header_size = 64; + f->seek(0x28); + section_table_pos = f->get_64(); + f->seek(0x3c); + } + int num_sections = f->get_16(); + int string_section_idx = f->get_16(); + + // Load the strings table + uint8_t *strings; + { + // Jump to the strings section header + f->seek(section_table_pos + string_section_idx * section_header_size); + + // Read strings data size and offset + int64_t string_data_pos; + int64_t string_data_size; + if (bits == 32) { + f->seek(f->get_position() + 0x10); + string_data_pos = f->get_32(); + string_data_size = f->get_32(); + } else { // 64 + f->seek(f->get_position() + 0x18); + string_data_pos = f->get_64(); + string_data_size = f->get_64(); + } + + // Read strings data + f->seek(string_data_pos); + strings = (uint8_t *)memalloc(string_data_size); + if (!strings) { + f->close(); + return ERR_OUT_OF_MEMORY; + } + f->get_buffer(strings, string_data_size); + } + + // Search for the "pck" section + + bool found = false; + for (int i = 0; i < num_sections; ++i) { + + int64_t section_header_pos = section_table_pos + i * section_header_size; + f->seek(section_header_pos); + + uint32_t name_offset = f->get_32(); + if (strcmp((char *)strings + name_offset, "pck") == 0) { + // "pck" section found, let's patch! + + if (bits == 32) { + f->seek(section_header_pos + 0x10); + f->store_32(p_embedded_start); + f->store_32(p_embedded_size); + } else { // 64 + f->seek(section_header_pos + 0x18); + f->store_64(p_embedded_start); + f->store_64(p_embedded_size); + } + + found = true; + break; + } + } + + memfree(strings); + f->close(); + + return found ? OK : ERR_FILE_CORRUPT; +} diff --git a/platform/x11/godot_x11.cpp b/platform/x11/godot_x11.cpp index 9baa4d6dca..755ef7a84f 100644 --- a/platform/x11/godot_x11.cpp +++ b/platform/x11/godot_x11.cpp @@ -43,6 +43,7 @@ int main(int argc, char *argv[]) { setlocale(LC_CTYPE, ""); char *cwd = (char *)malloc(PATH_MAX); + ERR_FAIL_COND_V(!cwd, ERR_OUT_OF_MEMORY); char *ret = getcwd(cwd, PATH_MAX); Error err = Main::setup(argv[0], argc - 1, &argv[1]); diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 624efe8815..9b35648046 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -2878,7 +2878,20 @@ OS::CursorShape OS_X11::get_cursor_shape() const { } void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) { + if (p_cursor.is_valid()) { + + Map<CursorShape, Vector<Variant> >::Element *cursor_c = cursors_cache.find(p_shape); + + if (cursor_c) { + if (cursor_c->get()[0] == p_cursor && cursor_c->get()[1] == p_hotspot) { + set_cursor_shape(p_shape); + return; + } + + cursors_cache.erase(p_shape); + } + Ref<Texture> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; @@ -2947,6 +2960,11 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c // Save it for a further usage cursors[p_shape] = XcursorImageLoadCursor(x11_display, cursor_image); + Vector<Variant> params; + params.push_back(p_cursor); + params.push_back(p_hotspot); + cursors_cache.insert(p_shape, params); + if (p_shape == current_cursor) { if (mouse_mode == MOUSE_MODE_VISIBLE || mouse_mode == MOUSE_MODE_CONFINED) { XDefineCursor(x11_display, x11_window, cursors[p_shape]); diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index 510487b599..a4c22cf08a 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -170,6 +170,7 @@ class OS_X11 : public OS_Unix { Cursor cursors[CURSOR_MAX]; Cursor null_cursor; CursorShape current_cursor; + Map<CursorShape, Vector<Variant> > cursors_cache; InputDefault *input; diff --git a/platform/x11/pck_embed.ld b/platform/x11/pck_embed.ld new file mode 100644 index 0000000000..fe09144d88 --- /dev/null +++ b/platform/x11/pck_embed.ld @@ -0,0 +1,10 @@ +SECTIONS +{ + /* Add a zero-sized section; the exporter will patch it to enclose the data appended to the executable (embedded PCK) */ + pck 0 (NOLOAD) : + { + /* Just some content to avoid the linker discarding the section */ + . = ALIGN(8); + } +} +INSERT AFTER .rodata; diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp index b7ace804ef..c7f622dee3 100644 --- a/scene/2d/animated_sprite.cpp +++ b/scene/2d/animated_sprite.cpp @@ -663,7 +663,7 @@ StringName AnimatedSprite::get_animation() const { String AnimatedSprite::get_configuration_warning() const { if (frames.is_null()) { - return TTR("A SpriteFrames resource must be created or set in the 'Frames' property in order for AnimatedSprite to display frames."); + return TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite to display frames."); } return String(); diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index a0d74dd283..6011941142 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -140,9 +140,6 @@ Transform2D Camera2D::get_camera_transform() { Point2 screen_offset = (anchor_mode == ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2()); Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom); - if (offset != Vector2()) - screen_rect.position += offset; - if (limit_smoothing_enabled) { if (screen_rect.position.x < limit[MARGIN_LEFT]) camera_pos.x -= screen_rect.position.x - limit[MARGIN_LEFT]; @@ -193,21 +190,8 @@ Transform2D Camera2D::get_camera_transform() { if (screen_rect.position.y < limit[MARGIN_TOP]) screen_rect.position.y = limit[MARGIN_TOP]; - if (offset != Vector2()) { - + if (offset != Vector2()) screen_rect.position += offset; - if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT]) - screen_rect.position.x = limit[MARGIN_RIGHT] - screen_rect.size.x; - - if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) - screen_rect.position.y = limit[MARGIN_BOTTOM] - screen_rect.size.y; - - if (screen_rect.position.x < limit[MARGIN_LEFT]) - screen_rect.position.x = limit[MARGIN_LEFT]; - - if (screen_rect.position.y < limit[MARGIN_TOP]) - screen_rect.position.y = limit[MARGIN_TOP]; - } camera_screen_center = screen_rect.position + screen_rect.size * 0.5; diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp index 23f6404e3e..7368efd21a 100644 --- a/scene/2d/canvas_item.cpp +++ b/scene/2d/canvas_item.cpp @@ -759,7 +759,7 @@ void CanvasItem::draw_multiline_colors(const Vector<Point2> &p_points, const Vec VisualServer::get_singleton()->canvas_item_add_multiline(canvas_item, p_points, p_colors, p_width, p_antialiased); } -void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled) { +void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled, float p_width, bool p_antialiased) { if (!drawing) { ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal."); @@ -767,13 +767,53 @@ void CanvasItem::draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_fil } if (p_filled) { + if (p_width != 1.0) { + WARN_PRINT("The draw_rect() \"width\" argument has no effect when \"filled\" is \"true\"."); + } + + if (p_antialiased) { + WARN_PRINT("The draw_rect() \"antialiased\" argument has no effect when \"filled\" is \"true\"."); + } VisualServer::get_singleton()->canvas_item_add_rect(canvas_item, p_rect, p_color); } else { - VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position, p_rect.position + Size2(p_rect.size.width, 0), p_color); - VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position, p_rect.position + Size2(0, p_rect.size.height), p_color); - VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position + Point2(0, p_rect.size.height), p_rect.position + p_rect.size, p_color); - VisualServer::get_singleton()->canvas_item_add_line(canvas_item, p_rect.position + Point2(p_rect.size.width, 0), p_rect.position + p_rect.size, p_color); + // Thick lines are offset depending on their width to avoid partial overlapping. + // Thin lines don't require an offset, so don't apply one in this case + float offset; + if (p_width >= 2) { + offset = p_width / 2.0; + } else { + offset = 0.0; + } + + VisualServer::get_singleton()->canvas_item_add_line( + canvas_item, + p_rect.position + Point2(-offset, 0), + p_rect.position + Size2(p_rect.size.width + offset, 0), + p_color, + p_width, + p_antialiased); + VisualServer::get_singleton()->canvas_item_add_line( + canvas_item, + p_rect.position + Point2(0, offset), + p_rect.position + Size2(0, p_rect.size.height - offset), + p_color, + p_width, + p_antialiased); + VisualServer::get_singleton()->canvas_item_add_line( + canvas_item, + p_rect.position + Point2(-offset, p_rect.size.height), + p_rect.position + Size2(p_rect.size.width + offset, p_rect.size.height), + p_color, + p_width, + p_antialiased); + VisualServer::get_singleton()->canvas_item_add_line( + canvas_item, + p_rect.position + Point2(p_rect.size.width, offset), + p_rect.position + Size2(p_rect.size.width, p_rect.size.height - offset), + p_color, + p_width, + p_antialiased); } } @@ -928,6 +968,9 @@ float CanvasItem::draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const ERR_FAIL_COND_V(p_char.length() != 1, 0); ERR_FAIL_COND_V(p_font.is_null(), 0); + if (p_font->has_outline()) { + p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.c_str()[0], Color(1, 1, 1), true); + } return p_font->draw_char(canvas_item, p_pos, p_char[0], p_next.c_str()[0], p_modulate); } @@ -1158,7 +1201,7 @@ void CanvasItem::_bind_methods() { ClassDB::bind_method(D_METHOD("draw_polyline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_polyline_colors, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_multiline", "points", "color", "width", "antialiased"), &CanvasItem::draw_multiline, DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_multiline_colors", "points", "colors", "width", "antialiased"), &CanvasItem::draw_multiline_colors, DEFVAL(1.0), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled"), &CanvasItem::draw_rect, DEFVAL(true)); + ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color", "filled", "width", "antialiased"), &CanvasItem::draw_rect, DEFVAL(true), DEFVAL(1.0), DEFVAL(false)); ClassDB::bind_method(D_METHOD("draw_circle", "position", "radius", "color"), &CanvasItem::draw_circle); ClassDB::bind_method(D_METHOD("draw_texture", "texture", "position", "modulate", "normal_map"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture", "rect", "tile", "modulate", "transpose", "normal_map"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant())); diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h index 2604eb04e4..9c6799a441 100644 --- a/scene/2d/canvas_item.h +++ b/scene/2d/canvas_item.h @@ -307,7 +307,7 @@ public: void draw_polyline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); void draw_multiline(const Vector<Point2> &p_points, const Color &p_color, float p_width = 1.0, bool p_antialiased = false); void draw_multiline_colors(const Vector<Point2> &p_points, const Vector<Color> &p_colors, float p_width = 1.0, bool p_antialiased = false); - void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true); + void draw_rect(const Rect2 &p_rect, const Color &p_color, bool p_filled = true, float p_width = 1.0, bool p_antialiased = false); void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color); void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref<Texture> &p_normal_map = Ref<Texture>()); void draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()); diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp index 36c88e395a..202c7c9cf2 100644 --- a/scene/2d/collision_object_2d.cpp +++ b/scene/2d/collision_object_2d.cpp @@ -389,7 +389,7 @@ String CollisionObject2D::get_configuration_warning() const { if (shapes.empty()) { if (!warning.empty()) { - warning += "\n"; + warning += "\n\n"; } warning += TTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape2D or CollisionPolygon2D as a child to define its shape."); } diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp index ef7644fcab..bb144dda96 100644 --- a/scene/2d/collision_polygon_2d.cpp +++ b/scene/2d/collision_polygon_2d.cpp @@ -70,7 +70,7 @@ void CollisionPolygon2D::_build_polygon() { w[(i << 1) + 1] = polygon[(i + 1) % polygon.size()]; } - w = PoolVector<Vector2>::Write(); + w.release(); concave->set_segments(segments); parent->shape_owner_add_shape(owner_id, concave); diff --git a/scene/2d/collision_shape_2d.cpp b/scene/2d/collision_shape_2d.cpp index 5440a1d8c3..f79d79d039 100644 --- a/scene/2d/collision_shape_2d.cpp +++ b/scene/2d/collision_shape_2d.cpp @@ -97,15 +97,8 @@ void CollisionShape2D::_notification(int p_what) { } owner_id = 0; parent = NULL; - } break; - /* - case NOTIFICATION_TRANSFORM_CHANGED: { - - if (!is_inside_scene()) - break; - _update_parent(); - } break;*/ + } break; case NOTIFICATION_DRAW: { if (!Engine::get_singleton()->is_editor_hint() && !get_tree()->is_debugging_collisions_hint()) { @@ -131,10 +124,13 @@ void CollisionShape2D::_notification(int p_what) { rect = rect.grow(3); if (one_way_collision) { - Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4); - dcol.a = 1.0; + // Draw an arrow indicating the one-way collision direction + draw_col = get_tree()->get_debug_collisions_color().inverted(); + if (disabled) { + draw_col = draw_col.darkened(0.25); + } Vector2 line_to(0, 20); - draw_line(Vector2(), line_to, dcol, 3); + draw_line(Vector2(), line_to, draw_col, 2, true); Vector<Vector2> pts; float tsize = 8; pts.push_back(line_to + (Vector2(0, tsize))); @@ -142,9 +138,9 @@ void CollisionShape2D::_notification(int p_what) { pts.push_back(line_to + (Vector2(-0.707 * tsize, 0))); Vector<Color> cols; for (int i = 0; i < 3; i++) - cols.push_back(dcol); + cols.push_back(draw_col); - draw_primitive(pts, cols, Vector<Vector2>()); //small arrow + draw_primitive(pts, cols, Vector<Vector2>()); } } break; } diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp index 75315bfc6e..1bddc4d22f 100644 --- a/scene/2d/cpu_particles_2d.cpp +++ b/scene/2d/cpu_particles_2d.cpp @@ -83,6 +83,10 @@ void CPUParticles2D::set_randomness_ratio(float p_ratio) { randomness_ratio = p_ratio; } +void CPUParticles2D::set_lifetime_randomness(float p_random) { + + lifetime_randomness = p_random; +} void CPUParticles2D::set_use_local_coordinates(bool p_enable) { local_coords = p_enable; @@ -123,6 +127,10 @@ float CPUParticles2D::get_randomness_ratio() const { return randomness_ratio; } +float CPUParticles2D::get_lifetime_randomness() const { + + return lifetime_randomness; +} bool CPUParticles2D::get_use_local_coordinates() const { @@ -262,6 +270,16 @@ void CPUParticles2D::restart() { } } +void CPUParticles2D::set_direction(Vector2 p_direction) { + + direction = p_direction; +} + +Vector2 CPUParticles2D::get_direction() const { + + return direction; +} + void CPUParticles2D::set_spread(float p_spread) { spread = p_spread; @@ -601,6 +619,10 @@ void CPUParticles2D::_particles_process(float p_delta) { } } + if (p.time * (1.0 - explosiveness_ratio) > p.lifetime) { + restart = true; + } + if (restart) { if (!emitting) { @@ -631,7 +653,7 @@ void CPUParticles2D::_particles_process(float p_delta) { p.hue_rot_rand = Math::randf(); p.anim_offset_rand = Math::randf(); - float angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; 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]); @@ -644,6 +666,7 @@ void CPUParticles2D::_particles_process(float p_delta) { p.custom[3] = 0.0; p.transform = Transform2D(); p.time = 0; + p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness); p.base_color = Color(1, 1, 1, 1); switch (emission_shape) { @@ -651,8 +674,9 @@ void CPUParticles2D::_particles_process(float p_delta) { //do none } break; case EMISSION_SHAPE_SPHERE: { - Vector3 sphere_shape = Vector3(Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0).normalized() * emission_sphere_radius; - p.transform[2] = Vector2(sphere_shape.x, sphere_shape.y); + float s = Math::randf(), t = 2.0 * Math_PI * 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; case EMISSION_SHAPE_RECTANGLE: { p.transform[2] = Vector2(Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0) * emission_rect_extents; @@ -685,6 +709,8 @@ void CPUParticles2D::_particles_process(float p_delta) { } else if (!p.active) { continue; + } else if (p.time > p.lifetime) { + p.active = false; } else { uint32_t alt_seed = p.seed; @@ -1121,6 +1147,8 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { if (material.is_null()) return; + Vector3 dir = material->get_direction(); + set_direction(Vector2(dir.x, dir.y)); set_spread(material->get_spread()); set_flatness(material->get_flatness()); @@ -1140,6 +1168,7 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) { Vector2 gravity = Vector2(material->get_gravity().x, material->get_gravity().y); set_gravity(gravity); + set_lifetime_randomness(material->get_lifetime_randomness()); #define CONVERT_PARAM(m_param) \ set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \ @@ -1174,6 +1203,7 @@ void CPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &CPUParticles2D::set_pre_process_time); ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &CPUParticles2D::set_explosiveness_ratio); ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &CPUParticles2D::set_randomness_ratio); + ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "random"), &CPUParticles2D::set_lifetime_randomness); ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &CPUParticles2D::set_use_local_coordinates); ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &CPUParticles2D::set_fixed_fps); ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &CPUParticles2D::set_fractional_delta); @@ -1186,6 +1216,7 @@ void CPUParticles2D::_bind_methods() { ClassDB::bind_method(D_METHOD("get_pre_process_time"), &CPUParticles2D::get_pre_process_time); ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &CPUParticles2D::get_explosiveness_ratio); ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &CPUParticles2D::get_randomness_ratio); + ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &CPUParticles2D::get_lifetime_randomness); ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &CPUParticles2D::get_use_local_coordinates); ClassDB::bind_method(D_METHOD("get_fixed_fps"), &CPUParticles2D::get_fixed_fps); ClassDB::bind_method(D_METHOD("get_fractional_delta"), &CPUParticles2D::get_fractional_delta); @@ -1212,6 +1243,7 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); @@ -1226,6 +1258,9 @@ void CPUParticles2D::_bind_methods() { //////////////////////////////// + ClassDB::bind_method(D_METHOD("set_direction", "direction"), &CPUParticles2D::set_direction); + ClassDB::bind_method(D_METHOD("get_direction"), &CPUParticles2D::get_direction); + ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &CPUParticles2D::set_spread); ClassDB::bind_method(D_METHOD("get_spread"), &CPUParticles2D::get_spread); @@ -1284,7 +1319,8 @@ void CPUParticles2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "emission_colors"), "set_emission_colors", "get_emission_colors"); ADD_GROUP("Flags", "flag_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY); - ADD_GROUP("Spread", ""); + ADD_GROUP("Direction", ""); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); ADD_GROUP("Gravity", ""); @@ -1387,11 +1423,13 @@ CPUParticles2D::CPUParticles2D() { 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_flatness(0); set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0); diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h index 813f5ddc6e..1cd22df9e7 100644 --- a/scene/2d/cpu_particles_2d.h +++ b/scene/2d/cpu_particles_2d.h @@ -96,6 +96,7 @@ private: float hue_rot_rand; float anim_offset_rand; float time; + float lifetime; Color base_color; uint32_t seed; @@ -139,6 +140,7 @@ private: float pre_process_time; float explosiveness_ratio; float randomness_ratio; + float lifetime_randomness; float speed_scale; bool local_coords; int fixed_fps; @@ -153,6 +155,7 @@ private: //////// + Vector2 direction; float spread; float flatness; @@ -199,6 +202,7 @@ public: void set_pre_process_time(float p_time); void set_explosiveness_ratio(float p_ratio); void set_randomness_ratio(float p_ratio); + void set_lifetime_randomness(float p_random); void set_visibility_aabb(const Rect2 &p_aabb); void set_use_local_coordinates(bool p_enable); void set_speed_scale(float p_scale); @@ -210,6 +214,7 @@ public: float get_pre_process_time() const; float get_explosiveness_ratio() const; float get_randomness_ratio() const; + float get_lifetime_randomness() const; Rect2 get_visibility_aabb() const; bool get_use_local_coordinates() const; float get_speed_scale() const; @@ -234,6 +239,9 @@ public: /////////////////// + void set_direction(Vector2 p_direction); + Vector2 get_direction() const; + void set_spread(float p_spread); float get_spread() const; diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp index 7f01ff8806..7b3eab175a 100644 --- a/scene/2d/light_2d.cpp +++ b/scene/2d/light_2d.cpp @@ -347,7 +347,7 @@ void Light2D::_notification(int p_what) { String Light2D::get_configuration_warning() const { if (!texture.is_valid()) { - return TTR("A texture with the shape of the light must be supplied to the 'texture' property."); + return TTR("A texture with the shape of the light must be supplied to the \"Texture\" property."); } return String(); diff --git a/scene/2d/light_occluder_2d.cpp b/scene/2d/light_occluder_2d.cpp index 3a3f90ac4b..313b23b9d4 100644 --- a/scene/2d/light_occluder_2d.cpp +++ b/scene/2d/light_occluder_2d.cpp @@ -268,7 +268,7 @@ String LightOccluder2D::get_configuration_warning() const { } if (occluder_polygon.is_valid() && occluder_polygon->get_polygon().size() == 0) { - return TTR("The occluder polygon for this occluder is empty. Please draw a polygon!"); + return TTR("The occluder polygon for this occluder is empty. Please draw a polygon."); } return String(); diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp index 7759897420..93c12f0103 100644 --- a/scene/2d/particles_2d.cpp +++ b/scene/2d/particles_2d.cpp @@ -410,6 +410,7 @@ Particles2D::Particles2D() { particles = VS::get_singleton()->particles_create(); + one_shot = false; // Needed so that set_emitting doesn't access uninitialized values set_emitting(true); set_one_shot(false); set_amount(8); diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp index e062067248..f2f53d4354 100644 --- a/scene/2d/path_2d.cpp +++ b/scene/2d/path_2d.cpp @@ -58,7 +58,7 @@ Rect2 Path2D::_edit_get_rect() const { } bool Path2D::_edit_use_rect() const { - return true; + return curve.is_valid() && curve->get_point_count() != 0; } bool Path2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 95acf13fad..39b3375f09 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -963,7 +963,7 @@ String RigidBody2D::get_configuration_warning() const { if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.elements[0].length() - 1.0) > 0.05 || ABS(t.elements[1].length() - 1.0) > 0.05)) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } warning += TTR("Size changes to RigidBody2D (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead."); } diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp index f6f1bad581..32a0b732c0 100644 --- a/scene/2d/polygon_2d.cpp +++ b/scene/2d/polygon_2d.cpp @@ -76,7 +76,7 @@ Rect2 Polygon2D::_edit_get_rect() const { } bool Polygon2D::_edit_use_rect() const { - return true; + return polygon.size() > 0; } bool Polygon2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const { diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 57dfe5176d..bf8d008bb2 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -100,6 +100,7 @@ Vector2 RayCast2D::get_collision_normal() const { void RayCast2D::set_enabled(bool p_enabled) { enabled = p_enabled; + update(); if (is_inside_tree() && !Engine::get_singleton()->is_editor_hint()) set_physics_process_internal(p_enabled); if (!p_enabled) @@ -167,19 +168,25 @@ void RayCast2D::_notification(int p_what) { xf.rotate(cast_to.angle()); xf.translate(Vector2(cast_to.length(), 0)); - //Vector2 tip = Vector2(0,s->get_length()); - Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4); - draw_line(Vector2(), cast_to, dcol, 3); + // Draw an arrow indicating where the RayCast is pointing to + Color draw_col = get_tree()->get_debug_collisions_color(); + if (!enabled) { + float g = draw_col.get_v(); + draw_col.r = g; + draw_col.g = g; + draw_col.b = g; + } + draw_line(Vector2(), cast_to, draw_col, 2, true); Vector<Vector2> pts; - float tsize = 4; + float tsize = 8; pts.push_back(xf.xform(Vector2(tsize, 0))); pts.push_back(xf.xform(Vector2(0, 0.707 * tsize))); pts.push_back(xf.xform(Vector2(0, -0.707 * tsize))); Vector<Color> cols; for (int i = 0; i < 3; i++) - cols.push_back(dcol); + cols.push_back(draw_col); - draw_primitive(pts, cols, Vector<Vector2>()); //small arrow + draw_primitive(pts, cols, Vector<Vector2>()); } break; diff --git a/scene/2d/remote_transform_2d.cpp b/scene/2d/remote_transform_2d.cpp index 1c38a91877..fe8cc5a5fc 100644 --- a/scene/2d/remote_transform_2d.cpp +++ b/scene/2d/remote_transform_2d.cpp @@ -110,7 +110,7 @@ void RemoteTransform2D::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_READY: { + case NOTIFICATION_ENTER_TREE: { _update_cache(); @@ -180,6 +180,10 @@ bool RemoteTransform2D::get_update_scale() const { return update_remote_scale; } +void RemoteTransform2D::force_update_cache() { + _update_cache(); +} + String RemoteTransform2D::get_configuration_warning() const { if (!has_node(remote_node) || !Object::cast_to<Node2D>(get_node(remote_node))) { @@ -193,6 +197,7 @@ void RemoteTransform2D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_remote_node", "path"), &RemoteTransform2D::set_remote_node); ClassDB::bind_method(D_METHOD("get_remote_node"), &RemoteTransform2D::get_remote_node); + ClassDB::bind_method(D_METHOD("force_update_cache"), &RemoteTransform2D::force_update_cache); ClassDB::bind_method(D_METHOD("set_use_global_coordinates", "use_global_coordinates"), &RemoteTransform2D::set_use_global_coordinates); ClassDB::bind_method(D_METHOD("get_use_global_coordinates"), &RemoteTransform2D::get_use_global_coordinates); diff --git a/scene/2d/remote_transform_2d.h b/scene/2d/remote_transform_2d.h index 16a5417592..e85fe33fc6 100644 --- a/scene/2d/remote_transform_2d.h +++ b/scene/2d/remote_transform_2d.h @@ -69,6 +69,8 @@ public: void set_update_scale(const bool p_update); bool get_update_scale() const; + void force_update_cache(); + virtual String get_configuration_warning() const; RemoteTransform2D(); diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index aa15255384..bf43fca864 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -137,7 +137,7 @@ String Bone2D::get_configuration_warning() const { String warning = Node2D::get_configuration_warning(); if (!skeleton) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } if (parent_bone) { warning += TTR("This Bone2D chain should end at a Skeleton2D node."); @@ -148,7 +148,7 @@ String Bone2D::get_configuration_warning() const { if (rest == Transform2D(0, 0, 0, 0, 0, 0)) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } warning += TTR("This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."); } diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index fc53c9e4ac..c79cd80e2e 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -234,6 +234,25 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const Size2 s = p_sc; Vector2 offset = p_offset; + if (compatibility_mode && !centered_textures) { + + if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { + offset.y += cell_size.y; + } else if (tile_origin == TILE_ORIGIN_CENTER) { + offset += cell_size / 2; + } + + if (s.y > s.x) { + if ((p_cell.flip_h && (p_cell.flip_v || p_cell.transpose)) || (p_cell.flip_v && !p_cell.transpose)) { + offset.y += s.y - s.x; + } + } else if (s.y < s.x) { + if ((p_cell.flip_v && (p_cell.flip_h || p_cell.transpose)) || (p_cell.flip_h && !p_cell.transpose)) { + offset.x += s.x - s.y; + } + } + } + if (p_cell.transpose) { SWAP(xform.elements[0].x, xform.elements[0].y); SWAP(xform.elements[1].x, xform.elements[1].y); @@ -244,16 +263,36 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const if (p_cell.flip_h) { xform.elements[0].x = -xform.elements[0].x; xform.elements[1].x = -xform.elements[1].x; - offset.x = s.x - offset.x; + if (compatibility_mode && !centered_textures) { + if (tile_origin == TILE_ORIGIN_TOP_LEFT || tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { + offset.x = s.x - offset.x; + } else if (tile_origin == TILE_ORIGIN_CENTER) { + offset.x = s.x - offset.x / 2; + } + } else { + offset.x = s.x - offset.x; + } } if (p_cell.flip_v) { xform.elements[0].y = -xform.elements[0].y; xform.elements[1].y = -xform.elements[1].y; - offset.y = s.y - offset.y; + if (compatibility_mode && !centered_textures) { + if (tile_origin == TILE_ORIGIN_TOP_LEFT) { + offset.y = s.y - offset.y; + } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { + offset.y += s.y; + } else if (tile_origin == TILE_ORIGIN_CENTER) { + offset.y += s.y; + } + } else { + offset.y = s.y - offset.y; + } + } + + if (centered_textures) { + offset += cell_size / 2 - s / 2; } - /* For a future CheckBox to Center Texture: - offset += cell_size / 2 - s / 2; */ xform.elements[2] += offset; } @@ -434,13 +473,24 @@ void TileMap::update_dirty_quadrants() { rect.size.x += fp_adjust; rect.size.y += fp_adjust; + if (compatibility_mode && !centered_textures) { + if (rect.size.y > rect.size.x) { + if ((c.flip_h && (c.flip_v || c.transpose)) || (c.flip_v && !c.transpose)) + tile_ofs.y += rect.size.y - rect.size.x; + } else if (rect.size.y < rect.size.x) { + if ((c.flip_v && (c.flip_h || c.transpose)) || (c.flip_h && !c.transpose)) + tile_ofs.x += rect.size.x - rect.size.y; + } + } + if (c.transpose) { SWAP(tile_ofs.x, tile_ofs.y); - /* For a future CheckBox to Center Texture: - rect.position.x += cell_size.x / 2 - rect.size.y / 2; - rect.position.y += cell_size.y / 2 - rect.size.x / 2; - } else { - rect.position += cell_size / 2 - rect.size / 2; */ + if (centered_textures) { + rect.position.x += cell_size.x / 2 - rect.size.y / 2; + rect.position.y += cell_size.y / 2 - rect.size.x / 2; + } + } else if (centered_textures) { + rect.position += cell_size / 2 - rect.size / 2; } if (c.flip_h) { @@ -453,7 +503,43 @@ void TileMap::update_dirty_quadrants() { tile_ofs.y = -tile_ofs.y; } - rect.position += tile_ofs; + if (compatibility_mode && !centered_textures) { + if (tile_origin == TILE_ORIGIN_TOP_LEFT) { + rect.position += tile_ofs; + + } else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) { + + rect.position += tile_ofs; + + if (c.transpose) { + if (c.flip_h) + rect.position.x -= cell_size.x; + else + rect.position.x += cell_size.x; + } else { + if (c.flip_v) + rect.position.y -= cell_size.y; + else + rect.position.y += cell_size.y; + } + + } else if (tile_origin == TILE_ORIGIN_CENTER) { + + rect.position += tile_ofs; + + if (c.flip_h) + rect.position.x -= cell_size.x / 2; + else + rect.position.x += cell_size.x / 2; + + if (c.flip_v) + rect.position.y -= cell_size.y / 2; + else + rect.position.y += cell_size.y / 2; + } + } else { + rect.position += tile_ofs; + } Ref<Texture> normal_map = tile_set->tile_get_normal_map(c.id); Color modulate = tile_set->tile_get_modulate(c.id); @@ -775,7 +861,7 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_ if (!E && p_tile == INVALID_CELL) return; //nothing to do - PosKey qk(p_x / _get_quadrant_size(), p_y / _get_quadrant_size()); + PosKey qk = pk.to_quadrant(_get_quadrant_size()); if (p_tile == INVALID_CELL) { //erase existing tile_map.erase(pk); @@ -934,7 +1020,7 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) { E->get().autotile_coord_x = (int)coord.x; E->get().autotile_coord_y = (int)coord.y; - PosKey qk(p_x / _get_quadrant_size(), p_y / _get_quadrant_size()); + PosKey qk = p.to_quadrant(_get_quadrant_size()); Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk); _make_quadrant_dirty(Q); @@ -1031,7 +1117,7 @@ void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord) c.autotile_coord_y = p_coord.y; tile_map[pk] = c; - PosKey qk(p_x / _get_quadrant_size(), p_y / _get_quadrant_size()); + PosKey qk = pk.to_quadrant(_get_quadrant_size()); Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk); if (!Q) @@ -1058,7 +1144,7 @@ void TileMap::_recreate_quadrants() { for (Map<PosKey, Cell>::Element *E = tile_map.front(); E; E = E->next()) { - PosKey qk(E->key().x / _get_quadrant_size(), E->key().y / _get_quadrant_size()); + PosKey qk = PosKey(E->key().x, E->key().y).to_quadrant(_get_quadrant_size()); Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk); if (!Q) { @@ -1156,10 +1242,7 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) { coord_x = decode_uint16(&local[8]); coord_y = decode_uint16(&local[10]); } - /* - if (x<-20 || y <-20 || x>4000 || y>4000) - continue; - */ + set_cell(x, y, v, flip_h, flip_v, transpose, Vector2(coord_x, coord_y)); } @@ -1192,13 +1275,17 @@ PoolVector<int> TileMap::_get_tile_data() const { idx += 3; } - w = PoolVector<int>::Write(); + w.release(); return data; } Rect2 TileMap::_edit_get_rect() const { - const_cast<TileMap *>(this)->update_dirty_quadrants(); + if (pending_update) { + const_cast<TileMap *>(this)->update_dirty_quadrants(); + } else { + const_cast<TileMap *>(this)->_recompute_rect_cache(); + } return rect_cache; } @@ -1570,6 +1657,32 @@ bool TileMap::is_y_sort_mode_enabled() const { return y_sort_mode; } +void TileMap::set_compatibility_mode(bool p_enable) { + + _clear_quadrants(); + compatibility_mode = p_enable; + _recreate_quadrants(); + emit_signal("settings_changed"); +} + +bool TileMap::is_compatibility_mode_enabled() const { + + return compatibility_mode; +} + +void TileMap::set_centered_textures(bool p_enable) { + + _clear_quadrants(); + centered_textures = p_enable; + _recreate_quadrants(); + emit_signal("settings_changed"); +} + +bool TileMap::is_centered_textures_enabled() const { + + return centered_textures; +} + Array TileMap::get_used_cells() const { Array a; @@ -1667,7 +1780,7 @@ String TileMap::get_configuration_warning() const { if (use_parent && !collision_parent) { if (!warning.empty()) { - warning += "\n"; + warning += "\n\n"; } return TTR("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."); } @@ -1707,6 +1820,12 @@ void TileMap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_y_sort_mode", "enable"), &TileMap::set_y_sort_mode); ClassDB::bind_method(D_METHOD("is_y_sort_mode_enabled"), &TileMap::is_y_sort_mode_enabled); + ClassDB::bind_method(D_METHOD("set_compatibility_mode", "enable"), &TileMap::set_compatibility_mode); + ClassDB::bind_method(D_METHOD("is_compatibility_mode_enabled"), &TileMap::is_compatibility_mode_enabled); + + ClassDB::bind_method(D_METHOD("set_centered_textures", "enable"), &TileMap::set_centered_textures); + ClassDB::bind_method(D_METHOD("is_centered_textures_enabled"), &TileMap::is_centered_textures_enabled); + ClassDB::bind_method(D_METHOD("set_collision_use_kinematic", "use_kinematic"), &TileMap::set_collision_use_kinematic); ClassDB::bind_method(D_METHOD("get_collision_use_kinematic"), &TileMap::get_collision_use_kinematic); @@ -1775,6 +1894,8 @@ void TileMap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_half_offset", PROPERTY_HINT_ENUM, "Offset X,Offset Y,Disabled,Offset Negative X,Offset Negative Y"), "set_half_offset", "get_half_offset"); ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_tile_origin", PROPERTY_HINT_ENUM, "Top Left,Center,Bottom Left"), "set_tile_origin", "get_tile_origin"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_y_sort"), "set_y_sort_mode", "is_y_sort_mode_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compatibility_mode"), "set_compatibility_mode", "is_compatibility_mode_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered_textures"), "set_centered_textures", "is_centered_textures_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "cell_clip_uv"), "set_clip_uv", "get_clip_uv"); ADD_GROUP("Collision", "collision_"); @@ -1832,6 +1953,8 @@ TileMap::TileMap() { use_kinematic = false; navigation = NULL; y_sort_mode = false; + compatibility_mode = false; + centered_textures = false; occluder_light_mask = 1; clip_uv = false; format = FORMAT_1; //Always initialize with the lowest format diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index 1caaefa213..e30b7eff83 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -94,6 +94,13 @@ private: bool operator==(const PosKey &p_k) const { return (y == p_k.y && x == p_k.x); } + PosKey to_quadrant(const int &p_quadrant_size) const { + // rounding down, instead of simply rounding towards zero (truncating) + return PosKey( + x > 0 ? x / p_quadrant_size : (x - (p_quadrant_size - 1)) / p_quadrant_size, + y > 0 ? y / p_quadrant_size : (y - (p_quadrant_size - 1)) / p_quadrant_size); + } + PosKey(int16_t p_x, int16_t p_y) { x = p_x; y = p_y; @@ -181,6 +188,8 @@ private: bool used_size_cache_dirty; bool quadrant_order_dirty; bool y_sort_mode; + bool compatibility_mode; + bool centered_textures; bool clip_uv; float fp_adjust; float friction; @@ -311,6 +320,12 @@ public: void set_y_sort_mode(bool p_enable); bool is_y_sort_mode_enabled() const; + void set_compatibility_mode(bool p_enable); + bool is_compatibility_mode_enabled() const; + + void set_centered_textures(bool p_enable); + bool is_centered_textures_enabled() const; + Array get_used_cells() const; Array get_used_cells_by_id(int p_id) const; Rect2 get_used_rect(); // Not const because of cache diff --git a/scene/2d/visibility_notifier_2d.cpp b/scene/2d/visibility_notifier_2d.cpp index 1cf037daf2..a1d074e6cd 100644 --- a/scene/2d/visibility_notifier_2d.cpp +++ b/scene/2d/visibility_notifier_2d.cpp @@ -327,7 +327,7 @@ void VisibilityEnabler2D::_node_removed(Node *p_node) { String VisibilityEnabler2D::get_configuration_warning() const { #ifdef TOOLS_ENABLED if (is_inside_tree() && get_parent() && (get_parent()->get_filename() == String() && get_parent() != get_tree()->get_edited_scene_root())) { - return TTR("VisibilityEnable2D works best when used with the edited scene root directly as parent."); + return TTR("VisibilityEnabler2D works best when used with the edited scene root directly as parent."); } #endif return String(); diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp index dfa8fce9be..263a2d8de6 100644 --- a/scene/3d/arvr_nodes.cpp +++ b/scene/3d/arvr_nodes.cpp @@ -61,7 +61,7 @@ String ARVRCamera::get_configuration_warning() const { // must be child node of ARVROrigin! ARVROrigin *origin = Object::cast_to<ARVROrigin>(get_parent()); if (origin == NULL) { - return TTR("ARVRCamera must have an ARVROrigin node as its parent"); + return TTR("ARVRCamera must have an ARVROrigin node as its parent."); }; return String(); diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp index ff28f60d4f..054c211d23 100644 --- a/scene/3d/audio_stream_player_3d.cpp +++ b/scene/3d/audio_stream_player_3d.cpp @@ -974,7 +974,7 @@ void AudioStreamPlayer3D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_degrees", PROPERTY_HINT_RANGE, "0.1,90,0.1"), "set_emission_angle", "get_emission_angle"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_filter_attenuation_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_emission_angle_filter_attenuation_db", "get_emission_angle_filter_attenuation_db"); ADD_GROUP("Attenuation Filter", "attenuation_filter_"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "50,50000,1"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_attenuation_filter_db", "get_attenuation_filter_db"); ADD_GROUP("Doppler", "doppler_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Physics"), "set_doppler_tracking", "get_doppler_tracking"); diff --git a/scene/3d/baked_lightmap.cpp b/scene/3d/baked_lightmap.cpp index 2b12e78158..c5ff4dadbc 100644 --- a/scene/3d/baked_lightmap.cpp +++ b/scene/3d/baked_lightmap.cpp @@ -221,6 +221,15 @@ Vector3 BakedLightmap::get_extents() const { return extents; } +void BakedLightmap::set_bake_default_texels_per_unit(const float &p_bake_texels_per_unit) { + bake_default_texels_per_unit = p_bake_texels_per_unit; + update_gizmo(); +} + +float BakedLightmap::get_bake_default_texels_per_unit() const { + return bake_default_texels_per_unit; +} + void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, List<PlotMesh> &plot_meshes, List<PlotLight> &plot_lights) { MeshInstance *mi = Object::cast_to<MeshInstance>(p_at_node); @@ -236,7 +245,7 @@ void BakedLightmap::_find_meshes_and_lights(Node *p_at_node, List<PlotMesh> &plo } } - if (all_have_uv2 && mesh->get_lightmap_size_hint() != Size2()) { + if (all_have_uv2) { //READY TO BAKE! size hint could be computed if not found, actually.. AABB aabb = mesh->get_aabb(); @@ -463,7 +472,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi btd.text = RTR("Lighting Meshes: ") + mesh_name + " (" + itos(pmc) + "/" + itos(mesh_list.size()) + ")"; btd.pass = step; btd.last_step = 0; - err = baker.make_lightmap(E->get().local_xform, E->get().mesh, lm, _bake_time, &btd); + err = baker.make_lightmap(E->get().local_xform, E->get().mesh, bake_default_texels_per_unit, lm, _bake_time, &btd); if (err != OK) { bake_end_function(); if (err == ERR_SKIP) @@ -473,7 +482,7 @@ BakedLightmap::BakeError BakedLightmap::bake(Node *p_from_node, bool p_create_vi step += 100; } else { - err = baker.make_lightmap(E->get().local_xform, E->get().mesh, lm); + err = baker.make_lightmap(E->get().local_xform, E->get().mesh, bake_default_texels_per_unit, lm); } if (err == OK) { @@ -790,6 +799,9 @@ void BakedLightmap::_bind_methods() { ClassDB::bind_method(D_METHOD("set_extents", "extents"), &BakedLightmap::set_extents); ClassDB::bind_method(D_METHOD("get_extents"), &BakedLightmap::get_extents); + ClassDB::bind_method(D_METHOD("set_bake_default_texels_per_unit", "texels"), &BakedLightmap::set_bake_default_texels_per_unit); + ClassDB::bind_method(D_METHOD("get_bake_default_texels_per_unit"), &BakedLightmap::get_bake_default_texels_per_unit); + ClassDB::bind_method(D_METHOD("set_propagation", "propagation"), &BakedLightmap::set_propagation); ClassDB::bind_method(D_METHOD("get_propagation"), &BakedLightmap::get_propagation); @@ -814,6 +826,7 @@ void BakedLightmap::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_energy", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_energy", "get_energy"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "bake_hdr"), "set_hdr", "is_hdr"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "bake_extents"), "set_extents", "get_extents"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "bake_default_texels_per_unit"), "set_bake_default_texels_per_unit", "get_bake_default_texels_per_unit"); ADD_GROUP("Capture", "capture_"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "capture_cell_size", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_capture_cell_size", "get_capture_cell_size"); ADD_GROUP("Data", ""); @@ -836,6 +849,7 @@ void BakedLightmap::_bind_methods() { BakedLightmap::BakedLightmap() { extents = Vector3(10, 10, 10); + bake_default_texels_per_unit = 20; bake_cell_size = 0.25; capture_cell_size = 0.5; diff --git a/scene/3d/baked_lightmap.h b/scene/3d/baked_lightmap.h index bb3f84719a..3a9f4cf01d 100644 --- a/scene/3d/baked_lightmap.h +++ b/scene/3d/baked_lightmap.h @@ -119,6 +119,7 @@ private: float bake_cell_size; float capture_cell_size; Vector3 extents; + float bake_default_texels_per_unit; float propagation; float energy; BakeQuality bake_quality; @@ -178,6 +179,9 @@ public: void set_extents(const Vector3 &p_extents); Vector3 get_extents() const; + void set_bake_default_texels_per_unit(const float &p_bake_texels_per_unit); + float get_bake_default_texels_per_unit() const; + void set_propagation(float p_propagation); float get_propagation() const; diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp index fc46cf5bdb..9d3e2983c4 100644 --- a/scene/3d/collision_object.cpp +++ b/scene/3d/collision_object.cpp @@ -371,7 +371,7 @@ String CollisionObject::get_configuration_warning() const { if (shapes.empty()) { if (warning == String()) { - warning += "\n"; + warning += "\n\n"; } warning += TTR("This node has no shape, so it can't collide or interact with other objects.\nConsider adding a CollisionShape or CollisionPolygon as a child to define its shape."); } diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp index 219ea56681..2b030641eb 100644 --- a/scene/3d/collision_shape.cpp +++ b/scene/3d/collision_shape.cpp @@ -120,7 +120,7 @@ String CollisionShape::get_configuration_warning() const { } if (!shape.is_valid()) { - return TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it!"); + return TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it."); } if (shape->is_class("PlaneShape")) { diff --git a/scene/3d/cpu_particles.cpp b/scene/3d/cpu_particles.cpp index 6ede9c10ef..7ab7363c7c 100644 --- a/scene/3d/cpu_particles.cpp +++ b/scene/3d/cpu_particles.cpp @@ -92,6 +92,10 @@ void CPUParticles::set_randomness_ratio(float p_ratio) { randomness_ratio = p_ratio; } +void CPUParticles::set_lifetime_randomness(float p_random) { + + lifetime_randomness = p_random; +} void CPUParticles::set_use_local_coordinates(bool p_enable) { local_coords = p_enable; @@ -130,6 +134,10 @@ float CPUParticles::get_randomness_ratio() const { return randomness_ratio; } +float CPUParticles::get_lifetime_randomness() const { + + return lifetime_randomness; +} bool CPUParticles::get_use_local_coordinates() const { @@ -237,6 +245,16 @@ void CPUParticles::restart() { } } +void CPUParticles::set_direction(Vector3 p_direction) { + + direction = p_direction; +} + +Vector3 CPUParticles::get_direction() const { + + return direction; +} + void CPUParticles::set_spread(float p_spread) { spread = p_spread; @@ -573,6 +591,10 @@ void CPUParticles::_particles_process(float p_delta) { } } + if (p.time * (1.0 - explosiveness_ratio) > p.lifetime) { + restart = true; + } + if (restart) { if (!emitting) { @@ -604,13 +626,13 @@ void CPUParticles::_particles_process(float p_delta) { p.anim_offset_rand = Math::randf(); if (flags[FLAG_DISABLE_Z]) { - float angle1_rad = (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; + float angle1_rad = Math::atan2(direction.y, direction.x) + (Math::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; 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::randf() * 2.0 - 1.0) * Math_PI * spread / 180.0; - float angle2_rad = (Math::randf() * 2.0 - 1.0) * (1.0 - flatness) * Math_PI * spread / 180.0; + 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; 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)); @@ -626,6 +648,7 @@ void CPUParticles::_particles_process(float p_delta) { p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp(1.0f, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation offset (0-1) p.transform = Transform(); p.time = 0; + p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness); p.base_color = Color(1, 1, 1, 1); switch (emission_shape) { @@ -633,7 +656,9 @@ void CPUParticles::_particles_process(float p_delta) { //do none } break; case EMISSION_SHAPE_SPHERE: { - p.transform.origin = Vector3(Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0).normalized() * emission_sphere_radius; + 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); + p.transform.origin = Vector3(radius * Math::cos(t), radius * Math::sin(t), emission_sphere_radius * s); } break; case EMISSION_SHAPE_BOX: { p.transform.origin = Vector3(Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0, Math::randf() * 2.0 - 1.0) * emission_box_extents; @@ -689,6 +714,8 @@ void CPUParticles::_particles_process(float p_delta) { } else if (!p.active) { continue; + } else if (p.time > p.lifetime) { + p.active = false; } else { uint32_t alt_seed = p.seed; @@ -1189,6 +1216,7 @@ void CPUParticles::convert_from_particles(Node *p_particles) { if (material.is_null()) return; + set_direction(material->get_direction()); set_spread(material->get_spread()); set_flatness(material->get_flatness()); @@ -1208,6 +1236,7 @@ void CPUParticles::convert_from_particles(Node *p_particles) { set_emission_box_extents(material->get_emission_box_extents()); set_gravity(material->get_gravity()); + set_lifetime_randomness(material->get_lifetime_randomness()); #define CONVERT_PARAM(m_param) \ set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \ @@ -1242,6 +1271,7 @@ void CPUParticles::_bind_methods() { ClassDB::bind_method(D_METHOD("set_pre_process_time", "secs"), &CPUParticles::set_pre_process_time); ClassDB::bind_method(D_METHOD("set_explosiveness_ratio", "ratio"), &CPUParticles::set_explosiveness_ratio); ClassDB::bind_method(D_METHOD("set_randomness_ratio", "ratio"), &CPUParticles::set_randomness_ratio); + ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "random"), &CPUParticles::set_lifetime_randomness); ClassDB::bind_method(D_METHOD("set_use_local_coordinates", "enable"), &CPUParticles::set_use_local_coordinates); ClassDB::bind_method(D_METHOD("set_fixed_fps", "fps"), &CPUParticles::set_fixed_fps); ClassDB::bind_method(D_METHOD("set_fractional_delta", "enable"), &CPUParticles::set_fractional_delta); @@ -1254,6 +1284,7 @@ void CPUParticles::_bind_methods() { ClassDB::bind_method(D_METHOD("get_pre_process_time"), &CPUParticles::get_pre_process_time); ClassDB::bind_method(D_METHOD("get_explosiveness_ratio"), &CPUParticles::get_explosiveness_ratio); ClassDB::bind_method(D_METHOD("get_randomness_ratio"), &CPUParticles::get_randomness_ratio); + ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &CPUParticles::get_lifetime_randomness); ClassDB::bind_method(D_METHOD("get_use_local_coordinates"), &CPUParticles::get_use_local_coordinates); ClassDB::bind_method(D_METHOD("get_fixed_fps"), &CPUParticles::get_fixed_fps); ClassDB::bind_method(D_METHOD("get_fractional_delta"), &CPUParticles::get_fractional_delta); @@ -1277,6 +1308,7 @@ void CPUParticles::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_speed_scale", "get_speed_scale"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "explosiveness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_explosiveness_ratio", "get_explosiveness_ratio"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_randomness_ratio", "get_randomness_ratio"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); ADD_PROPERTY(PropertyInfo(Variant::INT, "fixed_fps", PROPERTY_HINT_RANGE, "0,1000,1"), "set_fixed_fps", "get_fixed_fps"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fract_delta"), "set_fractional_delta", "get_fractional_delta"); ADD_GROUP("Drawing", ""); @@ -1290,6 +1322,9 @@ void CPUParticles::_bind_methods() { //////////////////////////////// + ClassDB::bind_method(D_METHOD("set_direction", "direction"), &CPUParticles::set_direction); + ClassDB::bind_method(D_METHOD("get_direction"), &CPUParticles::get_direction); + ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &CPUParticles::set_spread); ClassDB::bind_method(D_METHOD("get_spread"), &CPUParticles::get_spread); @@ -1350,7 +1385,8 @@ void CPUParticles::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_particle_flag", "get_particle_flag", FLAG_ALIGN_Y_TO_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_particle_flag", "get_particle_flag", FLAG_ROTATE_Y); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_particle_flag", "get_particle_flag", FLAG_DISABLE_Z); - ADD_GROUP("Spread", ""); + ADD_GROUP("Direction", ""); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); ADD_GROUP("Gravity", ""); @@ -1455,11 +1491,13 @@ CPUParticles::CPUParticles() { 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); diff --git a/scene/3d/cpu_particles.h b/scene/3d/cpu_particles.h index 6566792def..71de56f59e 100644 --- a/scene/3d/cpu_particles.h +++ b/scene/3d/cpu_particles.h @@ -95,6 +95,7 @@ private: float hue_rot_rand; float anim_offset_rand; float time; + float lifetime; Color base_color; uint32_t seed; @@ -137,6 +138,7 @@ private: float pre_process_time; float explosiveness_ratio; float randomness_ratio; + float lifetime_randomness; float speed_scale; bool local_coords; int fixed_fps; @@ -152,6 +154,7 @@ private: //////// + Vector3 direction; float spread; float flatness; @@ -199,6 +202,7 @@ public: void set_pre_process_time(float p_time); void set_explosiveness_ratio(float p_ratio); void set_randomness_ratio(float p_ratio); + void set_lifetime_randomness(float p_random); void set_visibility_aabb(const AABB &p_aabb); void set_use_local_coordinates(bool p_enable); void set_speed_scale(float p_scale); @@ -210,6 +214,7 @@ public: float get_pre_process_time() const; float get_explosiveness_ratio() const; float get_randomness_ratio() const; + float get_lifetime_randomness() const; AABB get_visibility_aabb() const; bool get_use_local_coordinates() const; float get_speed_scale() const; @@ -231,6 +236,9 @@ public: /////////////////// + void set_direction(Vector3 p_direction); + Vector3 get_direction() const; + void set_spread(float p_spread); float get_spread() const; diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp index 414e932f61..a04f156d80 100644 --- a/scene/3d/gi_probe.cpp +++ b/scene/3d/gi_probe.cpp @@ -571,4 +571,5 @@ GIProbe::GIProbe() { } GIProbe::~GIProbe() { + VS::get_singleton()->free(gi_probe); } diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 2e64872616..91595657b1 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -51,6 +51,7 @@ void Light::set_param(Param p_param, float p_value) { if (p_param == PARAM_SPOT_ANGLE) { _change_notify("spot_angle"); + update_configuration_warning(); } else if (p_param == PARAM_RANGE) { _change_notify("omni_range"); _change_notify("spot_range"); @@ -68,6 +69,10 @@ void Light::set_shadow(bool p_enable) { shadow = p_enable; VS::get_singleton()->light_set_shadow(light, p_enable); + + if (type == VisualServer::LIGHT_SPOT) { + update_configuration_warning(); + } } bool Light::has_shadow() const { @@ -408,7 +413,7 @@ DirectionalLight::DirectionalLight() : set_param(PARAM_SHADOW_NORMAL_BIAS, 0.8); set_param(PARAM_SHADOW_BIAS, 0.1); - set_param(PARAM_SHADOW_MAX_DISTANCE, 200); + set_param(PARAM_SHADOW_MAX_DISTANCE, 100); set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.25); set_shadow_mode(SHADOW_PARALLEL_4_SPLITS); set_shadow_depth_range(SHADOW_DEPTH_RANGE_STABLE); @@ -465,6 +470,20 @@ OmniLight::OmniLight() : set_shadow_detail(SHADOW_DETAIL_HORIZONTAL); } +String SpotLight::get_configuration_warning() const { + String warning = Light::get_configuration_warning(); + + if (has_shadow() && get_param(PARAM_SPOT_ANGLE) >= 90.0) { + if (warning != String()) { + warning += "\n\n"; + } + + warning += TTR("A SpotLight with an angle wider than 90 degrees cannot cast shadows."); + } + + return warning; +} + void SpotLight::_bind_methods() { ADD_GROUP("Spot", "spot_"); diff --git a/scene/3d/light.h b/scene/3d/light.h index ddd5bc6b3a..5d365758b5 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -221,6 +221,8 @@ protected: static void _bind_methods(); public: + virtual String get_configuration_warning() const; + SpotLight() : Light(VisualServer::LIGHT_SPOT) {} }; diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp index 2bcd0eaa46..a6ccdb5791 100644 --- a/scene/3d/particles.cpp +++ b/scene/3d/particles.cpp @@ -257,7 +257,7 @@ String Particles::get_configuration_warning() const { SpatialMaterial *spat = Object::cast_to<SpatialMaterial>(draw_passes[i]->surface_get_material(j).ptr()); anim_material_found = anim_material_found || (spat && spat->get_billboard_mode() == SpatialMaterial::BILLBOARD_PARTICLES); } - if (meshes_found && anim_material_found) break; + if (anim_material_found) break; } } @@ -411,6 +411,7 @@ Particles::Particles() { particles = VS::get_singleton()->particles_create(); set_base(particles); + one_shot = false; // Needed so that set_emitting doesn't access uninitialized values set_emitting(true); set_one_shot(false); set_amount(8); diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp index 84078911cb..d55c795d38 100644 --- a/scene/3d/path.cpp +++ b/scene/3d/path.cpp @@ -270,7 +270,7 @@ String PathFollow::get_configuration_warning() const { } else { Path *path = Object::cast_to<Path>(get_parent()); if (path->get_curve().is_valid() && !path->get_curve()->is_up_vector_enabled() && rotation_mode == ROTATION_ORIENTED) { - return TTR("PathFollow ROTATION_ORIENTED requires \"Up Vector\" enabled in its parent Path's Curve resource."); + return TTR("PathFollow's ROTATION_ORIENTED requires \"Up Vector\" to be enabled in its parent Path's Curve resource."); } } diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index d3aad7000d..2f8b2ecc5c 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -934,7 +934,7 @@ String RigidBody::get_configuration_warning() const { if ((get_mode() == MODE_RIGID || get_mode() == MODE_CHARACTER) && (ABS(t.basis.get_axis(0).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(1).length() - 1.0) > 0.05 || ABS(t.basis.get_axis(2).length() - 1.0) > 0.05)) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } warning += TTR("Size changes to RigidBody (in character or rigid modes) will be overridden by the physics engine when running.\nChange the size in children collision shapes instead."); } diff --git a/scene/3d/remote_transform.cpp b/scene/3d/remote_transform.cpp index add77e0272..76b0b0c92f 100644 --- a/scene/3d/remote_transform.cpp +++ b/scene/3d/remote_transform.cpp @@ -105,7 +105,7 @@ void RemoteTransform::_notification(int p_what) { switch (p_what) { - case NOTIFICATION_READY: { + case NOTIFICATION_ENTER_TREE: { _update_cache(); @@ -174,10 +174,14 @@ bool RemoteTransform::get_update_scale() const { return update_remote_scale; } +void RemoteTransform::force_update_cache() { + _update_cache(); +} + String RemoteTransform::get_configuration_warning() const { if (!has_node(remote_node) || !Object::cast_to<Spatial>(get_node(remote_node))) { - return TTR("Path property must point to a valid Spatial node to work."); + return TTR("The \"Remote Path\" property must point to a valid Spatial or Spatial-derived node to work."); } return String(); @@ -187,6 +191,7 @@ void RemoteTransform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_remote_node", "path"), &RemoteTransform::set_remote_node); ClassDB::bind_method(D_METHOD("get_remote_node"), &RemoteTransform::get_remote_node); + ClassDB::bind_method(D_METHOD("force_update_cache"), &RemoteTransform::force_update_cache); ClassDB::bind_method(D_METHOD("set_use_global_coordinates", "use_global_coordinates"), &RemoteTransform::set_use_global_coordinates); ClassDB::bind_method(D_METHOD("get_use_global_coordinates"), &RemoteTransform::get_use_global_coordinates); diff --git a/scene/3d/remote_transform.h b/scene/3d/remote_transform.h index b737a4f858..07e01284e5 100644 --- a/scene/3d/remote_transform.h +++ b/scene/3d/remote_transform.h @@ -68,6 +68,8 @@ public: void set_update_scale(const bool p_update); bool get_update_scale() const; + void force_update_cache(); + virtual String get_configuration_warning() const; RemoteTransform(); diff --git a/scene/3d/soft_body.cpp b/scene/3d/soft_body.cpp index a9d96292a1..386e127f8b 100644 --- a/scene/3d/soft_body.cpp +++ b/scene/3d/soft_body.cpp @@ -73,7 +73,7 @@ void SoftBodyVisualServerHandler::open() { } void SoftBodyVisualServerHandler::close() { - write_buffer = PoolVector<uint8_t>::Write(); + write_buffer.release(); } void SoftBodyVisualServerHandler::commit_changes() { @@ -712,6 +712,7 @@ SoftBody::SoftBody() : } SoftBody::~SoftBody() { + PhysicsServer::get_singleton()->free(physics_rid); } void SoftBody::reset_softbody_pin() { diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp index 9f73484b6a..67c79d8b5a 100644 --- a/scene/3d/sprite_3d.cpp +++ b/scene/3d/sprite_3d.cpp @@ -254,7 +254,7 @@ Ref<TriangleMesh> SpriteBase3D::generate_triangle_mesh() const { facesw[j] = vtx; } - facesw = PoolVector<Vector3>::Write(); + facesw.release(); triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); triangle_mesh->create(faces); @@ -1061,7 +1061,7 @@ StringName AnimatedSprite3D::get_animation() const { String AnimatedSprite3D::get_configuration_warning() const { if (frames.is_null()) { - return TTR("A SpriteFrames resource must be created or set in the 'Frames' property in order for AnimatedSprite3D to display frames."); + return TTR("A SpriteFrames resource must be created or set in the \"Frames\" property in order for AnimatedSprite3D to display frames."); } return String(); diff --git a/scene/3d/voxel_light_baker.cpp b/scene/3d/voxel_light_baker.cpp index 5fa8c43f9f..8e09930aed 100644 --- a/scene/3d/voxel_light_baker.cpp +++ b/scene/3d/voxel_light_baker.cpp @@ -1792,19 +1792,82 @@ void VoxelLightBaker::_lightmap_bake_point(uint32_t p_x, LightMap *p_line) { } } -Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float), void *p_bake_time_ud) { +Error VoxelLightBaker::make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, float default_texels_per_unit, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float), void *p_bake_time_ud) { //transfer light information to a lightmap Ref<Mesh> mesh = p_mesh; - int width = mesh->get_lightmap_size_hint().x; - int height = mesh->get_lightmap_size_hint().y; - //step 1 - create lightmap + int width; + int height; Vector<LightMap> lightmap; - lightmap.resize(width * height); - Transform xform = to_cell_space * p_xform; + if (mesh->get_lightmap_size_hint() == Size2()) { + double area = 0; + double uv_area = 0; + for (int i = 0; i < mesh->get_surface_count(); i++) { + Array arrays = mesh->surface_get_arrays(i); + PoolVector<Vector3> vertices = arrays[Mesh::ARRAY_VERTEX]; + PoolVector<Vector2> uv2 = arrays[Mesh::ARRAY_TEX_UV2]; + PoolVector<int> indices = arrays[Mesh::ARRAY_INDEX]; + + ERR_FAIL_COND_V(vertices.size() == 0, ERR_INVALID_PARAMETER); + ERR_FAIL_COND_V(uv2.size() == 0, ERR_INVALID_PARAMETER); + + int vc = vertices.size(); + PoolVector<Vector3>::Read vr = vertices.read(); + PoolVector<Vector2>::Read u2r = uv2.read(); + PoolVector<int>::Read ir; + int ic = 0; + + if (indices.size()) { + ic = indices.size(); + ir = indices.read(); + } + + int faces = ic ? ic / 3 : vc / 3; + for (int j = 0; j < faces; j++) { + Vector3 vertex[3]; + Vector2 uv[3]; + + for (int k = 0; k < 3; k++) { + int idx = ic ? ir[j * 3 + k] : j * 3 + k; + vertex[k] = xform.xform(vr[idx]); + uv[k] = u2r[idx]; + } + + Vector3 p1 = vertex[0]; + Vector3 p2 = vertex[1]; + Vector3 p3 = vertex[2]; + double a = p1.distance_to(p2); + double b = p2.distance_to(p3); + double c = p3.distance_to(p1); + double halfPerimeter = (a + b + c) / 2.0; + area += sqrt(halfPerimeter * (halfPerimeter - a) * (halfPerimeter - b) * (halfPerimeter - c)); + + Vector2 uv_p1 = uv[0]; + Vector2 uv_p2 = uv[1]; + Vector2 uv_p3 = uv[2]; + double uv_a = uv_p1.distance_to(uv_p2); + double uv_b = uv_p2.distance_to(uv_p3); + double uv_c = uv_p3.distance_to(uv_p1); + double uv_halfPerimeter = (uv_a + uv_b + uv_c) / 2.0; + uv_area += sqrt(uv_halfPerimeter * (uv_halfPerimeter - uv_a) * (uv_halfPerimeter - uv_b) * (uv_halfPerimeter - uv_c)); + } + } + + if (uv_area < 0.0001f) { + uv_area = 1.0; + } + + int pixels = (ceil((1.0 / sqrt(uv_area)) * sqrt(area * default_texels_per_unit))); + width = height = CLAMP(pixels, 2, 4096); + } else { + width = mesh->get_lightmap_size_hint().x; + height = mesh->get_lightmap_size_hint().y; + } + + lightmap.resize(width * height); //step 2 plot faces to lightmap for (int i = 0; i < mesh->get_surface_count(); i++) { diff --git a/scene/3d/voxel_light_baker.h b/scene/3d/voxel_light_baker.h index 295e099d47..2e2efc62ff 100644 --- a/scene/3d/voxel_light_baker.h +++ b/scene/3d/voxel_light_baker.h @@ -177,7 +177,7 @@ public: PoolVector<float> light; }; - Error make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float) = NULL, void *p_bake_time_ud = NULL); + Error make_lightmap(const Transform &p_xform, Ref<Mesh> &p_mesh, float default_texels_per_unit, LightMapData &r_lightmap, bool (*p_bake_time_func)(void *, float, float) = NULL, void *p_bake_time_ud = NULL); PoolVector<int> create_gi_probe_data(); Ref<MultiMesh> create_debug_multimesh(DebugMode p_mode = DEBUG_ALBEDO); diff --git a/scene/3d/world_environment.cpp b/scene/3d/world_environment.cpp index 3cd43cbf5b..8d46b4161d 100644 --- a/scene/3d/world_environment.cpp +++ b/scene/3d/world_environment.cpp @@ -80,7 +80,7 @@ Ref<Environment> WorldEnvironment::get_environment() const { String WorldEnvironment::get_configuration_warning() const { if (!environment.is_valid()) { - return TTR("WorldEnvironment needs an Environment resource."); + return TTR("WorldEnvironment requires its \"Environment\" property to contain an Environment to have a visible effect."); } if (/*!is_visible_in_tree() ||*/ !is_inside_tree()) diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 54f0fdc26a..6745b57cff 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -1342,15 +1342,15 @@ String AnimationTree::get_configuration_warning() const { if (!root.is_valid()) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } - warning += TTR("A root AnimationNode for the graph is not set."); + warning += TTR("No root AnimationNode for the graph is set."); } if (!has_node(animation_player)) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } warning += TTR("Path to an AnimationPlayer node containing animations is not set."); @@ -1361,7 +1361,7 @@ String AnimationTree::get_configuration_warning() const { if (!player) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } warning += TTR("Path set for AnimationPlayer does not lead to an AnimationPlayer node."); @@ -1370,10 +1370,10 @@ String AnimationTree::get_configuration_warning() const { if (!player->has_node(player->get_root())) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } - warning += TTR("AnimationPlayer root is not a valid node."); + warning += TTR("The AnimationPlayer root node is not a valid node."); return warning; } diff --git a/scene/animation/skeleton_ik.cpp b/scene/animation/skeleton_ik.cpp index 43c4b2aa51..7a1b10792b 100644 --- a/scene/animation/skeleton_ik.cpp +++ b/scene/animation/skeleton_ik.cpp @@ -406,6 +406,7 @@ void SkeletonIK::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { skeleton = Object::cast_to<Skeleton>(get_parent()); + set_process_priority(1); reload_chain(); } break; case NOTIFICATION_INTERNAL_PROCESS: { @@ -431,8 +432,6 @@ SkeletonIK::SkeletonIK() : skeleton(NULL), target_node_override(NULL), task(NULL) { - - set_process_priority(1); } SkeletonIK::~SkeletonIK() { diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp index c9cf5f8308..449076f863 100644 --- a/scene/gui/container.cpp +++ b/scene/gui/container.cpp @@ -175,9 +175,9 @@ String Container::get_configuration_warning() const { if (get_class() == "Container" && get_script().is_null()) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } - warning += TTR("Container by itself serves no purpose unless a script configures its children placement behavior.\nIf you don't intend to add a script, then please use a plain 'Control' node instead."); + warning += TTR("Container by itself serves no purpose unless a script configures its children placement behavior.\nIf you don't intend to add a script, use a plain Control node instead."); } return warning; } diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index eccd42cb9f..26be17f6c1 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2711,7 +2711,7 @@ String Control::get_configuration_warning() const { if (data.mouse_filter == MOUSE_FILTER_IGNORE && data.tooltip != "") { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } warning += TTR("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\"."); } diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 6463ee5ad5..222c75b21d 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -599,6 +599,8 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) { Vector2 mpos = Vector2(mb->get_position().x, mb->get_position().y); if (close_rect.size != Size2() && close_rect.has_point(mpos)) { + //send focus to parent + get_parent_control()->grab_focus(); emit_signal("close_request"); accept_event(); return; @@ -615,9 +617,7 @@ void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) { return; } - //send focus to parent emit_signal("raise_request"); - get_parent_control()->grab_focus(); } if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) { diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 91b76839d7..a3bc68ffcd 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -754,7 +754,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) { for (int i = current + 1; i <= items.size(); i++) { if (i == items.size()) { - if (current == 0) + if (current == 0 || current == -1) break; else i = 0; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 7a015f77db..d5347edb87 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -999,6 +999,8 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) { Ref<StyleBox> style = get_stylebox("normal"); int pixel_ofs = 0; Size2 size = get_size(); + bool display_clear_icon = !text.empty() && is_editable() && clear_button_enabled; + int r_icon_width = Control::get_icon("clear")->get_width(); switch (align) { @@ -1013,10 +1015,16 @@ void LineEdit::set_cursor_at_pixel_pos(int p_x) { pixel_ofs = int(style->get_offset().x); else pixel_ofs = int(size.width - (cached_width)) / 2; + + if (display_clear_icon) + pixel_ofs -= int(r_icon_width / 2 + style->get_margin(MARGIN_RIGHT)); } break; case ALIGN_RIGHT: { pixel_ofs = int(size.width - style->get_margin(MARGIN_RIGHT) - (cached_width)); + + if (display_clear_icon) + pixel_ofs -= int(r_icon_width + style->get_margin(MARGIN_RIGHT)); } break; } @@ -1191,7 +1199,7 @@ void LineEdit::set_cursor_position(int p_pos) { if (cursor_pos <= window_pos) { /* Adjust window if cursor goes too much to the left */ set_window_pos(MAX(0, cursor_pos - 1)); - } else if (cursor_pos > window_pos) { + } else { /* Adjust window if cursor goes too much to the right */ int window_width = get_size().width - style->get_minimum_size().width; bool display_clear_icon = !text.empty() && is_editable() && clear_button_enabled; diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp index 492e379440..3e003af396 100644 --- a/scene/gui/popup.cpp +++ b/scene/gui/popup.cpp @@ -48,6 +48,14 @@ void Popup::_notification(int p_what) { update_configuration_warning(); } + if (p_what == NOTIFICATION_EXIT_TREE) { + if (popped_up) { + popped_up = false; + notification(NOTIFICATION_POPUP_HIDE); + emit_signal("popup_hide"); + } + } + if (p_what == NOTIFICATION_ENTER_TREE) { //small helper to make editing of these easier in editor #ifdef TOOLS_ENABLED @@ -226,7 +234,7 @@ Popup::Popup() { String Popup::get_configuration_warning() const { if (is_visible_in_tree()) { - return TTR("Popups will hide by default unless you call popup() or any of the popup*() functions. Making them visible for editing is fine though, but they will hide upon running."); + return TTR("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."); } return String(); diff --git a/scene/gui/range.cpp b/scene/gui/range.cpp index d00acaf08a..e709bac377 100644 --- a/scene/gui/range.cpp +++ b/scene/gui/range.cpp @@ -35,9 +35,9 @@ String Range::get_configuration_warning() const { if (shared->exp_ratio && shared->min <= 0) { if (warning != String()) { - warning += "\n"; + warning += "\n\n"; } - warning += TTR("If exp_edit is true min_value must be > 0."); + warning += TTR("If \"Exp Edit\" is enabled, \"Min Value\" must be greater than 0."); } return warning; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 5b91299de6..d6c0981ebc 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1942,37 +1942,37 @@ Error RichTextLabel::append_bbcode(const String &p_bbcode) { if (col.begins_with("#")) color = Color::html(col); else if (col == "aqua") - color = Color::html("#00FFFF"); + color = Color(0, 1, 1); else if (col == "black") - color = Color::html("#000000"); + color = Color(0, 0, 0); else if (col == "blue") - color = Color::html("#0000FF"); + color = Color(0, 0, 1); else if (col == "fuchsia") - color = Color::html("#FF00FF"); + color = Color(1, 0, 1); else if (col == "gray" || col == "grey") - color = Color::html("#808080"); + color = Color(0.5, 0.5, 0.5); else if (col == "green") - color = Color::html("#008000"); + color = Color(0, 0.5, 0); else if (col == "lime") - color = Color::html("#00FF00"); + color = Color(0, 1, 0); else if (col == "maroon") - color = Color::html("#800000"); + color = Color(0.5, 0, 0); else if (col == "navy") - color = Color::html("#000080"); + color = Color(0, 0, 0.5); else if (col == "olive") - color = Color::html("#808000"); + color = Color(0.5, 0.5, 0); else if (col == "purple") - color = Color::html("#800080"); + color = Color(0.5, 0, 0.5); else if (col == "red") - color = Color::html("#FF0000"); + color = Color(1, 0, 0); else if (col == "silver") - color = Color::html("#C0C0C0"); + color = Color(0.75, 0.75, 0.75); else if (col == "teal") - color = Color::html("#008008"); + color = Color(0, 0.5, 0.5); else if (col == "white") - color = Color::html("#FFFFFF"); + color = Color(1, 1, 1); else if (col == "yellow") - color = Color::html("#FFFF00"); + color = Color(1, 1, 0); else color = base_color; diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp index d83ae47671..461281a4ed 100644 --- a/scene/gui/scroll_container.cpp +++ b/scene/gui/scroll_container.cpp @@ -486,7 +486,7 @@ String ScrollContainer::get_configuration_warning() const { } if (found != 1) - return TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox,HBox,etc), or a Control and set the custom minimum size manually."); + return TTR("ScrollContainer is intended to work with a single child control.\nUse a container as child (VBox, HBox, etc.), or a Control and set the custom minimum size manually."); else return ""; } diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index e778af3ceb..279253889c 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -173,7 +173,7 @@ void SpinBox::_line_edit_focus_exit() { _text_entered(line_edit->get_text()); } -inline void SpinBox::_adjust_width_for_icon(const Ref<Texture> icon) { +inline void SpinBox::_adjust_width_for_icon(const Ref<Texture> &icon) { int w = icon->get_width(); if (w != last_w) { diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index 49dc6d950c..9cf977d2d6 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -62,7 +62,7 @@ class SpinBox : public Range { void _line_edit_focus_exit(); - inline void _adjust_width_for_icon(const Ref<Texture> icon); + inline void _adjust_width_for_icon(const Ref<Texture> &icon); protected: void _gui_input(const Ref<InputEvent> &p_event); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index a6e3d644f6..ff0c723141 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -35,6 +35,7 @@ #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/project_settings.h" +#include "core/script_language.h" #include "scene/main/viewport.h" #ifdef TOOLS_ENABLED @@ -682,7 +683,7 @@ void TextEdit::_notification(int p_what) { } if (line_length_guideline) { - int x = xmargin_beg + cache.font->get_char_size('0').width * line_length_guideline_col - cursor.x_ofs; + int x = xmargin_beg + (int)cache.font->get_char_size('0').width * line_length_guideline_col - cursor.x_ofs; if (x > xmargin_beg && x < xmargin_end) { VisualServer::get_singleton()->canvas_item_add_line(ci, Point2(x, 0), Point2(x, size.height), cache.line_length_guideline_color); } @@ -1362,7 +1363,7 @@ void TextEdit::_notification(int p_what) { 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]).x, cmax_width); + int w2 = MIN(cache.font->get_string_size(completion_options[i].display).x, cmax_width); if (w2 > w) w = w2; } @@ -1370,6 +1371,11 @@ void TextEdit::_notification(int p_what) { w = cmax_width; } + // Add space for completion icons + const int icon_hsep = get_constant("hseparation", "ItemList"); + Size2 icon_area_size(get_row_height(), get_row_height()); + w += icon_area_size.width + icon_hsep; + int th = h + csb->get_minimum_size().y; if (cursor_pos.y + get_row_height() + th > get_size().height) { @@ -1397,7 +1403,7 @@ void TextEdit::_notification(int p_what) { } int line_from = CLAMP(completion_index - lines / 2, 0, completion_options.size() - lines); VisualServer::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, Size2(nofs, completion_rect.size.height)), cache.completion_existing_color); + draw_rect(Rect2(completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(nofs, completion_rect.size.height)), cache.completion_existing_color); for (int i = 0; i < lines; i++) { @@ -1405,12 +1411,26 @@ void TextEdit::_notification(int p_what) { ERR_CONTINUE(l < 0 || l >= completion_options.size()); Color text_color = cache.completion_font_color; for (int j = 0; j < color_regions.size(); j++) { - if (completion_options[l].begins_with(color_regions[j].begin_key)) { + if (completion_options[l].insert_text.begins_with(color_regions[j].begin_key)) { text_color = color_regions[j].color; } } int yofs = (get_row_height() - cache.font->get_height()) / 2; - draw_string(cache.font, Point2(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent() + yofs), completion_options[l], text_color, completion_rect.size.width); + Point2 title_pos(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent() + yofs); + + //draw completion icon if it is valid + Ref<Texture> icon = completion_options[l].icon; + Rect2 icon_area(completion_rect.position.x, completion_rect.position.y + i * get_row_height(), icon_area_size.width, icon_area_size.height); + if (icon.is_valid()) { + const real_t max_scale = 0.7f; + const real_t side = max_scale * icon_area.size.width; + real_t scale = MIN(side / icon->get_width(), side / icon->get_height()); + Size2 icon_size = icon->get_size() * scale; + draw_texture_rect(icon, Rect2(icon_area.position + (icon_area.size - icon_size) / 2, icon_size)); + } + + title_pos.x = icon_area.position.x + icon_area.size.width + icon_hsep; + draw_string(cache.font, title_pos, completion_options[l].display, text_color, completion_rect.size.width); } if (scrollw) { @@ -3267,28 +3287,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } break; - case KEY_U: { - if (!k->get_command() || k->get_shift()) { - scancode_handled = false; - break; - } else { - if (selection.active) { - int ini = selection.from_line; - int end = selection.to_line; - - for (int i = ini; i <= end; i++) { - _uncomment_line(i); - } - } else { - _uncomment_line(cursor.line); - if (cursor.column >= get_line(cursor.line).length()) { - cursor.column = MAX(0, get_line(cursor.line).length() - 1); - } - } - update(); - } - } break; - default: { scancode_handled = false; @@ -3347,24 +3345,6 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } } -void TextEdit::_uncomment_line(int p_line) { - String line_text = get_line(p_line); - for (int i = 0; i < line_text.length(); i++) { - if (line_text[i] == '#') { - _remove_text(p_line, i, p_line, i + 1); - if (p_line == selection.to_line && selection.to_column > line_text.length() - 1) { - selection.to_column -= 1; - if (selection.to_column >= selection.from_column) { - selection.active = false; - } - } - return; - } else if (line_text[i] != '\t' && line_text[i] != ' ') { - return; - } - } -} - void TextEdit::_scroll_up(real_t p_delta) { if (scrolling && smooth_scroll_enabled && SGN(target_v_scroll - v_scroll->get_value()) != SGN(-p_delta)) @@ -5925,12 +5905,12 @@ void TextEdit::_confirm_completion() { _remove_text(cursor.line, cursor.column - completion_base.length(), cursor.line, cursor.column); cursor_set_column(cursor.column - completion_base.length(), false); - insert_text_at_cursor(completion_current); + insert_text_at_cursor(completion_current.insert_text); // When inserted into the middle of an existing string/method, don't add an unnecessary quote/bracket. String line = text[cursor.line]; CharType next_char = line[cursor.column]; - CharType last_completion_char = completion_current[completion_current.length() - 1]; + CharType last_completion_char = completion_current.insert_text[completion_current.insert_text.length() - 1]; if ((last_completion_char == '"' || last_completion_char == '\'') && last_completion_char == next_char) { _base_remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1); @@ -6066,39 +6046,41 @@ void TextEdit::_update_completion_candidates() { completion_base = s; Vector<float> sim_cache; bool single_quote = s.begins_with("'"); - Vector<String> completion_options_casei; + Vector<ScriptCodeCompletionOption> completion_options_casei; + + for (List<ScriptCodeCompletionOption>::Element *E = completion_sources.front(); E; E = E->next()) { + ScriptCodeCompletionOption &option = E->get(); - for (int i = 0; i < completion_strings.size(); i++) { - if (single_quote && completion_strings[i].is_quoted()) { - completion_strings.write[i] = completion_strings[i].unquote().quote("'"); + if (single_quote && option.display.is_quoted()) { + option.display = option.display.unquote().quote("'"); } - if (inquote && restore_quotes == 1 && !completion_strings[i].is_quoted()) { + if (inquote && restore_quotes == 1 && !option.display.is_quoted()) { String quote = single_quote ? "'" : "\""; - completion_strings.write[i] = completion_strings[i].quote(quote); + option.display = option.display.quote(quote); } - if (completion_strings[i].begins_with(s)) { - completion_options.push_back(completion_strings[i]); - } else if (completion_strings[i].to_lower().begins_with(s.to_lower())) { - completion_options_casei.push_back(completion_strings[i]); + if (option.display.begins_with(s)) { + completion_options.push_back(option); + } else if (option.display.to_lower().begins_with(s.to_lower())) { + completion_options_casei.push_back(option); } } completion_options.append_array(completion_options_casei); if (completion_options.size() == 0) { - for (int i = 0; i < completion_strings.size(); i++) { - if (s.is_subsequence_of(completion_strings[i])) { - completion_options.push_back(completion_strings[i]); + for (int i = 0; i < completion_sources.size(); i++) { + if (s.is_subsequence_of(completion_sources[i].display)) { + completion_options.push_back(completion_sources[i]); } } } if (completion_options.size() == 0) { - for (int i = 0; i < completion_strings.size(); i++) { - if (s.is_subsequence_ofi(completion_strings[i])) { - completion_options.push_back(completion_strings[i]); + for (int i = 0; i < completion_sources.size(); i++) { + if (s.is_subsequence_ofi(completion_sources[i].display)) { + completion_options.push_back(completion_sources[i]); } } } @@ -6109,7 +6091,7 @@ void TextEdit::_update_completion_candidates() { return; } - if (completion_options.size() == 1 && s == completion_options[0]) { + if (completion_options.size() == 1 && s == completion_options[0].display) { // A perfect match, stop completion _cancel_completion(); return; @@ -6147,12 +6129,12 @@ void TextEdit::set_code_hint(const String &p_hint) { update(); } -void TextEdit::code_complete(const Vector<String> &p_strings, bool p_forced) { +void TextEdit::code_complete(const List<ScriptCodeCompletionOption> &p_strings, bool p_forced) { - completion_strings = p_strings; + completion_sources = p_strings; completion_active = true; completion_forced = p_forced; - completion_current = ""; + completion_current = ScriptCodeCompletionOption(); completion_index = 0; _update_completion_candidates(); } diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 30956ccb23..b47dac0902 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -255,11 +255,11 @@ private: Set<String> completion_prefixes; bool completion_enabled; - Vector<String> completion_strings; - Vector<String> completion_options; + List<ScriptCodeCompletionOption> completion_sources; + Vector<ScriptCodeCompletionOption> completion_options; bool completion_active; bool completion_forced; - String completion_current; + ScriptCodeCompletionOption completion_current; String completion_base; int completion_index; Rect2i completion_rect; @@ -395,7 +395,6 @@ private: void _update_selection_mode_word(); void _update_selection_mode_line(); - void _uncomment_line(int p_line); void _scroll_up(real_t p_delta); void _scroll_down(real_t p_delta); @@ -704,7 +703,7 @@ public: void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata); void set_completion(bool p_enabled, const Vector<String> &p_prefixes); - void code_complete(const Vector<String> &p_strings, bool p_forced = false); + void code_complete(const List<ScriptCodeCompletionOption> &p_strings, bool p_forced = false); void set_code_hint(const String &p_hint); void query_code_comple(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index c2493ab321..4005505830 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -572,13 +572,6 @@ int TreeItem::get_button_by_id(int p_column, int p_id) const { return -1; } -bool TreeItem::is_button_disabled(int p_column, int p_idx) const { - - ERR_FAIL_INDEX_V(p_column, cells.size(), false); - ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), false); - - return cells[p_column].buttons[p_idx].disabled; -} void TreeItem::set_button(int p_column, int p_idx, const Ref<Texture> &p_button) { ERR_FAIL_COND(p_button.is_null()); @@ -596,6 +589,23 @@ void TreeItem::set_button_color(int p_column, int p_idx, const Color &p_color) { _changed_notify(p_column); } +void TreeItem::set_button_disabled(int p_column, int p_idx, bool p_disabled) { + + ERR_FAIL_INDEX(p_column, cells.size()); + ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size()); + + cells.write[p_column].buttons.write[p_idx].disabled = p_disabled; + _changed_notify(p_column); +} + +bool TreeItem::is_button_disabled(int p_column, int p_idx) const { + + ERR_FAIL_INDEX_V(p_column, cells.size(), false); + ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), false); + + return cells[p_column].buttons[p_idx].disabled; +} + void TreeItem::set_editable(int p_column, bool p_editable) { ERR_FAIL_INDEX(p_column, cells.size()); @@ -785,6 +795,7 @@ void TreeItem::_bind_methods() { ClassDB::bind_method(D_METHOD("get_button", "column", "button_idx"), &TreeItem::get_button); ClassDB::bind_method(D_METHOD("set_button", "column", "button_idx", "button"), &TreeItem::set_button); ClassDB::bind_method(D_METHOD("erase_button", "column", "button_idx"), &TreeItem::erase_button); + ClassDB::bind_method(D_METHOD("set_button_disabled", "column", "button_idx", "disabled"), &TreeItem::set_button_disabled); ClassDB::bind_method(D_METHOD("is_button_disabled", "column", "button_idx"), &TreeItem::is_button_disabled); ClassDB::bind_method(D_METHOD("set_expand_right", "column", "enable"), &TreeItem::set_expand_right); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 45d451eb72..b6cdab766f 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -209,9 +209,10 @@ public: int get_button_id(int p_column, int p_idx) const; void erase_button(int p_column, int p_idx); int get_button_by_id(int p_column, int p_id) const; - bool is_button_disabled(int p_column, int p_idx) const; void set_button(int p_column, int p_idx, const Ref<Texture> &p_button); void set_button_color(int p_column, int p_idx, const Color &p_color); + void set_button_disabled(int p_column, int p_idx, bool p_disabled); + bool is_button_disabled(int p_column, int p_idx) const; /* range works for mode number or mode combo */ diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp index 88b942ee45..05bd911014 100644 --- a/scene/main/http_request.cpp +++ b/scene/main/http_request.cpp @@ -96,6 +96,11 @@ Error HTTPRequest::request(const String &p_url, const Vector<String> &p_custom_h ERR_FAIL_V(ERR_BUSY); } + if (timeout > 0) { + timer->stop(); + timer->start(timeout); + } + method = p_method; Error err = _parse_url(p_url); @@ -153,6 +158,8 @@ void HTTPRequest::_thread_func(void *p_userdata) { void HTTPRequest::cancel_request() { + timer->stop(); + if (!requesting) return; @@ -479,6 +486,23 @@ int HTTPRequest::get_body_size() const { return body_len; } +void HTTPRequest::set_timeout(int p_timeout) { + + ERR_FAIL_COND(p_timeout < 0); + timeout = p_timeout; +} + +int HTTPRequest::get_timeout() { + + return timeout; +} + +void HTTPRequest::_timeout() { + + cancel_request(); + call_deferred("_request_done", RESULT_TIMEOUT, 0, PoolStringArray(), PoolByteArray()); +} + void HTTPRequest::_bind_methods() { ClassDB::bind_method(D_METHOD("request", "url", "custom_headers", "ssl_validate_domain", "method", "request_data"), &HTTPRequest::request, DEFVAL(PoolStringArray()), DEFVAL(true), DEFVAL(HTTPClient::METHOD_GET), DEFVAL(String())); @@ -504,10 +528,16 @@ void HTTPRequest::_bind_methods() { ClassDB::bind_method(D_METHOD("_redirect_request"), &HTTPRequest::_redirect_request); ClassDB::bind_method(D_METHOD("_request_done"), &HTTPRequest::_request_done); + ClassDB::bind_method(D_METHOD("set_timeout", "timeout"), &HTTPRequest::set_timeout); + ClassDB::bind_method(D_METHOD("get_timeout"), &HTTPRequest::get_timeout); + + ClassDB::bind_method(D_METHOD("_timeout"), &HTTPRequest::_timeout); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "download_file", PROPERTY_HINT_FILE), "set_download_file", "get_download_file"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_threads"), "set_use_threads", "is_using_threads"); ADD_PROPERTY(PropertyInfo(Variant::INT, "body_size_limit", PROPERTY_HINT_RANGE, "-1,2000000000"), "set_body_size_limit", "get_body_size_limit"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max_redirects", PROPERTY_HINT_RANGE, "-1,64"), "set_max_redirects", "get_max_redirects"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "timeout", PROPERTY_HINT_RANGE, "0,86400"), "set_timeout", "get_timeout"); ADD_SIGNAL(MethodInfo("request_completed", PropertyInfo(Variant::INT, "result"), PropertyInfo(Variant::INT, "response_code"), PropertyInfo(Variant::POOL_STRING_ARRAY, "headers"), PropertyInfo(Variant::POOL_BYTE_ARRAY, "body"))); @@ -524,6 +554,7 @@ void HTTPRequest::_bind_methods() { BIND_ENUM_CONSTANT(RESULT_DOWNLOAD_FILE_CANT_OPEN); BIND_ENUM_CONSTANT(RESULT_DOWNLOAD_FILE_WRITE_ERROR); BIND_ENUM_CONSTANT(RESULT_REDIRECT_LIMIT_REACHED); + BIND_ENUM_CONSTANT(RESULT_TIMEOUT); } HTTPRequest::HTTPRequest() { @@ -546,6 +577,12 @@ HTTPRequest::HTTPRequest() { downloaded = 0; body_size_limit = -1; file = NULL; + + timer = memnew(Timer); + timer->set_one_shot(true); + timer->connect("timeout", this, "_timeout"); + add_child(timer); + timeout = 0; } HTTPRequest::~HTTPRequest() { diff --git a/scene/main/http_request.h b/scene/main/http_request.h index 2e58d579ba..f1f91235a6 100644 --- a/scene/main/http_request.h +++ b/scene/main/http_request.h @@ -35,6 +35,7 @@ #include "core/os/file_access.h" #include "core/os/thread.h" #include "node.h" +#include "scene/main/timer.h" class HTTPRequest : public Node { @@ -53,7 +54,8 @@ public: RESULT_REQUEST_FAILED, RESULT_DOWNLOAD_FILE_CANT_OPEN, RESULT_DOWNLOAD_FILE_WRITE_ERROR, - RESULT_REDIRECT_LIMIT_REACHED + RESULT_REDIRECT_LIMIT_REACHED, + RESULT_TIMEOUT }; @@ -92,6 +94,8 @@ private: int max_redirects; + int timeout; + void _redirect_request(const String &p_new_url); bool _handle_response(bool *ret_value); @@ -128,6 +132,13 @@ public: void set_max_redirects(int p_max); int get_max_redirects() const; + Timer *timer; + + void set_timeout(int p_timeout); + int get_timeout(); + + void _timeout(); + int get_downloaded_bytes() const; int get_body_size() const; diff --git a/scene/main/node.cpp b/scene/main/node.cpp index 5888760973..06d6f0871c 100644 --- a/scene/main/node.cpp +++ b/scene/main/node.cpp @@ -1759,7 +1759,7 @@ bool Node::has_persistent_groups() const { return false; } -void Node::_print_tree_pretty(const String prefix, const bool last) { +void Node::_print_tree_pretty(const String &prefix, const bool last) { String new_prefix = last ? String::utf8(" â”–â•´") : String::utf8(" â” â•´"); print_line(prefix + new_prefix + String(get_name())); @@ -2487,7 +2487,7 @@ bool Node::has_node_and_resource(const NodePath &p_path) const { Vector<StringName> leftover_path; Node *node = get_node_and_resource(p_path, res, leftover_path, false); - return (node && res.is_valid()); + return node; } Array Node::_get_node_and_resource(const NodePath &p_path) { @@ -2525,9 +2525,15 @@ Node *Node::get_node_and_resource(const NodePath &p_path, RES &r_res, Vector<Str int j = 0; // If not p_last_is_property, we shouldn't consider the last one as part of the resource for (; j < p_path.get_subname_count() - (int)p_last_is_property; j++) { - RES new_res = j == 0 ? node->get(p_path.get_subname(j)) : r_res->get(p_path.get_subname(j)); + Variant new_res_v = j == 0 ? node->get(p_path.get_subname(j)) : r_res->get(p_path.get_subname(j)); + + if (new_res_v.get_type() == Variant::NIL) { // Found nothing on that path + return NULL; + } + + RES new_res = new_res_v; - if (new_res.is_null()) { + if (new_res.is_null()) { // No longer a resource, assume property break; } diff --git a/scene/main/node.h b/scene/main/node.h index 9b9ca06455..982bfcd620 100644 --- a/scene/main/node.h +++ b/scene/main/node.h @@ -152,7 +152,7 @@ private: Ref<MultiplayerAPI> multiplayer; - void _print_tree_pretty(const String prefix, const bool last); + void _print_tree_pretty(const String &prefix, const bool last); void _print_tree(const Node *p_node); Node *_get_child_by_name(const StringName &p_name) const; diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp index 0e7cec57a4..5eeaff6411 100644 --- a/scene/main/scene_tree.cpp +++ b/scene/main/scene_tree.cpp @@ -453,9 +453,6 @@ void SceneTree::init() { //_quit=false; initialized = true; - input_handled = false; - - pause = false; root->_set_tree(this); MainLoop::init(); @@ -1252,7 +1249,7 @@ void SceneTree::_update_root_rect() { } } -void SceneTree::set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 p_minsize, real_t p_shrink) { +void SceneTree::set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 &p_minsize, real_t p_shrink) { stretch_mode = p_mode; stretch_aspect = p_aspect; @@ -1986,6 +1983,8 @@ SceneTree::SceneTree() { idle_process_time = 1; root = NULL; + input_handled = false; + pause = false; current_frame = 0; current_event = 0; tree_changed_name = "tree_changed"; diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h index 0bcb724929..98f2fe5e35 100644 --- a/scene/main/scene_tree.h +++ b/scene/main/scene_tree.h @@ -386,7 +386,7 @@ public: void get_nodes_in_group(const StringName &p_group, List<Node *> *p_list); bool has_group(const StringName &p_identifier) const; - void set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 p_minsize, real_t p_shrink = 1); + void set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 &p_minsize, real_t p_shrink = 1); void set_use_font_oversampling(bool p_oversampling); bool is_using_font_oversampling() const; diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 8561d9aedb..d147d43f50 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1431,6 +1431,7 @@ void Viewport::_gui_show_tooltip() { Control *which = NULL; String tooltip = _gui_get_tooltip(gui.tooltip, gui.tooltip->get_global_transform().xform_inv(gui.tooltip_pos), &which); + tooltip = tooltip.strip_edges(); if (tooltip.length() == 0) return; // bye @@ -1460,7 +1461,7 @@ void Viewport::_gui_show_tooltip() { gui.tooltip_label->set_anchor_and_margin(MARGIN_TOP, Control::ANCHOR_BEGIN, ttp->get_margin(MARGIN_TOP)); gui.tooltip_label->set_anchor_and_margin(MARGIN_RIGHT, Control::ANCHOR_END, -ttp->get_margin(MARGIN_RIGHT)); gui.tooltip_label->set_anchor_and_margin(MARGIN_BOTTOM, Control::ANCHOR_END, -ttp->get_margin(MARGIN_BOTTOM)); - gui.tooltip_label->set_text(tooltip.strip_edges()); + gui.tooltip_label->set_text(tooltip); } rp->add_child(gui.tooltip_popup); @@ -2578,7 +2579,7 @@ void Viewport::_drop_physics_mouseover() { List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) { - gui.modal_stack.push_back(p_control); + List<Control *>::Element *node = gui.modal_stack.push_back(p_control); if (gui.key_focus) p_control->_modal_set_prev_focus_owner(gui.key_focus->get_instance_id()); else @@ -2589,7 +2590,7 @@ List<Control *>::Element *Viewport::_gui_show_modal(Control *p_control) { _drop_mouse_focus(); } - return gui.modal_stack.back(); + return node; } Control *Viewport::_gui_get_focus_owner() { @@ -3064,6 +3065,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "arvr"), "set_use_arvr", "use_arvr"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "size_override_stretch"), "set_size_override_stretch", "is_size_override_stretch_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "own_world"), "set_use_own_world", "is_using_own_world"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world", PROPERTY_HINT_RESOURCE_TYPE, "World"), "set_world", "get_world"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "world_2d", PROPERTY_HINT_RESOURCE_TYPE, "World2D", 0), "set_world_2d", "get_world_2d"); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 0423fcb5f0..2533d91156 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -522,11 +522,14 @@ void register_scene_types() { ClassDB::register_class<VisualShaderNodeVec3Uniform>(); ClassDB::register_class<VisualShaderNodeTransformUniform>(); ClassDB::register_class<VisualShaderNodeTextureUniform>(); + ClassDB::register_class<VisualShaderNodeTextureUniformTriplanar>(); ClassDB::register_class<VisualShaderNodeCubeMapUniform>(); ClassDB::register_class<VisualShaderNodeIf>(); ClassDB::register_class<VisualShaderNodeSwitch>(); ClassDB::register_class<VisualShaderNodeFresnel>(); ClassDB::register_class<VisualShaderNodeExpression>(); + ClassDB::register_class<VisualShaderNodeIs>(); + ClassDB::register_class<VisualShaderNodeCompare>(); ClassDB::register_class<ShaderMaterial>(); ClassDB::register_virtual_class<CanvasItem>(); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 1ca643cd7a..64051fe304 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -403,7 +403,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { w[idx++] = scale.z; } - w = PoolVector<real_t>::Write(); + w.release(); r_ret = keys; return true; @@ -438,8 +438,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { idx++; } - wti = PoolVector<float>::Write(); - wtr = PoolVector<float>::Write(); + wti.release(); + wtr.release(); d["times"] = key_times; d["transitions"] = key_transitions; @@ -478,8 +478,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { idx++; } - wti = PoolVector<float>::Write(); - wtr = PoolVector<float>::Write(); + wti.release(); + wtr.release(); d["times"] = key_times; d["transitions"] = key_transitions; @@ -523,8 +523,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { idx++; } - wti = PoolVector<float>::Write(); - wpo = PoolVector<float>::Write(); + wti.release(); + wpo.release(); d["times"] = key_times; d["points"] = key_points; @@ -562,7 +562,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { idx++; } - wti = PoolVector<float>::Write(); + wti.release(); d["times"] = key_times; d["clips"] = clips; @@ -595,8 +595,8 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const { wcl[i] = vls[i].value; } - wti = PoolVector<float>::Write(); - wcl = PoolVector<String>::Write(); + wti.release(); + wcl.release(); d["times"] = key_times; d["clips"] = clips; @@ -863,7 +863,7 @@ Error Animation::transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, return OK; } -int Animation::transform_track_insert_key(int p_track, float p_time, const Vector3 p_loc, const Quat &p_rot, const Vector3 &p_scale) { +int Animation::transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quat &p_rot, const Vector3 &p_scale) { ERR_FAIL_INDEX_V(p_track, tracks.size(), -1); Track *t = tracks[p_track]; @@ -1815,7 +1815,7 @@ T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, Interpol next = idx; } - } else if (idx < 0) { + } else { // only allow extending first key to anim start if looping if (loop) diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 59f2ae24c7..6fff77d746 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -314,7 +314,7 @@ public: float track_get_key_time(int p_track, int p_key_idx) const; float track_get_key_transition(int p_track, int p_key_idx) const; - int transform_track_insert_key(int p_track, float p_time, const Vector3 p_loc, const Quat &p_rot = Quat(), const Vector3 &p_scale = Vector3()); + int transform_track_insert_key(int p_track, float p_time, const Vector3 &p_loc, const Quat &p_rot = Quat(), const Vector3 &p_scale = Vector3()); Error transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const; void track_set_interpolation_type(int p_track, InterpolationType p_interp); InterpolationType track_get_interpolation_type(int p_track) const; diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index 4b3e392013..5b61654c5d 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -564,7 +564,8 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { file->store_32(sub_chunk_2_size); //Subchunk2Size // Add data - PoolVector<uint8_t>::Read read_data = get_data().read(); + PoolVector<uint8_t> data = get_data(); + PoolVector<uint8_t>::Read read_data = data.read(); switch (format) { case AudioStreamSample::FORMAT_8_BITS: for (unsigned int i = 0; i < data_bytes; i++) { diff --git a/scene/resources/default_theme/background.png b/scene/resources/default_theme/background.png Binary files differdeleted file mode 100644 index 6c5f43e3ce..0000000000 --- a/scene/resources/default_theme/background.png +++ /dev/null diff --git a/scene/resources/default_theme/base_green.png b/scene/resources/default_theme/base_green.png Binary files differdeleted file mode 100644 index 03a5b313d7..0000000000 --- a/scene/resources/default_theme/base_green.png +++ /dev/null diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 4e2fe1f9b2..fb0fb4f8e3 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -177,13 +177,13 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // Font Colors - Color control_font_color = Color::html("e0e0e0"); - Color control_font_color_lower = Color::html("a0a0a0"); - Color control_font_color_low = Color::html("b0b0b0"); - Color control_font_color_hover = Color::html("f0f0f0"); + 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::html("ffffff"); - Color font_color_selection = Color::html("7d7d7d"); + Color control_font_color_pressed = Color(1, 1, 1); + Color font_color_selection = Color(0.49, 0.49, 0.49); // Panel @@ -432,12 +432,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("font", "TextEdit", default_font); - theme->set_color("background_color", "TextEdit", Color(0, 0, 0, 0)); - theme->set_color("completion_background_color", "TextEdit", Color::html("2C2A32")); - theme->set_color("completion_selected_color", "TextEdit", Color::html("434244")); - theme->set_color("completion_existing_color", "TextEdit", Color::html("21dfdfdf")); + theme->set_color("background_color", "TextEdit", Color(0, 0, 0)); + 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_font_color", "TextEdit", Color::html("aaaaaa")); + 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)); @@ -449,14 +449,14 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const 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)); theme->set_color("caret_color", "TextEdit", control_font_color); - theme->set_color("caret_background_color", "TextEdit", Color::html("000000")); + theme->set_color("caret_background_color", "TextEdit", Color(0, 0, 0)); theme->set_color("symbol_color", "TextEdit", control_font_color_hover); theme->set_color("brace_mismatch_color", "TextEdit", Color(1, 0.2, 0.2)); - theme->set_color("line_number_color", "TextEdit", Color::html("66aaaaaa")); - theme->set_color("safe_line_number_color", "TextEdit", Color::html("99aac8aa")); - theme->set_color("function_color", "TextEdit", Color::html("66a2ce")); - theme->set_color("member_variable_color", "TextEdit", Color::html("e64e59")); - theme->set_color("number_color", "TextEdit", Color::html("EB9532")); + theme->set_color("line_number_color", "TextEdit", Color(0.67, 0.67, 0.67, 0.4)); + theme->set_color("safe_line_number_color", "TextEdit", Color(0.67, 0.78, 0.67, 0.6)); + theme->set_color("function_color", "TextEdit", Color(0.4, 0.64, 0.81)); + theme->set_color("member_variable_color", "TextEdit", Color(0.9, 0.31, 0.35)); + theme->set_color("number_color", "TextEdit", Color(0.92, 0.58, 0.2)); theme->set_color("word_highlighted_color", "TextEdit", Color(0.8, 0.9, 0.9, 0.15)); theme->set_constant("completion_lines", "TextEdit", 7); @@ -651,7 +651,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("cursor_color", "Tree", Color(0, 0, 0)); 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::html("464646")); + 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_constant("hseparation", "Tree", 4 * scale); @@ -854,8 +854,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("bezier_len_pos", "GraphEdit", 80 * scale); theme->set_constant("bezier_len_neg", "GraphEdit", 160 * scale); - theme->set_icon("logo", "Icons", make_icon(logo_png)); - // Visual Node Ports theme->set_constant("port_grab_distance_horizontal", "GraphEdit", 48 * scale); theme->set_constant("port_grab_distance_vertical", "GraphEdit", 6 * scale); diff --git a/scene/resources/default_theme/dosfont.png b/scene/resources/default_theme/dosfont.png Binary files differdeleted file mode 100644 index e2739b94ea..0000000000 --- a/scene/resources/default_theme/dosfont.png +++ /dev/null diff --git a/scene/resources/default_theme/frame_focus.png b/scene/resources/default_theme/frame_focus.png Binary files differdeleted file mode 100644 index 1b24ba47d8..0000000000 --- a/scene/resources/default_theme/frame_focus.png +++ /dev/null diff --git a/scene/resources/default_theme/full_panel_bg.png b/scene/resources/default_theme/full_panel_bg.png Binary files differdeleted file mode 100644 index 85f753cc13..0000000000 --- a/scene/resources/default_theme/full_panel_bg.png +++ /dev/null diff --git a/scene/resources/default_theme/icon_play.png b/scene/resources/default_theme/icon_play.png Binary files differdeleted file mode 100644 index b9ed6e6d5b..0000000000 --- a/scene/resources/default_theme/icon_play.png +++ /dev/null diff --git a/scene/resources/default_theme/icon_stop.png b/scene/resources/default_theme/icon_stop.png Binary files differdeleted file mode 100644 index 0c1371ceb9..0000000000 --- a/scene/resources/default_theme/icon_stop.png +++ /dev/null diff --git a/scene/resources/default_theme/line_edit_focus.png b/scene/resources/default_theme/line_edit_focus.png Binary files differdeleted file mode 100644 index 1d74b74068..0000000000 --- a/scene/resources/default_theme/line_edit_focus.png +++ /dev/null diff --git a/scene/resources/default_theme/logo.png b/scene/resources/default_theme/logo.png Binary files differdeleted file mode 100644 index d0ef9d8aa7..0000000000 --- a/scene/resources/default_theme/logo.png +++ /dev/null diff --git a/scene/resources/default_theme/option_button_focus.png b/scene/resources/default_theme/option_button_focus.png Binary files differdeleted file mode 100644 index 402670f9a2..0000000000 --- a/scene/resources/default_theme/option_button_focus.png +++ /dev/null diff --git a/scene/resources/default_theme/popup_checked.png b/scene/resources/default_theme/popup_checked.png Binary files differdeleted file mode 100644 index b7b05640e1..0000000000 --- a/scene/resources/default_theme/popup_checked.png +++ /dev/null diff --git a/scene/resources/default_theme/popup_hover.png b/scene/resources/default_theme/popup_hover.png Binary files differdeleted file mode 100644 index bdb6ae8bd0..0000000000 --- a/scene/resources/default_theme/popup_hover.png +++ /dev/null diff --git a/scene/resources/default_theme/popup_unchecked.png b/scene/resources/default_theme/popup_unchecked.png Binary files differdeleted file mode 100644 index ff922335c3..0000000000 --- a/scene/resources/default_theme/popup_unchecked.png +++ /dev/null diff --git a/scene/resources/default_theme/reference_border.png b/scene/resources/default_theme/reference_border.png Binary files differdeleted file mode 100644 index 6a680f393c..0000000000 --- a/scene/resources/default_theme/reference_border.png +++ /dev/null diff --git a/scene/resources/default_theme/scroll_button_down.png b/scene/resources/default_theme/scroll_button_down.png Binary files differdeleted file mode 100644 index 1df4ef5b6b..0000000000 --- a/scene/resources/default_theme/scroll_button_down.png +++ /dev/null diff --git a/scene/resources/default_theme/scroll_button_down_hl.png b/scene/resources/default_theme/scroll_button_down_hl.png Binary files differdeleted file mode 100644 index ba79087393..0000000000 --- a/scene/resources/default_theme/scroll_button_down_hl.png +++ /dev/null diff --git a/scene/resources/default_theme/scroll_button_up.png b/scene/resources/default_theme/scroll_button_up.png Binary files differdeleted file mode 100644 index f425412f50..0000000000 --- a/scene/resources/default_theme/scroll_button_up.png +++ /dev/null diff --git a/scene/resources/default_theme/scroll_button_up_hl.png b/scene/resources/default_theme/scroll_button_up_hl.png Binary files differdeleted file mode 100644 index 615a236c52..0000000000 --- a/scene/resources/default_theme/scroll_button_up_hl.png +++ /dev/null diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 5e13a6625a..cf37c57407 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -10,14 +10,6 @@ static const unsigned char arrow_right_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x17, 0x3c, 0xf8, 0xf, 0x82, 0xf7, 0x13, 0x70, 0x48, 0x3c, 0xf8, 0xf2, 0x50, 0x1b, 0x43, 0x2, 0xa, 0xaf, 0xbe, 0xe0, 0xc6, 0x2e, 0xf1, 0xff, 0xe1, 0x7c, 0x12, 0x24, 0x10, 0x46, 0x11, 0xb6, 0x1c, 0xe1, 0x5c, 0xa, 0x0, 0x0, 0xe0, 0x14, 0x48, 0xb1, 0x3d, 0x1b, 0x7a, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char background_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x44, 0xa4, 0x8a, 0xc6, 0x0, 0x0, 0x1, 0xe, 0x50, 0x4c, 0x54, 0x45, 0x91, 0xc9, 0xab, 0x90, 0xc9, 0xab, 0x90, 0xc9, 0xaa, 0x90, 0xc8, 0xab, 0x91, 0xc9, 0xaa, 0x91, 0xc8, 0xab, 0x90, 0xc8, 0xaa, 0x8f, 0xc8, 0xab, 0x8f, 0xc9, 0xab, 0x8f, 0xc8, 0xaa, 0x90, 0xc7, 0xaa, 0x90, 0xc7, 0xab, 0x8f, 0xc7, 0xaa, 0x8f, 0xc7, 0xab, 0x8e, 0xc7, 0xab, 0x8e, 0xc6, 0xab, 0x8f, 0xc6, 0xab, 0x8e, 0xc6, 0xaa, 0x8f, 0xc6, 0xaa, 0x8e, 0xc7, 0xaa, 0x8e, 0xc5, 0xaa, 0x8e, 0xc5, 0xab, 0x8d, 0xc5, 0xaa, 0x8d, 0xc5, 0xab, 0x8d, 0xc6, 0xaa, 0x8d, 0xc6, 0xab, 0x8d, 0xc4, 0xaa, 0x8e, 0xc4, 0xab, 0x8d, 0xc4, 0xab, 0x8e, 0xc4, 0xaa, 0x8c, 0xc4, 0xaa, 0x8c, 0xc5, 0xaa, 0x8d, 0xc3, 0xab, 0x8d, 0xc3, 0xaa, 0x8c, 0xc3, 0xaa, 0x8c, 0xc4, 0xab, 0x8c, 0xc3, 0xab, 0x8c, 0xc2, 0xab, 0x8b, 0xc2, 0xaa, 0x8b, 0xc3, 0xaa, 0x8b, 0xc3, 0xab, 0x8c, 0xc2, 0xaa, 0x8b, 0xc2, 0xab, 0x8b, 0xc1, 0xaa, 0x8b, 0xc1, 0xab, 0x8a, 0xc2, 0xaa, 0x8a, 0xc1, 0xaa, 0x8a, 0xc0, 0xaa, 0x8b, 0xc0, 0xaa, 0x8a, 0xc1, 0xa9, 0x8a, 0xc0, 0xa9, 0x89, 0xc0, 0xaa, 0x8a, 0xbf, 0xaa, 0x89, 0xbf, 0xaa, 0x89, 0xbf, 0xa9, 0x8a, 0xbf, 0xa9, 0x88, 0xbf, 0xaa, 0x89, 0xbe, 0xaa, 0x89, 0xbe, 0xa9, 0x88, 0xbf, 0xa9, 0x88, 0xbe, 0xa9, 0x88, 0xbe, 0xaa, 0x88, 0xbd, 0xaa, 0x88, 0xbd, 0xa9, 0x89, 0xbd, 0xaa, 0x89, 0xbd, 0xa9, 0x87, 0xbe, 0xa9, 0x87, 0xbd, 0xaa, 0x87, 0xbe, 0xaa, 0x87, 0xbd, 0xa9, 0x87, 0xbc, 0xaa, 0x88, 0xbc, 0xa9, 0x88, 0xbc, 0xaa, 0x87, 0xbc, 0xa9, 0x86, 0xbc, 0xa9, 0x87, 0xbb, 0xaa, 0x87, 0xbb, 0xa9, 0x86, 0xbb, 0xa9, 0x86, 0xbc, 0xaa, 0x86, 0xbb, 0xaa, 0x86, 0xba, 0xaa, 0x86, 0xba, 0xa9, 0x85, 0xba, 0xa9, 0x85, 0xbb, 0xaa, 0x85, 0xbb, 0xa9, 0x85, 0xba, 0xaa, 0x85, 0xb9, 0xa9, 0x86, 0xb9, 0xa9, 0x86, 0xb9, 0xaa, 0x85, 0xb9, 0xaa, 0x3e, 0xa0, 0x4f, 0x4f, 0x0, 0x0, 0x2, 0x3, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x2d, 0x4a, 0x7, 0x82, 0x4, 0x37, 0x12, 0x2, 0xa, 0x4a, 0xea, 0x9e, 0xbd, 0xff, 0x3f, 0xf5, 0x6c, 0x4f, 0x4b, 0xda, 0x58, 0x91, 0x24, 0x10, 0x20, 0xf8, 0x5d, 0x20, 0x81, 0x1f, 0xa8, 0x1f, 0xf6, 0x7, 0xf5, 0x7d, 0x0, 0x0, 0x3c, 0x0, 0x8, 0x14, 0x28, 0xb8, 0x41, 0x0, 0x50, 0x7b, 0x70, 0x63, 0xc, 0x9, 0x1c, 0xaa, 0x52, 0xeb, 0x4, 0x5b, 0xfb, 0x1d, 0x89, 0x68, 0xe1, 0x39, 0x9c, 0x7d, 0x68, 0x77, 0x60, 0x8c, 0x7a, 0x80, 0xe5, 0x6e, 0xdc, 0x41, 0x47, 0x51, 0x5f, 0xb8, 0xdd, 0xed, 0xa0, 0x9f, 0xc6, 0xad, 0xba, 0xee, 0xfb, 0xee, 0xde, 0x97, 0x74, 0x6f, 0x98, 0x82, 0x26, 0x51, 0x30, 0xa6, 0x3f, 0x10, 0xc8, 0xad, 0x13, 0xe4, 0x83, 0x0, 0x7a, 0x4, 0x4a, 0xd9, 0x5c, 0xde, 0xd2, 0x16, 0x15, 0xf2, 0xac, 0xac, 0x3e, 0x8f, 0x5a, 0x15, 0x3a, 0x5a, 0xe0, 0x6a, 0x1, 0xdc, 0xbd, 0x9b, 0x47, 0x44, 0xb6, 0x1e, 0x44, 0x5b, 0xe7, 0x84, 0x4b, 0xc3, 0xc, 0x1b, 0x51, 0xeb, 0xaa, 0x54, 0xc7, 0xb3, 0xeb, 0xca, 0x1a, 0x36, 0xbc, 0x76, 0x64, 0x4a, 0x62, 0x54, 0x3c, 0xe7, 0xf4, 0xc0, 0xd4, 0x1b, 0xda, 0x48, 0xa4, 0xc1, 0xd7, 0x98, 0xc2, 0xac, 0x19, 0x76, 0xd7, 0x44, 0x80, 0x33, 0xfe, 0xcb, 0x2b, 0x97, 0x6d, 0x8e, 0x2, 0x36, 0x4a, 0xfd, 0xc, 0xef, 0xb1, 0x35, 0x76, 0x63, 0x62, 0xc6, 0x5b, 0x38, 0xd3, 0x7e, 0x0, 0x7b, 0xfe, 0xef, 0x48, 0x93, 0xff, 0xdc, 0x3d, 0xed, 0xf4, 0xc4, 0xc4, 0x99, 0x93, 0xd3, 0x68, 0x5c, 0x9e, 0xee, 0x87, 0x16, 0xca, 0x1f, 0xbb, 0x80, 0x9e, 0xa0, 0x5, 0x47, 0x0, 0xbc, 0x5f, 0x7, 0x79, 0xa9, 0x3, 0x99, 0x80, 0x8f, 0xa7, 0x16, 0x68, 0xcd, 0x3a, 0x3d, 0x32, 0x60, 0xc0, 0x6f, 0xd8, 0x2b, 0x8a, 0xe1, 0x20, 0xf, 0xe3, 0x4, 0xcf, 0xfa, 0x1a, 0xb, 0x90, 0xfb, 0x2a, 0x57, 0x4a, 0xa8, 0xc9, 0xb7, 0x91, 0x37, 0x82, 0xf7, 0x4c, 0xd2, 0xa9, 0x9a, 0x78, 0x8f, 0x53, 0x22, 0x40, 0xfd, 0x44, 0x5c, 0xdf, 0xeb, 0x89, 0x4a, 0xc9, 0x0, 0xe7, 0x74, 0x1, 0x28, 0xff, 0xa6, 0x7e, 0xa, 0x4, 0xe9, 0x43, 0xe2, 0x7, 0x7d, 0xaf, 0x9, 0xca, 0x61, 0x3, 0x88, 0x13, 0x20, 0xab, 0x50, 0x1e, 0x41, 0xbc, 0x68, 0x3, 0xd5, 0xc2, 0x69, 0xa4, 0x5b, 0x22, 0xbb, 0x35, 0xdc, 0x45, 0x72, 0x94, 0xba, 0x85, 0xee, 0x82, 0x54, 0x0, 0xcb, 0x45, 0xa4, 0x78, 0xa, 0xc0, 0x28, 0x1c, 0x91, 0x46, 0x50, 0xa3, 0x34, 0xcb, 0x63, 0xfa, 0xeb, 0xb8, 0xd8, 0x5e, 0x9e, 0xde, 0x2b, 0xa3, 0xda, 0x35, 0xd3, 0x62, 0xc4, 0x8e, 0xca, 0x39, 0xf0, 0xb1, 0x7a, 0xd6, 0x69, 0x5f, 0x5, 0xa1, 0xa4, 0xa3, 0x3a, 0xdf, 0x8, 0xd8, 0xcf, 0x62, 0xf7, 0x14, 0x4f, 0x5a, 0x87, 0xa5, 0xc1, 0x22, 0x51, 0xe2, 0xd5, 0x9a, 0xc1, 0x1c, 0x37, 0x5e, 0xd6, 0x7f, 0xed, 0xfb, 0x41, 0x5e, 0xb7, 0xf, 0x7c, 0xe3, 0xba, 0x7b, 0xd0, 0xa5, 0x3a, 0xb3, 0x8c, 0xd7, 0x2e, 0x4e, 0xd7, 0xba, 0xbb, 0xd7, 0xc6, 0xb, 0x8d, 0x17, 0x1f, 0xe3, 0x46, 0x9, 0x49, 0xa1, 0x8c, 0x13, 0x63, 0x4c, 0xa6, 0xfa, 0x2a, 0x8c, 0x38, 0x88, 0x6a, 0xc9, 0x32, 0x4c, 0x1b, 0xa3, 0x44, 0x43, 0xd9, 0x55, 0xdb, 0xce, 0xc1, 0xe9, 0x92, 0x2f, 0x4a, 0x25, 0x59, 0x36, 0x52, 0x52, 0x41, 0xc4, 0x16, 0x2, 0x41, 0x32, 0x7a, 0x73, 0x4b, 0x21, 0xb, 0x8, 0x57, 0x89, 0xc2, 0x90, 0x65, 0xa8, 0xdc, 0x46, 0x56, 0x14, 0x15, 0x8e, 0xc1, 0x20, 0xd7, 0xcc, 0x40, 0x76, 0x42, 0x3a, 0x83, 0xf, 0x83, 0x46, 0xf5, 0x27, 0xa7, 0x80, 0x7e, 0xcf, 0xd2, 0x74, 0xd0, 0x78, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const unsigned char base_green_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x1, 0x3, 0x0, 0x0, 0x0, 0x49, 0xb4, 0xe8, 0xb7, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x90, 0xc9, 0xab, 0xff, 0xff, 0xff, 0xc6, 0xd0, 0x9d, 0x30, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x18, 0xe4, 0x0, 0x0, 0x0, 0xa0, 0x0, 0x1, 0xf3, 0xdb, 0xea, 0x79, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char button_disabled_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xc7, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0xd0, 0x81, 0x66, 0x43, 0x31, 0x14, 0x87, 0xf1, 0xf, 0x5, 0x17, 0xb8, 0x28, 0x2e, 0x8, 0x71, 0xf3, 0x6, 0x19, 0xb6, 0xb9, 0xcb, 0xac, 0x95, 0xa4, 0xb7, 0xad, 0x6a, 0xd5, 0x68, 0x5f, 0xe4, 0x3e, 0x76, 0x1e, 0xe1, 0xbf, 0x21, 0xa6, 0xab, 0xf8, 0x1, 0x7c, 0x9c, 0x73, 0xe, 0xac, 0xe8, 0xe8, 0x19, 0x30, 0x58, 0xc6, 0xca, 0x62, 0x18, 0xe8, 0xe9, 0x58, 0x41, 0xc7, 0x1a, 0x87, 0x27, 0x10, 0x49, 0xe4, 0x5f, 0x89, 0x48, 0xc0, 0xe3, 0x58, 0xd3, 0x41, 0x8f, 0xb, 0xcb, 0xbd, 0x7c, 0xeb, 0xbf, 0x7b, 0x9, 0xb, 0x8e, 0x1e, 0x6, 0xfc, 0xad, 0x64, 0x6d, 0xb5, 0x79, 0xb0, 0x55, 0xd6, 0xad, 0xe0, 0x19, 0xc0, 0x10, 0xae, 0xda, 0x34, 0x5c, 0x45, 0xc0, 0x80, 0x25, 0x5e, 0xf4, 0xd5, 0x70, 0x11, 0x11, 0xb, 0x23, 0xe9, 0xac, 0xcf, 0x86, 0xb3, 0x48, 0x8c, 0x30, 0x92, 0x4f, 0xa, 0xd, 0x27, 0x91, 0x6b, 0x70, 0xd4, 0x47, 0xc3, 0xf1, 0x2f, 0x48, 0x7, 0x4d, 0xd, 0x87, 0x3a, 0xc2, 0x12, 0x67, 0xbd, 0x37, 0xcc, 0x75, 0x49, 0x43, 0xd8, 0xe9, 0xad, 0x61, 0x57, 0xcf, 0x1c, 0xf0, 0xfb, 0x32, 0xe9, 0xf5, 0xc9, 0xa4, 0x7d, 0x7d, 0x54, 0x8f, 0x7b, 0x59, 0xe6, 0x92, 0x14, 0x1f, 0x24, 0xcd, 0x3f, 0x7b, 0x6b, 0xa, 0xe, 0x6a, 0x82, 0x91, 0x45, 0x30, 0xba, 0x1, 0x4a, 0x51, 0xc4, 0x35, 0x1f, 0xe5, 0xa1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -62,10 +54,6 @@ static const unsigned char color_picker_sample_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x14, 0x8, 0x0, 0x0, 0x0, 0x0, 0x47, 0x29, 0xbc, 0x83, 0x0, 0x0, 0x0, 0x3c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xd5, 0x21, 0x11, 0x0, 0x30, 0xc, 0x4, 0xc1, 0xfa, 0x57, 0x53, 0x87, 0xed, 0x4, 0x45, 0xc4, 0xed, 0xa3, 0xc3, 0x4b, 0xfe, 0xbc, 0xd9, 0x9d, 0x35, 0x2b, 0xe, 0x0, 0x0, 0x0, 0x80, 0xed, 0x66, 0xc5, 0x1, 0x0, 0x0, 0x0, 0xe0, 0x6, 0x1, 0x0, 0x0, 0x90, 0x6, 0x70, 0x83, 0x0, 0x0, 0x0, 0x28, 0x3, 0x7c, 0x54, 0x93, 0xd6, 0xf1, 0xd1, 0x16, 0x8a, 0x17, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char dosfont_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 0x1, 0x0, 0x0, 0x0, 0x0, 0xeb, 0x45, 0x5c, 0x66, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x2, 0x64, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xbc, 0xd4, 0x81, 0x86, 0x2c, 0x47, 0x14, 0xc6, 0xf1, 0xcf, 0x45, 0x81, 0x32, 0x2, 0x38, 0x58, 0x17, 0xe4, 0x1, 0xa, 0x44, 0x8b, 0x7a, 0x98, 0xb2, 0xe2, 0xb8, 0x28, 0x2c, 0x68, 0x8d, 0x63, 0x5c, 0xb0, 0xef, 0x90, 0xb7, 0xe9, 0x6c, 0x71, 0x40, 0x9, 0x20, 0xd0, 0x63, 0x2d, 0x98, 0x0, 0xc, 0x88, 0x60, 0x54, 0xa7, 0xaa, 0xba, 0xef, 0x66, 0x67, 0x5d, 0x10, 0x37, 0xf7, 0xf, 0xc3, 0x4f, 0x39, 0x53, 0x87, 0xd2, 0xf8, 0x5a, 0x84, 0x9b, 0xb8, 0x81, 0xc3, 0x6b, 0xc4, 0x90, 0x1, 0xce, 0xee, 0xe4, 0xe1, 0x39, 0x6a, 0x84, 0x23, 0xda, 0x80, 0xe1, 0x7f, 0x8c, 0x4f, 0xf1, 0x29, 0x38, 0x8b, 0xd6, 0x87, 0x4, 0x8f, 0x32, 0xf, 0xa, 0x67, 0x99, 0x2a, 0x98, 0x4, 0x42, 0x94, 0xd1, 0x56, 0xf0, 0xd, 0xec, 0xd2, 0xc0, 0x9c, 0xa8, 0xc2, 0x7a, 0x44, 0x1, 0x6d, 0x90, 0xdd, 0x97, 0x13, 0x2e, 0x1, 0x28, 0x8f, 0x39, 0xf4, 0x19, 0x55, 0x42, 0x9f, 0xa1, 0x59, 0x41, 0x4, 0x10, 0x68, 0xe6, 0x6d, 0xe8, 0x23, 0xac, 0xeb, 0xf0, 0xd9, 0xbf, 0xdd, 0xc5, 0xdd, 0x2c, 0xf7, 0x4d, 0x23, 0x11, 0x5b, 0x86, 0x22, 0x82, 0x96, 0x0, 0x83, 0xea, 0xdd, 0x1c, 0x54, 0x15, 0x30, 0x8, 0x2a, 0x98, 0x8c, 0xf1, 0xf3, 0x6c, 0x54, 0x89, 0x2c, 0x5c, 0x75, 0xb2, 0x26, 0xee, 0x40, 0x47, 0xb2, 0x15, 0xc8, 0xe7, 0xeb, 0xd5, 0xca, 0x11, 0x70, 0xb0, 0xf4, 0xc, 0x72, 0xa6, 0x18, 0x25, 0x35, 0x40, 0x80, 0x69, 0x10, 0x8c, 0x35, 0xea, 0x1a, 0xb8, 0xa3, 0x6d, 0x30, 0xef, 0x40, 0x44, 0x20, 0x9c, 0x40, 0xaa, 0x56, 0x2b, 0xd8, 0xfe, 0x2f, 0x34, 0xe3, 0x58, 0xe4, 0xa3, 0x88, 0x93, 0x9, 0xce, 0x20, 0x90, 0xe0, 0xfb, 0xf4, 0xc3, 0xd5, 0xff, 0x5d, 0x8a, 0x57, 0xff, 0xf1, 0x7c, 0x49, 0x2a, 0x57, 0xc, 0xcc, 0x91, 0x99, 0x95, 0x2c, 0x87, 0x3f, 0xcf, 0xca, 0x88, 0xfc, 0xc4, 0xf7, 0xf7, 0x4f, 0x1d, 0xd6, 0xbf, 0x2a, 0x28, 0xcf, 0xfc, 0xe9, 0xd3, 0x5c, 0x21, 0x86, 0xb5, 0x34, 0x90, 0x99, 0xa7, 0x69, 0x2e, 0x64, 0xa7, 0xb0, 0x3c, 0xab, 0xa0, 0xf4, 0x13, 0xcf, 0xda, 0x20, 0xfd, 0xae, 0x1, 0x5a, 0x21, 0x4, 0x55, 0xca, 0x31, 0x24, 0x6d, 0xd0, 0x86, 0x76, 0xe0, 0xfb, 0x1d, 0x38, 0x72, 0xe0, 0x6, 0xbc, 0x41, 0xbb, 0xd8, 0xe5, 0x67, 0xf5, 0xd3, 0xb9, 0x24, 0x95, 0xcb, 0xff, 0xb0, 0x3a, 0xdc, 0x2d, 0xc, 0x15, 0xe4, 0x2a, 0xab, 0xa6, 0xda, 0xea, 0xe1, 0x23, 0x8, 0xca, 0xba, 0x74, 0x48, 0xee, 0xb3, 0x55, 0xa0, 0xc1, 0xaf, 0x15, 0x38, 0x3d, 0xba, 0xd9, 0xa2, 0x43, 0xa0, 0xa, 0x9e, 0xad, 0x7b, 0xd9, 0x40, 0x86, 0x6, 0xe4, 0xc9, 0x3d, 0x6c, 0x10, 0x6d, 0x85, 0x85, 0xc8, 0xb9, 0x61, 0x3, 0x36, 0xd, 0x3c, 0x5, 0x77, 0xd7, 0xe1, 0xf, 0x56, 0x52, 0x5e, 0x99, 0x7e, 0x73, 0x87, 0xe, 0xcf, 0xd, 0x3c, 0x27, 0x4a, 0xce, 0x74, 0x90, 0xb3, 0x78, 0x21, 0x4e, 0x7e, 0xf5, 0x1f, 0x7c, 0x83, 0xaa, 0xb7, 0x1d, 0xf0, 0xb6, 0x15, 0xdf, 0xa6, 0x17, 0xdc, 0x61, 0xc0, 0xb, 0x99, 0x97, 0x61, 0x83, 0x0, 0x8b, 0x88, 0x40, 0x26, 0xd0, 0xbf, 0xf0, 0xb, 0x2, 0xb0, 0xc3, 0x34, 0x89, 0x97, 0x30, 0xc6, 0xe1, 0xc0, 0x74, 0x3e, 0xc9, 0x9, 0x36, 0x6a, 0xd4, 0x4b, 0x1e, 0xc9, 0x44, 0x5a, 0x59, 0x19, 0xc2, 0x73, 0x2e, 0x21, 0x33, 0x99, 0x89, 0x96, 0x6, 0xb9, 0xc2, 0xfc, 0x75, 0x88, 0x5f, 0x40, 0xb3, 0x76, 0xe0, 0xd, 0x46, 0x91, 0x51, 0x2e, 0x72, 0xf6, 0xe6, 0xec, 0x17, 0x16, 0xc1, 0x96, 0x5, 0x18, 0xad, 0xb0, 0x43, 0x7e, 0xf, 0x13, 0xe0, 0xd1, 0xba, 0xfc, 0xe7, 0x77, 0xd3, 0x3b, 0xd0, 0xc3, 0x78, 0xf3, 0xb9, 0x22, 0xa2, 0xd3, 0x7b, 0x40, 0x6d, 0x3c, 0xc9, 0x35, 0xa7, 0x94, 0xb4, 0xec, 0x90, 0x47, 0x75, 0x15, 0x58, 0xf3, 0x3, 0xe, 0x1d, 0x38, 0x34, 0xf0, 0x4a, 0xb5, 0xe, 0x61, 0xa8, 0xb0, 0x90, 0xba, 0x57, 0xb0, 0x2e, 0xf3, 0xe2, 0x35, 0xbc, 0x82, 0xfe, 0x94, 0xfd, 0xca, 0xaa, 0x3b, 0xc8, 0x45, 0xee, 0x46, 0xe2, 0x74, 0x2c, 0xf5, 0x62, 0x6f, 0xdf, 0x87, 0xc1, 0x9e, 0x7d, 0xf7, 0xfb, 0xcf, 0x18, 0xe4, 0xa0, 0xf4, 0xf, 0x22, 0x3c, 0x3d, 0xa, 0x46, 0x1, 0x0, 0x24, 0x3a, 0x65, 0x42, 0x42, 0xc7, 0x4f, 0x7c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char dropdown_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x60, 0xf8, 0xc0, 0xcc, 0x0, 0x2, 0x60, 0x16, 0x98, 0x78, 0x67, 0x8, 0x81, 0x6f, 0x4d, 0xde, 0x9a, 0x0, 0x5, 0xde, 0x3a, 0x3d, 0xfc, 0x8f, 0x80, 0xaf, 0xba, 0x18, 0xde, 0x29, 0x2, 0x19, 0xbf, 0x61, 0x2, 0x6f, 0x62, 0x18, 0x3e, 0xb0, 0xbd, 0x97, 0x4, 0x32, 0xff, 0x80, 0xb9, 0xb1, 0x20, 0x93, 0xc0, 0x42, 0x8, 0x2e, 0x54, 0xe8, 0x9d, 0xdc, 0x9b, 0x54, 0x10, 0xb, 0x21, 0xc4, 0x4, 0x63, 0x1, 0x0, 0x86, 0x1f, 0x3b, 0x1e, 0x92, 0x22, 0x3f, 0x40, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -78,14 +66,6 @@ static const unsigned char focus_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x4, 0x3, 0x0, 0x0, 0x0, 0xa4, 0x5b, 0x41, 0xd4, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0xff, 0xff, 0xff, 0xb9, 0xa2, 0x9b, 0xc9, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x10, 0x32, 0x9, 0xd, 0x75, 0x56, 0x64, 0x48, 0xef, 0x9c, 0x39, 0x73, 0x46, 0x19, 0xc3, 0x6a, 0x6, 0x20, 0xd8, 0xc5, 0x10, 0x3, 0xa2, 0x8e, 0x32, 0x44, 0x82, 0xa8, 0xa9, 0xd8, 0x29, 0xa8, 0x12, 0xb0, 0x6, 0x29, 0x86, 0xdc, 0x9d, 0x33, 0x67, 0xce, 0x2b, 0x63, 0x10, 0x3, 0x1b, 0x6, 0x0, 0xdf, 0xc6, 0x11, 0x6d, 0xb8, 0xf4, 0x9c, 0xac, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char frame_focus_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x4, 0x3, 0x0, 0x0, 0x0, 0xa4, 0x5b, 0x41, 0xd4, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0xff, 0xff, 0xff, 0xcc, 0x40, 0x27, 0xb9, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x10, 0x32, 0x9, 0xd, 0x75, 0x56, 0x64, 0x48, 0xef, 0x9c, 0x39, 0x73, 0x46, 0x19, 0xc3, 0x6a, 0x6, 0x20, 0xd8, 0xc5, 0x10, 0x3, 0xa2, 0x8e, 0x32, 0x44, 0x82, 0xa8, 0xa9, 0xd8, 0x29, 0xa8, 0x12, 0xb0, 0x6, 0x29, 0x86, 0xdc, 0x9d, 0x33, 0x67, 0xce, 0x2b, 0x63, 0x10, 0x3, 0x1b, 0x6, 0x0, 0xdf, 0xc6, 0x11, 0x6d, 0xb8, 0xf4, 0x9c, 0xac, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const unsigned char full_panel_bg_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x4, 0x3, 0x0, 0x0, 0x0, 0x81, 0x54, 0x67, 0xc7, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x27, 0x27, 0x29, 0x26, 0x26, 0x28, 0x25, 0x25, 0x27, 0x24, 0x24, 0x26, 0x23, 0x23, 0x25, 0x22, 0x22, 0x24, 0x21, 0x21, 0x23, 0x1e, 0x1e, 0x20, 0x1d, 0x1d, 0x1f, 0x1c, 0x1c, 0x1e, 0x31, 0x30, 0x32, 0x50, 0x4e, 0x54, 0x4e, 0x4c, 0x50, 0x4c, 0x4a, 0x4e, 0x3d, 0x3b, 0x3f, 0x38, 0x36, 0x3a, 0xb3, 0xde, 0x6f, 0x4d, 0x0, 0x0, 0x0, 0x5a, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x60, 0x14, 0x52, 0x82, 0x3, 0x45, 0x1, 0x20, 0x5f, 0xd9, 0x35, 0xd, 0xe, 0x42, 0x8c, 0x4, 0x18, 0x98, 0xcc, 0x2a, 0x66, 0xc2, 0x41, 0x7b, 0xb2, 0x2, 0x83, 0x70, 0xd6, 0x9e, 0xbb, 0x70, 0x70, 0x7a, 0x99, 0x21, 0x83, 0x48, 0xf5, 0xfb, 0xff, 0x70, 0xf0, 0x6f, 0xbb, 0x23, 0x83, 0x6a, 0xcf, 0x7f, 0x24, 0x70, 0x22, 0x88, 0x41, 0x6d, 0x2e, 0xb2, 0xc0, 0xcd, 0x24, 0x8a, 0x5, 0x46, 0x5, 0x30, 0x2, 0x19, 0x23, 0x1a, 0x30, 0x22, 0xa, 0x23, 0x2a, 0x31, 0x22, 0x1b, 0x23, 0x39, 0x0, 0x0, 0x8c, 0xb1, 0x80, 0xd2, 0x41, 0x59, 0x8c, 0x74, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char graph_node_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x17, 0xd, 0x5, 0x12, 0xa1, 0x38, 0x83, 0x9b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x2, 0x74, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0x97, 0x3d, 0x6f, 0xd3, 0x60, 0x10, 0xc7, 0x7f, 0x17, 0x9b, 0x26, 0x25, 0x22, 0xad, 0xa, 0x8, 0xf1, 0x52, 0x75, 0x0, 0x16, 0x24, 0x90, 0x2a, 0x96, 0x7c, 0x1, 0x6, 0xc4, 0xce, 0xc4, 0x17, 0x0, 0x31, 0xb0, 0x30, 0x0, 0x23, 0x82, 0x85, 0x5, 0x9, 0x4, 0x5f, 0x80, 0x89, 0x1d, 0x31, 0xf0, 0x5, 0x58, 0x50, 0x25, 0x50, 0x59, 0x80, 0xa1, 0xe2, 0xad, 0x28, 0x34, 0x4a, 0x3, 0x25, 0x76, 0xea, 0xe7, 0x39, 0x6, 0x3f, 0x76, 0x6d, 0xc7, 0x49, 0x5f, 0xd8, 0x90, 0x6f, 0xb1, 0xf5, 0xe4, 0xb9, 0xdf, 0xdd, 0xfd, 0xef, 0x22, 0xf9, 0x84, 0x2d, 0x13, 0xa0, 0x6, 0x78, 0xee, 0x29, 0xe4, 0x4d, 0x1, 0xb, 0x18, 0xf7, 0x54, 0x32, 0x97, 0x6a, 0xc0, 0x7e, 0x60, 0xe, 0x38, 0xc, 0xb4, 0x80, 0x7d, 0x5, 0xc0, 0x26, 0xd0, 0x7, 0x3a, 0x40, 0x17, 0xf8, 0x3, 0xd8, 0x24, 0x6a, 0x13, 0x38, 0x35, 0x73, 0x60, 0xf6, 0x6a, 0xa3, 0xde, 0xb8, 0x38, 0x35, 0x55, 0x3f, 0x41, 0x89, 0xd, 0x87, 0xe1, 0x97, 0x20, 0xc, 0x5e, 0xae, 0xff, 0xea, 0x3d, 0x5, 0x3e, 0x2, 0x1b, 0xe2, 0x22, 0x2d, 0xcc, 0xcd, 0x1e, 0x7c, 0x78, 0x72, 0xe1, 0xf4, 0xa5, 0x7b, 0xb7, 0x1f, 0x7c, 0x9e, 0x6e, 0x35, 0xca, 0xfc, 0x19, 0xf4, 0x3, 0xee, 0xdc, 0xbf, 0x39, 0xff, 0x69, 0xe5, 0xc3, 0x8b, 0x6e, 0x6f, 0xed, 0x6, 0xb0, 0x22, 0x40, 0x3, 0x58, 0x3c, 0x7a, 0xe4, 0xf8, 0xab, 0x67, 0x4f, 0x9e, 0x77, 0xa3, 0xc8, 0x12, 0xd, 0xa3, 0x52, 0x80, 0x3f, 0xe5, 0xe3, 0xfb, 0x35, 0xae, 0x5c, 0xbb, 0x3c, 0xf7, 0xfd, 0xc7, 0xd7, 0xb, 0xc0, 0x92, 0xef, 0x74, 0x68, 0xfa, 0x9e, 0xdf, 0x1c, 0xfc, 0xe, 0xbb, 0x88, 0xc6, 0x47, 0xa, 0x2a, 0x59, 0x85, 0x95, 0x61, 0xb8, 0xc9, 0x30, 0x4, 0xdf, 0xf3, 0x9b, 0xae, 0x6c, 0x49, 0x0, 0x1e, 0x80, 0x51, 0x1b, 0xfb, 0xc7, 0x2, 0xc7, 0x5a, 0x3b, 0x88, 0x66, 0xcf, 0x63, 0xf3, 0x12, 0x80, 0x26, 0xbf, 0xa8, 0xb5, 0xa8, 0xa, 0x88, 0x22, 0x8, 0x8a, 0x22, 0x2a, 0x19, 0x37, 0x1d, 0xe9, 0xad, 0x9f, 0x6b, 0xb4, 0x55, 0x14, 0x5, 0x55, 0x44, 0xe2, 0x32, 0x6c, 0xe2, 0x24, 0x71, 0x18, 0x9d, 0x4, 0xb0, 0x6a, 0xd3, 0x1b, 0x2a, 0xe9, 0x4b, 0xfc, 0xae, 0xe4, 0x45, 0x19, 0x9f, 0x81, 0x2b, 0xdb, 0x15, 0xa6, 0xa2, 0x19, 0x2d, 0xec, 0x8, 0x24, 0x7, 0x30, 0xd6, 0x16, 0xf8, 0x82, 0xa8, 0xc6, 0x45, 0x68, 0x52, 0xbf, 0x4e, 0xce, 0x60, 0xeb, 0x42, 0x5c, 0xb4, 0x66, 0x9c, 0x6c, 0xc9, 0x1f, 0xa4, 0x0, 0xb0, 0x39, 0xc5, 0xc9, 0xa1, 0x28, 0x89, 0x5f, 0x14, 0xd1, 0x5a, 0x37, 0x32, 0x89, 0xf2, 0x82, 0xc6, 0x3, 0xe0, 0xda, 0xa, 0x22, 0x3a, 0xa9, 0xb, 0x9a, 0x26, 0xaa, 0xf1, 0x41, 0x9a, 0x42, 0x2, 0xb2, 0xb2, 0x6d, 0x6, 0x5b, 0xa3, 0xab, 0x23, 0xd5, 0x48, 0x32, 0x92, 0xe3, 0x33, 0x10, 0x37, 0xb7, 0x2a, 0xea, 0xee, 0x4a, 0x2a, 0x42, 0xe, 0x5a, 0x2a, 0xa2, 0x51, 0x37, 0x40, 0x85, 0x48, 0x96, 0xb4, 0x23, 0xdb, 0x88, 0x68, 0x5c, 0xc4, 0xcc, 0x3c, 0x14, 0xa7, 0x6f, 0xa2, 0x6, 0xaa, 0xb1, 0x7c, 0xd9, 0x30, 0xaa, 0x79, 0xc7, 0x49, 0x93, 0x78, 0xf7, 0xd1, 0xad, 0x79, 0x76, 0x69, 0x29, 0x20, 0xda, 0x34, 0x2c, 0x9e, 0x3d, 0xff, 0x7a, 0x27, 0x4e, 0x4b, 0xef, 0xde, 0xb4, 0x4b, 0x33, 0x58, 0xef, 0xf7, 0x76, 0x9b, 0x0, 0x35, 0xfe, 0xd1, 0x2a, 0x40, 0x5, 0xa8, 0x0, 0x15, 0xa0, 0x2, 0x54, 0x80, 0xa, 0xf0, 0x5f, 0x2, 0xa4, 0xe4, 0x13, 0x78, 0xd7, 0x19, 0xd8, 0x3d, 0xf8, 0xda, 0x4, 0x60, 0x81, 0xc0, 0x18, 0x13, 0xda, 0x68, 0x7, 0x5e, 0x11, 0x18, 0x63, 0x42, 0x20, 0x0, 0x6c, 0xcd, 0xad, 0xb2, 0x6b, 0x41, 0x38, 0x58, 0xee, 0x74, 0x57, 0xdb, 0x93, 0x20, 0x36, 0x82, 0x4e, 0x77, 0xb5, 0x1d, 0x84, 0x83, 0x65, 0x60, 0xd, 0x30, 0xc9, 0xe6, 0x3a, 0x3, 0x9c, 0x6b, 0x35, 0x67, 0x1f, 0x37, 0xea, 0xd3, 0x67, 0x3c, 0xcf, 0x2b, 0x15, 0xd7, 0x18, 0x63, 0x83, 0x70, 0xf0, 0xbe, 0xbf, 0xd1, 0xbb, 0xe, 0xbc, 0x5, 0xd6, 0x25, 0xb3, 0xc2, 0xb5, 0x80, 0x63, 0xc0, 0x21, 0xa0, 0x3e, 0x66, 0xf9, 0xe, 0x81, 0x9f, 0xc0, 0x37, 0xb7, 0x47, 0x1b, 0x29, 0x8, 0xea, 0x27, 0xfb, 0xe0, 0x98, 0x2a, 0xd4, 0x95, 0x1c, 0xed, 0x51, 0xf8, 0x51, 0xfb, 0xb, 0x1, 0xbe, 0x20, 0x9f, 0x90, 0x81, 0x17, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -178,10 +158,6 @@ static const unsigned char icon_parent_folder_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x68, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x33, 0xb8, 0x27, 0xfe, 0xe0, 0xfc, 0x83, 0x73, 0xf7, 0xc4, 0x71, 0x48, 0xdf, 0x11, 0x7b, 0x78, 0xe9, 0xc1, 0x3f, 0x20, 0xbc, 0xfe, 0x40, 0x12, 0x8f, 0x34, 0x4c, 0x9, 0xa6, 0xe1, 0x57, 0x80, 0x12, 0x17, 0x81, 0xf8, 0x2f, 0x58, 0xe1, 0x15, 0x34, 0x8b, 0x1e, 0x9c, 0x5, 0xa, 0x5e, 0xb8, 0x23, 0x6, 0x52, 0x70, 0x5b, 0x14, 0xac, 0xf0, 0xc, 0xaa, 0x82, 0x7d, 0xf, 0x8e, 0xde, 0x14, 0xf9, 0xcf, 0x8, 0x52, 0xc0, 0xc0, 0x70, 0x5b, 0xf4, 0xe1, 0xc9, 0x7, 0x47, 0xb1, 0xb8, 0x3, 0xaa, 0x0, 0xa, 0x48, 0x52, 0x80, 0xb0, 0xea, 0xc8, 0xc3, 0x83, 0xc, 0x83, 0xe, 0x0, 0x0, 0xb8, 0x27, 0x55, 0x4c, 0xbe, 0xc0, 0xd2, 0xac, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char icon_play_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x41, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x1b, 0x78, 0x70, 0xf8, 0xc1, 0xb5, 0x7, 0xde, 0xf8, 0x14, 0xfc, 0x7, 0xc1, 0x87, 0x3b, 0x1e, 0x6a, 0xe1, 0x54, 0x0, 0x85, 0xbf, 0x1f, 0x4c, 0x79, 0x22, 0x8c, 0x5d, 0x1, 0x2, 0xbe, 0x7f, 0x58, 0x7e, 0x9b, 0x1d, 0x43, 0x1, 0x1a, 0x3c, 0x4c, 0x91, 0x82, 0x77, 0x8, 0x2b, 0x8, 0x3b, 0x12, 0xd3, 0x9b, 0x84, 0x3, 0x8a, 0xfe, 0x0, 0x0, 0xa4, 0x15, 0x70, 0xca, 0x48, 0x40, 0x6f, 0xa6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char icon_reload_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0xb1, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xad, 0x50, 0x35, 0xba, 0xc2, 0x40, 0x10, 0x7e, 0xcd, 0x33, 0x5c, 0xca, 0x1c, 0x21, 0x87, 0xc1, 0xa9, 0xd3, 0x23, 0x47, 0xca, 0x69, 0xb0, 0x6, 0x77, 0xdb, 0xfd, 0x17, 0x2f, 0x91, 0x3e, 0xee, 0xd2, 0xc1, 0x4e, 0xb5, 0xdf, 0xcc, 0xaf, 0x5f, 0x9f, 0x7c, 0xdb, 0x5f, 0xda, 0x44, 0x17, 0x2f, 0x75, 0xba, 0xa4, 0xb1, 0xfd, 0xf5, 0xad, 0x8f, 0x1c, 0x86, 0x90, 0x5c, 0x33, 0x38, 0x72, 0x1e, 0xb4, 0xbe, 0x66, 0x28, 0xad, 0xe2, 0xab, 0x38, 0xcd, 0x63, 0xa9, 0x9d, 0xb8, 0x58, 0x68, 0x53, 0x5b, 0x1f, 0x33, 0xd6, 0x9f, 0xa5, 0xc1, 0x20, 0x91, 0xba, 0x7d, 0x80, 0x1e, 0x24, 0x94, 0xdc, 0x92, 0xa4, 0x2, 0x9, 0x1d, 0xe7, 0xe0, 0x9, 0x69, 0x15, 0xf7, 0x58, 0x4e, 0x40, 0xc2, 0xc3, 0x58, 0x8a, 0xb6, 0x31, 0xd1, 0x39, 0xd8, 0x27, 0xed, 0x83, 0x5b, 0x14, 0x33, 0x7d, 0x3d, 0xbb, 0x45, 0x5d, 0x12, 0x55, 0x97, 0x4, 0xe3, 0xb5, 0xf4, 0x8c, 0x77, 0xd6, 0xa7, 0x2c, 0x3b, 0x78, 0x4c, 0x52, 0x81, 0xa, 0x8e, 0x3a, 0xa9, 0x6a, 0x6b, 0xc, 0xe6, 0x3f, 0xa1, 0x8d, 0x86, 0x16, 0xe5, 0x39, 0x78, 0xa2, 0x4d, 0xea, 0xe, 0xfa, 0xdd, 0xa7, 0x0, 0x90, 0x4f, 0x8b, 0xd0, 0xe1, 0x9e, 0x1b, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -190,10 +166,6 @@ static const unsigned char icon_snap_grid_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xf3, 0xf3, 0xf3, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x85, 0x85, 0xff, 0x83, 0x83, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x80, 0x80, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0x84, 0x84, 0xff, 0xff, 0xff, 0xa, 0xa5, 0x43, 0x1, 0x0, 0x0, 0x0, 0x10, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xff, 0x1d, 0xac, 0xf2, 0xaf, 0x27, 0xed, 0xff, 0xee, 0xb4, 0x1b, 0x1c, 0xb6, 0xaa, 0xf1, 0x50, 0xa6, 0xdd, 0x5f, 0x0, 0x0, 0x0, 0x4e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x62, 0x0, 0x2, 0x40, 0x23, 0xd3, 0x60, 0x0, 0x40, 0xc, 0x3, 0xaf, 0x76, 0x93, 0xfd, 0x97, 0x7d, 0x9b, 0x55, 0x70, 0x12, 0x62, 0xaf, 0x68, 0x0, 0xc4, 0xe9, 0x3c, 0x1, 0x67, 0xf7, 0x17, 0x20, 0x95, 0xd6, 0xc6, 0xee, 0x80, 0x74, 0xde, 0x7b, 0x1f, 0x24, 0xb0, 0x64, 0x29, 0x1f, 0x53, 0x2e, 0xbe, 0x6e, 0x80, 0xf6, 0x19, 0x90, 0x9e, 0x36, 0x8b, 0xf7, 0xc0, 0x5c, 0xdf, 0x0, 0x66, 0x60, 0xae, 0xf3, 0xb9, 0x1, 0xfb, 0xe9, 0x1, 0xa6, 0x26, 0x1, 0xcd, 0x30, 0x66, 0x63, 0x6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char icon_stop_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x1e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x2, 0x7c, 0x60, 0x26, 0x28, 0xf3, 0xf0, 0x3f, 0x76, 0x8, 0x94, 0xa2, 0x97, 0x82, 0x51, 0x5, 0x84, 0x23, 0x8b, 0x30, 0x0, 0x0, 0x66, 0x60, 0x11, 0xdc, 0x92, 0xb3, 0xb7, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char icon_visibility_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x3, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0xdb, 0xe1, 0x4f, 0xe0, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc4, 0x0, 0x0, 0xe, 0xc4, 0x1, 0x95, 0x2b, 0xe, 0x1b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0x96, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xdf, 0xdf, 0xdf, 0xe3, 0xe3, 0xe3, 0xe6, 0xe6, 0xe6, 0xd5, 0xd5, 0xd5, 0xd8, 0xd8, 0xd8, 0xdb, 0xdb, 0xdb, 0xdd, 0xdd, 0xdd, 0xe1, 0xe1, 0xe1, 0xe3, 0xe3, 0xe3, 0xe4, 0xe4, 0xe4, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xe0, 0xe0, 0xe0, 0xde, 0xde, 0xde, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xb7, 0x7e, 0xd, 0xb6, 0x0, 0x0, 0x0, 0x32, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x8, 0x9, 0xa, 0xc, 0xd, 0xe, 0xf, 0x11, 0x12, 0x13, 0x2e, 0x2f, 0x32, 0x33, 0x36, 0x37, 0x38, 0x48, 0x49, 0x4b, 0x50, 0x53, 0x55, 0x56, 0x6c, 0x6d, 0x6e, 0x70, 0x77, 0x79, 0x7b, 0x7c, 0xc5, 0xd7, 0xd8, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1, 0xe2, 0xe3, 0xf0, 0xf2, 0xf3, 0xf4, 0xfe, 0x5e, 0x62, 0x1a, 0x26, 0x0, 0x0, 0x0, 0x86, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19, 0x8d, 0xc1, 0xb, 0x16, 0x42, 0x40, 0x0, 0x86, 0xd1, 0x2f, 0xa2, 0x77, 0x2a, 0x85, 0xde, 0x91, 0x5e, 0x33, 0x8a, 0x7f, 0xff, 0x9b, 0xcb, 0x99, 0x63, 0x1, 0xee, 0xa5, 0x9f, 0xc1, 0x3e, 0x6f, 0xea, 0xfc, 0xe0, 0xd1, 0x99, 0xdd, 0xe5, 0x94, 0xb, 0x9c, 0xf9, 0x57, 0x26, 0x9, 0x82, 0x5d, 0xa1, 0xdf, 0x92, 0x96, 0xf7, 0x94, 0x99, 0xd0, 0x1a, 0x1b, 0x7d, 0x7c, 0xe0, 0x2c, 0x25, 0x6c, 0x2b, 0x1b, 0x93, 0x4a, 0x17, 0xa0, 0x94, 0x2, 0xac, 0x64, 0x8, 0xa5, 0x12, 0x78, 0x48, 0x1, 0x56, 0x32, 0x8c, 0xa4, 0x7, 0x70, 0x93, 0x76, 0xc4, 0xd6, 0x6c, 0xc8, 0xa4, 0x2b, 0x30, 0xac, 0x54, 0x8c, 0x69, 0x4d, 0xad, 0xcc, 0x90, 0xd6, 0xba, 0x91, 0x49, 0xc3, 0x30, 0xb3, 0x6a, 0x22, 0x9c, 0xd5, 0x5b, 0xce, 0x2b, 0xa2, 0xe3, 0x9f, 0xf2, 0xba, 0xce, 0x8f, 0x3e, 0xbd, 0xfc, 0x1, 0xdb, 0xf3, 0x10, 0xc5, 0x78, 0x85, 0x14, 0x89, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -222,14 +194,6 @@ static const unsigned char line_edit_disabled_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x4e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x94, 0xc8, 0x67, 0x6b, 0x60, 0xe6, 0x60, 0x64, 0x80, 0x80, 0xff, 0xc, 0x7f, 0x7f, 0xfc, 0x6a, 0x60, 0x94, 0xfb, 0xc0, 0xce, 0xcf, 0xc2, 0x80, 0x10, 0xfc, 0xc3, 0xf0, 0xf3, 0x23, 0xa3, 0xe2, 0x4f, 0xe, 0x36, 0x54, 0xc1, 0x1f, 0xbf, 0x18, 0x95, 0xbe, 0x73, 0x70, 0xb0, 0x30, 0xc0, 0x1, 0x48, 0xf0, 0x7, 0x85, 0x82, 0x58, 0x2d, 0xc2, 0xe6, 0xa4, 0x4f, 0x20, 0xc7, 0x37, 0x32, 0xb3, 0x23, 0x39, 0xfe, 0xfb, 0xaf, 0x46, 0x0, 0xee, 0x2a, 0x2f, 0xce, 0x4c, 0x47, 0x66, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char line_edit_focus_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0xa8, 0x50, 0x4c, 0x54, 0x45, 0x1b, 0x17, 0x18, 0x1b, 0x17, 0x18, 0x1b, 0x17, 0x18, 0xc8, 0x68, 0x12, 0xef, 0xed, 0xe7, 0xef, 0xed, 0xe8, 0xf0, 0xed, 0xe8, 0xf0, 0xee, 0xe8, 0xf0, 0xed, 0xe7, 0xed, 0xeb, 0xe5, 0xee, 0xeb, 0xe5, 0xee, 0xeb, 0xe6, 0xec, 0xe9, 0xe3, 0xeb, 0xe9, 0xe3, 0xeb, 0xe9, 0xe2, 0xec, 0xe9, 0xe2, 0xe9, 0xe6, 0xe0, 0xea, 0xe7, 0xe0, 0xea, 0xe7, 0xe1, 0xe8, 0xe4, 0xdd, 0xe8, 0xe5, 0xde, 0xe8, 0xe5, 0xdd, 0xe8, 0xe4, 0xde, 0xe6, 0xe2, 0xdb, 0xe6, 0xe3, 0xdb, 0xe6, 0xe3, 0xdc, 0xe7, 0xe2, 0xdb, 0xe7, 0xe3, 0xdb, 0xe4, 0xe0, 0xd8, 0xe5, 0xe0, 0xd8, 0xe5, 0xe1, 0xd9, 0xe5, 0xe0, 0xd9, 0xe4, 0xe1, 0xd9, 0xe5, 0xe1, 0xd8, 0xe4, 0xe0, 0xd9, 0xe2, 0xdf, 0xd6, 0xe3, 0xdf, 0xd6, 0xe3, 0xde, 0xd6, 0xe2, 0xde, 0xd6, 0xe1, 0xdc, 0xd4, 0xe1, 0xdc, 0xd3, 0xe0, 0xdc, 0xd3, 0xe1, 0xdd, 0xd3, 0xe1, 0xdd, 0xd4, 0xdf, 0xda, 0xd0, 0xdf, 0xda, 0xd1, 0xdf, 0xdb, 0xd1, 0xe0, 0xda, 0xd1, 0xdd, 0xd8, 0xcf, 0xdd, 0xd8, 0xce, 0xde, 0xd9, 0xce, 0xde, 0xd8, 0xce, 0xdd, 0xd9, 0xce, 0xdc, 0xd6, 0xcc, 0xdb, 0xd6, 0xcc, 0xdc, 0xd6, 0xcb, 0xbd, 0x92, 0xbc, 0xa2, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x36, 0x61, 0xc5, 0x3a, 0xd, 0x83, 0x0, 0x0, 0x0, 0x72, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x4c, 0x8c, 0x55, 0x2, 0x4, 0x1, 0x8, 0x85, 0xc0, 0xc9, 0xfb, 0x1f, 0x76, 0x7b, 0x75, 0x3a, 0xf0, 0xc7, 0xc0, 0x27, 0xc1, 0x9d, 0x34, 0xe4, 0x4e, 0xb5, 0xa0, 0x68, 0x95, 0xf1, 0x93, 0xc4, 0xb0, 0xb7, 0xd6, 0x2, 0x7c, 0x2d, 0x46, 0xc3, 0x82, 0x45, 0xf8, 0x87, 0x16, 0x5a, 0xd7, 0x71, 0x21, 0x9e, 0x2c, 0x86, 0x52, 0x10, 0x89, 0xee, 0x86, 0x15, 0xd9, 0xf0, 0x6b, 0x7f, 0xac, 0x8b, 0xce, 0x85, 0xb4, 0x8b, 0xe1, 0xb7, 0x2e, 0x6, 0xd9, 0x53, 0x6a, 0x3c, 0x43, 0xa9, 0xd0, 0xcc, 0xd8, 0x5f, 0xd0, 0x4, 0xa2, 0xf6, 0x50, 0xac, 0x68, 0xff, 0x6d, 0xf9, 0x3f, 0xc, 0x93, 0x88, 0x59, 0x68, 0x81, 0x69, 0x18, 0x9e, 0x3, 0xba, 0x1b, 0x55, 0x0, 0x0, 0x0, 0x69, 0x26, 0x8d, 0xeb, 0x4b, 0xad, 0xe7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const unsigned char logo_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x80, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc3, 0x3e, 0x61, 0xcb, 0x0, 0x0, 0x19, 0xdb, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xec, 0x99, 0x3, 0x94, 0x7b, 0x39, 0x14, 0xc6, 0xd7, 0xb6, 0xed, 0x87, 0x62, 0x6d, 0xdb, 0x33, 0xe5, 0x6b, 0xc7, 0x6b, 0xdb, 0xb6, 0x77, 0x5c, 0xb7, 0x6b, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0xbd, 0xdb, 0x74, 0xbf, 0xde, 0xe6, 0x35, 0xff, 0xe6, 0xcc, 0xdb, 0x1d, 0x9f, 0x37, 0xd3, 0xe4, 0x9c, 0xdf, 0x49, 0x5e, 0x9c, 0x7c, 0x37, 0x37, 0x39, 0xed, 0x54, 0x2a, 0xa8, 0xa0, 0x82, 0xa, 0x2a, 0xa8, 0xa0, 0x82, 0xa, 0x2a, 0xa8, 0xa0, 0x82, 0xa, 0xf5, 0x17, 0x8c, 0x48, 0x6a, 0xe, 0x23, 0xd4, 0x73, 0xa5, 0x16, 0xe8, 0xba, 0x5f, 0xb, 0x74, 0xdf, 0xac, 0x87, 0x7a, 0x2f, 0x34, 0xc3, 0xfd, 0x9d, 0x66, 0x24, 0x71, 0x0, 0xca, 0xa2, 0x66, 0x34, 0xb3, 0xba, 0x37, 0x9e, 0x5f, 0x78, 0x92, 0x2e, 0x5f, 0x5, 0x3d, 0xd4, 0x77, 0xe6, 0x72, 0xd, 0xa7, 0x33, 0x50, 0x2a, 0xa3, 0x35, 0x9c, 0x5e, 0xd4, 0x1a, 0xcf, 0xfc, 0x19, 0x7c, 0xae, 0x35, 0x76, 0xbe, 0xa5, 0x5, 0x3a, 0x9f, 0xd5, 0x1a, 0xbb, 0x1e, 0xd4, 0x83, 0x3d, 0xb7, 0x1b, 0xe1, 0xbe, 0x4b, 0xcd, 0x48, 0xf2, 0x0, 0x4f, 0x2c, 0xe7, 0x9f, 0x4, 0x4b, 0x57, 0xc1, 0x13, 0x3f, 0x6b, 0x16, 0x8, 0xfc, 0xe9, 0x72, 0xd, 0x67, 0x94, 0xb4, 0xc6, 0x32, 0x67, 0x56, 0x41, 0x9e, 0xc, 0x2f, 0xeb, 0xfc, 0xa, 0xc6, 0x70, 0x97, 0xc7, 0xca, 0x2c, 0x3e, 0x8e, 0x53, 0x55, 0xc1, 0xb4, 0xb2, 0x1b, 0xeb, 0x70, 0xcd, 0x38, 0xb1, 0x29, 0x23, 0x92, 0x38, 0x79, 0xa4, 0xfd, 0xad, 0xbe, 0xff, 0x63, 0x53, 0x1b, 0xd1, 0xf4, 0x36, 0x7a, 0xa0, 0xf3, 0x77, 0x12, 0xb6, 0xe1, 0xc, 0x46, 0xb1, 0x94, 0x6, 0xac, 0x36, 0x26, 0x63, 0x28, 0xc2, 0x0, 0x1a, 0xd6, 0x3c, 0xf0, 0x89, 0xa9, 0x95, 0x32, 0x63, 0x18, 0x8c, 0x68, 0x66, 0x29, 0x23, 0x92, 0xdc, 0x5, 0xc2, 0x77, 0xe1, 0x7e, 0x7e, 0xaa, 0x2a, 0x4a, 0xa0, 0xf3, 0xf, 0xe4, 0xef, 0x30, 0x62, 0xf7, 0x1f, 0xec, 0x7d, 0x0, 0xfd, 0xfd, 0x83, 0xfe, 0x4a, 0x2, 0xea, 0xdf, 0x11, 0xee, 0x5, 0x7e, 0xc7, 0x55, 0x70, 0x4, 0xd2, 0xd3, 0x28, 0x95, 0xc6, 0xe6, 0xb4, 0xaf, 0x60, 0x46, 0x53, 0xbb, 0x18, 0xa1, 0xbe, 0xab, 0xb0, 0xd9, 0x3f, 0x83, 0xaa, 0x6b, 0xd6, 0x85, 0x8, 0xdf, 0x98, 0x56, 0x66, 0xbd, 0x61, 0x8f, 0x11, 0xcb, 0x2d, 0x36, 0x45, 0x9f, 0xc, 0x94, 0x6, 0x3, 0x1f, 0xfb, 0x2f, 0x23, 0xdc, 0x7f, 0x99, 0x1e, 0x18, 0x5d, 0x3, 0x50, 0xc2, 0x47, 0xb3, 0xcb, 0x43, 0xf8, 0x3d, 0xe1, 0xe6, 0xef, 0xc4, 0x26, 0x33, 0x50, 0x2, 0xd8, 0xf8, 0xae, 0x32, 0x8c, 0xc7, 0x94, 0xbf, 0x1c, 0x84, 0xc0, 0x9, 0x7e, 0xdc, 0x13, 0xcb, 0xcf, 0x3f, 0xf4, 0x97, 0x7f, 0x72, 0x7a, 0x33, 0x9a, 0xde, 0x1b, 0xfd, 0xd0, 0xe9, 0x47, 0x9f, 0x83, 0x86, 0xe6, 0x14, 0xe8, 0x2a, 0xe2, 0x1d, 0xf0, 0xa2, 0x27, 0x5e, 0x98, 0x56, 0xa9, 0x36, 0xa, 0x1, 0xaf, 0xea, 0xc5, 0x3d, 0xb1, 0x6c, 0xb, 0x4e, 0xfc, 0xdd, 0xd8, 0xdc, 0x12, 0x87, 0x8b, 0xce, 0xd3, 0x41, 0x21, 0x2, 0x44, 0x63, 0x4, 0xd2, 0x30, 0x98, 0x33, 0xe1, 0x9, 0x66, 0x1a, 0xd2, 0x78, 0x10, 0xe, 0x2f, 0xfa, 0x47, 0xf4, 0x60, 0x37, 0x84, 0xa4, 0xfe, 0x2a, 0xfd, 0xcb, 0x4, 0x44, 0x9a, 0x8b, 0xcf, 0xec, 0x34, 0xc6, 0xfe, 0xc1, 0xd7, 0x7a, 0xe1, 0x74, 0x4a, 0xbd, 0x51, 0x8, 0x10, 0x31, 0x3, 0x31, 0x4a, 0x53, 0xc0, 0x0, 0x17, 0x5e, 0xe4, 0xf3, 0x3c, 0x2a, 0xe3, 0x14, 0xc9, 0x8, 0xac, 0xac, 0x5, 0x61, 0x1c, 0xdd, 0xb1, 0xaf, 0xf5, 0xa2, 0xe9, 0x4c, 0x2b, 0x37, 0xbf, 0x27, 0x56, 0x58, 0x6, 0xc6, 0x66, 0x80, 0xd, 0xd1, 0xf6, 0x1f, 0xd1, 0x8f, 0xe8, 0xd3, 0x19, 0x31, 0x3e, 0x28, 0x95, 0xbd, 0x7, 0xfa, 0x55, 0x6, 0x30, 0x1a, 0x1, 0xae, 0xfc, 0xb, 0x3d, 0x20, 0x84, 0x1f, 0x4, 0x4c, 0x8, 0x82, 0x38, 0xd4, 0xfb, 0x11, 0xae, 0x82, 0xd5, 0x21, 0xec, 0xac, 0x38, 0xdd, 0xcb, 0x80, 0x55, 0xbc, 0xf1, 0xc2, 0x9a, 0xde, 0xa6, 0xc2, 0x5a, 0x65, 0xb1, 0xe1, 0x21, 0x3a, 0x60, 0x64, 0xdd, 0x78, 0x4c, 0x5e, 0x8b, 0xbb, 0xfb, 0x1, 0x78, 0x9a, 0x77, 0xe5, 0xbe, 0x6, 0xd, 0x79, 0x25, 0x1a, 0xf7, 0xaf, 0xd1, 0xb8, 0x2, 0x3c, 0x4d, 0xe7, 0xcc, 0xa2, 0x5e, 0xfb, 0xe1, 0xc4, 0xc3, 0xb8, 0x53, 0x8b, 0xa0, 0x4, 0x18, 0xc5, 0x32, 0x21, 0xe9, 0x3b, 0x0, 0xe1, 0x0, 0xd2, 0x24, 0x20, 0xee, 0xf5, 0xcb, 0x71, 0xaf, 0x1f, 0xd, 0x91, 0xef, 0x45, 0xde, 0xaf, 0xbc, 0x9e, 0x83, 0x90, 0x7c, 0x1c, 0xe0, 0x3c, 0x8e, 0x9c, 0xcf, 0xc7, 0x14, 0x75, 0xfe, 0x42, 0x5f, 0x23, 0x7a, 0x4, 0x7a, 0x9b, 0xce, 0x5a, 0x1a, 0xde, 0x6b, 0x6f, 0x18, 0xef, 0xf2, 0x75, 0xfe, 0x6, 0xc8, 0x9e, 0x82, 0x53, 0xf9, 0x43, 0x79, 0x73, 0x8d, 0x50, 0x6f, 0x15, 0x5d, 0x66, 0xa0, 0x7c, 0xb4, 0x41, 0x5c, 0xe4, 0x69, 0x81, 0x28, 0x23, 0xb1, 0x45, 0x1b, 0xa4, 0xed, 0x7c, 0xb9, 0x4c, 0x8c, 0xed, 0x38, 0x9e, 0x21, 0xc6, 0xf9, 0x1b, 0x1e, 0x60, 0x35, 0x33, 0x96, 0x5b, 0xc4, 0xdb, 0x7c, 0xee, 0xec, 0x43, 0x59, 0x2f, 0xea, 0xcf, 0xe2, 0x8d, 0x9f, 0x65, 0xea, 0xe1, 0xbe, 0x77, 0x78, 0xbf, 0x5f, 0x9a, 0xb1, 0xfc, 0x46, 0xde, 0xa6, 0xb3, 0x67, 0xa8, 0x4b, 0x3, 0xc0, 0xe2, 0xb7, 0x81, 0x1, 0x7c, 0x62, 0x88, 0xd, 0x66, 0x94, 0x1e, 0x1c, 0x8c, 0xb7, 0xb1, 0xd3, 0xf2, 0x77, 0x69, 0x94, 0xa9, 0xf1, 0x1e, 0xb8, 0x52, 0xde, 0xc1, 0x15, 0x73, 0x3a, 0xae, 0x1c, 0x1d, 0xcc, 0x8a, 0xbc, 0xff, 0xf4, 0xa, 0x38, 0xed, 0xb, 0xa2, 0xfe, 0xa1, 0x7a, 0x10, 0xfd, 0x10, 0x3d, 0xd5, 0xf9, 0x22, 0xff, 0x8, 0xfc, 0xef, 0x30, 0x5f, 0xfd, 0x79, 0x80, 0xa6, 0xb3, 0x97, 0xc1, 0x46, 0xbe, 0x5b, 0x39, 0x91, 0x10, 0x2d, 0xdc, 0x87, 0x8d, 0x96, 0x8, 0x3b, 0xe0, 0x58, 0x26, 0xb5, 0x1d, 0x29, 0x21, 0x82, 0xe6, 0x27, 0xf2, 0x78, 0x9a, 0x83, 0x77, 0xc6, 0x75, 0xf0, 0xa, 0x1b, 0x7a, 0x5b, 0xce, 0x9b, 0x7d, 0xa0, 0x5f, 0x9, 0x51, 0xa6, 0xe3, 0xaa, 0xba, 0x8f, 0xd7, 0x2f, 0xf2, 0xd8, 0xf6, 0x2c, 0xd4, 0x97, 0xc7, 0xca, 0xe4, 0x51, 0x6f, 0xa9, 0xfa, 0xf3, 0x2, 0x91, 0xe4, 0x6b, 0x7a, 0x79, 0x83, 0xab, 0x9b, 0xda, 0xcf, 0x41, 0xda, 0x19, 0x51, 0x67, 0xbc, 0x9, 0xf5, 0x31, 0xc2, 0x9e, 0x27, 0xd2, 0x95, 0xf9, 0x93, 0x21, 0x3c, 0xf, 0x11, 0x1b, 0xa4, 0xfb, 0x7e, 0x53, 0x94, 0x15, 0x1, 0xd5, 0x95, 0xfb, 0xe1, 0x6b, 0x29, 0x52, 0x1c, 0x49, 0x3d, 0x8c, 0xff, 0x29, 0xd6, 0xad, 0x2f, 0x3, 0x88, 0xa6, 0x1f, 0xe2, 0x1b, 0xc8, 0x45, 0x75, 0x3b, 0x10, 0x8d, 0x10, 0x79, 0x7c, 0xfe, 0x94, 0xaf, 0x93, 0xa0, 0xc9, 0x67, 0x60, 0x8, 0xdb, 0xe2, 0x6a, 0x68, 0xa5, 0xb2, 0x8a, 0xc8, 0x4c, 0xea, 0x8b, 0x11, 0xa2, 0xf, 0x6, 0x60, 0x4, 0x89, 0xf, 0xcc, 0x58, 0xa1, 0xa5, 0x8e, 0x1e, 0x82, 0xf9, 0x5d, 0xe1, 0x1e, 0x3f, 0xb5, 0x4f, 0x13, 0xc5, 0x13, 0x9, 0x31, 0x67, 0x56, 0xf5, 0x8, 0x38, 0xd1, 0xe0, 0x4f, 0x23, 0x9c, 0x0, 0x55, 0x8f, 0xc5, 0x78, 0x2c, 0x90, 0xda, 0x89, 0xba, 0x89, 0x6f, 0x60, 0x3c, 0x7, 0xd4, 0xcb, 0x3b, 0xc0, 0x84, 0x1, 0xbc, 0x42, 0x9b, 0x10, 0x49, 0x4c, 0x48, 0x20, 0x18, 0xab, 0xc4, 0xfd, 0x22, 0x3d, 0xe5, 0x37, 0x21, 0xca, 0x64, 0x50, 0xc6, 0xe4, 0x7e, 0xf4, 0x70, 0xe2, 0x73, 0x3c, 0x92, 0xf, 0x98, 0xec, 0xff, 0xcb, 0xc7, 0x70, 0xef, 0xbd, 0x86, 0x85, 0x17, 0xcb, 0x8b, 0x36, 0xb1, 0xf8, 0x9, 0xe, 0x93, 0xd3, 0xc3, 0xc0, 0xf6, 0x28, 0x48, 0x27, 0x3f, 0x81, 0x27, 0x38, 0x74, 0x92, 0x8a, 0x5f, 0xc8, 0xe0, 0xe4, 0x7f, 0x66, 0x9f, 0x2, 0x2c, 0x96, 0xf1, 0xb8, 0x9e, 0x21, 0x2f, 0x60, 0xef, 0x5, 0xe, 0xc7, 0x77, 0x78, 0x44, 0x9e, 0x30, 0x19, 0xff, 0xef, 0xbf, 0xdf, 0x8c, 0xa4, 0x7e, 0x31, 0xb0, 0x60, 0xc0, 0xc5, 0x47, 0x1c, 0x55, 0x88, 0xfd, 0xc0, 0x61, 0xb0, 0xb2, 0xf7, 0xfb, 0x5b, 0xcf, 0x77, 0xef, 0x8f, 0x44, 0xb0, 0xce, 0x6e, 0xb8, 0xf1, 0x13, 0xf0, 0xb, 0xd7, 0xdc, 0x83, 0xa9, 0xef, 0x6f, 0xbd, 0x60, 0x66, 0x2c, 0xea, 0xc1, 0xaa, 0xf0, 0xd1, 0x54, 0x19, 0x26, 0xd2, 0xa, 0xc0, 0xf7, 0x26, 0xfd, 0x15, 0x7e, 0x21, 0x3c, 0xd8, 0xb5, 0xe2, 0x43, 0xf4, 0xd5, 0x30, 0x49, 0xb8, 0xf0, 0xd4, 0xf, 0x10, 0xf5, 0x21, 0x3c, 0x58, 0x2e, 0x87, 0x31, 0x9c, 0x8c, 0xfc, 0xe5, 0x1c, 0xfe, 0xfc, 0x58, 0x16, 0xf5, 0x1e, 0xe6, 0x8b, 0x23, 0xd0, 0x96, 0x21, 0x6, 0x3, 0x6d, 0x44, 0x5a, 0xa4, 0x1d, 0xcb, 0x44, 0x1d, 0xc7, 0x6f, 0x30, 0xf8, 0xbe, 0xd3, 0x36, 0xe, 0x79, 0xce, 0xed, 0x6, 0x3f, 0x5f, 0xe7, 0x36, 0x6, 0x3f, 0x10, 0xa0, 0x7c, 0xfa, 0x6f, 0x5d, 0xbe, 0xfd, 0xa2, 0x99, 0xdd, 0x29, 0x7e, 0xcb, 0x85, 0xb3, 0xe3, 0xdf, 0xb6, 0x87, 0xb0, 0x80, 0x62, 0xed, 0x42, 0x33, 0x3f, 0x22, 0xff, 0x61, 0x18, 0x42, 0x2, 0x86, 0xd0, 0xe2, 0x6f, 0xbf, 0x68, 0xae, 0x4a, 0xfd, 0xf3, 0x56, 0xc2, 0x82, 0x9e, 0x94, 0x36, 0x85, 0x99, 0x56, 0xba, 0xc4, 0x51, 0x60, 0x3f, 0x80, 0x2d, 0xfe, 0xfb, 0xde, 0xe6, 0x73, 0xda, 0xdc, 0xfc, 0x7a, 0x3f, 0xdb, 0xb6, 0x60, 0x8f, 0x95, 0x61, 0x9c, 0xda, 0x93, 0x62, 0xe5, 0xde, 0x41, 0xbd, 0x2b, 0x40, 0x17, 0x8c, 0xe2, 0xbe, 0x4a, 0xdd, 0x34, 0xd5, 0x3, 0x76, 0x5b, 0x90, 0x16, 0x38, 0x7e, 0x67, 0xfe, 0x87, 0xb4, 0x8c, 0x63, 0x19, 0xcf, 0x77, 0x48, 0x3b, 0xd7, 0x1d, 0xfc, 0x5c, 0x9d, 0xe7, 0x3b, 0xe0, 0xba, 0xb8, 0xf8, 0xbc, 0xe, 0xa3, 0x7d, 0x89, 0x17, 0xce, 0x5d, 0x79, 0xa7, 0xab, 0xa7, 0x73, 0xa5, 0xf8, 0xbe, 0x96, 0xf3, 0x22, 0x34, 0x51, 0x12, 0x31, 0x23, 0x26, 0x2e, 0x16, 0x4e, 0x65, 0x44, 0x94, 0xc7, 0x94, 0x9f, 0x2d, 0xe2, 0xbb, 0xc6, 0x60, 0x14, 0x2, 0x3a, 0xfd, 0xd8, 0x1f, 0x6f, 0xbc, 0xf0, 0xa4, 0xaf, 0xe5, 0xfc, 0xd, 0x5c, 0x29, 0x3e, 0x1e, 0x71, 0x8b, 0xe3, 0x34, 0xbf, 0xc5, 0x5, 0x2d, 0x3, 0xb1, 0x21, 0x66, 0xc, 0x69, 0xe, 0xff, 0xa6, 0x32, 0x29, 0x5f, 0xe4, 0x59, 0x20, 0x36, 0x78, 0x44, 0x9b, 0x11, 0x62, 0x11, 0xa3, 0xd7, 0xc6, 0x12, 0xf1, 0xb0, 0xd6, 0x21, 0xd2, 0xd5, 0x83, 0x2, 0xd7, 0x7f, 0x90, 0x3b, 0x4f, 0x7e, 0xeb, 0x85, 0x33, 0x60, 0x72, 0xbd, 0x74, 0xaa, 0x69, 0xe2, 0x5c, 0x4c, 0x97, 0x62, 0xd6, 0x1a, 0x20, 0xe3, 0x79, 0x55, 0x44, 0x3d, 0xd7, 0xcc, 0x97, 0xf0, 0x36, 0xb9, 0xd0, 0x0, 0xfc, 0xed, 0x17, 0x4f, 0xb, 0xb7, 0xb4, 0x79, 0xed, 0x6, 0xe6, 0xdc, 0x2, 0x89, 0x2d, 0xa5, 0x1, 0xa5, 0x6b, 0x90, 0xda, 0x38, 0xaf, 0x43, 0xb4, 0xa7, 0xf4, 0x78, 0xad, 0x1, 0x94, 0xef, 0xff, 0x47, 0x7c, 0xad, 0x17, 0xac, 0xef, 0x2a, 0x3, 0x58, 0xbe, 0xfd, 0xe2, 0x85, 0xf1, 0x98, 0x7b, 0xca, 0x63, 0xfd, 0xcb, 0xbd, 0x39, 0x0, 0x3b, 0x8f, 0x45, 0x71, 0xbc, 0x9f, 0x6d, 0xd, 0xd6, 0xae, 0xd7, 0xb6, 0xed, 0xdd, 0x87, 0x6a, 0x6d, 0xdb, 0xb6, 0x8d, 0xc7, 0xba, 0xfd, 0xb4, 0xb6, 0x6d, 0xdb, 0xb6, 0xed, 0xde, 0xee, 0x2f, 0xed, 0x49, 0x5e, 0xa6, 0x93, 0x4f, 0x2f, 0x49, 0x1f, 0x32, 0xf3, 0x9f, 0x73, 0x73, 0x93, 0x1e, 0xfe, 0xef, 0xe9, 0x4d, 0xa6, 0xd5, 0x93, 0x73, 0x9d, 0xcd, 0xa4, 0x5c, 0x37, 0xd7, 0x6b, 0x60, 0x7e, 0xef, 0x37, 0xfc, 0xc0, 0x37, 0x5, 0x6a, 0x3f, 0xf7, 0x23, 0x9, 0xfd, 0x0, 0xbc, 0x2, 0x9e, 0xe6, 0xbd, 0xc5, 0xc3, 0xbe, 0xc6, 0xd6, 0x7, 0x79, 0xbe, 0xbe, 0x9f, 0x78, 0x90, 0x2d, 0x8f, 0x82, 0x67, 0x19, 0xbf, 0xce, 0xbd, 0x5f, 0xf0, 0x99, 0xff, 0x2a, 0x3a, 0x80, 0xb5, 0xd, 0xfb, 0x64, 0xb0, 0x88, 0x4f, 0xf4, 0x32, 0xb7, 0xeb, 0x75, 0x25, 0xed, 0x1c, 0x9f, 0xee, 0xd, 0x44, 0x52, 0xbd, 0xe3, 0xb7, 0x1, 0xe1, 0xfd, 0x1f, 0x1a, 0x0, 0x23, 0xb7, 0x16, 0x67, 0x4b, 0x38, 0x59, 0xd6, 0xe1, 0xab, 0x82, 0x79, 0xa4, 0x35, 0x4c, 0xd7, 0xe4, 0x73, 0x48, 0x81, 0xa1, 0xc3, 0x7c, 0xaf, 0xa1, 0x5f, 0xe6, 0x2c, 0xee, 0x17, 0x2, 0x32, 0xd6, 0x24, 0x30, 0x25, 0xf4, 0x6f, 0x92, 0xf7, 0x31, 0x5, 0x7d, 0x96, 0x56, 0x7a, 0x23, 0x8f, 0x9f, 0x67, 0xfa, 0x9a, 0x3a, 0x23, 0xf8, 0xbf, 0x26, 0x5f, 0x61, 0x4b, 0xfb, 0x23, 0xe9, 0x89, 0x24, 0x76, 0x94, 0xb7, 0x29, 0x39, 0x34, 0x14, 0xcf, 0x8f, 0x61, 0x3c, 0xd, 0x78, 0xb9, 0x67, 0x43, 0x5f, 0x63, 0xc7, 0xc1, 0xbc, 0xab, 0x48, 0x43, 0x8e, 0x7, 0xf9, 0xfc, 0xab, 0x10, 0xe6, 0xfb, 0x5a, 0xb2, 0x55, 0xfc, 0xec, 0xf2, 0x4f, 0x89, 0xaf, 0x96, 0xf1, 0xc8, 0x9c, 0x39, 0x6e, 0xa4, 0xc5, 0xbc, 0x71, 0x4d, 0xf4, 0x49, 0x9e, 0x79, 0x8c, 0xbe, 0x7a, 0xc9, 0xed, 0xae, 0x18, 0xd8, 0xf3, 0xed, 0x3f, 0x92, 0xe, 0x91, 0xd4, 0xd7, 0x2a, 0x4e, 0xeb, 0x81, 0x3, 0x76, 0xab, 0x95, 0x73, 0x43, 0x2, 0x39, 0x9f, 0xcb, 0x9c, 0x71, 0xcd, 0xfa, 0x7c, 0xee, 0x73, 0xaa, 0x66, 0x5e, 0x19, 0xfa, 0x1b, 0xae, 0xff, 0xe, 0x1f, 0x5f, 0xa2, 0x80, 0x19, 0x8a, 0xdd, 0x10, 0x8e, 0xe7, 0x47, 0xd8, 0xdb, 0xef, 0xa4, 0x97, 0xa3, 0x0, 0xa7, 0xb0, 0xe7, 0xb9, 0x1b, 0xbd, 0xef, 0x51, 0x98, 0xbf, 0x88, 0xd9, 0xec, 0x7, 0xe8, 0xca, 0x47, 0x4d, 0xcc, 0xf3, 0x8c, 0x4b, 0xe6, 0x6b, 0xa5, 0xe8, 0x12, 0x42, 0x37, 0xb4, 0x7c, 0x42, 0x2c, 0xbb, 0xf7, 0x6, 0x2, 0x6c, 0xc2, 0x6a, 0x28, 0xf1, 0xa6, 0xcf, 0x8, 0xb6, 0xce, 0x30, 0xdb, 0x55, 0x66, 0x1f, 0x58, 0xa9, 0x3f, 0xb0, 0x62, 0xdf, 0x64, 0x7f, 0x72, 0x4, 0x6f, 0xcd, 0x86, 0xbb, 0xb4, 0xf9, 0x5d, 0x92, 0x47, 0xdf, 0x2c, 0x64, 0x78, 0x9b, 0x3c, 0xfc, 0x29, 0x44, 0x30, 0x16, 0x82, 0xb, 0xb1, 0x1a, 0x64, 0xa7, 0x8b, 0x3d, 0xe2, 0x8f, 0xe4, 0x86, 0xf5, 0x2c, 0x1, 0x62, 0x85, 0x61, 0xbe, 0xa6, 0x64, 0x33, 0xc9, 0xfe, 0xcf, 0x5b, 0x71, 0xaa, 0x45, 0x69, 0x90, 0xb1, 0xeb, 0xc0, 0x8e, 0xd2, 0x65, 0xd7, 0xb8, 0xe5, 0xf, 0x7e, 0x5d, 0xfb, 0x1d, 0xed, 0x7b, 0xff, 0xba, 0x3d, 0x5, 0xc5, 0x8a, 0x83, 0xe9, 0xa, 0x1d, 0xd8, 0xfe, 0x52, 0xf3, 0x43, 0x5b, 0x10, 0xc8, 0x5a, 0x3f, 0x9d, 0x8e, 0xfd, 0x3f, 0x6c, 0xe6, 0x7a, 0x7e, 0x13, 0x18, 0xcb, 0x8d, 0x60, 0x25, 0x1c, 0x42, 0xf0, 0xa, 0x48, 0xe0, 0xad, 0xba, 0xa3, 0xf3, 0x8, 0xbc, 0xd5, 0x12, 0xe6, 0x7b, 0xac, 0xe7, 0xc, 0x3b, 0xa, 0x30, 0xd6, 0x93, 0xdc, 0xf6, 0x33, 0xdf, 0xd9, 0x97, 0xfa, 0x23, 0x99, 0xa1, 0x3d, 0xb3, 0x20, 0xf2, 0x23, 0xf9, 0x11, 0xcb, 0xeb, 0xf8, 0xf2, 0x87, 0x9e, 0xb, 0xa4, 0x4e, 0xd2, 0xda, 0x58, 0xe6, 0x12, 0xab, 0xc0, 0xf2, 0x1e, 0x20, 0x8b, 0xc, 0x5b, 0x2f, 0xd1, 0x85, 0xa7, 0x59, 0xfd, 0xcd, 0x3d, 0x10, 0xcd, 0xe, 0xa, 0x26, 0x66, 0xc, 0xf6, 0x37, 0x77, 0xe, 0x61, 0x3c, 0x34, 0x10, 0xcd, 0xd, 0x72, 0x91, 0x4, 0x79, 0x48, 0x90, 0x3c, 0x87, 0x60, 0x4b, 0xac, 0xbe, 0x4a, 0x61, 0x4, 0x65, 0xce, 0x2b, 0xd2, 0x29, 0x78, 0xbb, 0xf4, 0x29, 0xfd, 0x5c, 0x83, 0xbf, 0xb1, 0xed, 0x3b, 0x1e, 0x49, 0xd7, 0xec, 0x25, 0xef, 0x45, 0x8e, 0xc6, 0xa7, 0xef, 0x29, 0x52, 0x6d, 0xfc, 0x4e, 0xe4, 0xc2, 0x4c, 0xfa, 0x32, 0x5d, 0xe0, 0xd1, 0x4a, 0xd, 0xe2, 0xc5, 0x61, 0xd8, 0x1d, 0x1e, 0x8c, 0x15, 0xc6, 0x53, 0xf0, 0x15, 0x2, 0x91, 0xcc, 0x26, 0x6c, 0x6c, 0x77, 0x86, 0x20, 0xbb, 0x33, 0x7f, 0x12, 0x73, 0x1b, 0xd0, 0x15, 0x87, 0xb8, 0x16, 0x34, 0xc, 0x1b, 0x8a, 0xa1, 0x33, 0x70, 0x8e, 0xd6, 0xd4, 0x66, 0x10, 0x80, 0xb1, 0xf3, 0x40, 0x37, 0x52, 0x27, 0xc4, 0xbf, 0x7c, 0xf, 0x3f, 0x18, 0x4a, 0x14, 0xc7, 0x7b, 0x7a, 0xd1, 0xa1, 0x25, 0x1c, 0x1f, 0x3f, 0xd1, 0xa, 0x25, 0x79, 0x50, 0x86, 0xef, 0xf6, 0xe3, 0x37, 0x24, 0x5d, 0xe0, 0x4f, 0x48, 0xf0, 0x16, 0xdd, 0xef, 0x27, 0xce, 0x4d, 0xd7, 0x6a, 0xc7, 0x6d, 0xcf, 0x43, 0x8a, 0xd, 0x5d, 0xd, 0x3a, 0xb4, 0xfb, 0xac, 0xc1, 0x30, 0xee, 0x70, 0x56, 0xe3, 0x3f, 0x3a, 0x5b, 0x19, 0x97, 0x9d, 0x86, 0x4e, 0x2e, 0xc6, 0x14, 0xbf, 0xf3, 0x26, 0x4f, 0x2f, 0x3d, 0xe8, 0x48, 0xcb, 0xf8, 0x1a, 0xda, 0x5f, 0x17, 0x5f, 0x55, 0xd5, 0x77, 0xa4, 0xfd, 0xf8, 0xd, 0x9, 0x94, 0x9, 0xc6, 0x35, 0x8b, 0x71, 0x89, 0x8e, 0xb0, 0x8f, 0xfb, 0xef, 0x6, 0x76, 0x9f, 0x3d, 0x38, 0x18, 0xcd, 0x36, 0xf2, 0xd8, 0xc5, 0x2e, 0x5c, 0x73, 0xb8, 0x7d, 0xde, 0x30, 0x7, 0x38, 0x97, 0x39, 0xa0, 0x27, 0x11, 0xe6, 0x13, 0x5c, 0x73, 0xf2, 0x4e, 0x4f, 0x2f, 0x3f, 0x2, 0xb1, 0xdc, 0x12, 0x74, 0x28, 0xde, 0x3d, 0x48, 0xf1, 0xcd, 0xf1, 0x21, 0xad, 0xcf, 0xe7, 0x7d, 0x8f, 0xe8, 0x2, 0xe6, 0xeb, 0xd5, 0x39, 0x73, 0xde, 0xb5, 0xb1, 0x7e, 0xce, 0xe2, 0x3c, 0x67, 0x89, 0xe8, 0xad, 0x3, 0x5c, 0xf, 0x3a, 0xb4, 0xdb, 0x8c, 0x61, 0xb4, 0xa5, 0xcf, 0xb4, 0xf6, 0xa3, 0x3b, 0x69, 0x17, 0xe8, 0xd2, 0xf5, 0x28, 0xc6, 0x5a, 0xf1, 0xef, 0x5d, 0x3a, 0x71, 0x87, 0xb, 0xc1, 0xb8, 0xb2, 0x51, 0xf6, 0xd2, 0xa9, 0x1e, 0xd1, 0xf3, 0x21, 0xb2, 0x5e, 0x50, 0xba, 0x4d, 0x5e, 0x7e, 0x7d, 0x10, 0x8c, 0x65, 0x1b, 0xea, 0xd0, 0xfa, 0x72, 0x61, 0x8, 0xf0, 0x35, 0x28, 0xc3, 0x7e, 0xc7, 0x80, 0xbe, 0x12, 0x80, 0xc9, 0xa9, 0x3b, 0xf8, 0xce, 0x1f, 0xe7, 0xe9, 0x43, 0x7, 0x4f, 0x26, 0xd, 0x90, 0xe0, 0x1d, 0xc9, 0x89, 0x42, 0x2a, 0x89, 0xab, 0x2e, 0xc0, 0x5e, 0x5, 0xec, 0x3, 0xdc, 0xff, 0x21, 0x29, 0xef, 0x6, 0x1e, 0xe4, 0xf5, 0xe9, 0xbf, 0xe, 0x13, 0x80, 0xa4, 0x21, 0x9b, 0x93, 0xaf, 0xf0, 0xd4, 0xb1, 0xb9, 0xa7, 0xf, 0x1e, 0x90, 0xe0, 0x78, 0x56, 0xe1, 0xaf, 0x5a, 0x1c, 0x75, 0x2e, 0xbe, 0xe4, 0xf, 0x19, 0x49, 0x5f, 0xec, 0x6e, 0xfb, 0x8f, 0x17, 0xc6, 0x12, 0xe4, 0x4f, 0x55, 0xe3, 0x9d, 0x40, 0xa4, 0x2d, 0x18, 0x3a, 0x7e, 0x66, 0x77, 0x7d, 0x8c, 0xa7, 0x8f, 0x1e, 0x10, 0x77, 0x2c, 0x5, 0x68, 0x97, 0x78, 0x94, 0xc4, 0x26, 0xd2, 0x45, 0x60, 0x43, 0x0, 0x1, 0x52, 0xf7, 0xb2, 0x2f, 0x59, 0xde, 0x95, 0x0, 0xb5, 0x7f, 0xbf, 0xd2, 0x9a, 0x37, 0x80, 0x0, 0xbf, 0x6b, 0xc6, 0x2, 0xcd, 0x4, 0xd9, 0xdc, 0x89, 0xec, 0x3e, 0x8, 0xa0, 0xaa, 0x7, 0xc9, 0xae, 0x3a, 0xcd, 0xcb, 0x96, 0x29, 0x9e, 0x3e, 0x7c, 0x4, 0xe3, 0x85, 0xb5, 0x28, 0xc2, 0xe3, 0x46, 0x61, 0x9a, 0x91, 0xb, 0x9a, 0x13, 0x8b, 0x31, 0xd2, 0x72, 0xde, 0x9c, 0x47, 0x91, 0x7f, 0xb3, 0x88, 0x4e, 0x77, 0x25, 0x38, 0x94, 0xf, 0x44, 0xf9, 0x75, 0xb4, 0xe9, 0xbf, 0xab, 0x6, 0x93, 0x8e, 0x0, 0x5d, 0x4, 0x94, 0xfa, 0x90, 0xbd, 0xc5, 0xe, 0x9e, 0x7e, 0x70, 0xb0, 0x2, 0x8f, 0xaf, 0xc6, 0x94, 0x2c, 0x49, 0x8c, 0x75, 0x1, 0x36, 0x95, 0x26, 0xd9, 0x8, 0xa6, 0x5d, 0xfc, 0x5d, 0x60, 0xf2, 0xb, 0xd8, 0x87, 0xa1, 0x94, 0x16, 0x60, 0x19, 0xd9, 0x3d, 0x44, 0xb4, 0xcf, 0x57, 0x1c, 0x56, 0x9a, 0x1e, 0x88, 0x75, 0x1, 0xab, 0x67, 0x54, 0x7f, 0x20, 0x0, 0x71, 0x4, 0xd9, 0x8c, 0xdd, 0x6b, 0xe4, 0x87, 0x18, 0xe7, 0x92, 0x7, 0xa4, 0x13, 0x90, 0x7c, 0xa2, 0xf, 0x2, 0x4c, 0x5f, 0x7a, 0xe7, 0x96, 0x81, 0xce, 0x7, 0x96, 0x98, 0xbe, 0xb8, 0x5f, 0xa, 0x86, 0xa1, 0x8a, 0x31, 0xbb, 0xa8, 0xea, 0x4a, 0x7f, 0x45, 0xd2, 0x8c, 0x8d, 0x5f, 0x3f, 0x21, 0x41, 0xdc, 0x66, 0x9e, 0xba, 0x91, 0x47, 0x91, 0xd1, 0xcc, 0x5d, 0x81, 0x78, 0x61, 0x61, 0x67, 0x5f, 0x0, 0xed, 0x71, 0xe3, 0xe0, 0x40, 0xac, 0x10, 0xa3, 0x55, 0xff, 0x7, 0x24, 0xb0, 0x74, 0xb9, 0xbb, 0x40, 0x87, 0x21, 0x79, 0x8e, 0xbe, 0x90, 0x77, 0xb, 0x53, 0xfa, 0x13, 0x1, 0x58, 0x2c, 0xeb, 0x10, 0xdf, 0xb7, 0xa0, 0xec, 0x26, 0xc8, 0x9f, 0xd4, 0x21, 0xa5, 0x18, 0x4b, 0x5e, 0x33, 0xaf, 0x53, 0xab, 0xd, 0xdd, 0xd8, 0xe5, 0x5e, 0xd, 0xc3, 0x84, 0x0, 0x69, 0xfb, 0x68, 0xc6, 0x69, 0x58, 0x1b, 0x4a, 0x4c, 0xdf, 0xd5, 0xd3, 0xcf, 0x8e, 0xf0, 0xee, 0x33, 0x27, 0xb2, 0x61, 0x3e, 0x5d, 0x62, 0x55, 0x5a, 0xac, 0xee, 0x14, 0x5e, 0x8a, 0x8f, 0xd4, 0xc0, 0xea, 0x7f, 0x9f, 0xee, 0x73, 0x56, 0x30, 0x3e, 0x7d, 0x39, 0x9b, 0xc, 0x2e, 0xe, 0xf, 0xed, 0x36, 0x73, 0x51, 0x14, 0xad, 0x1f, 0x88, 0x17, 0x23, 0xc1, 0x78, 0xf1, 0x40, 0x56, 0xea, 0x1b, 0x18, 0x2c, 0x1, 0xcd, 0x90, 0x6d, 0x88, 0x9e, 0x4f, 0x43, 0x89, 0x19, 0x6b, 0x7a, 0xfa, 0xe1, 0x11, 0xde, 0x6d, 0xe6, 0xca, 0x5a, 0x8c, 0x8e, 0xe6, 0xcb, 0xac, 0x8b, 0xc2, 0x9b, 0xe6, 0xbe, 0xd, 0xc6, 0xf3, 0xb3, 0x58, 0x4c, 0xdb, 0xfb, 0xe2, 0x33, 0x7, 0x77, 0xa3, 0xe0, 0x33, 0xc6, 0x51, 0xec, 0x55, 0x29, 0xf4, 0xe, 0xb4, 0xaf, 0x4, 0xf2, 0x68, 0x98, 0xd4, 0xc9, 0xe6, 0xec, 0x9d, 0x40, 0x4, 0x63, 0x20, 0x18, 0x35, 0xa0, 0x19, 0x56, 0xda, 0xd8, 0x6, 0xaa, 0xce, 0xc7, 0xa, 0x47, 0x62, 0x7b, 0x74, 0x7f, 0x24, 0x0, 0xb, 0x68, 0x45, 0xf2, 0xf7, 0x83, 0xe4, 0xce, 0x9, 0x28, 0x73, 0xee, 0x91, 0xac, 0xfa, 0xcc, 0xf7, 0xd8, 0xb8, 0x8f, 0x7a, 0x1d, 0x1a, 0xde, 0x7d, 0xd6, 0xc4, 0xee, 0x32, 0x75, 0x1a, 0x2b, 0xfe, 0x30, 0x1e, 0xc3, 0xde, 0x92, 0x62, 0xeb, 0xc0, 0x68, 0x56, 0x87, 0x32, 0xcf, 0xd9, 0x84, 0x2, 0x15, 0x5d, 0x7c, 0xf7, 0xaf, 0xe6, 0xe9, 0xa7, 0x7, 0xc4, 0x5e, 0x96, 0xe2, 0x3c, 0x23, 0x39, 0x53, 0x8e, 0xe4, 0x4d, 0xea, 0x80, 0xde, 0x2f, 0x59, 0xf1, 0x4f, 0x51, 0xf8, 0x13, 0x58, 0xb0, 0xa3, 0x6c, 0xb6, 0xaa, 0x19, 0xff, 0x73, 0x77, 0xce, 0x51, 0x96, 0x2b, 0x69, 0x0, 0x3f, 0xe7, 0xd9, 0xb6, 0xed, 0x77, 0xb5, 0xb6, 0x6d, 0x7b, 0xdb, 0x5a, 0xdb, 0xb6, 0x6d, 0x7b, 0x9b, 0xd7, 0xcd, 0x35, 0x9f, 0xcd, 0xb1, 0x6d, 0xab, 0xbb, 0xb2, 0xbf, 0x4a, 0xbe, 0x4c, 0x32, 0x75, 0x36, 0xe7, 0x4e, 0xcf, 0xad, 0x34, 0xf2, 0xc7, 0xef, 0x54, 0xa5, 0x92, 0xfb, 0xb9, 0xaa, 0x82, 0xc1, 0x5b, 0x49, 0xfe, 0x3a, 0x84, 0x22, 0x98, 0xa, 0x3, 0x1e, 0x25, 0x1c, 0x4d, 0xa8, 0x2f, 0xfc, 0x1e, 0x22, 0x8e, 0x27, 0x89, 0xd6, 0xc7, 0x2c, 0x79, 0x6c, 0x52, 0xb, 0x0, 0xdf, 0x4e, 0x25, 0x41, 0x9f, 0xc2, 0xcf, 0x88, 0x18, 0xfc, 0x5e, 0x30, 0x8e, 0x5, 0xf3, 0x5c, 0x38, 0x6e, 0x24, 0xfd, 0xbd, 0xd7, 0xbd, 0xb1, 0xfb, 0x70, 0x5b, 0x5f, 0xf7, 0x3e, 0x4d, 0x1, 0xf0, 0x1a, 0x36, 0x30, 0x82, 0xbe, 0x92, 0x7e, 0x6c, 0xf0, 0xc2, 0x64, 0xd7, 0x8d, 0x8d, 0x7d, 0x8f, 0x12, 0x33, 0x92, 0x5a, 0x4, 0x4f, 0x94, 0xb8, 0x5a, 0x8b, 0x27, 0xb9, 0xda, 0x74, 0x63, 0x43, 0xdf, 0xa9, 0x16, 0x97, 0xaa, 0xee, 0x9f, 0x22, 0x14, 0xe1, 0x7f, 0x70, 0xa4, 0xd, 0x61, 0x1c, 0xd7, 0x42, 0x8c, 0xac, 0x71, 0x5e, 0xc9, 0xf1, 0xd2, 0x54, 0x63, 0x7f, 0x3a, 0xc9, 0x5, 0xc0, 0xbe, 0x7c, 0x6d, 0x10, 0x57, 0x30, 0xe2, 0x74, 0x70, 0xf1, 0xa2, 0x15, 0x19, 0x1a, 0x96, 0xfe, 0xed, 0x99, 0xe6, 0xfc, 0xb9, 0x16, 0x5f, 0x5a, 0x74, 0xf7, 0x6a, 0x45, 0x8, 0xd6, 0x28, 0x69, 0xa7, 0x80, 0x3f, 0xde, 0x94, 0x6a, 0xea, 0xbf, 0x3a, 0xd1, 0x5, 0xd0, 0x9c, 0xbf, 0x6, 0x5f, 0x27, 0x2c, 0xc7, 0x6e, 0x77, 0xba, 0x69, 0xe0, 0x3c, 0x8b, 0xcb, 0x54, 0x6f, 0x51, 0xaa, 0x4c, 0xf1, 0xb5, 0xcf, 0x89, 0x1b, 0xf4, 0x78, 0x6d, 0x43, 0xcf, 0x40, 0xaa, 0x69, 0xe0, 0xe2, 0x24, 0x17, 0x0, 0x33, 0xf5, 0x4a, 0x7c, 0x5d, 0x2f, 0x3e, 0xdb, 0x62, 0x3c, 0xdd, 0x3c, 0xad, 0x5, 0xd0, 0x1d, 0x3d, 0x2e, 0x44, 0x9f, 0xb, 0x40, 0xef, 0xf7, 0xd8, 0x2, 0xce, 0x4e, 0xf8, 0xa, 0x70, 0x19, 0x2b, 0xec, 0x82, 0x20, 0x6, 0xd2, 0x46, 0xc7, 0x25, 0x32, 0xd6, 0x37, 0xa, 0x29, 0xa0, 0xb0, 0xce, 0xb7, 0x79, 0xa3, 0x52, 0x14, 0xe1, 0xea, 0x0, 0x43, 0x1a, 0xa4, 0x8d, 0xa2, 0x21, 0x7a, 0xac, 0xd6, 0xef, 0x5d, 0x7d, 0xd, 0xc9, 0x2f, 0x80, 0x54, 0x93, 0x14, 0x0, 0x3e, 0xd7, 0x4b, 0x50, 0x0, 0xdd, 0x14, 0x40, 0xc1, 0x5e, 0x1, 0xa4, 0x75, 0x1, 0x78, 0xa, 0x94, 0x4e, 0x9a, 0x1, 0xf4, 0x84, 0xe8, 0x3e, 0x34, 0x8c, 0xdf, 0x6a, 0x7d, 0x14, 0x40, 0x9e, 0x0, 0x5d, 0x9c, 0xec, 0x15, 0xa0, 0x70, 0x25, 0xbe, 0x6e, 0xa8, 0x15, 0x1b, 0xa8, 0xd1, 0x7, 0xe9, 0x23, 0x6f, 0x3c, 0xd5, 0x68, 0x75, 0xb, 0xe8, 0xeb, 0xe5, 0x8d, 0x1c, 0x82, 0x5d, 0x25, 0xa, 0x9c, 0x98, 0x11, 0x5d, 0xbd, 0x37, 0x11, 0xa0, 0x44, 0xdf, 0x4, 0x66, 0x5a, 0x8a, 0xd7, 0xe8, 0x98, 0xe2, 0xaf, 0xcd, 0xd8, 0xed, 0x4e, 0x59, 0xbd, 0x9, 0x6c, 0xea, 0xff, 0xe9, 0x8d, 0x5a, 0x30, 0xb0, 0x2f, 0x7, 0xec, 0x3f, 0xa6, 0x5, 0x12, 0x6, 0x72, 0x2c, 0xd7, 0x4, 0x63, 0x26, 0xe6, 0xb5, 0xe1, 0xeb, 0x9, 0x8, 0xb2, 0xe9, 0x2f, 0xa5, 0x0, 0x52, 0xc9, 0x2e, 0x80, 0xc2, 0xb5, 0x7e, 0xc, 0x25, 0x1e, 0x26, 0x46, 0xbc, 0x8c, 0x6b, 0x18, 0xf3, 0x5a, 0x81, 0x3e, 0xb1, 0xdb, 0x4e, 0xdc, 0xce, 0xb5, 0xf8, 0xac, 0x9a, 0xff, 0x34, 0x8a, 0xb6, 0x84, 0x92, 0x1e, 0x37, 0x52, 0xc9, 0x3d, 0xbb, 0x52, 0xcd, 0x85, 0x47, 0x25, 0x7c, 0x5, 0x78, 0x8a, 0xf8, 0xab, 0xec, 0xc5, 0xae, 0x77, 0x13, 0x5, 0x70, 0xb2, 0xc5, 0x15, 0x60, 0xe0, 0x2d, 0x6c, 0x3, 0xeb, 0x74, 0xb5, 0x71, 0x3f, 0x0, 0xbd, 0xca, 0x6d, 0x41, 0xc6, 0xac, 0xe3, 0xaf, 0x1c, 0x38, 0xf2, 0xd8, 0xc4, 0xee, 0xff, 0x2d, 0xc5, 0xd3, 0x88, 0xed, 0x67, 0x6d, 0xc7, 0x90, 0x89, 0x43, 0xdc, 0xf2, 0x5f, 0xe6, 0x25, 0xd3, 0x61, 0x76, 0xaa, 0xb4, 0xb5, 0x74, 0x1, 0x37, 0x63, 0x9d, 0xbc, 0x5c, 0xf8, 0x7b, 0xa, 0x5, 0x1, 0x18, 0x2e, 0x7d, 0xbe, 0x6f, 0xab, 0xb4, 0xd7, 0x42, 0xbf, 0x10, 0x36, 0xac, 0x5f, 0xda, 0x10, 0xe6, 0xf5, 0x72, 0xd, 0x72, 0x15, 0xc7, 0x9e, 0xdc, 0xe6, 0x62, 0x52, 0xb, 0x80, 0xb8, 0x96, 0xaf, 0x61, 0x7b, 0xbd, 0xfd, 0x46, 0xb7, 0x0, 0x24, 0x5e, 0x12, 0xb3, 0x50, 0x1f, 0xcc, 0x78, 0x1a, 0xc8, 0x78, 0x28, 0x7e, 0xd0, 0xb7, 0x89, 0x7c, 0xfd, 0x83, 0x42, 0xf8, 0x6c, 0xba, 0xa5, 0x74, 0x8a, 0x8d, 0x6a, 0x3d, 0x1e, 0x41, 0x37, 0x30, 0x23, 0x9f, 0x9b, 0x6e, 0x29, 0x34, 0xd2, 0x7e, 0x12, 0xe1, 0xbf, 0xc4, 0x81, 0x3b, 0x30, 0x6e, 0xf, 0x38, 0x3e, 0x28, 0x57, 0xb4, 0x1a, 0xa7, 0xe, 0x94, 0x57, 0x0, 0x85, 0xf, 0x64, 0xdb, 0xaa, 0x27, 0x26, 0xb3, 0x0, 0x4a, 0x39, 0x9d, 0x28, 0x10, 0x9f, 0xeb, 0x23, 0x15, 0x9e, 0x8c, 0xc1, 0xd8, 0x16, 0xa, 0xe1, 0x6f, 0x4c, 0xe0, 0xf7, 0x90, 0xc3, 0x33, 0xac, 0x19, 0x9f, 0x6b, 0x1f, 0x3c, 0x91, 0xa, 0xbe, 0x98, 0x19, 0xfa, 0x38, 0xda, 0x97, 0xd2, 0xb6, 0xa3, 0xe8, 0x7e, 0x14, 0x4e, 0xa0, 0xd8, 0x9a, 0x43, 0x14, 0xd8, 0xca, 0x6c, 0x6b, 0xf9, 0x9, 0x9, 0xdd, 0x2, 0x1e, 0xe5, 0x27, 0xdf, 0x52, 0x11, 0x28, 0x21, 0x98, 0x88, 0x22, 0x9b, 0x8f, 0x6a, 0x1b, 0xd8, 0x6e, 0xca, 0xe8, 0x7c, 0x4d, 0xae, 0xad, 0x7c, 0x64, 0x5c, 0xe, 0x7d, 0x87, 0x22, 0x18, 0x7, 0x9d, 0x38, 0x87, 0xb6, 0x2e, 0x90, 0xa1, 0xc0, 0x61, 0xe5, 0x79, 0x4d, 0xd2, 0x92, 0xcf, 0xaa, 0x76, 0x3a, 0xf1, 0xfa, 0x9c, 0xc4, 0x49, 0x4d, 0x3e, 0x3e, 0x35, 0xe3, 0xab, 0xcc, 0x38, 0x8a, 0xae, 0x25, 0xe8, 0xfd, 0x52, 0xba, 0xa5, 0x7c, 0x83, 0x55, 0x87, 0x72, 0x9d, 0x23, 0x47, 0x30, 0x53, 0xdf, 0x80, 0x61, 0xe3, 0xae, 0xa2, 0xe6, 0x1, 0x5, 0xce, 0xc1, 0x93, 0x17, 0xa4, 0xef, 0xc9, 0x70, 0xc1, 0xe0, 0x6f, 0x66, 0xdb, 0xca, 0x67, 0x27, 0xab, 0x0, 0x2a, 0x4f, 0x26, 0x19, 0xeb, 0x3, 0x3f, 0xf3, 0x66, 0x1c, 0x26, 0x43, 0xf4, 0x6f, 0x49, 0xbe, 0xf4, 0x69, 0xc1, 0xd5, 0x97, 0x7f, 0x88, 0xed, 0xe7, 0x59, 0x71, 0xdc, 0xd4, 0x5c, 0xe2, 0x57, 0x1e, 0xef, 0xa2, 0x15, 0x38, 0x36, 0xc0, 0xe0, 0xb5, 0xc8, 0x7e, 0x41, 0xc2, 0xf6, 0xff, 0x26, 0x99, 0xa1, 0x76, 0xe2, 0x24, 0xa4, 0xa3, 0xcf, 0x29, 0xf0, 0x56, 0x84, 0xe6, 0xfc, 0x70, 0xb6, 0xbd, 0x7a, 0x41, 0x5c, 0x2f, 0x36, 0x56, 0x84, 0x95, 0xd1, 0x1a, 0x14, 0x4, 0xfa, 0x46, 0xb, 0xe6, 0xb8, 0xd2, 0x20, 0x7, 0xc7, 0x8a, 0xdf, 0xc8, 0xb4, 0x55, 0x4f, 0x4e, 0xc4, 0xde, 0xdf, 0x5a, 0x4e, 0xe3, 0xcf, 0x5f, 0xd3, 0x4d, 0x92, 0x34, 0x29, 0x82, 0x38, 0x11, 0x5d, 0x12, 0xcb, 0x42, 0x8f, 0xfc, 0x27, 0x96, 0xd6, 0xbf, 0x6c, 0x1d, 0x96, 0x69, 0x29, 0xfd, 0x80, 0x76, 0xf, 0x38, 0x14, 0x83, 0x15, 0x90, 0x5, 0x85, 0xa5, 0xec, 0x5b, 0xaf, 0x4c, 0xc8, 0xe3, 0xdf, 0x47, 0x24, 0x3e, 0x4a, 0xda, 0x29, 0x1, 0x5d, 0xa2, 0xaf, 0xf4, 0xeb, 0x58, 0x1c, 0xd3, 0xff, 0x3a, 0x55, 0xa6, 0xb5, 0xf2, 0x54, 0x1e, 0x39, 0x76, 0x90, 0x30, 0x14, 0x15, 0x95, 0x28, 0x17, 0x8a, 0x61, 0x6a, 0x18, 0x5c, 0xf4, 0x8d, 0x76, 0xe5, 0x68, 0x79, 0x2c, 0x9b, 0xbf, 0x47, 0xfe, 0x39, 0xb3, 0x3b, 0xf9, 0x95, 0x27, 0xe3, 0xcf, 0xcd, 0x7e, 0x42, 0x82, 0x38, 0xd0, 0xd6, 0x8e, 0x55, 0x8d, 0x31, 0xe3, 0xd8, 0x40, 0x26, 0xd2, 0x2e, 0xee, 0x3f, 0x3e, 0x19, 0xdf, 0xcd, 0x4d, 0xfb, 0xd0, 0x89, 0xbc, 0xbe, 0xdd, 0x24, 0x5, 0xe0, 0x48, 0x5b, 0x17, 0xfb, 0x65, 0xb5, 0x14, 0xb7, 0x13, 0xc0, 0x8f, 0xcc, 0xd6, 0xe4, 0xe7, 0x3a, 0x86, 0x4e, 0x66, 0xf6, 0xff, 0x42, 0xfc, 0x91, 0xe4, 0x4f, 0x9, 0xca, 0x9f, 0x44, 0xc4, 0x70, 0x8c, 0x18, 0xa6, 0xe2, 0x5e, 0xe2, 0x46, 0x51, 0xb4, 0x17, 0xf4, 0xac, 0xb5, 0x81, 0xd2, 0xa4, 0x5d, 0x67, 0x4a, 0xf, 0xe2, 0xc0, 0x8b, 0x67, 0xe9, 0xa3, 0xdf, 0xc7, 0xf0, 0x61, 0x47, 0xfd, 0x71, 0x29, 0x4e, 0xfe, 0x3a, 0x89, 0x1f, 0xf7, 0x1f, 0x5f, 0x9d, 0x8a, 0x4a, 0xbf, 0x6, 0x65, 0xab, 0x33, 0x35, 0x1c, 0xcd, 0xa, 0xc6, 0x58, 0xe4, 0x31, 0xc9, 0x9f, 0xf0, 0xb6, 0x82, 0xf2, 0xf0, 0x23, 0x3a, 0x87, 0x4f, 0x9a, 0x55, 0xc9, 0x6f, 0x1f, 0x6c, 0xc0, 0xfe, 0x85, 0xe2, 0x8b, 0x3b, 0x23, 0xa3, 0x7c, 0xae, 0x35, 0x6e, 0x9e, 0x97, 0x36, 0x1a, 0x3f, 0xf, 0x5e, 0x1, 0x7c, 0x32, 0x76, 0x67, 0x1f, 0xd9, 0x35, 0x76, 0x34, 0x2f, 0x6f, 0x96, 0x7b, 0xc6, 0x95, 0xad, 0x40, 0xf0, 0x94, 0xb4, 0x1e, 0x6d, 0x95, 0xa1, 0x59, 0xb4, 0xf4, 0x3f, 0x86, 0x7d, 0xf7, 0x56, 0x89, 0x87, 0x2, 0x67, 0xa, 0x51, 0x1a, 0x1d, 0x33, 0x26, 0xce, 0x5c, 0x9e, 0xa4, 0x5e, 0x11, 0xab, 0xb3, 0x8f, 0xe8, 0xfa, 0xd3, 0x11, 0x54, 0x7b, 0x27, 0xca, 0x36, 0x83, 0x93, 0x6d, 0xb3, 0x87, 0xe, 0x20, 0x2d, 0x33, 0x47, 0xfa, 0xed, 0xd5, 0xea, 0xcc, 0x4f, 0xfe, 0x70, 0x8e, 0x2d, 0xeb, 0x1e, 0xdf, 0x76, 0x90, 0xb6, 0xae, 0x38, 0x44, 0xca, 0x89, 0x1a, 0xf7, 0x72, 0x31, 0xf8, 0xb9, 0x78, 0x9d, 0xed, 0x1a, 0x3b, 0x82, 0x6a, 0xff, 0x30, 0xca, 0xf6, 0x7a, 0xa, 0x2b, 0x4a, 0x5a, 0x6b, 0x84, 0xe5, 0xa6, 0x5b, 0xd0, 0xd3, 0x56, 0x2d, 0xcc, 0xdc, 0x65, 0x7f, 0x38, 0x4b, 0x91, 0xce, 0xd1, 0xb6, 0x82, 0x12, 0x1f, 0x94, 0xa5, 0x38, 0x28, 0x5f, 0xae, 0x81, 0x13, 0xc1, 0x38, 0xb9, 0x69, 0x8f, 0xd3, 0xd9, 0xa3, 0x98, 0xf9, 0x5f, 0xa2, 0xda, 0xc7, 0x41, 0x12, 0x55, 0x55, 0xf4, 0x75, 0x2b, 0x84, 0xfb, 0xe1, 0x31, 0xf3, 0x9a, 0xe8, 0xeb, 0x90, 0x17, 0xc8, 0xe5, 0x58, 0xf4, 0xdd, 0xc4, 0xd3, 0xc7, 0x69, 0x33, 0x6b, 0xe6, 0x8f, 0x3c, 0x83, 0xfd, 0x76, 0x19, 0xb6, 0x19, 0x13, 0xa1, 0xaa, 0x20, 0xc2, 0x3f, 0x21, 0x7a, 0x4c, 0xc0, 0x6f, 0x66, 0x39, 0x68, 0xff, 0x77, 0x72, 0x7c, 0x3f, 0x13, 0x61, 0x5, 0x13, 0x62, 0x27, 0x5b, 0xaf, 0x1e, 0x73, 0xf1, 0xfa, 0x65, 0xb7, 0xcf, 0xf9, 0x3b, 0xb2, 0x1d, 0xc3, 0x4f, 0x8f, 0x69, 0xd9, 0x1f, 0x3b, 0x8e, 0x4, 0x7c, 0x27, 0xdd, 0x5a, 0x99, 0xc8, 0x60, 0x1c, 0x55, 0xef, 0x3a, 0x2a, 0xfd, 0x43, 0xa3, 0xcd, 0xe8, 0xb, 0xa6, 0x5c, 0xfa, 0x8a, 0x40, 0x43, 0x65, 0x43, 0xa6, 0x7d, 0x68, 0x46, 0x7c, 0x35, 0xcc, 0xb4, 0xd, 0x7e, 0x8a, 0x80, 0x6f, 0xd4, 0x76, 0x82, 0x97, 0x74, 0xb1, 0xb5, 0xb6, 0xcf, 0xb5, 0x10, 0x59, 0x81, 0xec, 0x7f, 0x7b, 0xdf, 0x62, 0x46, 0x8f, 0xce, 0x76, 0x78, 0xf0, 0x5d, 0xe6, 0x1c, 0xa, 0xf0, 0x6, 0xe2, 0xf1, 0x64, 0x92, 0xfe, 0x12, 0x72, 0xf3, 0x56, 0xda, 0xc7, 0x30, 0x76, 0x78, 0xc, 0xc9, 0x1f, 0x3d, 0x81, 0x7d, 0xee, 0x93, 0xcc, 0xfe, 0xa0, 0xb2, 0xe9, 0x83, 0x73, 0xf0, 0x54, 0xa5, 0x9d, 0x14, 0x4a, 0x74, 0x86, 0x67, 0xd6, 0x16, 0x9c, 0xed, 0x79, 0xf4, 0xbb, 0x6e, 0x8a, 0x7e, 0xcd, 0x19, 0xef, 0xfd, 0xcf, 0xd1, 0xe8, 0x9f, 0xeb, 0xcd, 0xca, 0xfd, 0x3e, 0x29, 0xeb, 0x31, 0xc1, 0x57, 0xdd, 0xb2, 0xa4, 0xdf, 0x49, 0xe2, 0x4f, 0xfd, 0x7f, 0xb6, 0xe8, 0x18, 0x60, 0xc7, 0x61, 0xe4, 0xe7, 0x70, 0xf2, 0x73, 0x24, 0xd7, 0x1f, 0x66, 0xdd, 0x61, 0xaa, 0xea, 0x78, 0xe8, 0xe4, 0xe6, 0x62, 0x42, 0x3b, 0x99, 0xc3, 0x49, 0x8d, 0xf4, 0xe3, 0x45, 0x2, 0x21, 0x7d, 0x25, 0x38, 0xb0, 0x87, 0xc0, 0x2c, 0xcd, 0x52, 0x94, 0xa9, 0x96, 0xca, 0x91, 0x53, 0x91, 0x78, 0x66, 0x1a, 0x1, 0x1e, 0x2a, 0xa2, 0x77, 0x65, 0x78, 0xb5, 0xf2, 0x6d, 0xb2, 0x85, 0x11, 0xdb, 0x7d, 0xe8, 0xfc, 0xcd, 0x74, 0xef, 0x73, 0x4f, 0xcf, 0xba, 0xc6, 0xc, 0xb9, 0x15, 0xae, 0xdb, 0x30, 0x4, 0xc4, 0x3c, 0x6, 0xa3, 0xf, 0x91, 0xbf, 0x33, 0xae, 0x8d, 0xb8, 0x46, 0x85, 0xce, 0x2b, 0x19, 0xd3, 0xf6, 0x6c, 0xa5, 0xf2, 0xef, 0x63, 0x39, 0xfc, 0x44, 0xae, 0x73, 0xec, 0xc4, 0x98, 0xb6, 0xbe, 0x2c, 0x85, 0xf6, 0x1b, 0x96, 0xfc, 0x85, 0x2c, 0xf9, 0x7b, 0xfd, 0x19, 0xea, 0xdb, 0x22, 0x31, 0x89, 0xf0, 0x25, 0x2a, 0x46, 0x35, 0xe3, 0x25, 0x2b, 0xc9, 0xd0, 0xdf, 0x1f, 0xf5, 0xb6, 0xbf, 0x1e, 0x3d, 0xbd, 0x77, 0xb9, 0x1d, 0x23, 0xd7, 0x63, 0xc8, 0x9d, 0xbe, 0x71, 0xfe, 0xb2, 0x2c, 0xc7, 0x53, 0xc9, 0x1, 0x3a, 0x7d, 0x1b, 0x24, 0x50, 0x9b, 0x28, 0x84, 0xb9, 0x24, 0xea, 0x57, 0xd8, 0xfb, 0x4a, 0xf6, 0xc8, 0x93, 0xeb, 0xf4, 0x39, 0x45, 0xe1, 0x7f, 0x94, 0xc2, 0xfa, 0x1b, 0xb2, 0x17, 0xc1, 0x2e, 0x3f, 0xf1, 0xa2, 0xd7, 0xd7, 0x6d, 0xdd, 0xc7, 0xc0, 0xaf, 0xa1, 0xc5, 0xe8, 0x7f, 0xf3, 0xcc, 0xb8, 0xdb, 0xed, 0x1c, 0x7d, 0x3e, 0x6, 0x39, 0x30, 0x41, 0xa0, 0x9d, 0x69, 0x46, 0xb9, 0x48, 0x5f, 0xec, 0xd2, 0x7d, 0xdd, 0xee, 0xa6, 0x8, 0x16, 0xc3, 0xed, 0x30, 0x44, 0x22, 0xbf, 0xc9, 0xc, 0x7e, 0x1d, 0xab, 0x43, 0x9a, 0xfe, 0x85, 0xf4, 0x4f, 0xcd, 0x75, 0xfd, 0xe9, 0x44, 0x38, 0xee, 0x91, 0x6f, 0xfd, 0xcb, 0x89, 0x8c, 0x9d, 0x41, 0xb1, 0x5c, 0xc4, 0xf8, 0xe3, 0xd8, 0x47, 0xdf, 0xc3, 0xf1, 0x0, 0xbf, 0xbb, 0x9, 0xee, 0x67, 0xc6, 0xaf, 0xf7, 0x65, 0x83, 0xa9, 0x57, 0x8f, 0x49, 0xbf, 0x7e, 0x4c, 0x79, 0xf4, 0x27, 0xb0, 0xe5, 0x7f, 0xed, 0x9c, 0x3, 0x90, 0x2c, 0x49, 0x13, 0x80, 0xfb, 0xff, 0xcf, 0xb6, 0x6d, 0x6b, 0x7a, 0xe6, 0x6c, 0xdb, 0xb6, 0x6f, 0x7d, 0xb6, 0x6d, 0xdb, 0x76, 0xe0, 0x7c, 0xb7, 0xec, 0x99, 0xd5, 0xd9, 0xb6, 0x6d, 0x63, 0xdf, 0x54, 0xdd, 0x57, 0xbd, 0x39, 0x13, 0xf5, 0x2a, 0x5e, 0x5f, 0xaf, 0x63, 0xd0, 0x19, 0xf1, 0x45, 0x66, 0x55, 0x67, 0xd6, 0x54, 0x67, 0x66, 0xf5, 0xcc, 0xf2, 0x8a, 0xb5, 0x8f, 0x7b, 0xf9, 0x7f, 0x5e, 0x29, 0x8, 0x49, 0x9a, 0x8d, 0xd, 0x75, 0x93, 0x18, 0x4d, 0x57, 0x2, 0x9b, 0x24, 0x19, 0x46, 0x8f, 0xd, 0x4f, 0x58, 0xc8, 0x9c, 0xec, 0xc1, 0xb5, 0xd1, 0x36, 0xbf, 0x11, 0xf3, 0x1, 0x7b, 0x7f, 0x9e, 0x2f, 0x61, 0x7b, 0xfd, 0x9a, 0x27, 0x72, 0x7e, 0x4d, 0x73, 0x0, 0x1d, 0x8c, 0x3, 0x4e, 0x79, 0x27, 0xf4, 0x72, 0xfd, 0x65, 0x7c, 0xbf, 0x2, 0xed, 0xc2, 0x9a, 0xb2, 0xee, 0xf0, 0xef, 0x1, 0xed, 0xe2, 0xee, 0x3d, 0xf, 0x9a, 0x3d, 0x35, 0xaf, 0x50, 0xd3, 0x3c, 0xaf, 0x57, 0x2a, 0xc2, 0x9, 0x9a, 0x88, 0x6f, 0x0, 0xad, 0x27, 0x49, 0x51, 0x6, 0x29, 0x48, 0x29, 0x61, 0xf6, 0x55, 0xb4, 0xad, 0xf9, 0x62, 0x31, 0xa3, 0xe6, 0x42, 0x6d, 0xc7, 0x5a, 0xf1, 0x63, 0x75, 0xaf, 0x92, 0x57, 0x63, 0x77, 0xfa, 0x75, 0xad, 0xa5, 0xf7, 0xb, 0xb2, 0x3c, 0x5, 0x26, 0x81, 0x73, 0xe9, 0x4e, 0x1d, 0x52, 0xd3, 0xac, 0x38, 0x49, 0x46, 0x6b, 0xdf, 0x82, 0x31, 0xd8, 0x63, 0x57, 0x8b, 0x1d, 0xed, 0x67, 0x13, 0xbd, 0x66, 0xc4, 0x7a, 0xae, 0x2f, 0x7b, 0xb5, 0xed, 0x22, 0xe2, 0x8f, 0x4d, 0xb1, 0x5d, 0x3b, 0x6a, 0xad, 0x8, 0x7c, 0x8b, 0xb8, 0x78, 0xd7, 0x76, 0xf7, 0xc6, 0x41, 0x3b, 0xdc, 0x2b, 0x55, 0xf1, 0xeb, 0xda, 0xe6, 0xe0, 0xfd, 0xf2, 0x2d, 0xbf, 0xb6, 0x7f, 0xd3, 0xe8, 0xf0, 0xb4, 0x98, 0xb1, 0x20, 0x36, 0x14, 0x1b, 0x84, 0x64, 0xcb, 0x1c, 0x36, 0x73, 0x85, 0x58, 0x87, 0x1a, 0xc7, 0x76, 0xfd, 0xa2, 0xfd, 0x21, 0xde, 0xdf, 0xf2, 0x8b, 0x88, 0x8f, 0xb0, 0x23, 0xe7, 0x6c, 0x86, 0xb5, 0x17, 0xb0, 0x1b, 0xa0, 0xf5, 0x68, 0xaf, 0x94, 0xc5, 0xaf, 0x6d, 0xdb, 0x9a, 0xee, 0xcd, 0x83, 0xa6, 0x19, 0x14, 0x68, 0x6c, 0x25, 0xe3, 0xe2, 0x9c, 0xcc, 0x17, 0x35, 0x28, 0xeb, 0x7a, 0xc1, 0x4e, 0x0, 0x2b, 0x87, 0xe8, 0x96, 0xe7, 0x68, 0x82, 0x75, 0xbc, 0x52, 0x96, 0x15, 0x6a, 0x5a, 0xae, 0x5e, 0x81, 0x6e, 0x75, 0xb, 0x2b, 0x63, 0x80, 0xda, 0x96, 0xf7, 0x79, 0x62, 0xdc, 0x2, 0xa7, 0x63, 0x37, 0x33, 0x37, 0xc1, 0xe6, 0x18, 0x3e, 0xad, 0x15, 0x51, 0x7c, 0x3b, 0x87, 0x34, 0xc0, 0xcd, 0x2b, 0x36, 0x6, 0x93, 0x78, 0xa5, 0x2a, 0xa9, 0xba, 0xf6, 0x29, 0xd9, 0x64, 0x1b, 0xdd, 0x3a, 0xe, 0xb4, 0xc5, 0x8f, 0x34, 0x47, 0x3b, 0xfa, 0x4a, 0xa, 0xbf, 0x1b, 0xdf, 0xc4, 0x98, 0x3c, 0xf4, 0xaf, 0x6d, 0x5b, 0x6, 0xff, 0x5e, 0x8a, 0x55, 0xf4, 0x35, 0x36, 0x28, 0x40, 0x27, 0x80, 0x22, 0x2f, 0xa, 0x6d, 0xe, 0xcf, 0x47, 0x3c, 0x69, 0xf7, 0xf0, 0x4a, 0x59, 0xd2, 0xf5, 0x1d, 0x4b, 0x52, 0xe4, 0x4f, 0x29, 0xec, 0x57, 0x14, 0xbd, 0x83, 0x8d, 0x3f, 0xc8, 0xd7, 0xd6, 0x27, 0x31, 0x3f, 0x47, 0x84, 0xff, 0xbc, 0xf8, 0xe6, 0xf0, 0xd5, 0x7c, 0xca, 0xd, 0xe1, 0x46, 0x8d, 0x56, 0xa0, 0xa3, 0x69, 0xb3, 0xec, 0x61, 0xfb, 0x45, 0xf8, 0xb6, 0xb9, 0xf6, 0x28, 0xd2, 0x16, 0xf7, 0x1a, 0xca, 0xe4, 0x65, 0x85, 0x9a, 0xd6, 0x47, 0x39, 0x68, 0x53, 0x94, 0x7a, 0x13, 0x9c, 0xe5, 0xd7, 0xb5, 0xd7, 0xfb, 0xf5, 0x1d, 0x53, 0xf, 0xec, 0x43, 0x64, 0xc7, 0x64, 0x74, 0x76, 0x6f, 0x4a, 0xba, 0x5e, 0x92, 0xa1, 0x52, 0x62, 0xa7, 0x1d, 0x7c, 0x87, 0xb4, 0xad, 0x23, 0x89, 0x8f, 0x77, 0x7d, 0x5c, 0xff, 0x74, 0xd4, 0x5e, 0x22, 0xec, 0x91, 0xc6, 0xe4, 0x3, 0xbe, 0x25, 0xb7, 0x47, 0x7a, 0x15, 0x25, 0xf2, 0x6b, 0xe5, 0xdc, 0x5c, 0x2b, 0x9d, 0xfe, 0xb, 0xd0, 0x8, 0x61, 0x22, 0x55, 0x7f, 0x42, 0xdb, 0x1d, 0xda, 0x22, 0xc6, 0x68, 0x21, 0xca, 0xd7, 0xf5, 0x89, 0x5f, 0xc7, 0x9d, 0x8b, 0x7e, 0xd, 0x77, 0x7e, 0xf0, 0x7b, 0x8a, 0x88, 0x91, 0x27, 0x3, 0x5a, 0xc9, 0x1, 0x9, 0x56, 0xa8, 0x6d, 0x9b, 0xcc, 0xab, 0x44, 0x49, 0xd7, 0x7, 0x17, 0xf3, 0xd9, 0xe0, 0xf3, 0xe2, 0x69, 0xaa, 0x6f, 0x57, 0xa0, 0xab, 0x1d, 0x72, 0xa1, 0xd0, 0xa, 0xad, 0xe1, 0x47, 0xde, 0x6, 0x4e, 0xf3, 0x2a, 0x55, 0x52, 0x75, 0x1d, 0x3b, 0xd2, 0x4, 0xaf, 0xf1, 0xa8, 0xcb, 0xf3, 0x76, 0xa2, 0xcb, 0x1d, 0xee, 0x43, 0xc5, 0xce, 0xc5, 0xc7, 0x2a, 0x6c, 0x2d, 0x7c, 0x4a, 0x3, 0x1c, 0xe6, 0x55, 0xb2, 0xf8, 0x75, 0xc1, 0xec, 0x7c, 0x86, 0x78, 0x51, 0x6e, 0x1e, 0x2, 0xd1, 0x36, 0x81, 0x35, 0x3f, 0x78, 0xe2, 0xd7, 0x8, 0xe2, 0x63, 0x6d, 0x1b, 0xdc, 0x79, 0x50, 0x85, 0x42, 0x82, 0xf6, 0x43, 0x3b, 0xf4, 0x51, 0xc0, 0xb8, 0x5d, 0x45, 0xad, 0x6b, 0x62, 0xb0, 0x8d, 0xbf, 0x2, 0x6d, 0x48, 0xd5, 0xb6, 0x7f, 0x86, 0x6e, 0xf4, 0x2a, 0x5d, 0x32, 0xd, 0xd9, 0x9a, 0x74, 0x43, 0xf0, 0x85, 0x49, 0x18, 0x5a, 0x81, 0x2e, 0x17, 0xd8, 0xb3, 0xbd, 0x5f, 0x55, 0x98, 0x83, 0x71, 0xf0, 0x97, 0xc1, 0xf2, 0x53, 0x72, 0x8f, 0x2e, 0xca, 0x5e, 0x8f, 0x13, 0x6f, 0xf4, 0x97, 0xe4, 0xa5, 0xce, 0xab, 0x6, 0xf1, 0xeb, 0x83, 0xde, 0x74, 0x43, 0x56, 0xa3, 0x35, 0xda, 0x5, 0x2, 0x21, 0x1b, 0x47, 0x7c, 0xbc, 0xd8, 0xf1, 0xd7, 0x5d, 0xb2, 0x36, 0x4a, 0xd0, 0xb2, 0xef, 0xb0, 0xb0, 0x42, 0x61, 0x3e, 0xc8, 0x34, 0xe6, 0x56, 0x46, 0xef, 0xce, 0x29, 0x2e, 0x36, 0x8a, 0x1b, 0x67, 0x8f, 0xa5, 0x71, 0xcc, 0xfc, 0xab, 0xb0, 0xb9, 0x57, 0x2d, 0x42, 0xa7, 0xbf, 0x1, 0xe1, 0xa3, 0xd2, 0xe8, 0x92, 0xa4, 0x71, 0xbc, 0xb1, 0x12, 0x74, 0x61, 0xdf, 0xf2, 0xa8, 0x37, 0xcd, 0x92, 0xa3, 0x78, 0x1b, 0x52, 0xd0, 0x49, 0x3c, 0x11, 0x1a, 0x61, 0x43, 0xae, 0xfd, 0xa, 0xda, 0x8d, 0xb3, 0xc6, 0xf9, 0xfe, 0xf8, 0x6c, 0x2b, 0xfe, 0x19, 0xaf, 0x5a, 0xc4, 0xaf, 0xcf, 0x2e, 0x44, 0xc2, 0xde, 0x4f, 0x87, 0x49, 0xce, 0x29, 0xd0, 0x0, 0xe1, 0xd8, 0x21, 0x5b, 0x20, 0x62, 0xce, 0xbd, 0x1e, 0x45, 0xd6, 0xd6, 0x11, 0x36, 0x38, 0x31, 0xec, 0x51, 0x59, 0xb1, 0x8a, 0x62, 0xcb, 0x7c, 0x0, 0xd9, 0x7, 0x33, 0x8d, 0x9d, 0xab, 0xa5, 0x1b, 0x73, 0x53, 0xa4, 0x9b, 0x7a, 0xfe, 0xe7, 0x39, 0x92, 0x6e, 0xc8, 0x2d, 0xcc, 0x7d, 0x3e, 0x81, 0x9f, 0xac, 0x93, 0x1b, 0x6f, 0x2d, 0x59, 0xff, 0x46, 0xbf, 0x21, 0xbb, 0xa0, 0x57, 0x4d, 0xc2, 0xd, 0x6f, 0xc6, 0x8d, 0x7f, 0x26, 0xd, 0x60, 0x35, 0x41, 0x3c, 0xc4, 0x28, 0xdb, 0x6, 0xfb, 0x9a, 0xd1, 0x23, 0x8e, 0xfd, 0xf8, 0x67, 0xfc, 0x1, 0x45, 0x3f, 0x97, 0xa2, 0x2f, 0xa, 0x53, 0x31, 0xfe, 0xcf, 0xdf, 0xc8, 0xc5, 0x67, 0x16, 0x1a, 0xe1, 0x60, 0xeb, 0xad, 0x4e, 0x89, 0x86, 0xdc, 0xe1, 0xe9, 0xc6, 0xce, 0x99, 0xbc, 0x6a, 0x13, 0x1a, 0xe0, 0x4c, 0x6e, 0xfe, 0x67, 0x93, 0x5c, 0xb4, 0x26, 0xa1, 0x83, 0x82, 0x98, 0x3c, 0xd8, 0x63, 0x83, 0x72, 0xfc, 0x54, 0x41, 0x8b, 0xaf, 0x3b, 0x1f, 0x8b, 0xb3, 0x7e, 0x1f, 0xc5, 0x5a, 0x3c, 0xd3, 0xd4, 0x35, 0x27, 0x7a, 0x1a, 0x6f, 0x10, 0x42, 0xcc, 0x14, 0xc4, 0x2c, 0xc4, 0x1a, 0x9f, 0x81, 0xe6, 0x9, 0xf8, 0x8d, 0xdf, 0x90, 0x5b, 0xdb, 0x97, 0xb7, 0x8c, 0xaa, 0x13, 0x6e, 0xbe, 0x9b, 0x93, 0x91, 0xcf, 0x34, 0x75, 0x6a, 0x50, 0xa2, 0xe3, 0x50, 0x5, 0x88, 0xd5, 0x24, 0xf4, 0x26, 0xd8, 0x1f, 0xee, 0x66, 0xfc, 0x17, 0xe8, 0x28, 0xec, 0x78, 0x6b, 0x1c, 0xb, 0xbe, 0xca, 0xb2, 0xff, 0xf1, 0x86, 0x29, 0x34, 0xc2, 0x42, 0xec, 0x77, 0x7, 0x58, 0xd2, 0xab, 0x66, 0x21, 0x1, 0x5f, 0x83, 0x26, 0x21, 0xa, 0xb4, 0xd8, 0x91, 0x70, 0xdd, 0x1d, 0xbf, 0x97, 0x6e, 0xec, 0x4a, 0xc1, 0xc4, 0x8c, 0xe7, 0xce, 0x34, 0x75, 0xa7, 0x60, 0x4d, 0xc6, 0xeb, 0xc3, 0x26, 0xb0, 0x23, 0x1c, 0x83, 0xdf, 0xb5, 0x70, 0x3f, 0x3c, 0xb, 0xda, 0x7e, 0xcd, 0x81, 0x42, 0x8c, 0x2, 0x4d, 0xd3, 0xfe, 0x63, 0x5e, 0xcf, 0x1b, 0xa6, 0xac, 0x74, 0x48, 0x2f, 0x6b, 0x54, 0xb9, 0x64, 0x1a, 0xbb, 0x2e, 0xee, 0x2f, 0x8, 0x49, 0x86, 0x15, 0xad, 0xa2, 0x60, 0xbb, 0x28, 0x8, 0xfd, 0xf0, 0x57, 0x60, 0xfc, 0xb6, 0x49, 0xd5, 0x65, 0x23, 0xdf, 0x7b, 0xcd, 0x7, 0x32, 0x7c, 0xa6, 0x85, 0x39, 0x61, 0x3e, 0xe0, 0x4b, 0xb3, 0xce, 0x3e, 0x7b, 0x2d, 0x74, 0x2c, 0xe2, 0xab, 0x88, 0xd5, 0xd0, 0x37, 0x12, 0xd, 0x90, 0x8, 0x42, 0x22, 0xe7, 0xe2, 0xc4, 0x6e, 0x4b, 0x13, 0x3c, 0x16, 0x16, 0xfd, 0xe0, 0xee, 0x2, 0xca, 0x1a, 0x2b, 0x6b, 0xac, 0xc, 0x72, 0x8a, 0xcf, 0x26, 0x7e, 0xf2, 0x41, 0xbe, 0xde, 0xc4, 0x14, 0xb2, 0x93, 0xb5, 0xf2, 0xb2, 0x5e, 0x34, 0x4d, 0xe0, 0xec, 0x47, 0xf8, 0x91, 0x3d, 0x27, 0xd, 0x30, 0xc2, 0x8d, 0xb0, 0x14, 0x49, 0xdd, 0x1b, 0x9e, 0x0, 0xd, 0x24, 0xbd, 0xc7, 0xa0, 0x84, 0xd0, 0x66, 0xde, 0xa0, 0xe1, 0x29, 0x62, 0x66, 0xf6, 0x6, 0x29, 0xac, 0x31, 0x9, 0xd4, 0x12, 0x3b, 0x4e, 0x5e, 0x43, 0xd6, 0x8e, 0xc7, 0xf8, 0x13, 0x97, 0x47, 0xbf, 0x4, 0x13, 0x79, 0xa3, 0x22, 0x49, 0x23, 0x2c, 0xb, 0xfb, 0x92, 0xe0, 0xdb, 0xe0, 0x67, 0xd0, 0x16, 0x4a, 0x8a, 0xf0, 0x3d, 0xac, 0x31, 0xf4, 0xf, 0x60, 0x3d, 0x73, 0x11, 0xaf, 0xad, 0x6, 0x80, 0x81, 0x35, 0x0, 0xfc, 0x43, 0xec, 0x9d, 0xf0, 0x7f, 0x6f, 0xf4, 0x24, 0x91, 0x74, 0x53, 0xf7, 0x1c, 0xb0, 0x3f, 0x9c, 0x43, 0xc1, 0x3a, 0x40, 0x67, 0x28, 0x2, 0xfa, 0x77, 0xe6, 0xf6, 0x1e, 0x81, 0xf5, 0x3b, 0x56, 0x3c, 0xb8, 0xb7, 0xf, 0x58, 0x93, 0x2, 0x1f, 0xd2, 0x4b, 0x91, 0x5, 0x6c, 0x1b, 0xae, 0x2b, 0x33, 0x2f, 0xfc, 0x49, 0xec, 0xd1, 0x90, 0x34, 0xc0, 0x58, 0x9, 0x45, 0xf0, 0xe1, 0x42, 0xb8, 0x1e, 0x4e, 0x1e, 0x89, 0x5f, 0x48, 0xa1, 0x80, 0x1b, 0xd2, 0x50, 0x7f, 0x80, 0x29, 0xb2, 0x12, 0xb4, 0x8c, 0x6d, 0x94, 0xc1, 0xcc, 0xb, 0x79, 0xd8, 0x4c, 0xfe, 0x34, 0xbd, 0x5c, 0x25, 0x11, 0x9a, 0xc0, 0x7c, 0xcb, 0xf6, 0x33, 0xb4, 0xa6, 0x98, 0xe3, 0xc1, 0xdc, 0x4, 0xc1, 0xff, 0x53, 0x74, 0x2b, 0x3e, 0x73, 0x7b, 0xe5, 0x2f, 0x89, 0xf0, 0x68, 0x3f, 0x8b, 0xd3, 0xdd, 0x27, 0x8f, 0x7f, 0x85, 0xfe, 0x1b, 0x7e, 0xc6, 0xfe, 0x1a, 0xfd, 0x21, 0xbc, 0xcc, 0x69, 0xf, 0xd0, 0xf, 0x33, 0x77, 0x2b, 0xf6, 0xfe, 0x2b, 0x1d, 0xfa, 0xe4, 0xd2, 0x5e, 0x65, 0x48, 0x22, 0x9c, 0xe4, 0xa9, 0x38, 0xd1, 0x77, 0xc2, 0x43, 0xd8, 0x77, 0xc0, 0x35, 0x70, 0x16, 0xff, 0x60, 0xf9, 0x70, 0xd8, 0x3, 0x7b, 0xd, 0xae, 0xcd, 0xe2, 0x95, 0xbd, 0x24, 0x92, 0x48, 0x22, 0x89, 0x24, 0x92, 0x48, 0x22, 0x89, 0x24, 0x92, 0x48, 0x22, 0x89, 0xfc, 0xb, 0x31, 0x1b, 0x93, 0xfa, 0xac, 0xe1, 0x98, 0xc3, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char mini_checkerboard_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x98, 0xa0, 0xbd, 0x0, 0x0, 0x0, 0x17, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x78, 0x0, 0x5, 0xff, 0xa1, 0x60, 0xa0, 0x4, 0x60, 0xc, 0x98, 0xc4, 0x0, 0x9, 0x0, 0x0, 0x44, 0x81, 0xef, 0x81, 0xc1, 0x26, 0x8e, 0x8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -242,10 +206,6 @@ static const unsigned char option_button_disabled_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x1, 0x2f, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3f, 0x3f, 0x5a, 0x5a, 0x5a, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x59, 0x59, 0x59, 0x2a, 0x2a, 0x30, 0x4b, 0x4b, 0x4b, 0x22, 0x22, 0x27, 0x35, 0x35, 0x35, 0x4a, 0x4a, 0x4a, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x56, 0x56, 0x56, 0x62, 0x62, 0x62, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x48, 0x48, 0x48, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43, 0x54, 0x54, 0x54, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x52, 0x52, 0x52, 0x42, 0x42, 0x42, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x51, 0x51, 0x51, 0x40, 0x40, 0x40, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x4f, 0x4f, 0x4f, 0x3f, 0x3f, 0x3f, 0x4d, 0x4d, 0x4d, 0x3e, 0x3e, 0x3e, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x4c, 0x4c, 0x4c, 0x3d, 0x3d, 0x3d, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x4a, 0x4a, 0x4a, 0x3b, 0x3b, 0x3b, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x49, 0x49, 0x49, 0x3a, 0x3a, 0x3a, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x39, 0x39, 0x39, 0x47, 0x47, 0x47, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x46, 0x46, 0x46, 0xd3, 0xa7, 0xd4, 0x88, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0xec, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0x8e, 0x5, 0x4e, 0x0, 0x31, 0x10, 0x45, 0xff, 0xef, 0x56, 0xc2, 0xe2, 0xee, 0x4e, 0x3c, 0xc8, 0xd, 0xb8, 0x38, 0xa7, 0xc0, 0xdd, 0xdd, 0x5d, 0xbb, 0x94, 0x4c, 0xd2, 0xc1, 0xdf, 0x4a, 0x47, 0x5e, 0x27, 0xc3, 0xc, 0x80, 0x64, 0x24, 0xb8, 0xc7, 0x4f, 0x2c, 0x6b, 0xd5, 0x90, 0xff, 0xdd, 0x23, 0x7e, 0xc1, 0xa2, 0xb6, 0x64, 0xad, 0x26, 0x82, 0xc6, 0xef, 0x45, 0xbc, 0xe3, 0x1, 0x2c, 0x69, 0x9b, 0xc8, 0x7f, 0x5, 0x36, 0x1e, 0x41, 0x84, 0xd6, 0x4, 0x25, 0x90, 0xb7, 0x39, 0x6c, 0x4c, 0x2f, 0xbe, 0x68, 0xdf, 0x13, 0xa1, 0x9e, 0xc8, 0xa4, 0xb7, 0xe7, 0x47, 0x93, 0x63, 0x1b, 0xf9, 0xdc, 0x8, 0x88, 0x60, 0xbf, 0x4, 0xff, 0xd2, 0x56, 0x93, 0xe3, 0xb7, 0xb2, 0xf6, 0x2c, 0x36, 0x1, 0x16, 0xf4, 0x5f, 0x42, 0xc4, 0x17, 0x8f, 0xb5, 0xc0, 0xa5, 0x8, 0x30, 0x5f, 0xc2, 0x5d, 0xcf, 0xc9, 0xd, 0x74, 0x87, 0x8b, 0x5e, 0x56, 0x22, 0x24, 0xf7, 0x6d, 0xc2, 0xd1, 0x80, 0x26, 0x27, 0x5d, 0x5b, 0x67, 0x7d, 0x2f, 0x80, 0x4d, 0xc9, 0x7f, 0x9, 0x63, 0xa7, 0x61, 0x23, 0xc7, 0x74, 0x3d, 0xf, 0xae, 0x41, 0x84, 0x6f, 0x13, 0xe6, 0x26, 0xfa, 0x36, 0x46, 0x73, 0xbc, 0xba, 0x3b, 0xd6, 0xca, 0x8, 0xd0, 0xd6, 0x36, 0x4e, 0x35, 0xeb, 0xad, 0xd7, 0xb0, 0x60, 0x72, 0xdc, 0xda, 0x9c, 0x2, 0x67, 0x76, 0x64, 0x82, 0x99, 0x9b, 0xb6, 0x80, 0xb0, 0x7e, 0x8d, 0xf6, 0x5a, 0xdd, 0xe1, 0xb5, 0xba, 0xba, 0xb1, 0x0, 0xcd, 0xc7, 0x50, 0x23, 0xeb, 0xfb, 0x7f, 0xb4, 0xc8, 0x22, 0x18, 0xdd, 0x0, 0xd5, 0xec, 0x4e, 0x53, 0xc6, 0x18, 0x44, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char option_button_focus_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0xb1, 0x50, 0x4c, 0x54, 0x45, 0x95, 0xa9, 0xb0, 0x92, 0xa7, 0xae, 0x8e, 0xa2, 0xa9, 0x8a, 0x9d, 0xa4, 0x85, 0x98, 0x9f, 0x80, 0x93, 0x9b, 0x7b, 0x8f, 0x96, 0x77, 0x8a, 0x92, 0x72, 0x86, 0x8c, 0x6e, 0x80, 0x88, 0x69, 0x7c, 0x84, 0x64, 0x77, 0x7f, 0x60, 0x72, 0x7a, 0x5b, 0x6e, 0x75, 0x56, 0x69, 0x71, 0xc8, 0xe3, 0xe7, 0xc8, 0xe2, 0xe7, 0xca, 0xe3, 0xe7, 0xce, 0xe6, 0xe9, 0xce, 0xe6, 0xea, 0xd0, 0xe6, 0xe9, 0xce, 0xe5, 0xea, 0xd0, 0xe6, 0xea, 0xce, 0xe5, 0xe9, 0xd0, 0xe5, 0xe9, 0xd3, 0xe7, 0xeb, 0xd4, 0xe7, 0xeb, 0xd9, 0xea, 0xed, 0xd7, 0xe9, 0xed, 0xd7, 0xea, 0xed, 0xdc, 0xec, 0xef, 0xdc, 0xeb, 0xef, 0xe0, 0xed, 0xf1, 0xdf, 0xee, 0xf1, 0xdf, 0xed, 0xf1, 0xe0, 0xee, 0xf1, 0xe3, 0xf0, 0xf2, 0xe2, 0xef, 0xf2, 0xe3, 0xef, 0xf2, 0xe6, 0xf1, 0xf3, 0xe8, 0xf2, 0xf5, 0xe8, 0xf3, 0xf4, 0xe8, 0xf2, 0xf4, 0xe8, 0xf3, 0xf5, 0xd6, 0x5a, 0x5b, 0xd4, 0x57, 0x58, 0xe5, 0x89, 0x89, 0xd5, 0x57, 0x59, 0xd5, 0x58, 0x59, 0xd5, 0x59, 0x5a, 0xd6, 0x59, 0x5a, 0xd6, 0x5a, 0x5c, 0xd7, 0x5b, 0x5c, 0xd7, 0x5b, 0x5d, 0xd8, 0x5c, 0x5d, 0xd8, 0x5c, 0x5e, 0xd8, 0x5d, 0x5f, 0xd9, 0x5d, 0x5f, 0xe8, 0x6c, 0x6e, 0x20, 0x6, 0x32, 0x78, 0x0, 0x0, 0x0, 0x2c, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xac, 0x80, 0x68, 0x47, 0x0, 0x0, 0x0, 0x72, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0xc8, 0xc1, 0x8d, 0xc2, 0x30, 0x18, 0x6, 0xd1, 0x99, 0xdf, 0x8e, 0x7c, 0x59, 0x6d, 0xb, 0x14, 0x40, 0xff, 0xa5, 0x50, 0x0, 0x6d, 0x4, 0xe4, 0xf, 0x59, 0x8, 0x42, 0xde, 0xf1, 0x35, 0xce, 0xd0, 0x2b, 0xbf, 0x6e, 0x5d, 0xe5, 0x10, 0xbb, 0x95, 0x3b, 0x48, 0x2a, 0xe4, 0xd2, 0xec, 0x9a, 0xe6, 0x2, 0xcf, 0xd, 0x56, 0x30, 0x24, 0x48, 0x6, 0xb8, 0x82, 0xc2, 0x0, 0xd6, 0x3b, 0xf6, 0x6a, 0x12, 0xc0, 0xc8, 0x6e, 0x77, 0x3c, 0xa, 0xa3, 0xb3, 0x4d, 0x19, 0x76, 0xa5, 0xb, 0x12, 0x1b, 0xb8, 0x82, 0xc6, 0x22, 0x7c, 0x42, 0xc4, 0x40, 0x41, 0x59, 0x8a, 0x42, 0x80, 0x39, 0xc1, 0xae, 0x6c, 0x7c, 0xb9, 0xe2, 0x8f, 0x43, 0xf4, 0x9f, 0xb3, 0x17, 0x98, 0xa8, 0x1a, 0xb6, 0xa7, 0xd9, 0xa6, 0x4e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char option_button_hover_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x1, 0x41, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x40, 0x4b, 0x5f, 0x5a, 0x6c, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x5f, 0x5a, 0x6b, 0x2a, 0x2a, 0x30, 0x56, 0x53, 0x64, 0x22, 0x22, 0x27, 0x3e, 0x3b, 0x46, 0x57, 0x53, 0x63, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x5b, 0x57, 0x68, 0x5a, 0x56, 0x67, 0x67, 0x63, 0x76, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x4d, 0x4a, 0x57, 0x49, 0x46, 0x52, 0x48, 0x45, 0x51, 0x5a, 0x56, 0x65, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x5b, 0x57, 0x66, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x59, 0x55, 0x64, 0x47, 0x44, 0x50, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x58, 0x54, 0x64, 0x46, 0x43, 0x50, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x56, 0x53, 0x63, 0x45, 0x42, 0x4f, 0x56, 0x53, 0x62, 0x45, 0x42, 0x4e, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x55, 0x51, 0x62, 0x44, 0x41, 0x4e, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x55, 0x51, 0x60, 0x44, 0x41, 0x4d, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x43, 0x40, 0x4c, 0x54, 0x50, 0x5f, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x47, 0x43, 0x51, 0x43, 0x3f, 0x4d, 0x42, 0x3f, 0x4c, 0x53, 0x4f, 0x5f, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x53, 0x50, 0x5f, 0x53, 0x4f, 0x5e, 0x5f, 0x5a, 0x6c, 0xd3, 0x26, 0x54, 0x35, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0xe5, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x85, 0x91, 0x43, 0x62, 0xc5, 0x60, 0x18, 0x45, 0xef, 0x8d, 0x51, 0xdb, 0xee, 0x46, 0xca, 0x6d, 0x77, 0x58, 0xce, 0x6b, 0xdb, 0x7c, 0x8a, 0xad, 0xea, 0x44, 0x1f, 0x4e, 0x92, 0x1f, 0x4c, 0x0, 0xe0, 0x9, 0x61, 0xf0, 0x89, 0x32, 0x12, 0xcd, 0xd4, 0x8, 0xef, 0x1f, 0x35, 0x54, 0xa0, 0x68, 0x1a, 0x34, 0x89, 0x8, 0x86, 0xa4, 0xd, 0x57, 0xb4, 0xdf, 0x79, 0x5, 0x89, 0x94, 0xba, 0xf9, 0xb3, 0xc0, 0xce, 0xeb, 0xf0, 0x17, 0x1c, 0xab, 0x11, 0x9, 0x1a, 0xf9, 0x96, 0x84, 0x5d, 0x5e, 0x43, 0x15, 0x7, 0x2e, 0x42, 0x41, 0x51, 0xd3, 0xbe, 0x67, 0xd5, 0x6b, 0x42, 0x3a, 0x38, 0x9b, 0xf5, 0x2e, 0x20, 0xfa, 0x5, 0x33, 0x41, 0x69, 0xf4, 0xeb, 0x49, 0x6c, 0x19, 0xe6, 0xbd, 0xdd, 0xd, 0x48, 0xa0, 0x92, 0xb, 0x36, 0x72, 0x6a, 0x26, 0xf0, 0x14, 0xa, 0x10, 0x72, 0xe1, 0x7d, 0xf4, 0xf6, 0x35, 0x1b, 0xc3, 0xe3, 0x18, 0x9d, 0x50, 0xf0, 0xe4, 0xc2, 0x17, 0xae, 0x27, 0xd3, 0xe4, 0x6e, 0xe8, 0xf8, 0x7e, 0xbc, 0x1, 0x48, 0x9e, 0x57, 0xf8, 0xc5, 0xfc, 0xbd, 0x7a, 0x98, 0xc4, 0x94, 0x47, 0xbf, 0xe4, 0xce, 0x48, 0x8, 0x6e, 0x69, 0x91, 0x63, 0x47, 0x73, 0x49, 0xbc, 0x77, 0x3e, 0xd7, 0x4b, 0x3b, 0x12, 0x36, 0x16, 0xb3, 0x85, 0x6a, 0x68, 0xce, 0x39, 0x62, 0xc6, 0xba, 0x3d, 0x8d, 0xe7, 0x91, 0x20, 0xac, 0xad, 0xa6, 0xc2, 0xe, 0x6, 0xcc, 0x74, 0xc, 0x2d, 0xe7, 0xf9, 0x55, 0x2, 0x28, 0x94, 0x37, 0xab, 0xee, 0xa1, 0xcc, 0xbf, 0xdb, 0xed, 0x3, 0x70, 0xe6, 0x4f, 0x4a, 0xc3, 0xed, 0xed, 0xf3, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -270,18 +230,6 @@ static const unsigned char popup_bg_disabled_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x78, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0x67, 0x7a, 0x85, 0x66, 0x7a, 0x86, 0x68, 0x7b, 0x86, 0x57, 0x51, 0x51, 0x4c, 0x42, 0x40, 0x4d, 0x43, 0x41, 0x56, 0x4c, 0x4b, 0x4d, 0x44, 0x41, 0x4e, 0x44, 0x42, 0x4f, 0x45, 0x43, 0x67, 0x7b, 0x87, 0x4f, 0x44, 0x43, 0x50, 0x45, 0x44, 0x52, 0x46, 0x44, 0x51, 0x46, 0x45, 0x4b, 0x40, 0x3f, 0x51, 0x47, 0x45, 0x52, 0x48, 0x46, 0x53, 0x48, 0x47, 0x4b, 0x41, 0x3f, 0x54, 0x49, 0x46, 0x55, 0x4a, 0x47, 0x55, 0x49, 0x47, 0x68, 0x7c, 0x88, 0x4a, 0x40, 0x3e, 0x55, 0x4b, 0x49, 0x56, 0x4d, 0x4b, 0x53, 0x49, 0x47, 0x50, 0x46, 0x44, 0x4a, 0x41, 0x3e, 0x48, 0x3e, 0x3c, 0x4b, 0x42, 0x3f, 0x49, 0x3f, 0x3d, 0x46, 0x3d, 0x3c, 0x47, 0x3d, 0x3b, 0x47, 0x3e, 0x3b, 0x49, 0x40, 0x3d, 0x45, 0x3c, 0x3b, 0x46, 0x3c, 0x3a, 0xdd, 0x63, 0x56, 0x8d, 0x0, 0x0, 0x0, 0xad, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x2d, 0x88, 0x35, 0x42, 0x4, 0x0, 0xc, 0x4, 0x77, 0x93, 0x9c, 0xbb, 0xf4, 0xc8, 0xff, 0xdf, 0x84, 0xb5, 0xb8, 0x5b, 0x84, 0x0, 0x37, 0xc5, 0xca, 0x10, 0xd, 0xc9, 0xce, 0xaa, 0xea, 0x24, 0x40, 0xca, 0x41, 0x64, 0x2b, 0x5, 0x87, 0x34, 0xa8, 0x88, 0x54, 0xef, 0x82, 0x80, 0x89, 0x34, 0x36, 0x96, 0xe0, 0x14, 0xa4, 0x12, 0xa6, 0x24, 0x18, 0xe1, 0xa8, 0x50, 0x59, 0x7c, 0x73, 0x30, 0x50, 0x55, 0x4a, 0x31, 0xd7, 0xb4, 0x89, 0xa1, 0x51, 0xb2, 0x9c, 0x1, 0x2c, 0x4, 0x83, 0x15, 0x12, 0x30, 0xab, 0xe9, 0x5a, 0x1, 0xb4, 0x40, 0xa1, 0x29, 0xbe, 0x75, 0xe, 0x5a, 0x70, 0xbe, 0x2a, 0xff, 0x12, 0xf1, 0xef, 0x1b, 0x5f, 0x8d, 0x5b, 0x68, 0xd, 0xdc, 0xe3, 0xf1, 0x71, 0x16, 0x3e, 0x5b, 0xc8, 0x33, 0xa9, 0xc7, 0xbc, 0x7f, 0xa4, 0x22, 0x6a, 0xb5, 0x90, 0xcb, 0xb2, 0x1a, 0x25, 0x67, 0x8b, 0x8f, 0x6f, 0xf8, 0x64, 0xa8, 0x35, 0x7a, 0x25, 0xa8, 0xa7, 0x1, 0x38, 0xc, 0xcc, 0xab, 0x4c, 0x5, 0xea, 0xe3, 0x76, 0x2f, 0x54, 0x93, 0xf3, 0xf, 0x4f, 0x10, 0x8d, 0x4c, 0x16, 0x9d, 0xcf, 0x1f, 0xd1, 0xf9, 0x3, 0x34, 0xc8, 0x4a, 0xb4, 0x1d, 0xb, 0xcd, 0x83, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char popup_checked_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x56, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xc0, 0x3, 0x6e, 0xf0, 0xde, 0x3f, 0xf5, 0xe0, 0x30, 0x9c, 0xfb, 0x9f, 0xf1, 0xc1, 0xda, 0x7, 0xff, 0x1f, 0x9c, 0x85, 0xb, 0x3c, 0xa8, 0x1, 0x72, 0xdf, 0x3d, 0x56, 0x61, 0x78, 0x70, 0xf8, 0xc1, 0x99, 0x3b, 0x62, 0xf, 0xbc, 0x1e, 0xfc, 0x5, 0x42, 0x2f, 0xa0, 0xcc, 0xfd, 0x53, 0x40, 0x99, 0x6b, 0xf, 0xde, 0x3, 0xc9, 0x6a, 0xb0, 0x52, 0xa0, 0xec, 0xe5, 0x7, 0xff, 0x81, 0x70, 0xed, 0x7f, 0x46, 0x20, 0x17, 0x2a, 0x74, 0xfa, 0xc1, 0xb1, 0x1b, 0xbc, 0x10, 0x1e, 0x0, 0xfd, 0x1f, 0x33, 0x9, 0xf7, 0x50, 0x16, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const unsigned char popup_hover_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x2d, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0x20, 0x2e, 0x31, 0x83, 0xae, 0xb7, 0xb3, 0xd8, 0xe1, 0xaf, 0xd5, 0xde, 0xac, 0xd2, 0xdb, 0xa9, 0xcf, 0xd8, 0xa5, 0xcc, 0xd5, 0xa2, 0xc9, 0xd2, 0x9e, 0xc6, 0xcf, 0x9b, 0xc3, 0xcc, 0x97, 0xc0, 0xc9, 0x94, 0xbd, 0xc6, 0x91, 0xba, 0xc3, 0x8d, 0xb7, 0xc0, 0x9c, 0x2c, 0x91, 0xa9, 0x0, 0x0, 0x0, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x62, 0x14, 0x4, 0x3, 0x1, 0x26, 0x41, 0x28, 0x60, 0x62, 0x80, 0xd0, 0xc, 0x74, 0x61, 0x98, 0x80, 0x1, 0x3, 0xd3, 0x7b, 0x28, 0x0, 0x0, 0x1a, 0x86, 0xe, 0x98, 0x2c, 0x61, 0xda, 0x2e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const unsigned char popup_unchecked_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x18, 0x32, 0xe0, 0x0, 0x0, 0x0, 0x1, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0, 0x0, 0x0, 0xa, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x3, 0x0, 0x0, 0x10, 0x0, 0x1, 0xb3, 0xac, 0xe2, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char popup_window_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x46, 0x8, 0x3, 0x0, 0x0, 0x0, 0x8d, 0x2b, 0xf6, 0x48, 0x0, 0x0, 0x1, 0x6b, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xe8, 0xe5, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x1d, 0x22, 0x0, 0x0, 0x0, 0x1a, 0x19, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1e, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x1d, 0x21, 0x17, 0x16, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x1b, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x1e, 0x1c, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x20, 0x25, 0x20, 0x1e, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x20, 0x25, 0x0, 0x0, 0x0, 0x20, 0x20, 0x25, 0x20, 0x1d, 0x25, 0x20, 0x1d, 0x22, 0x1d, 0x1d, 0x22, 0x1d, 0x1d, 0x20, 0x1d, 0x1a, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0x30, 0x38, 0xe8, 0xe5, 0xf1, 0xe5, 0xe2, 0xeb, 0xe3, 0xe1, 0xe8, 0xe1, 0xdf, 0xe7, 0xe0, 0xde, 0xe6, 0xdf, 0xdd, 0xe5, 0xde, 0xdc, 0xe4, 0xdd, 0xdb, 0xe3, 0xdc, 0xda, 0xe2, 0xda, 0xd8, 0xe0, 0xd9, 0xd7, 0xdf, 0xd7, 0xd6, 0xdf, 0xd6, 0xd4, 0xdd, 0xd5, 0xd3, 0xdc, 0xd4, 0xd1, 0xdb, 0xd3, 0xd0, 0xda, 0xd1, 0xce, 0xd8, 0xd0, 0xcd, 0xd7, 0xcf, 0xcd, 0xd7, 0xe2, 0xdf, 0xeb, 0x48, 0x46, 0x51, 0x42, 0x40, 0x4b, 0x40, 0x3e, 0x48, 0x40, 0x3d, 0x48, 0x48, 0x45, 0x50, 0x42, 0x3f, 0x4a, 0x3f, 0x3d, 0x48, 0x47, 0x44, 0x50, 0x41, 0x3f, 0x4a, 0x3f, 0x3d, 0x47, 0x41, 0x3e, 0x49, 0x3f, 0x3c, 0x47, 0x46, 0x43, 0x4f, 0x3e, 0x3c, 0x46, 0x40, 0x3e, 0x49, 0x3d, 0x3b, 0x46, 0x45, 0x43, 0x4e, 0x3d, 0x3b, 0x45, 0x44, 0x42, 0x4d, 0x3d, 0x3a, 0x45, 0x3e, 0x3c, 0x47, 0x3c, 0x3a, 0x44, 0x43, 0x42, 0x4c, 0x43, 0x40, 0x4c, 0x3e, 0x3b, 0x46, 0x3b, 0x39, 0x43, 0x43, 0x3f, 0x4c, 0x43, 0x3f, 0x4b, 0x3a, 0x38, 0x42, 0x42, 0x3e, 0x4b, 0x42, 0x3e, 0x49, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3f, 0x3e, 0x48, 0x39, 0x37, 0x40, 0x38, 0x36, 0x40, 0x3e, 0x3d, 0x48, 0x38, 0x36, 0x3f, 0x3e, 0x3d, 0x47, 0x3a, 0x38, 0x41, 0x38, 0x35, 0x3f, 0x37, 0x35, 0x3e, 0x39, 0x36, 0x40, 0x37, 0x34, 0x3e, 0x3d, 0x3a, 0x46, 0x36, 0x34, 0x3d, 0x3d, 0x3a, 0x44, 0x37, 0x35, 0x3f, 0x35, 0x33, 0x3c, 0x46, 0x44, 0x4f, 0xac, 0xa5, 0x1, 0x25, 0x0, 0x0, 0x0, 0x33, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xa2, 0x3, 0x9, 0x17, 0xc, 0x20, 0xf, 0x2a, 0x5e, 0x12, 0x30, 0x68, 0x46, 0x20, 0x4e, 0xa2, 0x7d, 0x3a, 0x4f, 0xa4, 0x7d, 0x3f, 0x25, 0x60, 0xc0, 0xb8, 0x57, 0x1d, 0xba, 0x59, 0xbd, 0x5b, 0x22, 0xbf, 0x5e, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xa1, 0x9f, 0x9e, 0x52, 0x92, 0x15, 0x44, 0x7e, 0xd8, 0x5, 0xc7, 0xf4, 0xac, 0x0, 0x0, 0x1, 0x98, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xed, 0xd6, 0x55, 0x9e, 0x14, 0x31, 0x10, 0x80, 0xf1, 0xb2, 0x20, 0x1d, 0xdc, 0x9d, 0x3b, 0x2c, 0xa7, 0x87, 0x4b, 0xe0, 0xee, 0xd0, 0x82, 0xcb, 0xea, 0xb4, 0x86, 0x79, 0x23, 0x93, 0xaa, 0xcc, 0xf, 0xd7, 0xfd, 0x9e, 0xff, 0xed, 0x1d, 0x21, 0xf8, 0xe2, 0xfe, 0x1c, 0x8a, 0x17, 0x32, 0xa1, 0xa2, 0x2b, 0x48, 0x66, 0xb8, 0xa2, 0x28, 0x10, 0x9a, 0xd1, 0xf7, 0x3d, 0x16, 0x66, 0xfa, 0x45, 0x74, 0x9b, 0xd2, 0x97, 0x52, 0xe2, 0x2f, 0xa6, 0x40, 0x5f, 0x4c, 0x1d, 0xf3, 0x97, 0x52, 0x5e, 0x46, 0xf7, 0xee, 0xe3, 0x88, 0x8a, 0x48, 0x9e, 0x8a, 0xec, 0x8c, 0x28, 0x2c, 0xa7, 0xf0, 0x99, 0xd2, 0x6e, 0xe7, 0x8e, 0x10, 0x9b, 0xd1, 0x11, 0xe7, 0xe, 0xd1, 0x17, 0x8e, 0x2, 0xe6, 0x55, 0xf8, 0x42, 0x4a, 0x74, 0x18, 0xbe, 0xf8, 0xac, 0x9b, 0x5f, 0x4a, 0xb7, 0x36, 0x20, 0xa5, 0xf9, 0x2f, 0x90, 0x50, 0x11, 0x36, 0x13, 0x49, 0xa9, 0xe7, 0x6c, 0x5e, 0xcf, 0x2e, 0x99, 0xf4, 0xd, 0xb8, 0x8c, 0x5, 0xa7, 0x28, 0x8, 0x98, 0x9, 0x68, 0xba, 0x41, 0x66, 0x1b, 0x8a, 0xa2, 0xb0, 0x4d, 0x59, 0x30, 0xa5, 0x94, 0xa3, 0x94, 0x52, 0x0, 0x6f, 0x53, 0x6f, 0x7c, 0x82, 0x16, 0xcc, 0x5a, 0x51, 0x14, 0xbd, 0x98, 0x79, 0x4c, 0x29, 0x72, 0xee, 0xac, 0x8c, 0xea, 0xac, 0xb9, 0x51, 0xa0, 0xce, 0xa, 0x44, 0x60, 0x46, 0xa4, 0x28, 0x2, 0x9b, 0x1, 0x2a, 0x5a, 0xa, 0x9a, 0x49, 0xa9, 0xe8, 0x79, 0x20, 0x33, 0x38, 0xaf, 0x68, 0xc5, 0x68, 0xc6, 0x95, 0xa2, 0xe7, 0x72, 0x67, 0x3d, 0x97, 0x52, 0x24, 0xcf, 0x66, 0x9e, 0x30, 0xa5, 0xef, 0x5a, 0x34, 0x6b, 0xdf, 0xa5, 0x14, 0xa4, 0x0, 0xb3, 0x42, 0x8c, 0xe5, 0x38, 0x37, 0xb4, 0x14, 0x3d, 0xd2, 0xda, 0xb4, 0x3d, 0xa2, 0x68, 0xe3, 0xc0, 0xcc, 0x35, 0x8a, 0x9e, 0x86, 0x4c, 0xa7, 0x15, 0x85, 0x9d, 0x6c, 0xb6, 0x13, 0x16, 0xe8, 0x54, 0x78, 0xbc, 0x8e, 0x60, 0x86, 0xd7, 0xd1, 0x17, 0xd3, 0x37, 0x6e, 0x48, 0x30, 0x4f, 0x70, 0x81, 0xbe, 0xed, 0x97, 0xd1, 0xfe, 0x6d, 0x44, 0xf7, 0xed, 0xa7, 0x63, 0x39, 0x79, 0x8c, 0xf6, 0xef, 0x8b, 0xe8, 0x61, 0xe6, 0x8d, 0x55, 0x5b, 0xae, 0x9e, 0x62, 0x3e, 0x1c, 0xd1, 0x3b, 0xf7, 0x9b, 0xc7, 0xfb, 0x9b, 0xab, 0x46, 0xcd, 0xab, 0x4b, 0xcd, 0xfd, 0x3b, 0x11, 0x1d, 0xe, 0x76, 0xf5, 0xc5, 0x2b, 0xe5, 0xf3, 0x67, 0x49, 0xcf, 0xcb, 0x2b, 0x8f, 0xea, 0xee, 0xe0, 0x10, 0xd1, 0xf0, 0xb2, 0x58, 0xb, 0x61, 0x75, 0xd6, 0x26, 0xcd, 0x56, 0x43, 0x58, 0x2b, 0x5e, 0x86, 0x88, 0x4e, 0x63, 0x33, 0x84, 0xf7, 0x1f, 0x26, 0xd5, 0x87, 0xf7, 0x61, 0x68, 0xc6, 0x29, 0xa2, 0x73, 0xdb, 0x5e, 0x2d, 0x57, 0x1f, 0xab, 0x56, 0xcb, 0xab, 0xed, 0x5c, 0xfe, 0xc4, 0x5d, 0xf1, 0x27, 0x1a, 0x8f, 0xba, 0x8d, 0xd7, 0xa0, 0x9a, 0x40, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -302,22 +250,10 @@ static const unsigned char radio_unchecked_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4, 0x3, 0x4, 0x9, 0x9, 0x9, 0x6, 0x6, 0x6, 0xa, 0xa, 0xb, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x7f, 0x7f, 0x82, 0xd9, 0xd9, 0xd9, 0x47, 0x47, 0x48, 0x2b, 0x6e, 0xf2, 0xbf, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x88, 0xd1, 0xf7, 0x64, 0xf6, 0x2, 0xb3, 0xed, 0xd7, 0x0, 0x0, 0x0, 0x49, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x2, 0x61, 0x15, 0xed, 0xa9, 0x20, 0x5a, 0x72, 0xf5, 0x99, 0x33, 0xbb, 0x26, 0x1, 0x19, 0x73, 0xcf, 0x0, 0xc1, 0x4d, 0x6, 0x6, 0xd6, 0x35, 0x20, 0xc6, 0xa9, 0x0, 0x6, 0xb6, 0x3d, 0x20, 0xc6, 0xe9, 0x4, 0x6, 0xf6, 0x33, 0x60, 0x50, 0xc0, 0xc0, 0x1, 0x61, 0x34, 0xc0, 0x19, 0x70, 0x29, 0xb8, 0x62, 0xb8, 0x76, 0x84, 0x81, 0xc, 0x96, 0x20, 0x2b, 0xa6, 0xc0, 0x2d, 0x45, 0x0, 0x0, 0x37, 0xca, 0x3d, 0x81, 0xb4, 0x84, 0xb6, 0x80, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char reference_border_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x2, 0x3, 0x0, 0x0, 0x0, 0x62, 0x9d, 0x17, 0xf2, 0x0, 0x0, 0x0, 0xc, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xff, 0xd1, 0xd1, 0xff, 0xb7, 0xb7, 0xff, 0x41, 0x41, 0x2b, 0x2, 0x77, 0xea, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x0, 0x25, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x58, 0xff, 0xff, 0xff, 0x2f, 0x86, 0x6, 0x6, 0x6, 0x26, 0x86, 0xa3, 0xa1, 0xa1, 0xc1, 0xc, 0x47, 0x18, 0x18, 0x84, 0x49, 0x22, 0xc0, 0xda, 0xc0, 0x6, 0x80, 0x8d, 0x2, 0x0, 0x36, 0x2b, 0x14, 0x3d, 0x85, 0x39, 0x85, 0x31, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char scroll_bg_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x45, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x40, 0x3e, 0x4a, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x20, 0x20, 0x24, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1e, 0x1e, 0x23, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0x14, 0xee, 0x69, 0x20, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0x19, 0x40, 0x5d, 0x66, 0x28, 0x93, 0xf0, 0xfc, 0x94, 0xfc, 0xfd, 0x67, 0x1a, 0x96, 0x95, 0x1c, 0xf0, 0x43, 0x52, 0x0, 0x0, 0x0, 0x55, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x55, 0x8e, 0x45, 0x2, 0x80, 0x50, 0x10, 0x42, 0xc1, 0xee, 0xfb, 0x5f, 0xd4, 0xd6, 0xdf, 0xfd, 0x36, 0xd3, 0x3, 0x4, 0xd, 0x90, 0x6, 0xb2, 0x25, 0x39, 0xe0, 0xd2, 0xf9, 0xcb, 0x6a, 0x60, 0x6f, 0x27, 0xb7, 0xbc, 0x58, 0xb7, 0x53, 0x4d, 0x0, 0xf2, 0x3f, 0x5e, 0x36, 0x43, 0x5f, 0xc3, 0xf0, 0xdf, 0x17, 0xd7, 0xa6, 0xae, 0x60, 0x10, 0xff, 0x57, 0x16, 0xc5, 0x5a, 0xf1, 0x60, 0xe3, 0xe7, 0x5f, 0x37, 0x46, 0x74, 0xba, 0x9a, 0x16, 0xef, 0x37, 0x1c, 0x6f, 0x61, 0x47, 0x1, 0xa5, 0xc7, 0x32, 0x47, 0x38, 0x12, 0x92, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char scroll_button_down_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0x59, 0x59, 0x59, 0xb3, 0x52, 0xf2, 0x5, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xf1, 0x33, 0x66, 0x2, 0x1, 0x2a, 0xa3, 0x73, 0xe6, 0xcc, 0x19, 0x10, 0x35, 0x40, 0x1, 0x8, 0xa3, 0x73, 0x6, 0x1, 0x73, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0x5a, 0xfa, 0x3d, 0xf9, 0xfa, 0xe2, 0x64, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const unsigned char scroll_button_down_hl_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xce, 0xce, 0xce, 0x59, 0x59, 0x59, 0xb8, 0xf5, 0x6d, 0x48, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xf1, 0x33, 0x66, 0x2, 0x1, 0x2a, 0xa3, 0x73, 0xe6, 0xcc, 0x19, 0x10, 0x35, 0x40, 0x1, 0x8, 0xa3, 0x73, 0x6, 0x1, 0x73, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0x5a, 0xfa, 0x3d, 0xf9, 0xfa, 0xe2, 0x64, 0xe2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char scroll_button_left_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0x59, 0x59, 0x59, 0x8e, 0x47, 0x76, 0xf1, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x3e, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0x51, 0x19, 0x33, 0xa1, 0x8c, 0xae, 0x55, 0x50, 0xc6, 0x2e, 0x28, 0xa3, 0x7b, 0xf7, 0x6e, 0x8, 0xa3, 0xe7, 0xcc, 0x19, 0xa8, 0x14, 0x9c, 0xd1, 0x7b, 0x17, 0xa6, 0xfd, 0x1d, 0x86, 0x81, 0x60, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0xcc, 0x4e, 0x3f, 0xd1, 0x4, 0x90, 0xbf, 0x60, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -334,14 +270,6 @@ static const unsigned char scroll_button_right_hl_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0x2e, 0x3d, 0xb1, 0x1e, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x49, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0xc8, 0x31, 0x16, 0x2, 0x20, 0x10, 0x43, 0xc1, 0xe4, 0x83, 0xdc, 0xff, 0xb8, 0x88, 0xf, 0x57, 0xb, 0x8b, 0x80, 0x53, 0xe, 0xf2, 0x23, 0x18, 0xc6, 0x68, 0x61, 0x74, 0xca, 0xa, 0x2e, 0x74, 0xf9, 0x85, 0xfd, 0x17, 0x5c, 0x81, 0xfb, 0x11, 0x2a, 0xaa, 0x65, 0x80, 0x20, 0xc3, 0x5f, 0xaf, 0x2b, 0x96, 0xce, 0x78, 0xea, 0x88, 0x39, 0x95, 0x91, 0x70, 0x29, 0x94, 0xd9, 0x6b, 0x87, 0xf5, 0xfe, 0x0, 0xc6, 0xa7, 0x1b, 0x66, 0x7b, 0x42, 0xf1, 0x14, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char scroll_button_up_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0x59, 0x59, 0x59, 0xb3, 0x52, 0xf2, 0x5, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xb1, 0x33, 0x3a, 0x67, 0x40, 0x19, 0x33, 0x67, 0x42, 0x18, 0x9d, 0x33, 0x67, 0xce, 0x0, 0x33, 0x66, 0x2, 0x1, 0x2a, 0x3, 0x9f, 0x39, 0x10, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0x59, 0xc8, 0x3d, 0xf9, 0xf, 0x68, 0xc5, 0xa9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const unsigned char scroll_button_up_hl_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xce, 0xce, 0xce, 0x59, 0x59, 0x59, 0xb8, 0xf5, 0x6d, 0x48, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xb1, 0x33, 0x3a, 0x67, 0x40, 0x19, 0x33, 0x67, 0x42, 0x18, 0x9d, 0x33, 0x67, 0xce, 0x0, 0x33, 0x66, 0x2, 0x1, 0x2a, 0x3, 0x9f, 0x39, 0x10, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0x59, 0xc8, 0x3d, 0xf9, 0xf, 0x68, 0xc5, 0xa9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char scroll_grabber_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x5d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x5b, 0x59, 0x61, 0x5b, 0x59, 0x61, 0x5a, 0x58, 0x60, 0x59, 0x57, 0x5f, 0x5a, 0x58, 0x60, 0x5a, 0x58, 0x60, 0x57, 0x56, 0x5e, 0x58, 0x56, 0x5e, 0x56, 0x55, 0x5d, 0x57, 0x55, 0x5d, 0x57, 0x55, 0x5d, 0x55, 0x53, 0x5b, 0x55, 0x53, 0x5b, 0x54, 0x53, 0x5b, 0x55, 0x54, 0x5c, 0x54, 0x52, 0x5a, 0x55, 0x53, 0x5b, 0x5a, 0x58, 0x60, 0x56, 0x54, 0x5c, 0x54, 0x53, 0x5a, 0x55, 0x53, 0x5b, 0x53, 0x51, 0x59, 0x52, 0x51, 0x59, 0x52, 0x50, 0x58, 0x51, 0x50, 0x58, 0x51, 0x4f, 0x57, 0x50, 0x4e, 0x56, 0x4f, 0x4d, 0x55, 0x50, 0x4f, 0x57, 0x54, 0x52, 0x5a, 0xae, 0x55, 0xff, 0xf7, 0x0, 0x0, 0x0, 0x12, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x2c, 0xb8, 0xf4, 0x2e, 0xf2, 0xb8, 0xf4, 0xf5, 0xf4, 0xf5, 0xb8, 0x2f, 0xf2, 0x2e, 0xb8, 0xf4, 0xb8, 0x66, 0xf6, 0xf7, 0x12, 0x0, 0x0, 0x0, 0x48, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x64, 0xc7, 0xb1, 0x11, 0x80, 0x40, 0x8, 0x45, 0x41, 0xff, 0x83, 0x2, 0xe, 0xfb, 0x2f, 0x13, 0xe2, 0xf3, 0x6, 0x12, 0x1d, 0x37, 0x5b, 0xae, 0x97, 0x5f, 0x84, 0xdd, 0x68, 0xe2, 0x1e, 0x41, 0xb8, 0x77, 0x58, 0x6, 0xb6, 0xe8, 0x88, 0xd1, 0xe1, 0x93, 0xad, 0x63, 0xab, 0xa3, 0x3a, 0xa3, 0x26, 0xa9, 0x4a, 0x52, 0xf9, 0xc, 0x62, 0xcf, 0xa7, 0x8f, 0x1f, 0x1e, 0xbd, 0xff, 0x84, 0xee, 0x2, 0x0, 0x54, 0x76, 0x10, 0x19, 0x1e, 0xd7, 0x1d, 0x9b, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -422,10 +350,6 @@ static const unsigned char toggle_on_disabled_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0xa2, 0x9d, 0x7e, 0x84, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x12, 0x0, 0x0, 0xb, 0x12, 0x1, 0xd2, 0xdd, 0x7e, 0xfc, 0x0, 0x0, 0x6, 0x54, 0x49, 0x44, 0x41, 0x54, 0x68, 0x43, 0xed, 0x59, 0x4b, 0x6f, 0x1b, 0x55, 0x14, 0x3e, 0x71, 0xfc, 0x9a, 0xd8, 0x4e, 0x9c, 0x38, 0x6e, 0x62, 0xe7, 0x21, 0xb5, 0x6e, 0x51, 0xd5, 0x5, 0xa8, 0xac, 0x93, 0x14, 0x89, 0x22, 0x84, 0xba, 0x60, 0x53, 0xb1, 0x29, 0x12, 0x42, 0xa0, 0xfe, 0x1, 0x7e, 0x1, 0x7b, 0xb6, 0x6c, 0xaa, 0x82, 0xa8, 0xc4, 0x96, 0x5f, 0x50, 0x21, 0x55, 0x34, 0x1b, 0x4a, 0x17, 0x65, 0x51, 0x9, 0x85, 0x3c, 0x9b, 0xb4, 0x4d, 0xfd, 0x76, 0xfc, 0x7e, 0xf3, 0x7d, 0x37, 0x33, 0xc6, 0x76, 0xed, 0xcc, 0x38, 0x4e, 0x52, 0x21, 0x7a, 0xa4, 0xa3, 0xc9, 0x4c, 0xee, 0x3d, 0xf7, 0xbc, 0xee, 0xb9, 0xdf, 0x3d, 0x16, 0x79, 0x4b, 0x6f, 0x3d, 0xf0, 0xbf, 0xf6, 0xc0, 0xc8, 0x80, 0xd6, 0x73, 0xbc, 0xc1, 0x9c, 0x3a, 0xe8, 0xfc, 0x1, 0x97, 0xb3, 0x3c, 0xbc, 0xa9, 0x8f, 0xe4, 0xd3, 0x60, 0x4b, 0x93, 0xad, 0x1a, 0x60, 0x83, 0x34, 0xb2, 0xa3, 0x8d, 0x47, 0xf5, 0x6f, 0x56, 0x65, 0x58, 0x52, 0xe8, 0x18, 0x83, 0x68, 0x70, 0x3, 0x5c, 0x7, 0x57, 0xdb, 0x98, 0xdf, 0xc8, 0x47, 0x92, 0x99, 0xf2, 0xfc, 0x3f, 0xd, 0x75, 0x82, 0xbd, 0x60, 0xbf, 0xce, 0xe3, 0x78, 0x6a, 0xba, 0x33, 0xe8, 0x18, 0x33, 0x39, 0x66, 0x7a, 0x1c, 0xf7, 0xff, 0x86, 0xf1, 0x34, 0xbc, 0x8, 0x3e, 0x0, 0xa7, 0x75, 0xce, 0xe1, 0x59, 0xd1, 0x1d, 0x63, 0x64, 0xc8, 0x6b, 0xeb, 0x1c, 0xa5, 0x38, 0xd, 0xb3, 0xeb, 0x86, 0x7, 0xf1, 0x9c, 0xf7, 0xf9, 0x26, 0x96, 0xc1, 0x1f, 0x39, 0x9d, 0xce, 0xb, 0x36, 0xdb, 0xe8, 0xb8, 0xcd, 0x66, 0xd3, 0x46, 0x40, 0xc7, 0xd5, 0xfe, 0x24, 0xe6, 0x35, 0x41, 0x8d, 0x46, 0xa3, 0xd8, 0x68, 0xd4, 0xf, 0x2a, 0x95, 0xca, 0x66, 0x36, 0x9b, 0xb9, 0xf, 0x7e, 0x8, 0xd9, 0x7b, 0xe0, 0x18, 0x98, 0x8e, 0xa8, 0xf5, 0xcb, 0x86, 0x7e, 0xca, 0xd3, 0x78, 0x46, 0x7d, 0x2, 0xbc, 0x38, 0x36, 0xe6, 0x5d, 0x9, 0x4, 0x82, 0xb7, 0x5d, 0x2e, 0xf7, 0x3b, 0x6f, 0xd8, 0x5e, 0x53, 0x9f, 0xc1, 0x1f, 0x52, 0x2e, 0x97, 0xd6, 0x12, 0x89, 0xd8, 0x9d, 0x42, 0x21, 0xf7, 0x1b, 0x26, 0x3c, 0x3, 0x67, 0xf4, 0x6c, 0x78, 0x6d, 0x4b, 0xf4, 0x72, 0x0, 0xbf, 0xd1, 0xf8, 0x49, 0xf0, 0x85, 0xc9, 0xc9, 0xe9, 0xcf, 0xa7, 0xa6, 0xa6, 0xbf, 0x42, 0xb4, 0xf9, 0xed, 0x4c, 0x49, 0xd3, 0xec, 0x32, 0x3b, 0x3b, 0x2b, 0x93, 0x93, 0x93, 0xa2, 0x69, 0x9a, 0x40, 0x87, 0xbe, 0xeb, 0xd7, 0x6a, 0x35, 0x89, 0xc7, 0xe3, 0xb2, 0xb7, 0xb7, 0x27, 0xc5, 0x62, 0x4d, 0x90, 0x15, 0x95, 0x64, 0x32, 0xfe, 0x43, 0x2a, 0x15, 0xff, 0x19, 0x93, 0x36, 0xc1, 0x29, 0xdd, 0x9, 0x1d, 0xdb, 0xa1, 0xdb, 0x1, 0xc6, 0x9e, 0x67, 0xe4, 0x23, 0x53, 0x53, 0xc1, 0xaf, 0x61, 0xfc, 0xd7, 0x67, 0x9e, 0xe6, 0xb6, 0x51, 0x59, 0x98, 0xb, 0xca, 0xcc, 0xcc, 0x8c, 0x24, 0x12, 0x9, 0x65, 0x58, 0x36, 0x87, 0x6d, 0xde, 0xec, 0x51, 0xd3, 0xb0, 0x3, 0x35, 0xb7, 0x4d, 0x3c, 0x1e, 0x8f, 0xf8, 0xfd, 0x7e, 0xe5, 0xac, 0xfd, 0xfd, 0x7d, 0xd9, 0x7d, 0x1e, 0x93, 0x66, 0xbd, 0xd6, 0x84, 0x13, 0xee, 0x26, 0x93, 0xb1, 0xbb, 0xb0, 0x67, 0x43, 0xcf, 0x4, 0x16, 0xcb, 0x96, 0x13, 0x58, 0xe0, 0xda, 0x89, 0x2e, 0x76, 0x83, 0x43, 0x1e, 0x8f, 0xef, 0xe3, 0x60, 0x70, 0xe6, 0x1b, 0x78, 0xbd, 0x7b, 0xcc, 0xe9, 0x66, 0x1, 0x96, 0x8b, 0x9c, 0x9f, 0x93, 0x89, 0x89, 0x9, 0xd9, 0xdc, 0xdc, 0x84, 0x31, 0x9, 0xa9, 0x54, 0xb8, 0x85, 0xfb, 0xd5, 0xb1, 0xa6, 0xd4, 0x6a, 0xd, 0x29, 0x14, 0xca, 0x92, 0x4c, 0x66, 0xf0, 0xcc, 0x4a, 0x28, 0x14, 0x12, 0xaf, 0xc7, 0x2d, 0xa9, 0x4c, 0x7e, 0xc4, 0xed, 0x72, 0xbd, 0x57, 0xa9, 0x94, 0xb7, 0xaa, 0xd5, 0xca, 0x2e, 0x84, 0xe4, 0xc1, 0x1d, 0xc2, 0xba, 0x8d, 0xe3, 0x3b, 0x2b, 0xfd, 0xa5, 0x50, 0x68, 0xfe, 0x5b, 0x87, 0xc3, 0x11, 0x38, 0x5d, 0x6b, 0xbb, 0xa4, 0x23, 0x9a, 0xe1, 0x50, 0x40, 0x45, 0x71, 0x6d, 0x6d, 0x4d, 0x72, 0xb9, 0xf2, 0xc0, 0xcb, 0x97, 0x4a, 0x55, 0x39, 0x38, 0x48, 0x29, 0x27, 0x8c, 0xda, 0x9a, 0x92, 0xcb, 0x97, 0x6c, 0x28, 0xda, 0x91, 0x4c, 0x26, 0xc5, 0x7a, 0xc0, 0x6d, 0x40, 0xa1, 0x2d, 0x6f, 0xb6, 0x6f, 0x2a, 0xa6, 0x3f, 0xcf, 0xf9, 0x89, 0xf1, 0x71, 0xff, 0xa, 0xa, 0xde, 0xf9, 0x81, 0x57, 0x1f, 0x72, 0x82, 0xcb, 0x39, 0xa2, 0x14, 0xdf, 0xd9, 0xd9, 0x51, 0xfb, 0xf8, 0xb8, 0xc4, 0xb9, 0x94, 0x11, 0xe, 0x87, 0x85, 0x32, 0x69, 0xb, 0x6c, 0x5a, 0xa6, 0x6d, 0x60, 0x9e, 0x6c, 0x2d, 0xea, 0xe5, 0x0, 0xbf, 0xd7, 0x3b, 0x7e, 0xdd, 0xea, 0xe2, 0x73, 0x73, 0x61, 0xb9, 0x7a, 0xf5, 0x5d, 0xb9, 0x75, 0xeb, 0x33, 0xb9, 0x79, 0xf3, 0x53, 0xec, 0xdb, 0xc3, 0xa4, 0xd1, 0x34, 0xa7, 0xfa, 0x66, 0x43, 0x14, 0x8c, 0xf7, 0x6b, 0xd7, 0x96, 0x8e, 0x14, 0x1b, 0xc, 0x6, 0x11, 0xbd, 0x3, 0x49, 0xa7, 0x99, 0xa9, 0xc3, 0x11, 0x65, 0x64, 0x32, 0x19, 0xa1, 0x4c, 0x92, 0xd7, 0xeb, 0xa3, 0x4d, 0x2c, 0xec, 0x2c, 0xe6, 0xad, 0xda, 0xd7, 0xcb, 0x1, 0xe3, 0x48, 0x19, 0xcb, 0xd1, 0xbf, 0x78, 0xf1, 0x2, 0x3c, 0xec, 0x92, 0x7, 0xf, 0x56, 0xe5, 0xfe, 0xfd, 0x5f, 0xe5, 0xfa, 0xf5, 0xf, 0x85, 0x4e, 0x31, 0x68, 0x79, 0x99, 0x8e, 0xb7, 0x46, 0x4c, 0xfd, 0x74, 0x9a, 0x38, 0xe6, 0x64, 0x88, 0xb2, 0x28, 0x93, 0xe4, 0x74, 0xba, 0x22, 0x78, 0x10, 0xc0, 0x31, 0x3, 0x7a, 0x3a, 0x80, 0xe3, 0x58, 0x3, 0xdc, 0x4, 0x39, 0x56, 0x54, 0xa0, 0xa1, 0xf3, 0xf3, 0x61, 0x79, 0xfa, 0xf4, 0x2f, 0x79, 0xfe, 0xfc, 0x5, 0x3c, 0x9e, 0x93, 0x8d, 0x8d, 0x2d, 0x44, 0xfd, 0x70, 0x76, 0x34, 0x9a, 0x40, 0x4, 0x2, 0x2a, 0x1b, 0xac, 0x10, 0x8f, 0xba, 0x7c, 0x7e, 0xf8, 0xe8, 0x1b, 0x6b, 0x51, 0x16, 0x65, 0x2a, 0xc3, 0x46, 0xed, 0xac, 0x6d, 0x7c, 0xa1, 0x8d, 0x7d, 0x1d, 0xa0, 0x8e, 0x41, 0x22, 0x3c, 0x2b, 0xa, 0xe3, 0x88, 0x51, 0x46, 0x66, 0xb3, 0xd9, 0xd6, 0xf0, 0x78, 0x3c, 0x26, 0xd3, 0xd3, 0xd3, 0xea, 0x1d, 0xd5, 0x57, 0x9e, 0x3c, 0xf9, 0x53, 0x96, 0x96, 0xac, 0x65, 0x1, 0x8a, 0xae, 0x14, 0x8a, 0xa6, 0xf0, 0xdd, 0x8a, 0x6a, 0x6a, 0xc, 0x65, 0x51, 0x26, 0x49, 0xc7, 0x31, 0xaf, 0xc1, 0xf6, 0x6e, 0x64, 0xa1, 0xb0, 0x35, 0xd0, 0x14, 0xb1, 0xb5, 0x29, 0xd9, 0xed, 0x2e, 0x39, 0x77, 0x2e, 0x20, 0x3e, 0x9f, 0xaf, 0x35, 0xd6, 0xe7, 0x1b, 0x57, 0x86, 0x1b, 0xb4, 0xbe, 0xbe, 0xcd, 0xf4, 0x93, 0xcb, 0x97, 0x2f, 0x9b, 0xca, 0xab, 0x56, 0xab, 0x32, 0xa6, 0xf5, 0x7, 0x3b, 0xa6, 0x2, 0xba, 0x6, 0x50, 0x16, 0x65, 0x92, 0x8, 0x8c, 0xf8, 0x0, 0x77, 0x9c, 0xa7, 0xdd, 0xab, 0x11, 0x24, 0x14, 0xeb, 0xf5, 0x9a, 0xa5, 0x8d, 0xc8, 0xc8, 0x33, 0x3, 0xfc, 0xfe, 0x43, 0x7, 0xd0, 0x11, 0x91, 0xc8, 0x79, 0x5, 0x5c, 0xda, 0xe9, 0xf1, 0xe3, 0xdf, 0xe5, 0xca, 0x15, 0x73, 0x7, 0x14, 0x8b, 0x45, 0x5, 0x68, 0x4e, 0x8a, 0x28, 0x8b, 0x32, 0x49, 0xba, 0x4d, 0x7c, 0xe9, 0x0, 0x42, 0xed, 0x47, 0x2, 0x3d, 0x43, 0x77, 0x65, 0x71, 0xa9, 0xd8, 0x70, 0x38, 0x9c, 0xe7, 0xac, 0x28, 0xb2, 0xba, 0xfa, 0x50, 0x6e, 0xdc, 0xf8, 0x4, 0x11, 0xce, 0x1, 0xbc, 0x78, 0x55, 0xd, 0x78, 0xf5, 0x2a, 0xd1, 0xb1, 0xef, 0xf9, 0x4e, 0x47, 0x99, 0x51, 0x2a, 0x95, 0x52, 0x68, 0x2e, 0x16, 0xb3, 0xe4, 0x7f, 0x33, 0x71, 0x4a, 0x16, 0x65, 0x92, 0x90, 0x95, 0x44, 0x82, 0xbc, 0x2d, 0x1e, 0x9, 0x84, 0xd4, 0x25, 0x8, 0xd0, 0xd7, 0x87, 0x63, 0x63, 0xc5, 0x74, 0x5, 0x4a, 0xab, 0xd5, 0x65, 0x77, 0xf7, 0x5, 0x40, 0xcb, 0x81, 0x3c, 0x7a, 0xf4, 0x87, 0xbc, 0x7c, 0x19, 0x55, 0xd3, 0x8, 0x63, 0xa3, 0xd1, 0x7d, 0x14, 0xb5, 0xc3, 0x8, 0x6c, 0x6f, 0x6f, 0x22, 0x1a, 0x85, 0xd6, 0x7b, 0x2f, 0xd9, 0xe5, 0x72, 0x51, 0x16, 0x16, 0x16, 0x30, 0x2e, 0x27, 0x4, 0x34, 0xc3, 0x90, 0xdf, 0xef, 0x51, 0x38, 0x60, 0x6b, 0x6b, 0xb, 0xd1, 0x6f, 0xc2, 0x11, 0x89, 0x7b, 0xb8, 0x24, 0x3d, 0x82, 0xcc, 0xa4, 0xee, 0x4, 0x25, 0xbe, 0x17, 0xcc, 0xb5, 0x61, 0x60, 0x11, 0xe, 0x58, 0xb6, 0xdb, 0xed, 0x87, 0x67, 0x88, 0x9, 0x21, 0x63, 0x70, 0x7e, 0x67, 0xa5, 0xd9, 0xfc, 0xf7, 0x6a, 0xc1, 0xed, 0x61, 0x18, 0xcf, 0xe9, 0xfc, 0x5f, 0xfb, 0x7b, 0x2f, 0x91, 0x75, 0xec, 0xd0, 0x11, 0x6c, 0x53, 0x2a, 0x4e, 0x34, 0x47, 0x88, 0x7b, 0x1c, 0xe2, 0x25, 0x2a, 0x12, 0x89, 0x20, 0x13, 0x5f, 0x49, 0x3a, 0x53, 0xe0, 0xed, 0x70, 0x2b, 0x1a, 0x7d, 0xf9, 0x3d, 0x64, 0xed, 0x80, 0x79, 0xcc, 0xb4, 0x4, 0xf7, 0x72, 0x0, 0xb7, 0xc2, 0x8, 0x6e, 0x57, 0x39, 0xdc, 0x7, 0x3e, 0x40, 0x36, 0x9c, 0x5c, 0x55, 0xb2, 0x60, 0x4d, 0x36, 0x5f, 0x56, 0x38, 0x9e, 0x88, 0xb0, 0x54, 0xca, 0x43, 0xf9, 0xc1, 0x32, 0x81, 0x91, 0xa7, 0xf1, 0xb9, 0x5c, 0x4e, 0x9e, 0xed, 0x45, 0xa5, 0x51, 0xaf, 0xd5, 0x62, 0xb1, 0xfd, 0xef, 0x70, 0x17, 0x60, 0xf4, 0x59, 0x9c, 0x58, 0xc, 0xfb, 0x5e, 0x86, 0xa8, 0xa2, 0x6a, 0x2f, 0x61, 0x42, 0x86, 0xc6, 0x6b, 0xda, 0xd8, 0xfb, 0x67, 0x7a, 0x1b, 0xc4, 0x7d, 0x3e, 0x5, 0x3c, 0xe1, 0x74, 0xd8, 0x64, 0x71, 0x71, 0x11, 0x20, 0xcb, 0x81, 0x14, 0xae, 0x48, 0xa5, 0x6a, 0xe8, 0xdc, 0xde, 0x96, 0xc4, 0xdf, 0x88, 0x8f, 0xa6, 0x8d, 0xaa, 0x42, 0x1c, 0xe, 0xcf, 0x2, 0x84, 0xcd, 0xa1, 0x86, 0xc4, 0x64, 0xfb, 0xd9, 0xbe, 0xba, 0xd, 0x22, 0xf5, 0x7f, 0x44, 0x36, 0xfd, 0x2, 0x9b, 0xd8, 0x20, 0xe9, 0x88, 0x3e, 0x8d, 0x35, 0xeb, 0x7, 0x44, 0xd0, 0x8, 0xf9, 0xd2, 0xef, 0xf, 0x7c, 0x81, 0x73, 0xb4, 0x3, 0x43, 0x5b, 0x8, 0xe6, 0xd0, 0x43, 0x86, 0xec, 0x7, 0xd4, 0xd2, 0xe9, 0xc4, 0x3d, 0x34, 0x46, 0x7e, 0x82, 0x22, 0xeb, 0x60, 0x4b, 0xfd, 0x0, 0x43, 0x69, 0xa3, 0x23, 0x44, 0xf4, 0xb4, 0xe8, 0xf1, 0x78, 0x57, 0xd0, 0x1b, 0xb8, 0xed, 0x76, 0x6b, 0x97, 0x86, 0xb6, 0xea, 0xc, 0x4, 0x94, 0x4a, 0xc5, 0xbf, 0xd1, 0x3, 0xb8, 0x93, 0xcf, 0xb7, 0x3a, 0x42, 0x3c, 0x56, 0xc, 0x1c, 0xd0, 0xa1, 0x81, 0x59, 0x4f, 0x90, 0x30, 0x8a, 0xcd, 0x50, 0x42, 0xbb, 0x5, 0xf4, 0x3, 0x97, 0xf4, 0x9e, 0xe0, 0x45, 0x42, 0xcb, 0x37, 0xd1, 0x25, 0xea, 0xe5, 0x3f, 0x82, 0x1c, 0x9e, 0xf3, 0x28, 0xc6, 0xeb, 0x7a, 0x4f, 0x70, 0x15, 0xe3, 0x78, 0xff, 0xe7, 0x9e, 0x67, 0x4f, 0x90, 0x85, 0xa4, 0x67, 0x45, 0x35, 0x6b, 0x68, 0x1a, 0x1d, 0x22, 0x17, 0x4, 0x10, 0xa1, 0x30, 0x23, 0x78, 0x32, 0x74, 0x77, 0x85, 0xcf, 0x20, 0xae, 0x7d, 0x97, 0xa0, 0x61, 0xed, 0x5d, 0x61, 0xa6, 0x3a, 0x23, 0xce, 0xfd, 0x4e, 0x48, 0xda, 0x1, 0x7c, 0xba, 0xa5, 0x98, 0x39, 0x80, 0xe3, 0x8d, 0xaa, 0xc3, 0x13, 0x83, 0x75, 0x80, 0x37, 0x1b, 0x66, 0x86, 0x71, 0xa9, 0xb0, 0x22, 0xe3, 0x34, 0x1d, 0x64, 0xfc, 0x10, 0x62, 0xfc, 0x2e, 0xc0, 0x54, 0x27, 0xd8, 0x31, 0xc, 0xef, 0xdb, 0x12, 0x37, 0x8c, 0x1b, 0x44, 0xb9, 0xae, 0x12, 0x3c, 0xc8, 0xd4, 0x53, 0x1f, 0xdb, 0xfe, 0xab, 0xd0, 0x91, 0x46, 0x9f, 0xba, 0x26, 0x6f, 0x17, 0xf8, 0xf, 0x79, 0xe0, 0x1f, 0xd, 0x80, 0x80, 0xb4, 0xad, 0xe9, 0x2a, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char tool_button_pressed_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x1, 0xfe, 0x50, 0x4c, 0x54, 0x45, 0x29, 0x3a, 0x40, 0x2d, 0x3e, 0x44, 0x26, 0x34, 0x3b, 0x24, 0x34, 0x39, 0x23, 0x31, 0x38, 0x22, 0x31, 0x37, 0x22, 0x31, 0x37, 0x22, 0x30, 0x36, 0x22, 0x31, 0x36, 0x26, 0x34, 0x3c, 0x32, 0x44, 0x4c, 0x26, 0x34, 0x39, 0x23, 0x31, 0x36, 0x21, 0x2e, 0x34, 0x1f, 0x2c, 0x30, 0x1f, 0x2b, 0x2f, 0x1f, 0x2a, 0x2e, 0x1e, 0x2b, 0x2f, 0x1f, 0x2b, 0x2e, 0x36, 0x4b, 0x52, 0x25, 0x33, 0x38, 0x20, 0x2f, 0x32, 0x1c, 0x29, 0x2e, 0x1b, 0x26, 0x2a, 0x1a, 0x23, 0x26, 0x18, 0x22, 0x26, 0x19, 0x22, 0x26, 0x19, 0x23, 0x26, 0x19, 0x26, 0x29, 0x20, 0x2d, 0x32, 0x25, 0x31, 0x38, 0x3c, 0x51, 0x59, 0x23, 0x31, 0x37, 0x1f, 0x2b, 0x31, 0x1a, 0x25, 0x2b, 0x17, 0x20, 0x24, 0x15, 0x1c, 0x21, 0x14, 0x1b, 0x21, 0x14, 0x1c, 0x21, 0x13, 0x1b, 0x21, 0x15, 0x1d, 0x21, 0x1a, 0x25, 0x2a, 0x40, 0x57, 0x60, 0x23, 0x31, 0x36, 0x1f, 0x2b, 0x31, 0x1b, 0x25, 0x29, 0x16, 0x1e, 0x23, 0x14, 0x1b, 0x1d, 0x12, 0x19, 0x1d, 0x12, 0x1b, 0x1d, 0x14, 0x1a, 0x1d, 0x45, 0x5e, 0x67, 0x22, 0x32, 0x37, 0x20, 0x2d, 0x31, 0x1a, 0x26, 0x2a, 0x15, 0x1f, 0x25, 0x14, 0x1c, 0x1f, 0x12, 0x1b, 0x1f, 0x12, 0x1b, 0x20, 0x14, 0x1b, 0x1f, 0x15, 0x1e, 0x24, 0x1a, 0x25, 0x29, 0x4b, 0x64, 0x6d, 0x23, 0x32, 0x38, 0x20, 0x2e, 0x32, 0x1b, 0x27, 0x2b, 0x17, 0x22, 0x27, 0x16, 0x1e, 0x23, 0x14, 0x1e, 0x23, 0x16, 0x20, 0x24, 0x14, 0x1e, 0x22, 0x15, 0x1e, 0x22, 0x17, 0x21, 0x27, 0x1c, 0x27, 0x2c, 0x4f, 0x6a, 0x75, 0x21, 0x2f, 0x33, 0x1d, 0x29, 0x2d, 0x19, 0x23, 0x2a, 0x18, 0x22, 0x27, 0x16, 0x21, 0x27, 0x18, 0x23, 0x29, 0x17, 0x21, 0x26, 0x19, 0x23, 0x29, 0x1c, 0x28, 0x2d, 0x21, 0x2e, 0x33, 0x54, 0x70, 0x7c, 0x23, 0x33, 0x38, 0x22, 0x30, 0x34, 0x1e, 0x2a, 0x2f, 0x1a, 0x26, 0x2d, 0x1a, 0x25, 0x2b, 0x19, 0x25, 0x2b, 0x1a, 0x26, 0x2d, 0x1a, 0x26, 0x2c, 0x18, 0x25, 0x2a, 0x1a, 0x24, 0x2a, 0x1a, 0x25, 0x2c, 0x1d, 0x2a, 0x2f, 0x22, 0x2f, 0x34, 0x59, 0x77, 0x82, 0x23, 0x33, 0x39, 0x22, 0x30, 0x35, 0x1f, 0x2c, 0x31, 0x1c, 0x28, 0x30, 0x1c, 0x28, 0x2e, 0x1b, 0x29, 0x2f, 0x1c, 0x2a, 0x31, 0x1b, 0x28, 0x2f, 0x1c, 0x28, 0x2d, 0x1b, 0x27, 0x2f, 0x1f, 0x2b, 0x31, 0x5e, 0x7d, 0x8a, 0x24, 0x34, 0x39, 0x21, 0x2f, 0x37, 0x20, 0x2d, 0x34, 0x1d, 0x2b, 0x33, 0x1d, 0x2b, 0x32, 0x1d, 0x2d, 0x35, 0x1e, 0x2e, 0x36, 0x1f, 0x2e, 0x36, 0x1d, 0x2b, 0x34, 0x1d, 0x2b, 0x31, 0x1d, 0x2b, 0x32, 0x20, 0x2d, 0x32, 0x21, 0x2f, 0x36, 0x63, 0x83, 0x90, 0x25, 0x34, 0x39, 0x21, 0x31, 0x36, 0x1f, 0x2e, 0x34, 0x1f, 0x2e, 0x34, 0x1f, 0x2e, 0x36, 0x20, 0x31, 0x39, 0x21, 0x33, 0x3b, 0x21, 0x32, 0x3b, 0x1f, 0x30, 0x37, 0x1f, 0x2e, 0x35, 0x1e, 0x2d, 0x33, 0x1f, 0x2d, 0x33, 0x21, 0x30, 0x36, 0x67, 0x8a, 0x97, 0x24, 0x33, 0x39, 0x20, 0x30, 0x36, 0x1f, 0x2f, 0x35, 0x21, 0x30, 0x37, 0x22, 0x32, 0x39, 0x21, 0x35, 0x3e, 0x24, 0x37, 0x41, 0x24, 0x36, 0x41, 0x21, 0x33, 0x3c, 0x21, 0x31, 0x38, 0x1e, 0x2f, 0x35, 0x1e, 0x2e, 0x35, 0x20, 0x2e, 0x35, 0x24, 0x31, 0x39, 0x6c, 0x90, 0x9e, 0x22, 0x30, 0x36, 0x1f, 0x2e, 0x36, 0x20, 0x30, 0x36, 0x20, 0x31, 0x39, 0x23, 0x34, 0x3d, 0x23, 0x37, 0x41, 0x26, 0x3c, 0x47, 0x26, 0x3b, 0x46, 0x22, 0x35, 0x3f, 0x22, 0x32, 0x3b, 0x1f, 0x30, 0x37, 0x1f, 0x2e, 0x35, 0x1f, 0x2d, 0x35, 0x21, 0x30, 0x36, 0x72, 0x96, 0xa5, 0x7e, 0x8c, 0xc3, 0xb0, 0x0, 0x0, 0x0, 0xaa, 0x74, 0x52, 0x4e, 0x53, 0xc3, 0xc3, 0xe6, 0xd7, 0xcb, 0xc3, 0xbf, 0xbe, 0xbd, 0xe5, 0xc3, 0xd7, 0xc0, 0xac, 0xa0, 0x9a, 0x98, 0x98, 0x98, 0xc3, 0xcb, 0xac, 0x92, 0x82, 0x7b, 0x78, 0x78, 0x7b, 0x82, 0xac, 0xcb, 0xc3, 0xc3, 0xa0, 0x82, 0x6f, 0x67, 0x64, 0x63, 0x64, 0x67, 0x82, 0xc3, 0xbf, 0x9a, 0x7a, 0x67, 0x5e, 0x5b, 0x5a, 0x5e, 0xc3, 0xbd, 0x98, 0x78, 0x64, 0x5b, 0x57, 0x57, 0x5b, 0x64, 0x78, 0xc3, 0xbd, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x57, 0x5a, 0x63, 0x77, 0xc3, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x5a, 0x63, 0x77, 0x98, 0xc3, 0xbd, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x5a, 0x63, 0x77, 0x98, 0xc3, 0xbd, 0x98, 0x77, 0x63, 0x5a, 0x57, 0x56, 0x57, 0x5a, 0x63, 0x77, 0xc3, 0xbb, 0x96, 0x76, 0x63, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x5a, 0x63, 0x76, 0x96, 0xc3, 0xb5, 0x92, 0x75, 0x62, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x59, 0x62, 0x74, 0x92, 0xc3, 0xa9, 0x8b, 0x71, 0x61, 0x59, 0x57, 0x56, 0x56, 0x57, 0x59, 0x61, 0x71, 0x8b, 0xa9, 0xc3, 0x95, 0x7e, 0x6b, 0x5e, 0x59, 0x57, 0x56, 0x56, 0x57, 0x59, 0x5e, 0x6b, 0x7e, 0x95, 0xc3, 0x4f, 0x78, 0x99, 0x30, 0x0, 0x0, 0x0, 0x67, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x5c, 0x8b, 0x5, 0x2, 0xc3, 0x30, 0xc, 0xc4, 0x72, 0x5d, 0x39, 0xf4, 0xff, 0x67, 0x8e, 0x79, 0x1a, 0x37, 0xa0, 0xa0, 0x6d, 0x5d, 0x6b, 0x2a, 0x5a, 0xfd, 0x30, 0xe6, 0x1, 0xf4, 0xa7, 0x76, 0xfa, 0x37, 0x74, 0x7, 0x98, 0x52, 0x83, 0x46, 0x97, 0x41, 0xfb, 0xd6, 0x2d, 0x86, 0xae, 0xfe, 0x84, 0x6b, 0x6d, 0x32, 0x6e, 0x58, 0x28, 0x22, 0x3a, 0x41, 0x32, 0xde, 0xd7, 0x6a, 0x67, 0x5b, 0xb7, 0xb7, 0xc9, 0xb0, 0xd8, 0xd6, 0x3a, 0x65, 0x34, 0xb4, 0x21, 0x8f, 0x1c, 0x3, 0x6d, 0x21, 0x84, 0x5d, 0x32, 0x8a, 0x48, 0x22, 0x6e, 0xda, 0xa8, 0x92, 0x36, 0x3e, 0x87, 0xea, 0x7b, 0x7e, 0x0, 0x62, 0xa8, 0x25, 0xad, 0x68, 0x1d, 0x7d, 0x1a, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char tooltip_bg_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0xdd, 0xdd, 0xdd, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0xbc, 0x3, 0x4f, 0xe9, 0x0, 0x0, 0x0, 0xd, 0x74, 0x52, 0x4e, 0x53, 0xa, 0x1a, 0x26, 0x29, 0x2a, 0x48, 0x65, 0x6d, 0x6e, 0x66, 0xf5, 0xfe, 0xcc, 0xff, 0xb7, 0x4a, 0xbe, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x60, 0x54, 0x76, 0x1, 0x2, 0x23, 0x1, 0x6, 0xd1, 0xf4, 0xe, 0x20, 0x28, 0xb, 0x64, 0xd0, 0x5c, 0x7d, 0x17, 0x8, 0x76, 0x4d, 0x62, 0x70, 0x7f, 0x7f, 0x6, 0x8, 0xfe, 0x95, 0x30, 0x78, 0xdc, 0x1, 0x31, 0xce, 0xb6, 0x50, 0xc8, 0x80, 0x1b, 0x8, 0xb7, 0x2, 0x6e, 0x29, 0xdc, 0x19, 0x0, 0xcf, 0x24, 0x4d, 0xb3, 0xd0, 0x4d, 0xb9, 0x40, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; @@ -438,18 +362,6 @@ static const unsigned char tree_bg_disabled_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x4e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x94, 0xc8, 0x67, 0x6b, 0x60, 0xe6, 0x60, 0x64, 0x80, 0x80, 0xff, 0xc, 0x7f, 0x7f, 0xfc, 0x6a, 0x60, 0x94, 0xfb, 0xc0, 0xce, 0xcf, 0xc2, 0x80, 0x10, 0xfc, 0xc3, 0xf0, 0xf3, 0x23, 0xa3, 0xe2, 0x4f, 0xe, 0x36, 0x54, 0xc1, 0x1f, 0xbf, 0x18, 0x95, 0xbe, 0x73, 0x70, 0xb0, 0x30, 0xc0, 0x1, 0x48, 0xf0, 0x7, 0x85, 0x82, 0x58, 0x2d, 0xc2, 0xe6, 0xa4, 0x4f, 0x20, 0xc7, 0x37, 0x32, 0xb3, 0x23, 0x39, 0xfe, 0xfb, 0xaf, 0x46, 0x0, 0xee, 0x2a, 0x2f, 0xce, 0x4c, 0x47, 0x66, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; -static const unsigned char tree_bg_focus_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0x73, 0x7a, 0x7a, 0xf4, 0x0, 0x0, 0x2, 0x7f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x62, 0x91, 0x16, 0x97, 0x30, 0x63, 0x60, 0x60, 0x38, 0xc9, 0x30, 0x30, 0xc0, 0x9c, 0x11, 0xe8, 0x80, 0xff, 0x6b, 0x3, 0x7f, 0xd, 0x88, 0xed, 0xc1, 0xeb, 0xd9, 0x18, 0x58, 0x60, 0x1c, 0x9e, 0xac, 0xdd, 0x0, 0x5a, 0xcb, 0x6, 0xc5, 0x99, 0x23, 0x6, 0xa2, 0xaf, 0xe4, 0xb3, 0xe5, 0x8a, 0x39, 0x69, 0xf8, 0xcf, 0xa8, 0x82, 0x2d, 0x52, 0xe0, 0x1e, 0x61, 0x63, 0xe0, 0x93, 0x29, 0x7a, 0x66, 0xdb, 0xdb, 0x7a, 0x5d, 0x92, 0x96, 0x45, 0x12, 0x55, 0xf, 0x24, 0xbd, 0x4, 0x50, 0x22, 0x81, 0x98, 0x70, 0x96, 0x63, 0x2b, 0x91, 0x3d, 0xdb, 0x80, 0xb0, 0xfd, 0x52, 0xf7, 0x85, 0x6d, 0xfe, 0xf9, 0xfb, 0x2f, 0x0, 0x2, 0x80, 0x18, 0x80, 0xa7, 0x4a, 0xa8, 0x6a, 0x40, 0xf8, 0x15, 0xc0, 0x9c, 0x61, 0x43, 0x77, 0xd3, 0xd, 0x48, 0x34, 0xce, 0x5e, 0x0, 0x84, 0xd0, 0x24, 0xe7, 0xf1, 0xa8, 0x17, 0x0, 0x3, 0x94, 0x7d, 0xef, 0x1c, 0xec, 0xe, 0x98, 0x38, 0x60, 0x33, 0xc7, 0x34, 0xb6, 0x90, 0xb5, 0x1, 0xf0, 0x76, 0xfb, 0x47, 0x3d, 0xe6, 0x59, 0x62, 0x89, 0x5, 0x60, 0x8f, 0xb1, 0x7d, 0x70, 0x6a, 0x9c, 0x20, 0xf1, 0x5e, 0x82, 0x49, 0x5c, 0xff, 0x27, 0x7f, 0xcc, 0x73, 0x1c, 0xd0, 0x6f, 0xe, 0xb4, 0x3b, 0x0, 0x52, 0x3, 0x35, 0x4e, 0x94, 0xa0, 0x37, 0x0, 0x9b, 0xa4, 0x18, 0x37, 0x5e, 0xd2, 0xe8, 0xd3, 0x2d, 0xd7, 0xbd, 0x52, 0x61, 0x3b, 0x97, 0x3b, 0x5c, 0xb9, 0x3, 0x98, 0xb1, 0xa, 0x8c, 0x34, 0xeb, 0x68, 0xef, 0xc2, 0x9f, 0x22, 0xc, 0x4e, 0xf2, 0x80, 0x42, 0xa8, 0x4e, 0xdd, 0x89, 0x8f, 0x50, 0xb4, 0x84, 0x9d, 0xbd, 0xb7, 0x33, 0x6d, 0xc0, 0x7b, 0x9, 0xc8, 0x17, 0xdf, 0x13, 0x4b, 0xca, 0xf3, 0x2f, 0xe, 0x24, 0x69, 0x8e, 0xf7, 0x68, 0x2d, 0x81, 0xfb, 0xa9, 0xfc, 0xe2, 0xbc, 0x73, 0xdc, 0x51, 0x7c, 0x1d, 0x9, 0xdd, 0x1, 0x72, 0xb6, 0x59, 0x1, 0x26, 0xe, 0xc2, 0xb8, 0x85, 0xf7, 0xe, 0xd8, 0x71, 0xe2, 0x9e, 0x6e, 0xae, 0x8e, 0x18, 0x2d, 0x0, 0x9, 0x1f, 0xd2, 0xbd, 0x17, 0xb4, 0x14, 0xc2, 0xc7, 0x29, 0x2, 0x33, 0x9f, 0x1c, 0xc5, 0xbc, 0x3, 0x5b, 0x9, 0x8c, 0xf9, 0xe2, 0x80, 0xff, 0xa0, 0x3, 0x53, 0x27, 0xe1, 0x6e, 0xac, 0x26, 0x3d, 0x60, 0x2d, 0x37, 0x36, 0xb9, 0x26, 0xc7, 0xa3, 0xd9, 0x9a, 0x2e, 0xea, 0xa7, 0x7a, 0x3, 0x38, 0x8, 0x23, 0xb8, 0x25, 0x51, 0x3a, 0xfb, 0xc3, 0x5c, 0x2c, 0x0, 0xf0, 0x69, 0xa, 0xce, 0x8f, 0x47, 0x5b, 0x18, 0x7f, 0x9f, 0x46, 0x3, 0x6f, 0x73, 0xff, 0xb5, 0x4, 0x26, 0xf5, 0x62, 0x1f, 0x43, 0xbc, 0x81, 0xa4, 0x3f, 0x12, 0xeb, 0x18, 0xd2, 0x74, 0x37, 0xf6, 0xe8, 0xcb, 0x1f, 0xa2, 0x88, 0x3d, 0x16, 0x1e, 0xed, 0x25, 0x38, 0xc5, 0x5e, 0x82, 0xd3, 0x2d, 0x13, 0x89, 0x25, 0x74, 0x47, 0xf0, 0xfb, 0x9e, 0xf1, 0x32, 0x86, 0x29, 0xc6, 0xe2, 0x0, 0xd, 0xae, 0x1f, 0x1d, 0x30, 0x9, 0x2d, 0xf6, 0x47, 0xcd, 0xc8, 0x23, 0x3e, 0x4c, 0x41, 0x77, 0x53, 0xae, 0x2f, 0x0, 0xbe, 0x97, 0xc0, 0xb7, 0xbd, 0xfb, 0x8, 0x76, 0x20, 0x56, 0x80, 0x50, 0x32, 0x5f, 0x46, 0x12, 0x68, 0xf6, 0x24, 0xa1, 0xb5, 0xf9, 0xd7, 0x9f, 0x25, 0xc9, 0x9c, 0x75, 0x81, 0x1b, 0x3e, 0x4f, 0xc1, 0xe8, 0x24, 0x16, 0x42, 0xd2, 0x40, 0x1c, 0xd9, 0xb6, 0x26, 0xc, 0xa4, 0x58, 0x1b, 0x70, 0x3e, 0x2c, 0x0, 0xdd, 0xb8, 0x8a, 0x76, 0x73, 0x5d, 0x57, 0x32, 0xc9, 0x45, 0xfe, 0x23, 0x3a, 0x2c, 0x8, 0x52, 0x32, 0xef, 0x0, 0xdd, 0x7e, 0x9d, 0xd9, 0xbe, 0xc6, 0xe5, 0xbe, 0xd6, 0x31, 0x1c, 0x88, 0x16, 0xad, 0xa2, 0x74, 0xd1, 0xae, 0x24, 0x95, 0xc4, 0xad, 0x6, 0xb, 0x0, 0x59, 0x1c, 0x67, 0xe7, 0x5c, 0x33, 0x6b, 0xef, 0x25, 0x68, 0x37, 0x58, 0xa8, 0x5, 0xfa, 0x17, 0x28, 0xaa, 0x1a, 0xa9, 0x96, 0x46, 0x77, 0x1c, 0xf8, 0x16, 0x71, 0xa0, 0x2f, 0xfc, 0x5a, 0xe7, 0x5d, 0x6b, 0x13, 0x76, 0x73, 0x89, 0x38, 0x72, 0x35, 0x1, 0x10, 0xfa, 0x9, 0x20, 0xe, 0xa4, 0xa9, 0x9f, 0xba, 0xc6, 0x5, 0x2f, 0x0, 0x6d, 0x43, 0x77, 0x6c, 0xab, 0x66, 0x6c, 0xa7, 0x7f, 0x73, 0x60, 0x77, 0x21, 0xe7, 0xf7, 0x53, 0x36, 0x75, 0x2, 0xfc, 0x37, 0x96, 0x15, 0xd1, 0x28, 0xc6, 0xff, 0x65, 0xa0, 0xd, 0x60, 0x2, 0x63, 0x4, 0x0, 0xf5, 0x8e, 0x13, 0x81, 0xf4, 0x3c, 0x86, 0x81, 0x1, 0x49, 0x0, 0x33, 0xd4, 0x35, 0xaa, 0x8d, 0x7e, 0xfe, 0xa5, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const unsigned char tree_cursor_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x96, 0xdd, 0xe3, 0x0, 0x0, 0x0, 0xc3, 0x50, 0x4c, 0x54, 0x45, 0xd4, 0xab, 0x9e, 0xd3, 0xaa, 0x9d, 0xd4, 0xab, 0x9e, 0xd3, 0xaa, 0x9d, 0xd4, 0xab, 0x9c, 0xd4, 0xac, 0x9e, 0xd5, 0xaf, 0xa3, 0xd5, 0xb0, 0xa3, 0xd5, 0xaf, 0xa3, 0xd5, 0xad, 0xa1, 0xd5, 0xaf, 0xa3, 0xd5, 0xad, 0xa1, 0xd5, 0xb0, 0xa3, 0xd6, 0xad, 0xa0, 0xd6, 0xad, 0xa0, 0xd5, 0xb0, 0xa3, 0xd7, 0xb1, 0xa5, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa7, 0xd7, 0xb1, 0xa5, 0xd7, 0xb1, 0xa5, 0xd8, 0xb3, 0xa8, 0xd8, 0xb5, 0xaa, 0xda, 0xb3, 0xa8, 0xda, 0xb3, 0xa8, 0xd8, 0xb3, 0xa8, 0xd8, 0xb5, 0xaa, 0xda, 0xb3, 0xa8, 0xd8, 0xb3, 0xa8, 0xdb, 0xb7, 0xad, 0xda, 0xb8, 0xae, 0xdb, 0xb9, 0xad, 0xdb, 0xb9, 0xad, 0xdb, 0xb7, 0xad, 0xdd, 0xba, 0xb1, 0xdd, 0xbb, 0xb1, 0xdd, 0xbd, 0xb1, 0xdd, 0xbf, 0xb3, 0xdd, 0xbd, 0xb3, 0xdf, 0xc1, 0xb7, 0xdf, 0xc0, 0xb5, 0xdf, 0xbf, 0xb5, 0xe1, 0xc3, 0xb9, 0xe1, 0xc3, 0xbb, 0xe1, 0xc5, 0xbb, 0xe2, 0xc7, 0xbe, 0xe1, 0xc5, 0xbd, 0xe4, 0xcb, 0xc2, 0xe3, 0xca, 0xc1, 0xe3, 0xcb, 0xc3, 0xe6, 0xce, 0xc6, 0xe6, 0xd0, 0xc6, 0xe8, 0xd1, 0xca, 0xe8, 0xd1, 0xca, 0xe8, 0xd0, 0xca, 0xe8, 0xcf, 0xca, 0xb7, 0x7d, 0x69, 0xb1, 0x77, 0x63, 0xac, 0x73, 0x5c, 0xa6, 0x69, 0x56, 0x9c, 0x67, 0x54, 0x93, 0x62, 0x51, 0x88, 0x60, 0x50, 0x9e, 0xe4, 0xa3, 0x87, 0x0, 0x0, 0x0, 0x3a, 0x74, 0x52, 0x4e, 0x53, 0x32, 0x2f, 0x30, 0x33, 0x38, 0x40, 0x32, 0x2f, 0x2f, 0x2f, 0x31, 0x33, 0x33, 0x33, 0x36, 0x38, 0x31, 0x2f, 0x30, 0x31, 0x33, 0x33, 0x35, 0x2f, 0x2f, 0x2f, 0x30, 0x32, 0x33, 0x33, 0x33, 0x2f, 0x2f, 0x2f, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x32, 0x2f, 0x2f, 0x2f, 0xb8, 0xf, 0x95, 0x41, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x4d, 0xc9, 0x1, 0xa, 0x2, 0x31, 0xc, 0x44, 0xd1, 0xff, 0xdb, 0xec, 0x2a, 0x1e, 0x48, 0xc0, 0xfb, 0x7b, 0x2c, 0x3b, 0x96, 0x2c, 0x88, 0x3, 0x19, 0x78, 0x19, 0x5f, 0xfc, 0xa7, 0x7c, 0xb, 0x78, 0xd5, 0xb3, 0x3c, 0x45, 0xf5, 0xea, 0xf2, 0x21, 0xb4, 0xc2, 0xd8, 0xbc, 0x19, 0xcd, 0xb0, 0xab, 0xbc, 0x83, 0xa4, 0x1f, 0x6c, 0x1e, 0x82, 0xca, 0x67, 0x2c, 0x2d, 0xe, 0x25, 0x31, 0x67, 0x6a, 0x51, 0x99, 0xc0, 0xc8, 0xbe, 0x35, 0xcc, 0x45, 0xc, 0xca, 0xdc, 0x1c, 0x6, 0x70, 0x8f, 0xa1, 0xd7, 0x36, 0x13, 0xe8, 0xb5, 0x6d, 0x18, 0x6b, 0xb3, 0xf8, 0x65, 0xe6, 0xb, 0x36, 0x5c, 0x24, 0xde, 0x86, 0x96, 0x3a, 0xaf, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const unsigned char tree_cursor_unfocus_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xe, 0x0, 0x0, 0x0, 0xe, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x96, 0xdd, 0xe3, 0x0, 0x0, 0x0, 0x96, 0x50, 0x4c, 0x54, 0x45, 0xc0, 0xb5, 0xb2, 0xbf, 0xb4, 0xb1, 0xc0, 0xb5, 0xb2, 0xbf, 0xb4, 0xb1, 0xbf, 0xb5, 0xb1, 0xc0, 0xb5, 0xb2, 0xc3, 0xb8, 0xb5, 0xc3, 0xb8, 0xb5, 0xc2, 0xb7, 0xb4, 0xc3, 0xb8, 0xb5, 0xc2, 0xb7, 0xb4, 0xc3, 0xb8, 0xb5, 0xc2, 0xb7, 0xb4, 0xc3, 0xb8, 0xb5, 0xc5, 0xba, 0xb7, 0xc5, 0xbc, 0xb9, 0xc5, 0xbc, 0xb9, 0xc5, 0xbc, 0xb9, 0xc5, 0xbc, 0xb9, 0xc5, 0xba, 0xb7, 0xc5, 0xba, 0xb7, 0xc6, 0xbd, 0xba, 0xc7, 0xbe, 0xbb, 0xc7, 0xbe, 0xbb, 0xc6, 0xbd, 0xba, 0xc7, 0xbe, 0xbb, 0xc6, 0xbd, 0xba, 0xca, 0xc1, 0xbe, 0xca, 0xc1, 0xbe, 0xcd, 0xc4, 0xc1, 0xcd, 0xc6, 0xc3, 0xd0, 0xc9, 0xc6, 0xcf, 0xc8, 0xc5, 0xd2, 0xcb, 0xc8, 0xd3, 0xcb, 0xc9, 0xd3, 0xcc, 0xc9, 0xd5, 0xcd, 0xcb, 0xd4, 0xcc, 0xca, 0xd7, 0xd1, 0xcf, 0xd6, 0xd0, 0xce, 0xda, 0xd4, 0xd2, 0xdd, 0xd7, 0xd5, 0xdd, 0xd7, 0xd5, 0x9a, 0x8b, 0x86, 0x94, 0x85, 0x80, 0x8e, 0x80, 0x7a, 0x88, 0x79, 0x74, 0x81, 0x75, 0x6f, 0x7a, 0x6f, 0x6a, 0x73, 0x69, 0x65, 0x9a, 0x51, 0xd2, 0xe3, 0x0, 0x0, 0x0, 0x2b, 0x74, 0x52, 0x4e, 0x53, 0x32, 0x2f, 0x30, 0x33, 0x38, 0x40, 0x32, 0x2f, 0x2f, 0x31, 0x33, 0x33, 0x36, 0x38, 0x31, 0x2f, 0x30, 0x31, 0x33, 0x33, 0x35, 0x2f, 0x2f, 0x30, 0x32, 0x33, 0x33, 0x2f, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x32, 0x2f, 0x82, 0xd8, 0x8a, 0x2f, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x62, 0xd1, 0x66, 0x40, 0x6, 0x2c, 0x8c, 0x57, 0x0, 0x2d, 0xc9, 0x87, 0x15, 0x4, 0x51, 0x8, 0x42, 0xd1, 0x7, 0x13, 0x3b, 0xd9, 0xfe, 0x1b, 0x1c, 0x16, 0xcf, 0xf, 0xa6, 0xab, 0x6a, 0xd3, 0x2a, 0xbf, 0x53, 0xb7, 0x66, 0xa8, 0x63, 0xe9, 0xd4, 0xbb, 0x88, 0x82, 0xcb, 0x47, 0xd9, 0xb, 0x54, 0xde, 0xec, 0x57, 0x97, 0xde, 0x63, 0x94, 0x12, 0xab, 0xec, 0xec, 0x56, 0xce, 0x69, 0x28, 0xc8, 0x9f, 0xbf, 0x9c, 0x39, 0xd8, 0x16, 0x47, 0x69, 0x65, 0xc, 0xe, 0xc3, 0x8e, 0xeb, 0x69, 0x28, 0x1, 0x0, 0xb0, 0xae, 0x0, 0x0, 0x90, 0x3f, 0xa6, 0x5b, 0x1b, 0xad, 0x12, 0x69, 0xd7, 0x5c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - static const unsigned char tree_title_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x1, 0x3, 0x0, 0x0, 0x0, 0x25, 0x3d, 0x6d, 0x22, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x25, 0x23, 0x25, 0x4c, 0x4a, 0x4e, 0x1, 0xf9, 0x98, 0x2e, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x11, 0x0, 0x0, 0x0, 0x30, 0x0, 0x1, 0x6e, 0xa6, 0xf, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; diff --git a/scene/resources/default_theme/tool_button_pressed.png b/scene/resources/default_theme/tool_button_pressed.png Binary files differdeleted file mode 100644 index 5494475792..0000000000 --- a/scene/resources/default_theme/tool_button_pressed.png +++ /dev/null diff --git a/scene/resources/default_theme/tree_bg_focus.png b/scene/resources/default_theme/tree_bg_focus.png Binary files differdeleted file mode 100644 index aadc6b0db4..0000000000 --- a/scene/resources/default_theme/tree_bg_focus.png +++ /dev/null diff --git a/scene/resources/default_theme/tree_cursor.png b/scene/resources/default_theme/tree_cursor.png Binary files differdeleted file mode 100644 index 2b8722d066..0000000000 --- a/scene/resources/default_theme/tree_cursor.png +++ /dev/null diff --git a/scene/resources/default_theme/tree_cursor_unfocus.png b/scene/resources/default_theme/tree_cursor_unfocus.png Binary files differdeleted file mode 100644 index bfaebbea85..0000000000 --- a/scene/resources/default_theme/tree_cursor_unfocus.png +++ /dev/null diff --git a/scene/resources/dynamic_font_stb.cpp b/scene/resources/dynamic_font_stb.cpp index 3b44f05b94..ccff617a16 100644 --- a/scene/resources/dynamic_font_stb.cpp +++ b/scene/resources/dynamic_font_stb.cpp @@ -55,7 +55,7 @@ void DynamicFontData::lock() { void DynamicFontData::unlock() { - fr = PoolVector<uint8_t>::Read(); + fr.release(); } void DynamicFontData::set_font_data(const PoolVector<uint8_t> &p_font) { diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 6443b44bb6..aff274cd21 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -98,7 +98,7 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { } } - facesw = PoolVector<Vector3>::Write(); + facesw.release(); triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh)); triangle_mesh->create(faces); @@ -436,7 +436,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { r[i] = t; } - r = PoolVector<Vector3>::Write(); + r.release(); arrays[ARRAY_VERTEX] = vertices; if (!has_indices) { @@ -452,7 +452,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { iw[j + 2] = j + 1; } - iw = PoolVector<int>::Write(); + iw.release(); arrays[ARRAY_INDEX] = new_indices; } else { @@ -461,7 +461,7 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const { SWAP(ir[j + 1], ir[j + 2]); } - ir = PoolVector<int>::Write(); + ir.release(); arrays[ARRAY_INDEX] = indices; } } diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index 691d73c181..dc6ef2b49c 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -45,6 +45,7 @@ void ParticlesMaterial::init_shaders() { shader_names = memnew(ShaderNames); + shader_names->direction = "direction"; shader_names->spread = "spread"; shader_names->flatness = "flatness"; shader_names->initial_linear_velocity = "initial_linear_velocity"; @@ -100,6 +101,8 @@ void ParticlesMaterial::init_shaders() { shader_names->trail_color_modifier = "trail_color_modifier"; shader_names->gravity = "gravity"; + + shader_names->lifetime_randomness = "lifetime_randomness"; } void ParticlesMaterial::finish_shaders() { @@ -144,6 +147,7 @@ void ParticlesMaterial::_update_shader() { String code = "shader_type particles;\n"; + code += "uniform vec3 direction;\n"; code += "uniform float spread;\n"; code += "uniform float flatness;\n"; code += "uniform float initial_linear_velocity;\n"; @@ -171,6 +175,7 @@ void ParticlesMaterial::_update_shader() { code += "uniform float hue_variation_random;\n"; code += "uniform float anim_speed_random;\n"; code += "uniform float anim_offset_random;\n"; + code += "uniform float lifetime_randomness;\n"; switch (emission_shape) { case EMISSION_SHAPE_POINT: { @@ -283,7 +288,11 @@ 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 += " if (RESTART) {\n"; + code += " bool restart = false;\n"; + code += " if (CUSTOM.y > CUSTOM.w) {\n"; + code += " restart = true;\n"; + code += " }\n\n"; + code += " if (RESTART || restart) {\n"; if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(0.0, 0.0), 0.0).r;\n"; @@ -304,25 +313,26 @@ void ParticlesMaterial::_update_shader() { if (flags[FLAG_DISABLE_Z]) { - code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle1_rad = atan(direction.y, direction.x) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n"; code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; } else { //initiate velocity spread in 3D - code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; - code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; + code += " float angle1_rad = atan(direction.x, direction.z) + rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle2_rad = atan(direction.y, abs(direction.z)) + rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n"; code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n"; code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n"; - code += " vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; - code += " direction = normalize(direction);\n"; - code += " VELOCITY = direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; + code += " vec3 vec_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; + code += " vec_direction = normalize(vec_direction);\n"; + code += " VELOCITY = vec_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; } code += " float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);\n"; code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle code += " CUSTOM.y = 0.0;\n"; // phase + code += " CUSTOM.w = LIFETIME * (1.0 - lifetime_randomness * rand_from_seed(alt_seed));\n"; code += " CUSTOM.z = (anim_offset + tex_anim_offset) * mix(1.0, anim_offset_rand, anim_offset_random);\n"; // animation offset (0-1) switch (emission_shape) { @@ -330,7 +340,10 @@ void ParticlesMaterial::_update_shader() { //do none } break; case EMISSION_SHAPE_SPHERE: { - code += " TRANSFORM[3].xyz = normalize(vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0)) * emission_sphere_radius;\n"; + code += " float s = rand_from_seed(alt_seed) * 2.0 - 1.0;\n"; + code += " float t = rand_from_seed(alt_seed) * 2.0 * pi;\n"; + code += " float radius = emission_sphere_radius * sqrt(1.0 - s * s);\n"; + code += " TRANSFORM[3].xyz = vec3(radius * cos(t), radius * sin(t), emission_sphere_radius * s);\n"; } break; case EMISSION_SHAPE_BOX: { code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0) * emission_box_extents;\n"; @@ -571,6 +584,9 @@ void ParticlesMaterial::_update_shader() { code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } + code += " if (CUSTOM.y > CUSTOM.w) {"; + code += " ACTIVE = false;\n"; + code += " }\n"; code += "}\n"; code += "\n"; @@ -627,6 +643,17 @@ bool ParticlesMaterial::_is_shader_dirty() const { return dirty; } +void ParticlesMaterial::set_direction(Vector3 p_direction) { + + direction = p_direction; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->direction, direction); +} + +Vector3 ParticlesMaterial::get_direction() const { + + return direction; +} + void ParticlesMaterial::set_spread(float p_spread) { spread = p_spread; @@ -998,6 +1025,17 @@ Vector3 ParticlesMaterial::get_gravity() const { return gravity; } +void ParticlesMaterial::set_lifetime_randomness(float p_lifetime) { + + lifetime_randomness = p_lifetime; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->lifetime_randomness, lifetime_randomness); +} + +float ParticlesMaterial::get_lifetime_randomness() const { + + return lifetime_randomness; +} + RID ParticlesMaterial::get_shader_rid() const { ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); @@ -1042,6 +1080,9 @@ Shader::Mode ParticlesMaterial::get_shader_mode() const { void ParticlesMaterial::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_direction", "degrees"), &ParticlesMaterial::set_direction); + ClassDB::bind_method(D_METHOD("get_direction"), &ParticlesMaterial::get_direction); + ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &ParticlesMaterial::set_spread); ClassDB::bind_method(D_METHOD("get_spread"), &ParticlesMaterial::get_spread); @@ -1099,6 +1140,11 @@ void ParticlesMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("get_gravity"), &ParticlesMaterial::get_gravity); ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &ParticlesMaterial::set_gravity); + ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "randomness"), &ParticlesMaterial::set_lifetime_randomness); + ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &ParticlesMaterial::get_lifetime_randomness); + + ADD_GROUP("Time", ""); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); ADD_GROUP("Trail", "trail_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_divisor", PROPERTY_HINT_RANGE, "1,1000000,1"), "set_trail_divisor", "get_trail_divisor"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_size_modifier", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_trail_size_modifier", "get_trail_size_modifier"); @@ -1115,7 +1161,8 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_flag", "get_flag", FLAG_ALIGN_Y_TO_VELOCITY); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_flag", "get_flag", FLAG_ROTATE_Y); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_flag", "get_flag", FLAG_DISABLE_Z); - ADD_GROUP("Spread", ""); + ADD_GROUP("Direction", ""); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); ADD_GROUP("Gravity", ""); @@ -1200,6 +1247,7 @@ void ParticlesMaterial::_bind_methods() { ParticlesMaterial::ParticlesMaterial() : element(this) { + set_direction(Vector3(1, 0, 0)); set_spread(45); set_flatness(0); set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0); @@ -1219,6 +1267,7 @@ ParticlesMaterial::ParticlesMaterial() : set_emission_box_extents(Vector3(1, 1, 1)); set_trail_divisor(1); set_gravity(Vector3(0, -9.8, 0)); + set_lifetime_randomness(0); emission_point_count = 1; for (int i = 0; i < PARAM_MAX; i++) { diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 42bf60ff48..6fe381db0a 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -129,6 +129,7 @@ private: static SelfList<ParticlesMaterial>::List *dirty_materials; struct ShaderNames { + StringName direction; StringName spread; StringName flatness; StringName initial_linear_velocity; @@ -184,6 +185,8 @@ private: StringName trail_color_modifier; StringName gravity; + + StringName lifetime_randomness; }; static ShaderNames *shader_names; @@ -194,6 +197,7 @@ private: _FORCE_INLINE_ void _queue_shader_change(); _FORCE_INLINE_ bool _is_shader_dirty() const; + Vector3 direction; float spread; float flatness; @@ -223,6 +227,8 @@ private: Vector3 gravity; + float lifetime_randomness; + //do not save emission points here protected: @@ -230,6 +236,9 @@ protected: virtual void _validate_property(PropertyInfo &property) const; public: + void set_direction(Vector3 p_direction); + Vector3 get_direction() const; + void set_spread(float p_spread); float get_spread() const; @@ -282,6 +291,9 @@ public: void set_gravity(const Vector3 &p_gravity); Vector3 get_gravity() const; + void set_lifetime_randomness(float p_lifetime); + float get_lifetime_randomness() const; + static void init_shaders(); static void finish_shaders(); static void flush_changes(); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 339f008a3d..12bf007bb1 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1537,9 +1537,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r f->store_line("]\n"); //one empty line } - { - } - #ifdef TOOLS_ENABLED //keep order from cached ids Set<int> cached_ids_found; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 496b1b2bdc..b294991248 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -307,7 +307,7 @@ Array SurfaceTool::commit_to_arrays() { } } - w = PoolVector<Vector3>::Write(); + w.release(); a[i] = array; } break; @@ -335,7 +335,7 @@ Array SurfaceTool::commit_to_arrays() { } } - w = PoolVector<Vector2>::Write(); + w.release(); a[i] = array; } break; case Mesh::ARRAY_TANGENT: { @@ -358,7 +358,7 @@ Array SurfaceTool::commit_to_arrays() { w[idx + 3] = d < 0 ? -1 : 1; } - w = PoolVector<float>::Write(); + w.release(); a[i] = array; } break; @@ -375,7 +375,7 @@ Array SurfaceTool::commit_to_arrays() { w[idx] = v.color; } - w = PoolVector<Color>::Write(); + w.release(); a[i] = array; } break; case Mesh::ARRAY_BONES: { @@ -396,7 +396,7 @@ Array SurfaceTool::commit_to_arrays() { } } - w = PoolVector<int>::Write(); + w.release(); a[i] = array; } break; @@ -418,7 +418,7 @@ Array SurfaceTool::commit_to_arrays() { } } - w = PoolVector<float>::Write(); + w.release(); a[i] = array; } break; @@ -436,7 +436,7 @@ Array SurfaceTool::commit_to_arrays() { w[idx] = E->get(); } - w = PoolVector<int>::Write(); + w.release(); a[i] = array; } break; @@ -769,7 +769,7 @@ void SurfaceTool::create_from(const Ref<Mesh> &p_existing, int p_surface) { material = p_existing->surface_get_material(p_surface); } -void SurfaceTool::create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String p_blend_shape_name) { +void SurfaceTool::create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String &p_blend_shape_name) { clear(); primitive = p_existing->surface_get_primitive_type(p_surface); Array arr = p_existing->surface_get_blend_shape_arrays(p_surface); diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index c4c71dca13..e3aec6ce0e 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -136,7 +136,7 @@ public: static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays); Array commit_to_arrays(); void create_from(const Ref<Mesh> &p_existing, int p_surface); - void create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String p_blend_shape_name); + void create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String &p_blend_shape_name); void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform); Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = Mesh::ARRAY_COMPRESS_DEFAULT); diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 899abfc9f9..bd5ce91e77 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -731,6 +731,8 @@ void TileSet::tile_set_shape(int p_id, int p_shape_id, const Ref<Shape2D> &p_sha Ref<Shape2D> TileSet::tile_get_shape(int p_id, int p_shape_id) const { ERR_FAIL_COND_V(!tile_map.has(p_id), Ref<Shape2D>()); + ERR_FAIL_COND_V(p_shape_id < 0, Ref<Shape2D>()); + if (p_shape_id < tile_map[p_id].shapes_data.size()) return tile_map[p_id].shapes_data[p_shape_id].shape; @@ -740,6 +742,7 @@ Ref<Shape2D> TileSet::tile_get_shape(int p_id, int p_shape_id) const { void TileSet::tile_set_shape_transform(int p_id, int p_shape_id, const Transform2D &p_offset) { ERR_FAIL_COND(!tile_map.has(p_id)); + ERR_FAIL_COND(p_shape_id < 0); if (p_shape_id >= tile_map[p_id].shapes_data.size()) tile_map[p_id].shapes_data.resize(p_shape_id + 1); @@ -750,6 +753,8 @@ void TileSet::tile_set_shape_transform(int p_id, int p_shape_id, const Transform Transform2D TileSet::tile_get_shape_transform(int p_id, int p_shape_id) const { ERR_FAIL_COND_V(!tile_map.has(p_id), Transform2D()); + ERR_FAIL_COND_V(p_shape_id < 0, Transform2D()); + if (p_shape_id < tile_map[p_id].shapes_data.size()) return tile_map[p_id].shapes_data[p_shape_id].shape_transform; @@ -780,6 +785,8 @@ void TileSet::tile_set_shape_one_way(int p_id, int p_shape_id, const bool p_one_ bool TileSet::tile_get_shape_one_way(int p_id, int p_shape_id) const { ERR_FAIL_COND_V(!tile_map.has(p_id), false); + ERR_FAIL_COND_V(p_shape_id < 0, false); + if (p_shape_id < tile_map[p_id].shapes_data.size()) return tile_map[p_id].shapes_data[p_shape_id].one_way_collision; @@ -800,6 +807,8 @@ void TileSet::tile_set_shape_one_way_margin(int p_id, int p_shape_id, float p_ma float TileSet::tile_get_shape_one_way_margin(int p_id, int p_shape_id) const { ERR_FAIL_COND_V(!tile_map.has(p_id), 0); + ERR_FAIL_COND_V(p_shape_id < 0, 0); + if (p_shape_id < tile_map[p_id].shapes_data.size()) return tile_map[p_id].shapes_data[p_shape_id].one_way_collision_margin; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 7265c9b457..8475a34818 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -67,6 +67,14 @@ String VisualShaderNode::generate_global(Shader::Mode p_mode, VisualShader::Type return String(); } +String VisualShaderNode::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + return String(); +} + +String VisualShaderNode::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + return String(); +} + Vector<StringName> VisualShaderNode::get_editable_properties() const { return Vector<StringName>(); } @@ -449,7 +457,10 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port ERR_FAIL_COND_V(node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_TRANSFORM, String()); StringBuilder global_code; + StringBuilder global_code_per_node; + Map<Type, StringBuilder> global_code_per_func; StringBuilder code; + Set<StringName> classes; global_code += String() + "shader_type canvas_item;\n"; @@ -474,7 +485,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port code += "\nvoid fragment() {\n"; Set<int> processed; - Error err = _write_node(p_type, global_code, code, default_tex_params, input_connections, output_connections, p_node, processed, true); + Error err = _write_node(p_type, global_code, global_code_per_node, global_code_per_func, code, default_tex_params, input_connections, output_connections, p_node, processed, true, classes); ERR_FAIL_COND_V(err != OK, String()); if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR) { @@ -489,6 +500,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port //set code secretly global_code += "\n\n"; String final_code = global_code; + final_code += global_code_per_node; final_code += code; return final_code; } @@ -833,7 +845,7 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { } } -Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBuilder &code, Vector<VisualShader::DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview) const { +Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<VisualShader::DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const { const Ref<VisualShaderNode> vsnode = graph[type].nodes[node].node; @@ -850,7 +862,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui continue; } - Error err = _write_node(type, global_code, code, def_tex_params, input_connections, output_connections, from_node, processed, for_preview); + Error err = _write_node(type, global_code, global_code_per_node, global_code_per_func, code, def_tex_params, input_connections, output_connections, from_node, processed, for_preview, r_classes); if (err) return err; } @@ -958,6 +970,14 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui if (!skip_global) { global_code += vsnode->generate_global(get_mode(), type, node); + + if (!r_classes.has(vsnode->get_class_name())) { + global_code_per_node += vsnode->generate_global_per_node(get_mode(), type, node); + for (int i = 0; i < TYPE_MAX; i++) { + global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node); + } + r_classes.insert(vsnode->get_class_name()); + } } //handle normally @@ -976,8 +996,12 @@ void VisualShader::_update_shader() const { dirty = false; StringBuilder global_code; + StringBuilder global_code_per_node; + Map<Type, StringBuilder> global_code_per_func; StringBuilder code; Vector<VisualShader::DefaultTextureParam> default_tex_params; + Set<StringName> classes; + List<int> insertion_pos; static const char *shader_mode_str[Shader::MODE_MAX] = { "spatial", "canvas_item", "particles" }; global_code += String() + "shader_type " + shader_mode_str[shader_mode] + ";\n"; @@ -1056,8 +1080,9 @@ void VisualShader::_update_shader() const { code += "\nvoid " + String(func_name[i]) + "() {\n"; Set<int> processed; - Error err = _write_node(Type(i), global_code, code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false); + Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes); ERR_FAIL_COND(err != OK); + insertion_pos.push_back(code.get_string_length()); code += "}\n"; } @@ -1065,7 +1090,13 @@ void VisualShader::_update_shader() const { //set code secretly global_code += "\n\n"; String final_code = global_code; - final_code += code; + final_code += global_code_per_node; + String tcode = code; + for (int i = 0; i < TYPE_MAX; i++) { + tcode = tcode.insert(insertion_pos[i], global_code_per_func[Type(i)]); + } + final_code += tcode; + const_cast<VisualShader *>(this)->set_code(final_code); for (int i = 0; i < default_tex_params.size(); i++) { const_cast<VisualShader *>(this)->set_default_texture_param(default_tex_params[i].name, default_tex_params[i].param); diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 83db51b1b0..b3c0ab6e0b 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -103,7 +103,7 @@ private: } }; - Error _write_node(Type p_type, StringBuilder &global_code, StringBuilder &code, Vector<DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview) const; + Error _write_node(Type p_type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const; void _input_type_changed(Type p_type, int p_id); @@ -208,6 +208,8 @@ public: virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; 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 = 0; //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 virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index a44471a365..06f18472ce 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -357,9 +357,13 @@ int VisualShaderNodeTexture::get_output_port_count() const { return 2; } VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_output_port_type(int p_port) const { + if (p_port == 0 && source == SOURCE_DEPTH) + return PORT_TYPE_SCALAR; return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } String VisualShaderNodeTexture::get_output_port_name(int p_port) const { + if (p_port == 0 && source == SOURCE_DEPTH) + return "depth"; return p_port == 0 ? "rgb" : "alpha"; } @@ -475,6 +479,41 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: return code; } + if (p_for_preview) // DEPTH_TEXTURE is not supported in preview(canvas_item) shader + { + if (source == SOURCE_DEPTH) { + String code; + code += "\t" + p_output_vars[0] + " = 0.0;\n"; + code += "\t" + p_output_vars[1] + " = 1.0;\n"; + return code; + } + } + + if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) { + + String code = "\t{\n"; + if (p_input_vars[0] == String()) { //none bound, do nothing + + code += "\t\tfloat _depth = 0.0;\n"; + + } else if (p_input_vars[1] == String()) { + //no lod + code += "\t\tfloat _depth = texture( DEPTH_TEXTURE , " + p_input_vars[0] + ".xy ).r;\n"; + } else { + code += "\t\tfloat _depth = textureLod( DEPTH_TEXTURE , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " ).r;\n"; + } + + code += "\t\t" + p_output_vars[0] + " = _depth;\n"; + code += "\t\t" + p_output_vars[1] + " = 1.0;\n"; + code += "\t}\n"; + return code; + } else if (source == SOURCE_DEPTH) { + String code; + code += "\t" + p_output_vars[0] + " = 0.0;\n"; + code += "\t" + p_output_vars[1] + " = 1.0;\n"; + return code; + } + //none String code; code += "\t" + p_output_vars[0] + " = vec3(0.0);\n"; @@ -543,6 +582,14 @@ String VisualShaderNodeTexture::get_warning(Shader::Mode p_mode, VisualShader::T return String(); // all good } + if (source == SOURCE_DEPTH && p_mode == Shader::MODE_SPATIAL && p_type == VisualShader::TYPE_FRAGMENT) { + + if (get_output_port_for_preview() == 0) { // DEPTH_TEXTURE is not supported in preview(canvas_item) shader + return TTR("Invalid source for preview."); + } + return String(); // all good + } + return TTR("Invalid source for shader."); } @@ -557,7 +604,7 @@ void VisualShaderNodeTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeTexture::set_texture_type); ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeTexture::get_texture_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D"), "set_source", "get_source"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,Screen,Texture2D,NormalMap2D,Depth"), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); @@ -565,6 +612,7 @@ void VisualShaderNodeTexture::_bind_methods() { BIND_ENUM_CONSTANT(SOURCE_SCREEN); BIND_ENUM_CONSTANT(SOURCE_2D_TEXTURE); BIND_ENUM_CONSTANT(SOURCE_2D_NORMAL); + BIND_ENUM_CONSTANT(SOURCE_DEPTH); BIND_ENUM_CONSTANT(TYPE_DATA); BIND_ENUM_CONSTANT(TYPE_COLOR); BIND_ENUM_CONSTANT(TYPE_NORMALMAP); @@ -2920,6 +2968,98 @@ VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { color_default = COLOR_DEFAULT_WHITE; } +////////////// Texture Uniform (Triplanar) + +String VisualShaderNodeTextureUniformTriplanar::get_caption() const { + return "TextureUniformTriplanar"; +} + +int VisualShaderNodeTextureUniformTriplanar::get_input_port_count() const { + return 2; +} + +VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniformTriplanar::get_input_port_type(int p_port) const { + if (p_port == 0) { + return PORT_TYPE_VECTOR; + } else if (p_port == 1) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "weights"; + } else if (p_port == 1) { + return "pos"; + } + return ""; +} + +String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + + String code; + + code += "// TRIPLANAR FUNCTION GLOBAL CODE\n"; + code += "\tvec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos) {\n"; + code += "\t\tvec4 samp = vec4(0.0);\n"; + code += "\t\tsamp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;\n"; + code += "\t\tsamp += texture(p_sampler, p_triplanar_pos.xz) * p_weights.y;\n"; + code += "\t\tsamp += texture(p_sampler, p_triplanar_pos.zy * vec2(-1.0, 1.0)) * p_weights.x;\n"; + code += "\t\treturn samp;\n"; + code += "\t}\n"; + code += "\n"; + code += "\tuniform vec3 triplanar_scale = vec3(1.0, 1.0, 1.0);\n"; + code += "\tuniform vec3 triplanar_offset;\n"; + code += "\tuniform float triplanar_sharpness = 0.5;\n"; + code += "\n"; + code += "\tvarying vec3 triplanar_power_normal;\n"; + code += "\tvarying vec3 triplanar_pos;\n"; + + return code; +} + +String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + + String code; + + if (p_type == VisualShader::TYPE_VERTEX) { + + code += "\t// TRIPLANAR FUNCTION VERTEX CODE\n"; + code += "\t\ttriplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n"; + code += "\t\ttriplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n"; + code += "\t\ttriplanar_pos = VERTEX * triplanar_scale + triplanar_offset;\n"; + code += "\t\ttriplanar_pos *= vec3(1.0, -1.0, 1.0);\n"; + } + + return code; +} + +String VisualShaderNodeTextureUniformTriplanar::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 id = get_uniform_name(); + String code = "\t{\n"; + + if (p_input_vars[0] == String() && p_input_vars[1] == String()) { + code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", triplanar_power_normal, triplanar_pos );\n"; + } else if (p_input_vars[0] != String() && p_input_vars[1] == String()) { + code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", " + p_input_vars[0] + ", triplanar_pos );\n"; + } else if (p_input_vars[0] == String() && p_input_vars[1] != String()) { + code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", triplanar_power_normal," + p_input_vars[1] + " );\n"; + } else { + code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + " );\n"; + } + + code += "\t\t" + p_output_vars[0] + " = n_tex_read.rgb;\n"; + code += "\t\t" + p_output_vars[1] + " = n_tex_read.a;\n"; + code += "\t}\n"; + + return code; +} + +VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() { +} + ////////////// CubeMap Uniform String VisualShaderNodeCubeMapUniform::get_caption() const { @@ -3152,3 +3292,317 @@ VisualShaderNodeFresnel::VisualShaderNodeFresnel() { set_input_port_default_value(2, false); set_input_port_default_value(3, 1.0); } + +////////////// Is + +String VisualShaderNodeIs::get_caption() const { + + return "Is"; +} + +int VisualShaderNodeIs::get_input_port_count() const { + + return 1; +} + +VisualShaderNodeIs::PortType VisualShaderNodeIs::get_input_port_type(int p_port) const { + + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeIs::get_input_port_name(int p_port) const { + + return ""; +} + +int VisualShaderNodeIs::get_output_port_count() const { + + return 1; +} + +VisualShaderNodeIs::PortType VisualShaderNodeIs::get_output_port_type(int p_port) const { + + return PORT_TYPE_BOOLEAN; +} + +String VisualShaderNodeIs::get_output_port_name(int p_port) const { + + return ""; +} + +String VisualShaderNodeIs::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 { + + static const char *funcs[FUNC_IS_NAN + 1] = { + "isinf($)", + "isnan($)" + }; + + String code; + code += "\t" + p_output_vars[0] + "=" + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; + return code; +} + +void VisualShaderNodeIs::set_function(Function p_func) { + + func = p_func; + emit_changed(); +} + +VisualShaderNodeIs::Function VisualShaderNodeIs::get_function() const { + + return func; +} + +Vector<StringName> VisualShaderNodeIs::get_editable_properties() const { + + Vector<StringName> props; + props.push_back("function"); + return props; +} + +void VisualShaderNodeIs::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIs::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIs::get_function); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Inf,NaN"), "set_function", "get_function"); + + BIND_ENUM_CONSTANT(FUNC_IS_INF); + BIND_ENUM_CONSTANT(FUNC_IS_NAN); +} + +VisualShaderNodeIs::VisualShaderNodeIs() { + + func = FUNC_IS_INF; + set_input_port_default_value(0, 0.0); +} + +////////////// Compare + +String VisualShaderNodeCompare::get_caption() const { + + return "Compare"; +} + +int VisualShaderNodeCompare::get_input_port_count() const { + + if (ctype == CTYPE_SCALAR && (func == FUNC_EQUAL || func == FUNC_NOT_EQUAL)) { + return 3; + } + return 2; +} + +VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(int p_port) const { + + if (p_port == 2) + return PORT_TYPE_SCALAR; + switch (ctype) { + case CTYPE_SCALAR: + return PORT_TYPE_SCALAR; + case CTYPE_VECTOR: + return PORT_TYPE_VECTOR; + case CTYPE_BOOLEAN: + return PORT_TYPE_BOOLEAN; + case CTYPE_TRANSFORM: + return PORT_TYPE_TRANSFORM; + } + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeCompare::get_input_port_name(int p_port) const { + if (p_port == 0) + return "a"; + else if (p_port == 1) + return "b"; + else if (p_port == 2) + return "tolerance"; + return ""; +} + +int VisualShaderNodeCompare::get_output_port_count() const { + return 1; +} + +VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_output_port_type(int p_port) const { + return PORT_TYPE_BOOLEAN; +} + +String VisualShaderNodeCompare::get_output_port_name(int p_port) const { + if (p_port == 0) + return "result"; + return ""; +} + +String VisualShaderNodeCompare::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { + + if (ctype == CTYPE_BOOLEAN || ctype == CTYPE_TRANSFORM) { + if (func > FUNC_NOT_EQUAL) { + return TTR("Invalid comparsion function for that type."); + } + } + + return ""; +} + +String VisualShaderNodeCompare::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 { + + static const char *ops[FUNC_LESS_THAN_EQUAL + 1] = { + "==", + "!=", + ">", + ">=", + "<", + "<=", + }; + + static const char *funcs[FUNC_LESS_THAN_EQUAL + 1] = { + "equal($)", + "notEqual($)", + "greaterThan($)", + "greaterThanEqual($)", + "lessThan($)", + "lessThanEqual($)", + }; + + static const char *conds[COND_ANY + 1] = { + "all($)", + "any($)", + }; + + String code; + switch (ctype) { + case CTYPE_SCALAR: + if (func == FUNC_EQUAL) { + code += "\t" + p_output_vars[0] + "=(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ");"; + } else if (func == FUNC_NOT_EQUAL) { + code += "\t" + p_output_vars[0] + "=!(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ");"; + } else { + code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + } + break; + + case CTYPE_VECTOR: + code += "\t{\n"; + code += "\t\tbvec3 _bv=" + String(funcs[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n"; + code += "\t\t" + p_output_vars[0] + "=" + String(conds[condition]).replace("$", "_bv") + ";\n"; + code += "\t}\n"; + break; + + case CTYPE_BOOLEAN: + if (func > FUNC_NOT_EQUAL) + return "\t" + p_output_vars[0] + "=false;\n"; + code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + break; + + case CTYPE_TRANSFORM: + if (func > FUNC_NOT_EQUAL) + return "\t" + p_output_vars[0] + "=false;\n"; + code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + break; + + default: + break; + } + return code; +} + +void VisualShaderNodeCompare::set_comparsion_type(ComparsionType p_type) { + + ctype = p_type; + + switch (ctype) { + case CTYPE_SCALAR: + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 0.0); + break; + case CTYPE_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)); + break; + case CTYPE_BOOLEAN: + set_input_port_default_value(0, false); + set_input_port_default_value(1, false); + break; + case CTYPE_TRANSFORM: + set_input_port_default_value(0, Transform()); + set_input_port_default_value(1, Transform()); + break; + } + emit_changed(); +} + +VisualShaderNodeCompare::ComparsionType VisualShaderNodeCompare::get_comparsion_type() const { + + return ctype; +} + +void VisualShaderNodeCompare::set_function(Function p_func) { + + func = p_func; + emit_changed(); +} + +VisualShaderNodeCompare::Function VisualShaderNodeCompare::get_function() const { + + return func; +} + +void VisualShaderNodeCompare::set_condition(Condition p_cond) { + + condition = p_cond; + emit_changed(); +} + +VisualShaderNodeCompare::Condition VisualShaderNodeCompare::get_condition() const { + + return condition; +} + +Vector<StringName> VisualShaderNodeCompare::get_editable_properties() const { + Vector<StringName> props; + props.push_back("type"); + props.push_back("function"); + if (ctype == CTYPE_VECTOR) + props.push_back("condition"); + return props; +} + +void VisualShaderNodeCompare::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_comparsion_type", "type"), &VisualShaderNodeCompare::set_comparsion_type); + ClassDB::bind_method(D_METHOD("get_comparsion_type"), &VisualShaderNodeCompare::get_comparsion_type); + + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeCompare::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeCompare::get_function); + + ClassDB::bind_method(D_METHOD("set_condition", "condition"), &VisualShaderNodeCompare::set_condition); + ClassDB::bind_method(D_METHOD("get_condition"), &VisualShaderNodeCompare::get_condition); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Scalar,Vector,Boolean,Transform"), "set_comparsion_type", "get_comparsion_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "a == b,a != b,a > b,a >= b,a < b,a <= b"), "set_function", "get_function"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "condition", PROPERTY_HINT_ENUM, "All,Any"), "set_condition", "get_condition"); + + BIND_ENUM_CONSTANT(CTYPE_SCALAR); + BIND_ENUM_CONSTANT(CTYPE_VECTOR); + BIND_ENUM_CONSTANT(CTYPE_BOOLEAN); + BIND_ENUM_CONSTANT(CTYPE_TRANSFORM); + + BIND_ENUM_CONSTANT(FUNC_EQUAL); + BIND_ENUM_CONSTANT(FUNC_NOT_EQUAL); + BIND_ENUM_CONSTANT(FUNC_GREATER_THAN); + BIND_ENUM_CONSTANT(FUNC_GREATER_THAN_EQUAL); + BIND_ENUM_CONSTANT(FUNC_LESS_THAN); + BIND_ENUM_CONSTANT(FUNC_LESS_THAN_EQUAL); + + BIND_ENUM_CONSTANT(COND_ALL); + BIND_ENUM_CONSTANT(COND_ANY); +} + +VisualShaderNodeCompare::VisualShaderNodeCompare() { + ctype = CTYPE_SCALAR; + func = FUNC_EQUAL; + condition = COND_ALL; + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 0.0); + set_input_port_default_value(2, CMP_EPSILON); +} diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index ef64b50711..cafc7a0f00 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -198,7 +198,8 @@ public: SOURCE_TEXTURE, SOURCE_SCREEN, SOURCE_2D_TEXTURE, - SOURCE_2D_NORMAL + SOURCE_2D_NORMAL, + SOURCE_DEPTH }; enum TextureType { @@ -1424,6 +1425,25 @@ VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::ColorDefault) /////////////////////////////////////// +class VisualShaderNodeTextureUniformTriplanar : public VisualShaderNodeTextureUniform { + GDCLASS(VisualShaderNodeTextureUniformTriplanar, VisualShaderNodeTextureUniform); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + 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; //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 + + VisualShaderNodeTextureUniformTriplanar(); +}; + +/////////////////////////////////////// + class VisualShaderNodeCubeMapUniform : public VisualShaderNode { GDCLASS(VisualShaderNodeCubeMapUniform, VisualShaderNode); @@ -1512,4 +1532,115 @@ public: VisualShaderNodeFresnel(); }; +/////////////////////////////////////// +/// Is +/////////////////////////////////////// + +class VisualShaderNodeIs : public VisualShaderNode { + GDCLASS(VisualShaderNodeIs, VisualShaderNode); + +public: + enum Function { + FUNC_IS_INF, + FUNC_IS_NAN, + }; + +protected: + Function func; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + 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; //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 + + void set_function(Function p_func); + Function get_function() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeIs(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeIs::Function) + +/////////////////////////////////////// +/// Compare +/////////////////////////////////////// + +class VisualShaderNodeCompare : public VisualShaderNode { + GDCLASS(VisualShaderNodeCompare, VisualShaderNode); + +public: + enum ComparsionType { + CTYPE_SCALAR, + CTYPE_VECTOR, + CTYPE_BOOLEAN, + CTYPE_TRANSFORM + }; + + enum Function { + FUNC_EQUAL, + FUNC_NOT_EQUAL, + FUNC_GREATER_THAN, + FUNC_GREATER_THAN_EQUAL, + FUNC_LESS_THAN, + FUNC_LESS_THAN_EQUAL, + }; + + enum Condition { + COND_ALL, + COND_ANY, + }; + +protected: + ComparsionType ctype; + Function func; + Condition condition; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + 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; //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 + + void set_comparsion_type(ComparsionType p_func); + ComparsionType get_comparsion_type() const; + + void set_function(Function p_func); + Function get_function() const; + + void set_condition(Condition p_mode); + Condition get_condition() const; + + virtual Vector<StringName> get_editable_properties() const; + virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const; + + VisualShaderNodeCompare(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeCompare::ComparsionType) +VARIANT_ENUM_CAST(VisualShaderNodeCompare::Function) +VARIANT_ENUM_CAST(VisualShaderNodeCompare::Condition) + #endif // VISUAL_SHADER_NODES_H diff --git a/servers/arvr/arvr_positional_tracker.cpp b/servers/arvr/arvr_positional_tracker.cpp index aabe617a8a..cbda3556c5 100644 --- a/servers/arvr/arvr_positional_tracker.cpp +++ b/servers/arvr/arvr_positional_tracker.cpp @@ -79,7 +79,7 @@ ARVRServer::TrackerType ARVRPositionalTracker::get_type() const { return type; }; -void ARVRPositionalTracker::set_name(const String p_name) { +void ARVRPositionalTracker::set_name(const String &p_name) { name = p_name; }; diff --git a/servers/arvr/arvr_positional_tracker.h b/servers/arvr/arvr_positional_tracker.h index 0d6a69540f..775579b089 100644 --- a/servers/arvr/arvr_positional_tracker.h +++ b/servers/arvr/arvr_positional_tracker.h @@ -73,7 +73,7 @@ protected: public: void set_type(ARVRServer::TrackerType p_type); ARVRServer::TrackerType get_type() const; - void set_name(const String p_name); + void set_name(const String &p_name); StringName get_name() const; int get_tracker_id() const; void set_joy_id(int p_joy_id); diff --git a/servers/arvr_server.cpp b/servers/arvr_server.cpp index f6a01939da..f7ce1d3c5d 100644 --- a/servers/arvr_server.cpp +++ b/servers/arvr_server.cpp @@ -87,11 +87,11 @@ real_t ARVRServer::get_world_scale() const { }; void ARVRServer::set_world_scale(real_t p_world_scale) { - if (world_scale < 0.01) { - world_scale = 0.01; - } else if (world_scale > 1000.0) { - world_scale = 1000.0; - }; + if (p_world_scale < 0.01) { + p_world_scale = 0.01; + } else if (p_world_scale > 1000.0) { + p_world_scale = 1000.0; + } world_scale = p_world_scale; }; @@ -100,7 +100,7 @@ Transform ARVRServer::get_world_origin() const { return world_origin; }; -void ARVRServer::set_world_origin(const Transform p_world_origin) { +void ARVRServer::set_world_origin(const Transform &p_world_origin) { world_origin = p_world_origin; }; diff --git a/servers/arvr_server.h b/servers/arvr_server.h index e7d635a8d9..c0301ebaab 100644 --- a/servers/arvr_server.h +++ b/servers/arvr_server.h @@ -123,7 +123,7 @@ public: and in the virtual world out of sync */ Transform get_world_origin() const; - void set_world_origin(const Transform p_world_origin); + void set_world_origin(const Transform &p_world_origin); /* center_on_hmd calculates a new reference frame. This ensures the HMD is positioned to 0,0,0 facing 0,0,-1 (need to verify this direction) diff --git a/servers/audio/effects/audio_effect_chorus.cpp b/servers/audio/effects/audio_effect_chorus.cpp index c2f8b97c1a..216a0a4aa6 100644 --- a/servers/audio/effects/audio_effect_chorus.cpp +++ b/servers/audio/effects/audio_effect_chorus.cpp @@ -333,28 +333,28 @@ void AudioEffectChorus::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/1/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1"), "set_voice_rate_hz", "get_voice_rate_hz", 0); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/1/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_voice_depth_ms", "get_voice_depth_ms", 0); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/1/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1"), "set_voice_level_db", "get_voice_level_db", 0); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/1/cutoff_hz", PROPERTY_HINT_RANGE, "1,16000,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 0); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/1/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 0); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/1/pan", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_voice_pan", "get_voice_pan", 0); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/2/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01"), "set_voice_delay_ms", "get_voice_delay_ms", 1); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/2/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1"), "set_voice_rate_hz", "get_voice_rate_hz", 1); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/2/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_voice_depth_ms", "get_voice_depth_ms", 1); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/2/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1"), "set_voice_level_db", "get_voice_level_db", 1); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/2/cutoff_hz", PROPERTY_HINT_RANGE, "1,16000,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 1); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/2/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 1); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/2/pan", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_voice_pan", "get_voice_pan", 1); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/3/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01"), "set_voice_delay_ms", "get_voice_delay_ms", 2); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/3/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1"), "set_voice_rate_hz", "get_voice_rate_hz", 2); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/3/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_voice_depth_ms", "get_voice_depth_ms", 2); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/3/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1"), "set_voice_level_db", "get_voice_level_db", 2); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/3/cutoff_hz", PROPERTY_HINT_RANGE, "1,16000,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 2); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/3/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 2); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/3/pan", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_voice_pan", "get_voice_pan", 2); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/4/delay_ms", PROPERTY_HINT_RANGE, "0,50,0.01"), "set_voice_delay_ms", "get_voice_delay_ms", 3); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/4/rate_hz", PROPERTY_HINT_RANGE, "0.1,20,0.1"), "set_voice_rate_hz", "get_voice_rate_hz", 3); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/4/depth_ms", PROPERTY_HINT_RANGE, "0,20,0.01"), "set_voice_depth_ms", "get_voice_depth_ms", 3); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/4/level_db", PROPERTY_HINT_RANGE, "-60,24,0.1"), "set_voice_level_db", "get_voice_level_db", 3); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/4/cutoff_hz", PROPERTY_HINT_RANGE, "1,16000,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 3); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/4/cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_voice_cutoff_hz", "get_voice_cutoff_hz", 3); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "voice/4/pan", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_voice_pan", "get_voice_pan", 3); } diff --git a/servers/audio/effects/audio_effect_distortion.cpp b/servers/audio/effects/audio_effect_distortion.cpp index 37305bd7f4..278647c304 100644 --- a/servers/audio/effects/audio_effect_distortion.cpp +++ b/servers/audio/effects/audio_effect_distortion.cpp @@ -173,7 +173,7 @@ void AudioEffectDistortion::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Clip,ATan,LoFi,Overdrive,WaveShape"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "pre_gain", PROPERTY_HINT_RANGE, "-60,60,0.01"), "set_pre_gain", "get_pre_gain"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "keep_hf_hz", PROPERTY_HINT_RANGE, "1,20000,1"), "set_keep_hf_hz", "get_keep_hf_hz"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "keep_hf_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_keep_hf_hz", "get_keep_hf_hz"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "drive", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_drive", "get_drive"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "post_gain", PROPERTY_HINT_RANGE, "-80,24,0.01"), "set_post_gain", "get_post_gain"); diff --git a/servers/audio/effects/audio_effect_filter.cpp b/servers/audio/effects/audio_effect_filter.cpp index dc86d6ffbb..3841f2b5a0 100644 --- a/servers/audio/effects/audio_effect_filter.cpp +++ b/servers/audio/effects/audio_effect_filter.cpp @@ -156,7 +156,7 @@ void AudioEffectFilter::_bind_methods() { ClassDB::bind_method(D_METHOD("set_db", "amount"), &AudioEffectFilter::set_db); ClassDB::bind_method(D_METHOD("get_db"), &AudioEffectFilter::get_db); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "cutoff_hz", PROPERTY_HINT_RANGE, "1,40000,0.1"), "set_cutoff", "get_cutoff"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "cutoff_hz", PROPERTY_HINT_RANGE, "1,20500,1"), "set_cutoff", "get_cutoff"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "resonance", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_resonance", "get_resonance"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "gain", PROPERTY_HINT_RANGE, "0,4,0.01"), "set_gain", "get_gain"); ADD_PROPERTY(PropertyInfo(Variant::INT, "db", PROPERTY_HINT_ENUM, "6 dB,12 dB,18 dB,24 dB"), "set_db", "get_db"); diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp index d40de669fd..8a52f29729 100644 --- a/servers/physics/shape_sw.cpp +++ b/servers/physics/shape_sw.cpp @@ -1524,8 +1524,8 @@ void ConcavePolygonShapeSW::_setup(PoolVector<Vector3> p_faces) { _aabb.merge_with(bvh_arrayw[i].aabb); } - w = PoolVector<Face>::Write(); - vw = PoolVector<Vector3>::Write(); + w.release(); + vw.release(); int count = 0; _VolumeSW_BVH *bvh_tree = _volume_sw_build_bvh(bvh_arrayw, src_face_count, count); diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp index 0043b948b0..48799a56fb 100644 --- a/servers/physics_2d/shape_2d_sw.cpp +++ b/servers/physics_2d/shape_2d_sw.cpp @@ -986,7 +986,7 @@ Variant ConcavePolygonShape2DSW::get_data() const { w[(i << 1) + 1] = points[segments[i].points[1]]; } - w = PoolVector<Vector2>::Write(); + w.release(); return rsegments; } diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 42b9f19d9d..14fefbf195 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -785,6 +785,17 @@ ShaderLanguage::DataPrecision ShaderLanguage::get_token_precision(TokenType p_ty return PRECISION_MEDIUMP; } +String ShaderLanguage::get_precision_name(DataPrecision p_type) { + switch (p_type) { + case PRECISION_LOWP: return "lowp"; + case PRECISION_MEDIUMP: return "mediump"; + case PRECISION_HIGHP: return "highp"; + default: + break; + } + return ""; +} + String ShaderLanguage::get_datatype_name(DataType p_type) { switch (p_type) { @@ -849,7 +860,7 @@ void ShaderLanguage::clear() { } } -bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type) { +bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type, IdentifierType *r_type, int *r_array_size) { if (p_builtin_types.has(p_identifier)) { @@ -871,6 +882,9 @@ bool ShaderLanguage::_find_identifier(const BlockNode *p_block, const Map<String if (r_data_type) { *r_data_type = p_block->variables[p_identifier].type; } + if (r_array_size) { + *r_array_size = p_block->variables[p_identifier].array_size; + } if (r_type) { *r_type = IDENTIFIER_LOCAL_VAR; } @@ -1328,725 +1342,730 @@ bool ShaderLanguage::_validate_operator(OperatorNode *p_op, DataType *r_ret_type const ShaderLanguage::BuiltinFuncDef ShaderLanguage::builtin_func_defs[] = { //constructors - { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID } }, - { "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_VOID } }, - { "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_BOOL, TYPE_VOID } }, - { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_VOID } }, - { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID } }, - { "bvec3", TYPE_BVEC3, { TYPE_BVEC2, TYPE_BOOL, TYPE_VOID } }, - { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BVEC2, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC2, TYPE_BOOL, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BOOL, TYPE_BOOL, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BVEC2, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC3, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_BVEC3, TYPE_BOOL, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID } }, - - { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_VOID } }, - { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VOID } }, - { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "vec3", TYPE_VEC3, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - - { "int", TYPE_INT, { TYPE_INT, TYPE_VOID } }, - { "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_VOID } }, - { "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_INT, TYPE_VOID } }, - { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_VOID } }, - { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID } }, - { "ivec3", TYPE_IVEC3, { TYPE_IVEC2, TYPE_INT, TYPE_VOID } }, - { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_IVEC2, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC2, TYPE_INT, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_IVEC2, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC3, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_IVEC3, TYPE_INT, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } }, - - { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID } }, - { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_VOID } }, - { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_UINT, TYPE_VOID } }, - { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_VOID } }, - { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID } }, - { "uvec3", TYPE_UVEC3, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID } }, - { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UVEC2, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC2, TYPE_UINT, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UVEC2, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC3, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } }, - - { "mat2", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "mat3", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "mat4", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "mat2", TYPE_MAT2, { TYPE_FLOAT, TYPE_VOID } }, - { "mat3", TYPE_MAT3, { TYPE_FLOAT, TYPE_VOID } }, - { "mat4", TYPE_MAT4, { TYPE_FLOAT, TYPE_VOID } }, + { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec2", TYPE_BVEC2, { TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec3", TYPE_BVEC3, { TYPE_BVEC2, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec3", TYPE_BVEC3, { TYPE_BOOL, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC2, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BOOL, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BOOL, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_BOOL, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_BVEC3, TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + + { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec2", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec3", TYPE_VEC3, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec3", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + + { "int", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec2", TYPE_IVEC2, { TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec3", TYPE_IVEC3, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec3", TYPE_IVEC3, { TYPE_INT, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_INT, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_INT, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + + { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec2", TYPE_UVEC2, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec3", TYPE_UVEC3, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec3", TYPE_UVEC3, { TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UINT, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_UINT, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + + { "mat2", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "mat3", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "mat4", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "mat2", TYPE_MAT2, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "mat3", TYPE_MAT3, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "mat4", TYPE_MAT4, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, //conversion scalars - { "int", TYPE_INT, { TYPE_BOOL, TYPE_VOID } }, - { "int", TYPE_INT, { TYPE_INT, TYPE_VOID } }, - { "int", TYPE_INT, { TYPE_UINT, TYPE_VOID } }, - { "int", TYPE_INT, { TYPE_FLOAT, TYPE_VOID } }, + { "int", TYPE_INT, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "int", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "int", TYPE_INT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "int", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, - { "float", TYPE_FLOAT, { TYPE_BOOL, TYPE_VOID } }, - { "float", TYPE_FLOAT, { TYPE_INT, TYPE_VOID } }, - { "float", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID } }, - { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, + { "float", TYPE_FLOAT, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "float", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "float", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "float", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, - { "uint", TYPE_UINT, { TYPE_BOOL, TYPE_VOID } }, - { "uint", TYPE_UINT, { TYPE_INT, TYPE_VOID } }, - { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID } }, - { "uint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID } }, + { "uint", TYPE_UINT, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "uint", TYPE_UINT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "uint", TYPE_UINT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, - { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID } }, - { "bool", TYPE_BOOL, { TYPE_INT, TYPE_VOID } }, - { "bool", TYPE_BOOL, { TYPE_UINT, TYPE_VOID } }, - { "bool", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID } }, + { "bool", TYPE_BOOL, { TYPE_BOOL, TYPE_VOID }, TAG_GLOBAL }, + { "bool", TYPE_BOOL, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "bool", TYPE_BOOL, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "bool", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, //conversion vectors - { "ivec2", TYPE_IVEC2, { TYPE_BVEC2, TYPE_VOID } }, - { "ivec2", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID } }, - { "ivec2", TYPE_IVEC2, { TYPE_UVEC2, TYPE_VOID } }, - { "ivec2", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID } }, - - { "vec2", TYPE_VEC2, { TYPE_BVEC2, TYPE_VOID } }, - { "vec2", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID } }, - { "vec2", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID } }, - { "vec2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - - { "uvec2", TYPE_UVEC2, { TYPE_BVEC2, TYPE_VOID } }, - { "uvec2", TYPE_UVEC2, { TYPE_IVEC2, TYPE_VOID } }, - { "uvec2", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID } }, - { "uvec2", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID } }, - - { "bvec2", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID } }, - { "bvec2", TYPE_BVEC2, { TYPE_IVEC2, TYPE_VOID } }, - { "bvec2", TYPE_BVEC2, { TYPE_UVEC2, TYPE_VOID } }, - { "bvec2", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID } }, - - { "ivec3", TYPE_IVEC3, { TYPE_BVEC3, TYPE_VOID } }, - { "ivec3", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID } }, - { "ivec3", TYPE_IVEC3, { TYPE_UVEC3, TYPE_VOID } }, - { "ivec3", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID } }, - - { "vec3", TYPE_VEC3, { TYPE_BVEC3, TYPE_VOID } }, - { "vec3", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID } }, - { "vec3", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID } }, - { "vec3", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - - { "uvec3", TYPE_UVEC3, { TYPE_BVEC3, TYPE_VOID } }, - { "uvec3", TYPE_UVEC3, { TYPE_IVEC3, TYPE_VOID } }, - { "uvec3", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID } }, - { "uvec3", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID } }, - - { "bvec3", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID } }, - { "bvec3", TYPE_BVEC3, { TYPE_IVEC3, TYPE_VOID } }, - { "bvec3", TYPE_BVEC3, { TYPE_UVEC3, TYPE_VOID } }, - { "bvec3", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID } }, - - { "ivec4", TYPE_IVEC4, { TYPE_BVEC4, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_UVEC4, TYPE_VOID } }, - { "ivec4", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "vec4", TYPE_VEC4, { TYPE_BVEC4, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID } }, - { "vec4", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "uvec4", TYPE_UVEC4, { TYPE_BVEC4, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_IVEC4, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID } }, - { "uvec4", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "bvec4", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_IVEC4, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_UVEC4, TYPE_VOID } }, - { "bvec4", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID } }, + { "ivec2", TYPE_IVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "ivec2", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "ivec2", TYPE_IVEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "ivec2", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + + { "vec2", TYPE_VEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "vec2", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "vec2", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "vec2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + + { "uvec2", TYPE_UVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "uvec2", TYPE_UVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "uvec2", TYPE_UVEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "uvec2", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + + { "bvec2", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "bvec2", TYPE_BVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "bvec2", TYPE_BVEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "bvec2", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + + { "ivec3", TYPE_IVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "ivec3", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "ivec3", TYPE_IVEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "ivec3", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + + { "vec3", TYPE_VEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "vec3", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "vec3", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "vec3", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + + { "uvec3", TYPE_UVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "uvec3", TYPE_UVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "uvec3", TYPE_UVEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "uvec3", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + + { "bvec3", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "bvec3", TYPE_BVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "bvec3", TYPE_BVEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "bvec3", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + + { "ivec4", TYPE_IVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "ivec4", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "vec4", TYPE_VEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "vec4", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "uvec4", TYPE_UVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "uvec4", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "bvec4", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "bvec4", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, //conversion between matrixes - { "mat2", TYPE_MAT2, { TYPE_MAT3, TYPE_VOID } }, - { "mat2", TYPE_MAT2, { TYPE_MAT4, TYPE_VOID } }, - { "mat3", TYPE_MAT3, { TYPE_MAT2, TYPE_VOID } }, - { "mat3", TYPE_MAT3, { TYPE_MAT4, TYPE_VOID } }, - { "mat4", TYPE_MAT4, { TYPE_MAT2, TYPE_VOID } }, - { "mat4", TYPE_MAT4, { TYPE_MAT3, TYPE_VOID } }, + { "mat2", TYPE_MAT2, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL }, + { "mat2", TYPE_MAT2, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL }, + { "mat3", TYPE_MAT3, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL }, + { "mat3", TYPE_MAT3, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL }, + { "mat4", TYPE_MAT4, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL }, + { "mat4", TYPE_MAT4, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL }, //builtins - trigonometry - { "radians", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "radians", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "radians", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "radians", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "degrees", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "degrees", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "degrees", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "degrees", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "sin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "sin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "sin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "sin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "cos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "cos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "cos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "cos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "tan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "tan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "tan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "tan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "asin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "asin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "asin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "asin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "acos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "acos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "acos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "acos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "sinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "sinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "sinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "sinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "cosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "cosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "cosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "cosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "tanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "tanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "tanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "tanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "asinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "asinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "asinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "asinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "acosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "acosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "acosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "acosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "atanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "atanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "atanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "atanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, + { "radians", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "radians", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "radians", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "radians", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "degrees", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "degrees", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "degrees", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "degrees", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "sin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "sin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "sin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "sin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "cos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "cos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "cos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "cos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "tan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "tan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "tan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "tan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "asin", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "asin", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "asin", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "asin", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "acos", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "acos", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "acos", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "acos", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "atan", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "atan", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "atan", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "atan", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "sinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "sinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "sinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "sinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "cosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "cosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "cosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "cosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "tanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "tanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "tanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "tanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "asinh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "asinh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "asinh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "asinh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "acosh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "acosh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "acosh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "acosh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "atanh", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "atanh", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "atanh", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "atanh", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, //builtins - exponential - { "pow", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - { "exp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "exp", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "exp", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "exp", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "log", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "log", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "log", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "log", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "exp2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "exp2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "exp2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "exp2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "log2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "log2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "log2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "log2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "sqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "sqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "sqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "sqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "inversesqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "inversesqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "inversesqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "inversesqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, + { "pow", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "pow", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "pow", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "pow", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "exp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "exp", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "exp", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "exp", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "log", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "log", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "log", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "log", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "exp2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "exp2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "exp2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "exp2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "log2", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "log2", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "log2", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "log2", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "sqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "sqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "sqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "sqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "inversesqrt", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "inversesqrt", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "inversesqrt", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "inversesqrt", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, //builtins - common - { "abs", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "abs", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "abs", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "abs", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "abs", TYPE_INT, { TYPE_INT, TYPE_VOID } }, - { "abs", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID } }, - { "abs", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID } }, - { "abs", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID } }, - - { "sign", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "sign", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "sign", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "sign", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "sign", TYPE_INT, { TYPE_INT, TYPE_VOID } }, - { "sign", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID } }, - { "sign", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID } }, - { "sign", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID } }, - - { "floor", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "floor", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "floor", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "floor", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "trunc", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "trunc", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "trunc", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "trunc", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "round", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "round", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "round", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "round", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "roundEven", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "roundEven", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "roundEven", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "roundEven", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "ceil", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "ceil", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "ceil", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "ceil", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "fract", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "fract", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "fract", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "fract", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "mod", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "modf", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "modf", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "modf", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "modf", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "min", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "min", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID } }, - { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } }, - { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID } }, - { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } }, - { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID } }, - { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } }, - { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID } }, - - { "min", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID } }, - { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } }, - { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID } }, - { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } }, - { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID } }, - { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } }, - { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID } }, - - { "max", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "max", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID } }, - { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } }, - { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID } }, - { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } }, - { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID } }, - { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } }, - { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID } }, - - { "max", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID } }, - { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } }, - { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID } }, - { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } }, - { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID } }, - { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } }, - { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID } }, - - { "clamp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - - { "clamp", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID } }, - { "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } }, - { "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } }, - { "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } }, - { "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID } }, - { "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID } }, - { "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID } }, - - { "clamp", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID } }, - { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } }, - { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } }, - { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } }, - { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID } }, - { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_UINT, TYPE_VOID } }, - { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_UINT, TYPE_VOID } }, - - { "mix", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "mix", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_BOOL, TYPE_VOID } }, - { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_BOOL, TYPE_VOID } }, - { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_BVEC2, TYPE_VOID } }, - { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_BOOL, TYPE_VOID } }, - { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_BVEC3, TYPE_VOID } }, - { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BOOL, TYPE_VOID } }, - { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BVEC4, TYPE_VOID } }, - { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "step", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "step", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "step", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "step", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - { "step", TYPE_VEC2, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID } }, - { "step", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID } }, - { "step", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC4, TYPE_VOID } }, - { "smoothstep", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID } }, - { "smoothstep", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "smoothstep", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "smoothstep", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - { "smoothstep", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID } }, - { "smoothstep", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC3, TYPE_VOID } }, - { "smoothstep", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC4, TYPE_VOID } }, - - { "isnan", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID } }, - { "isnan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID } }, - { "isnan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID } }, - { "isnan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "isinf", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID } }, - { "isinf", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID } }, - { "isinf", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID } }, - { "isinf", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "floatBitsToInt", TYPE_INT, { TYPE_FLOAT, TYPE_VOID } }, - { "floatBitsToInt", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID } }, - { "floatBitsToInt", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID } }, - { "floatBitsToInt", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "floatBitsToUint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID } }, - { "floatBitsToUint", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID } }, - { "floatBitsToUint", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID } }, - { "floatBitsToUint", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "intBitsToFloat", TYPE_FLOAT, { TYPE_INT, TYPE_VOID } }, - { "intBitsToFloat", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID } }, - { "intBitsToFloat", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID } }, - { "intBitsToFloat", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID } }, - - { "uintBitsToFloat", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID } }, - { "uintBitsToFloat", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID } }, - { "uintBitsToFloat", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID } }, - { "uintBitsToFloat", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID } }, + { "abs", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "abs", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "abs", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "abs", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "abs", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "abs", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "abs", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "abs", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "sign", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "sign", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "sign", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "sign", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "sign", TYPE_INT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "sign", TYPE_IVEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "sign", TYPE_IVEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "sign", TYPE_IVEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "floor", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "floor", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "floor", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "floor", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "trunc", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "trunc", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "trunc", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "trunc", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "round", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "round", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "round", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "round", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "roundEven", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "roundEven", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "roundEven", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "roundEven", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "ceil", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "ceil", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "ceil", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "ceil", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "fract", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "fract", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "fract", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "fract", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "mod", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "mod", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "mod", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "mod", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "modf", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "modf", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "modf", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "modf", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "min", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "min", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + + { "min", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "min", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + + { "max", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "max", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + + { "max", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "max", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + + { "clamp", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_VEC2, { TYPE_VEC2, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_VEC3, { TYPE_VEC3, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_VEC4, { TYPE_VEC4, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "clamp", TYPE_INT, { TYPE_INT, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_IVEC2, { TYPE_IVEC2, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_IVEC3, { TYPE_IVEC3, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_IVEC4, { TYPE_IVEC4, TYPE_INT, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + + { "clamp", TYPE_UINT, { TYPE_UINT, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_UVEC2, { TYPE_UVEC2, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_UVEC3, { TYPE_UVEC3, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "clamp", TYPE_UVEC4, { TYPE_UVEC4, TYPE_UINT, TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + + { "mix", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "mix", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "mix", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL }, + { "mix", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "step", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "step", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "step", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "step", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "step", TYPE_VEC2, { TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "step", TYPE_VEC3, { TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "step", TYPE_VEC4, { TYPE_FLOAT, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "smoothstep", TYPE_FLOAT, { TYPE_FLOAT, TYPE_FLOAT, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "smoothstep", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "smoothstep", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "smoothstep", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "smoothstep", TYPE_VEC2, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "smoothstep", TYPE_VEC3, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "smoothstep", TYPE_VEC4, { TYPE_FLOAT, TYPE_FLOAT, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "isnan", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "isnan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "isnan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "isnan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "isinf", TYPE_BOOL, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "isinf", TYPE_BVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "isinf", TYPE_BVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "isinf", TYPE_BVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "floatBitsToInt", TYPE_INT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "floatBitsToInt", TYPE_IVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "floatBitsToInt", TYPE_IVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "floatBitsToInt", TYPE_IVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "floatBitsToUint", TYPE_UINT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "floatBitsToUint", TYPE_UVEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "floatBitsToUint", TYPE_UVEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "floatBitsToUint", TYPE_UVEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "intBitsToFloat", TYPE_FLOAT, { TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "intBitsToFloat", TYPE_VEC2, { TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "intBitsToFloat", TYPE_VEC3, { TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "intBitsToFloat", TYPE_VEC4, { TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "uintBitsToFloat", TYPE_FLOAT, { TYPE_UINT, TYPE_VOID }, TAG_GLOBAL }, + { "uintBitsToFloat", TYPE_VEC2, { TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "uintBitsToFloat", TYPE_VEC3, { TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "uintBitsToFloat", TYPE_VEC4, { TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, //builtins - geometric - { "length", TYPE_FLOAT, { TYPE_VEC2, TYPE_VOID } }, - { "length", TYPE_FLOAT, { TYPE_VEC3, TYPE_VOID } }, - { "length", TYPE_FLOAT, { TYPE_VEC4, TYPE_VOID } }, - { "distance", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "distance", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "distance", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - { "dot", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "dot", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "dot", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - { "cross", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "normalize", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "normalize", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "normalize", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - { "reflect", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "refract", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - - { "faceforward", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "faceforward", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "faceforward", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "matrixCompMult", TYPE_MAT2, { TYPE_MAT2, TYPE_MAT2, TYPE_VOID } }, - { "matrixCompMult", TYPE_MAT3, { TYPE_MAT3, TYPE_MAT3, TYPE_VOID } }, - { "matrixCompMult", TYPE_MAT4, { TYPE_MAT4, TYPE_MAT4, TYPE_VOID } }, - - { "outerProduct", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "outerProduct", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "outerProduct", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "transpose", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID } }, - { "transpose", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID } }, - { "transpose", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID } }, - - { "determinant", TYPE_FLOAT, { TYPE_MAT2, TYPE_VOID } }, - { "determinant", TYPE_FLOAT, { TYPE_MAT3, TYPE_VOID } }, - { "determinant", TYPE_FLOAT, { TYPE_MAT4, TYPE_VOID } }, - - { "inverse", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID } }, - { "inverse", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID } }, - { "inverse", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID } }, - - { "lessThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "lessThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "lessThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "lessThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } }, - { "lessThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } }, - { "lessThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } }, - - { "lessThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } }, - { "lessThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } }, - { "lessThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } }, - - { "greaterThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "greaterThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "greaterThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "greaterThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } }, - { "greaterThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } }, - { "greaterThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } }, - - { "greaterThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } }, - { "greaterThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } }, - { "greaterThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } }, - - { "lessThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "lessThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "lessThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "lessThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } }, - { "lessThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } }, - { "lessThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } }, - - { "lessThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } }, - { "lessThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } }, - { "lessThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } }, - - { "greaterThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "greaterThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "greaterThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "greaterThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } }, - { "greaterThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } }, - { "greaterThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } }, - - { "greaterThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } }, - { "greaterThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } }, - { "greaterThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } }, - - { "equal", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "equal", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "equal", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "equal", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } }, - { "equal", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } }, - { "equal", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } }, - - { "equal", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } }, - { "equal", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } }, - { "equal", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } }, - - { "equal", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID } }, - { "equal", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID } }, - { "equal", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID } }, - - { "notEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "notEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "notEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID } }, - - { "notEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID } }, - { "notEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID } }, - { "notEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID } }, + { "length", TYPE_FLOAT, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "length", TYPE_FLOAT, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "length", TYPE_FLOAT, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "distance", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "distance", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "distance", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "dot", TYPE_FLOAT, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "dot", TYPE_FLOAT, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "dot", TYPE_FLOAT, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "cross", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "normalize", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "normalize", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "normalize", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "reflect", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "refract", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "faceforward", TYPE_VEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "faceforward", TYPE_VEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "faceforward", TYPE_VEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "matrixCompMult", TYPE_MAT2, { TYPE_MAT2, TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL }, + { "matrixCompMult", TYPE_MAT3, { TYPE_MAT3, TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL }, + { "matrixCompMult", TYPE_MAT4, { TYPE_MAT4, TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL }, + + { "outerProduct", TYPE_MAT2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "outerProduct", TYPE_MAT3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "outerProduct", TYPE_MAT4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "transpose", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL }, + { "transpose", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL }, + { "transpose", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL }, + + { "determinant", TYPE_FLOAT, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL }, + { "determinant", TYPE_FLOAT, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL }, + { "determinant", TYPE_FLOAT, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL }, + + { "inverse", TYPE_MAT2, { TYPE_MAT2, TYPE_VOID }, TAG_GLOBAL }, + { "inverse", TYPE_MAT3, { TYPE_MAT3, TYPE_VOID }, TAG_GLOBAL }, + { "inverse", TYPE_MAT4, { TYPE_MAT4, TYPE_VOID }, TAG_GLOBAL }, + + { "lessThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "lessThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "lessThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "lessThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "lessThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "lessThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "lessThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "lessThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "lessThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "greaterThan", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThan", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThan", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "greaterThan", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThan", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThan", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "greaterThan", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThan", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThan", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "lessThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "lessThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "lessThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "lessThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "lessThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "lessThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "lessThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "lessThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "lessThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "greaterThanEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThanEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThanEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "greaterThanEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThanEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThanEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "greaterThanEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThanEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "greaterThanEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "equal", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "equal", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "equal", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "equal", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "equal", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "equal", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "equal", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "equal", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "equal", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "equal", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "equal", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "equal", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "notEqual", TYPE_BVEC2, { TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "notEqual", TYPE_BVEC3, { TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "notEqual", TYPE_BVEC4, { TYPE_VEC4, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + { "notEqual", TYPE_BVEC2, { TYPE_IVEC2, TYPE_IVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "notEqual", TYPE_BVEC3, { TYPE_IVEC3, TYPE_IVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "notEqual", TYPE_BVEC4, { TYPE_IVEC4, TYPE_IVEC4, TYPE_VOID }, TAG_GLOBAL }, - { "notEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID } }, - { "notEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID } }, - { "notEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID } }, + { "notEqual", TYPE_BVEC2, { TYPE_UVEC2, TYPE_UVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "notEqual", TYPE_BVEC3, { TYPE_UVEC3, TYPE_UVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "notEqual", TYPE_BVEC4, { TYPE_UVEC4, TYPE_UVEC4, TYPE_VOID }, TAG_GLOBAL }, - { "notEqual", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID } }, - { "notEqual", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID } }, - { "notEqual", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID } }, + { "notEqual", TYPE_BVEC2, { TYPE_BVEC2, TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "notEqual", TYPE_BVEC3, { TYPE_BVEC3, TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "notEqual", TYPE_BVEC4, { TYPE_BVEC4, TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL }, - { "any", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID } }, - { "any", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID } }, - { "any", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID } }, + { "any", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "any", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "any", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL }, - { "all", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID } }, - { "all", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID } }, - { "all", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID } }, + { "all", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "all", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "all", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL }, - { "not", TYPE_BOOL, { TYPE_BVEC2, TYPE_VOID } }, - { "not", TYPE_BOOL, { TYPE_BVEC3, TYPE_VOID } }, - { "not", TYPE_BOOL, { TYPE_BVEC4, TYPE_VOID } }, + { "not", TYPE_BVEC2, { TYPE_BVEC2, TYPE_VOID }, TAG_GLOBAL }, + { "not", TYPE_BVEC3, { TYPE_BVEC3, TYPE_VOID }, TAG_GLOBAL }, + { "not", TYPE_BVEC4, { TYPE_BVEC4, TYPE_VOID }, TAG_GLOBAL }, //builtins - texture - { "textureSize", TYPE_IVEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID } }, - { "textureSize", TYPE_IVEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID } }, - { "textureSize", TYPE_IVEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID } }, - { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER2DARRAY, TYPE_INT, TYPE_VOID } }, - { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER2DARRAY, TYPE_INT, TYPE_VOID } }, - { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER2DARRAY, TYPE_INT, TYPE_VOID } }, - { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER3D, TYPE_INT, TYPE_VOID } }, - { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID } }, - { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID } }, - { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID } }, - - { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID } }, - { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - - { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID } }, - { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - - { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID } }, - { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - - { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID } }, - { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - - { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID } }, - { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - - { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID } }, - { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - - { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VOID } }, - { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - - { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VOID } }, - { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - - { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VOID } }, - { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - - { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID } }, - { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - - { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID } }, - { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID } }, - { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VOID } }, - { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_VOID } }, - { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VOID } }, - { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_VOID } }, - { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VOID } }, - { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VOID } }, - { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VOID } }, - { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID } }, - { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - - { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID } }, - { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID } }, - { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID } }, - - { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID } }, - { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID } }, - { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID } }, - - { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID } }, - { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID } }, - { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID } }, - - { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID } }, - { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID } }, - - { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID } }, - { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, - { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID } }, + { "textureSize", TYPE_IVEC2, { TYPE_SAMPLER2D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "textureSize", TYPE_IVEC2, { TYPE_ISAMPLER2D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "textureSize", TYPE_IVEC2, { TYPE_USAMPLER2D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER2DARRAY, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "textureSize", TYPE_IVEC3, { TYPE_SAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "textureSize", TYPE_IVEC3, { TYPE_ISAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "textureSize", TYPE_IVEC3, { TYPE_USAMPLER3D, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "textureSize", TYPE_IVEC2, { TYPE_SAMPLERCUBE, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + + { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "texture", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "texture", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "texture", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "texture", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "texture", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "texture", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "texture", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "texture", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "texture", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + { "textureProj", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureLod", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureLod", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_IVEC2, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + + { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + + { "texelFetch", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "texelFetch", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + { "texelFetch", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_IVEC3, TYPE_INT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC3, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureProjLod", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureProjLod", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "textureProjLod", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC4, TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + + { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2D, TYPE_VEC2, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER2DARRAY, TYPE_VEC3, TYPE_VEC2, TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "textureGrad", TYPE_VEC4, { TYPE_SAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "textureGrad", TYPE_IVEC4, { TYPE_ISAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "textureGrad", TYPE_UVEC4, { TYPE_USAMPLER3D, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "textureGrad", TYPE_VEC4, { TYPE_SAMPLERCUBE, TYPE_VEC3, TYPE_VEC3, TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + + { "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "dFdx", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "dFdx", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, - { "dFdx", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "dFdx", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "dFdx", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "dFdx", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, + { "dFdy", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "dFdy", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "dFdy", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "dFdy", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, - { "dFdy", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "dFdy", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "dFdy", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "dFdy", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, - - { "fwidth", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID } }, - { "fwidth", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID } }, - { "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID } }, - { "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID } }, + { "fwidth", TYPE_FLOAT, { TYPE_FLOAT, TYPE_VOID }, TAG_GLOBAL }, + { "fwidth", TYPE_VEC2, { TYPE_VEC2, TYPE_VOID }, TAG_GLOBAL }, + { "fwidth", TYPE_VEC3, { TYPE_VEC3, TYPE_VOID }, TAG_GLOBAL }, + { "fwidth", TYPE_VEC4, { TYPE_VEC4, TYPE_VOID }, TAG_GLOBAL }, + + //sub-functions - { NULL, TYPE_VOID, { TYPE_VOID } } + //array + { "length", TYPE_INT, { TYPE_VOID }, TAG_ARRAY }, + + { NULL, TYPE_VOID, { TYPE_VOID }, TAG_GLOBAL } }; @@ -2058,11 +2077,11 @@ const ShaderLanguage::BuiltinFuncOutArgs ShaderLanguage::builtin_func_out_args[] bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p_func, DataType *r_ret_type) { - ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, NULL); + ERR_FAIL_COND_V(p_func->op != OP_CALL && p_func->op != OP_CONSTRUCT, false); Vector<DataType> args; - ERR_FAIL_COND_V(p_func->arguments[0]->type != Node::TYPE_VARIABLE, NULL); + ERR_FAIL_COND_V(p_func->arguments[0]->type != Node::TYPE_VARIABLE, false); StringName name = static_cast<VariableNode *>(p_func->arguments[0])->name.operator String(); @@ -2080,6 +2099,11 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, OperatorNode *p while (builtin_func_defs[idx].name) { + if (completion_class != builtin_func_defs[idx].tag) { + idx++; + continue; + } + if (name == builtin_func_defs[idx].name) { failed_builtin = true; @@ -2720,6 +2744,8 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI if (!(p_builtin_types.has(var->name) && p_builtin_types[var->name].constant)) { return true; } + } else if (p_node->type == Node::TYPE_ARRAY) { + return true; } if (r_message) @@ -2730,6 +2756,7 @@ bool ShaderLanguage::_validate_assign(Node *p_node, const Map<StringName, BuiltI ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types) { Vector<Expression> expression; + //Vector<TokenType> operators; while (true) { @@ -2838,7 +2865,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error("No matching constructor found for: '" + String(funcname->name) + "'"); return NULL; } - //validate_Function_call() expr = _reduce_expression(p_block, func); @@ -2894,6 +2920,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error("No matching function found for: '" + String(funcname->name) + "'"); return NULL; } + completion_class = TAG_GLOBAL; // reset sub-class expr = func; @@ -2904,8 +2931,9 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons DataType data_type; IdentifierType ident_type; + int array_size = 0; - if (!_find_identifier(p_block, p_builtin_types, identifier, &data_type, &ident_type)) { + if (!_find_identifier(p_block, p_builtin_types, identifier, &data_type, &ident_type, &array_size)) { _set_error("Unknown identifier in expression: " + String(identifier)); return NULL; } @@ -2915,10 +2943,68 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons return NULL; } - VariableNode *varname = alloc_node<VariableNode>(); - varname->name = identifier; - varname->datatype_cache = data_type; - expr = varname; + Node *index_expression = NULL; + Node *call_expression = NULL; + + if (array_size > 0) { + tk = _get_token(); + + if (tk.type != TK_BRACKET_OPEN && tk.type != TK_PERIOD) { + _set_error("Expected '[' or '.'"); + return NULL; + } + + if (tk.type == TK_PERIOD) { + completion_class = TAG_ARRAY; + call_expression = _parse_and_reduce_expression(p_block, p_builtin_types); + if (!call_expression) + return NULL; + data_type = call_expression->get_datatype(); + } else { // indexing + + index_expression = _parse_and_reduce_expression(p_block, p_builtin_types); + if (!index_expression) + return NULL; + + if (index_expression->get_datatype() != TYPE_INT && index_expression->get_datatype() != TYPE_UINT) { + _set_error("Only integer expressions are allowed for indexing"); + return NULL; + } + + if (index_expression->type == Node::TYPE_CONSTANT) { + ConstantNode *cnode = (ConstantNode *)index_expression; + if (cnode) { + if (!cnode->values.empty()) { + int value = cnode->values[0].sint; + if (value < 0 || value >= array_size) { + _set_error(vformat("Index [%s] out of range [%s..%s]", value, 0, array_size - 1)); + return NULL; + } + } + } + } + + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return NULL; + } + } + + ArrayNode *arrname = alloc_node<ArrayNode>(); + arrname->name = identifier; + arrname->datatype_cache = data_type; + arrname->index_expression = index_expression; + arrname->call_expression = call_expression; + expr = arrname; + + } else { + + VariableNode *varname = alloc_node<VariableNode>(); + varname->name = identifier; + varname->datatype_cache = data_type; + expr = varname; + } } } else if (tk.type == TK_OP_ADD) { @@ -2969,7 +3055,6 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons _set_error("Expected identifier as member"); return NULL; } - DataType dt = expr->get_datatype(); String ident = identifier; @@ -3705,11 +3790,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui tk = _get_token(); - VariableDeclarationNode *vardecl = alloc_node<VariableDeclarationNode>(); - vardecl->datatype = type; - vardecl->precision = precision; - - p_block->statements.push_back(vardecl); + Node *vardecl = NULL; while (true) { @@ -3728,15 +3809,207 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui var.type = type; var.precision = precision; var.line = tk_line; + var.array_size = 0; - VariableDeclarationNode::Declaration decl; + tk = _get_token(); - decl.name = name; - decl.initializer = NULL; + if (tk.type == TK_BRACKET_OPEN) { + bool unknown_size = false; - tk = _get_token(); + ArrayDeclarationNode *node = alloc_node<ArrayDeclarationNode>(); + node->datatype = type; + node->precision = precision; + vardecl = (Node *)node; + + ArrayDeclarationNode::Declaration decl; + decl.name = name; + decl.size = 0U; + + tk = _get_token(); + + if (tk.type == TK_BRACKET_CLOSE) { + unknown_size = true; + } else { + + if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) { + _set_error("Expected integer constant > 0 or ']'"); + return ERR_PARSE_ERROR; + } + + tk = _get_token(); + + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']'"); + return ERR_PARSE_ERROR; + } + + decl.size = ((uint32_t)tk.constant); + var.array_size = decl.size; + } + + bool full_def = false; + + tk = _get_token(); + if (tk.type == TK_OP_ASSIGN) { + tk = _get_token(); + + if (tk.type != TK_CURLY_BRACKET_OPEN) { + + if (unknown_size) { + _set_error("Expected '{'"); + return ERR_PARSE_ERROR; + } + + full_def = true; + + DataPrecision precision2 = PRECISION_DEFAULT; + if (is_token_precision(tk.type)) { + precision2 = get_token_precision(tk.type); + tk = _get_token(); + if (!is_token_nonvoid_datatype(tk.type)) { + _set_error("Expected datatype after precision"); + return ERR_PARSE_ERROR; + } + } + if (!is_token_variable_datatype(tk.type)) { + _set_error("Invalid data type for array"); + return ERR_PARSE_ERROR; + } + DataType type2 = get_token_datatype(tk.type); + + int array_size2 = 0; + + tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { + Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); + if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) { + _set_error("Expected single integer constant > 0"); + return ERR_PARSE_ERROR; + } + + ConstantNode *cnode = (ConstantNode *)n; + if (cnode->values.size() == 1) { + array_size2 = cnode->values[0].sint; + if (array_size2 <= 0) { + _set_error("Expected single integer constant > 0"); + return ERR_PARSE_ERROR; + } + } else { + _set_error("Expected single integer constant > 0"); + return ERR_PARSE_ERROR; + } + + tk = _get_token(); + if (tk.type != TK_BRACKET_CLOSE) { + _set_error("Expected ']"); + return ERR_PARSE_ERROR; + } else { + tk = _get_token(); + } + } else { + _set_error("Expected '["); + return ERR_PARSE_ERROR; + } + + if (precision != precision2 || type != type2 || var.array_size != array_size2) { + String error_str = "Cannot convert from '"; + if (precision2 != PRECISION_DEFAULT) { + error_str += get_precision_name(precision2); + error_str += " "; + } + error_str += get_datatype_name(type2); + error_str += "["; + error_str += itos(array_size2); + error_str += "]'"; + error_str += " to '"; + if (precision != PRECISION_DEFAULT) { + error_str += get_precision_name(precision); + error_str += " "; + } + error_str += get_datatype_name(type); + error_str += "["; + error_str += itos(var.array_size); + error_str += "]'"; + _set_error(error_str); + return ERR_PARSE_ERROR; + } + } + + bool curly = tk.type == TK_CURLY_BRACKET_OPEN; + + if (unknown_size) { + if (!curly) { + _set_error("Expected '{'"); + return ERR_PARSE_ERROR; + } + } else { + if (full_def) { + if (curly) { + _set_error("Expected '('"); + return ERR_PARSE_ERROR; + } + } + } + + if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization + while (true) { + + Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); + if (!n) { + return ERR_PARSE_ERROR; + } + + if (var.type != n->get_datatype()) { + _set_error("Invalid assignment of '" + get_datatype_name(n->get_datatype()) + "' to '" + get_datatype_name(var.type) + "'"); + return ERR_PARSE_ERROR; + } + + tk = _get_token(); + if (tk.type == TK_COMMA) { + decl.initializer.push_back(n); + continue; + } else if (!curly && tk.type == TK_PARENTHESIS_CLOSE) { + decl.initializer.push_back(n); + break; + } else if (curly && tk.type == TK_CURLY_BRACKET_CLOSE) { + decl.initializer.push_back(n); + break; + } else { + if (curly) + _set_error("Expected '}' or ','"); + else + _set_error("Expected ')' or ','"); + return ERR_PARSE_ERROR; + } + } + if (unknown_size) { + decl.size = decl.initializer.size(); + var.array_size = decl.initializer.size(); + } else if (decl.initializer.size() != var.array_size) { + _set_error("Array size mismatch"); + return ERR_PARSE_ERROR; + } + tk = _get_token(); + } + } else { + if (unknown_size) { + _set_error("Expected array initialization"); + return ERR_PARSE_ERROR; + } + } + + node->declarations.push_back(decl); + } else if (tk.type == TK_OP_ASSIGN) { + + VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>(); + node->datatype = type; + node->precision = precision; + vardecl = (Node *)node; + + VariableDeclarationNode::Declaration decl; + decl.name = name; + decl.initializer = NULL; - if (tk.type == TK_OP_ASSIGN) { //variable created with assignment! must parse an expression Node *n = _parse_and_reduce_expression(p_block, p_builtin_types); if (!n) @@ -3749,11 +4022,22 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Bui return ERR_PARSE_ERROR; } tk = _get_token(); + node->declarations.push_back(decl); + } else { + VariableDeclarationNode *node = alloc_node<VariableDeclarationNode>(); + node->datatype = type; + node->precision = precision; + vardecl = (Node *)node; + + VariableDeclarationNode::Declaration decl; + decl.name = name; + decl.initializer = NULL; + node->declarations.push_back(decl); } - p_block->variables[name] = var; + p_block->statements.push_back(vardecl); - vardecl->declarations.push_back(decl); + p_block->variables[name] = var; if (tk.type == TK_COMMA) { tk = _get_token(); @@ -4369,6 +4653,14 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct type = get_token_datatype(tk.type); + TkPos prev_pos = _get_tkpos(); + tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { + _set_error("Cannot use arrays as return types"); + return ERR_PARSE_ERROR; + } + _set_tkpos(prev_pos); + _get_completable_identifier(NULL, COMPLETION_MAIN_FUNCTION, name); if (name == StringName()) { @@ -4522,6 +4814,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { + _set_error("Arrays as parameters are not implemented yet"); + return ERR_PARSE_ERROR; + } if (tk.type != TK_IDENTIFIER) { _set_error("Expected identifier for argument name"); return ERR_PARSE_ERROR; @@ -4542,6 +4838,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct func_node->arguments.push_back(arg); tk = _get_token(); + if (tk.type == TK_BRACKET_OPEN) { + _set_error("Arrays as parameters are not implemented yet"); + return ERR_PARSE_ERROR; + } if (tk.type == TK_COMMA) { tk = _get_token(); @@ -4684,7 +4984,7 @@ Error ShaderLanguage::compile(const String &p_code, const Map<StringName, Functi return OK; } -Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint) { +Error ShaderLanguage::complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint) { clear(); @@ -4705,8 +5005,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } break; case COMPLETION_RENDER_MODE: { for (int i = 0; i < p_render_modes.size(); i++) { - - r_options->push_back(p_render_modes[i]); + ScriptCodeCompletionOption option(p_render_modes[i], ScriptCodeCompletionOption::KIND_ENUM); + r_options->push_back(option); } return OK; @@ -4714,8 +5014,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct case COMPLETION_MAIN_FUNCTION: { for (const Map<StringName, FunctionInfo>::Element *E = p_functions.front(); E; E = E->next()) { - - r_options->push_back(E->key()); + ScriptCodeCompletionOption option(E->key(), ScriptCodeCompletionOption::KIND_FUNCTION); + r_options->push_back(option); } return OK; @@ -4724,70 +5024,86 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct case COMPLETION_FUNCTION_CALL: { bool comp_ident = completion_type == COMPLETION_IDENTIFIER; - Set<String> matches; - + Map<String, ScriptCodeCompletionOption::Kind> matches; StringName skip_function; - BlockNode *block = completion_block; - while (block) { - - if (comp_ident) { - for (const Map<StringName, BlockNode::Variable>::Element *E = block->variables.front(); E; E = E->next()) { + if (completion_class == TAG_GLOBAL) { + while (block) { + if (comp_ident) { + for (const Map<StringName, BlockNode::Variable>::Element *E = block->variables.front(); E; E = E->next()) { - if (E->get().line < completion_line) { - matches.insert(E->key()); + if (E->get().line < completion_line) { + matches.insert(E->key(), ScriptCodeCompletionOption::KIND_VARIABLE); + } } } - } - if (block->parent_function) { - if (comp_ident) { - for (int i = 0; i < block->parent_function->arguments.size(); i++) { - matches.insert(block->parent_function->arguments[i].name); + if (block->parent_function) { + if (comp_ident) { + for (int i = 0; i < block->parent_function->arguments.size(); i++) { + matches.insert(block->parent_function->arguments[i].name, ScriptCodeCompletionOption::KIND_FUNCTION); + } } + skip_function = block->parent_function->name; } - skip_function = block->parent_function->name; + block = block->parent_block; } - block = block->parent_block; - } - if (comp_ident && skip_function != StringName() && p_functions.has(skip_function)) { + if (comp_ident && skip_function != StringName() && p_functions.has(skip_function)) { - for (Map<StringName, BuiltInInfo>::Element *E = p_functions[skip_function].built_ins.front(); E; E = E->next()) { - matches.insert(E->key()); + for (Map<StringName, BuiltInInfo>::Element *E = p_functions[skip_function].built_ins.front(); E; E = E->next()) { + ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER; + if (E->get().constant) { + kind = ScriptCodeCompletionOption::KIND_CONSTANT; + } + matches.insert(E->key(), kind); + } } - } - if (comp_ident) { - for (const Map<StringName, ShaderNode::Varying>::Element *E = shader->varyings.front(); E; E = E->next()) { - matches.insert(E->key()); + if (comp_ident) { + for (const Map<StringName, ShaderNode::Varying>::Element *E = shader->varyings.front(); E; E = E->next()) { + matches.insert(E->key(), ScriptCodeCompletionOption::KIND_VARIABLE); + } + for (const Map<StringName, ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) { + matches.insert(E->key(), ScriptCodeCompletionOption::KIND_MEMBER); + } } - for (const Map<StringName, ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) { - matches.insert(E->key()); + + for (int i = 0; i < shader->functions.size(); i++) { + if (!shader->functions[i].callable || shader->functions[i].name == skip_function) + continue; + matches.insert(String(shader->functions[i].name), ScriptCodeCompletionOption::KIND_FUNCTION); } - } - for (int i = 0; i < shader->functions.size(); i++) { - if (!shader->functions[i].callable || shader->functions[i].name == skip_function) - continue; - matches.insert(String(shader->functions[i].name) + "("); - } + int idx = 0; - int idx = 0; + while (builtin_func_defs[idx].name) { - while (builtin_func_defs[idx].name) { + matches.insert(String(builtin_func_defs[idx].name), ScriptCodeCompletionOption::KIND_FUNCTION); + idx++; + } - matches.insert(String(builtin_func_defs[idx].name) + "("); - idx++; + } else { // sub-class + int idx = 0; + + while (builtin_func_defs[idx].name) { + if (builtin_func_defs[idx].tag == completion_class) { + matches.insert(String(builtin_func_defs[idx].name), ScriptCodeCompletionOption::KIND_FUNCTION); + } + idx++; + } } - for (Set<String>::Element *E = matches.front(); E; E = E->next()) { - r_options->push_back(E->get()); + for (Map<String, ScriptCodeCompletionOption::Kind>::Element *E = matches.front(); E; E = E->next()) { + ScriptCodeCompletionOption option(E->key(), E->value()); + if (E->value() == ScriptCodeCompletionOption::KIND_FUNCTION) { + option.insert_text += "("; + } + r_options->push_back(option); } return OK; - } break; case COMPLETION_CALL_ARGUMENTS: { @@ -4840,6 +5156,11 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct if (completion_function == builtin_func_defs[idx].name) { + if (builtin_func_defs[idx].tag != completion_class) { + idx++; + continue; + } + if (calltip.length()) calltip += "\n"; @@ -4923,8 +5244,8 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct } for (int i = 0; i < limit; i++) { - r_options->push_back(String::chr(colv[i])); - r_options->push_back(String::chr(coordv[i])); + r_options->push_back(ScriptCodeCompletionOption(String::chr(colv[i]), ScriptCodeCompletionOption::KIND_PLAIN_TEXT)); + r_options->push_back(ScriptCodeCompletionOption(String::chr(coordv[i]), ScriptCodeCompletionOption::KIND_PLAIN_TEXT)); } } break; @@ -4951,6 +5272,7 @@ ShaderLanguage::ShaderNode *ShaderLanguage::get_shader() { ShaderLanguage::ShaderLanguage() { nodes = NULL; + completion_class = TAG_GLOBAL; } ShaderLanguage::~ShaderLanguage() { diff --git a/servers/visual/shader_language.h b/servers/visual/shader_language.h index 934dc2c403..8253bce468 100644 --- a/servers/visual/shader_language.h +++ b/servers/visual/shader_language.h @@ -33,6 +33,7 @@ #include "core/list.h" #include "core/map.h" +#include "core/script_language.h" #include "core/string_name.h" #include "core/typedefs.h" #include "core/ustring.h" @@ -287,7 +288,9 @@ public: TYPE_CONSTANT, TYPE_OPERATOR, TYPE_CONTROL_FLOW, - TYPE_MEMBER + TYPE_MEMBER, + TYPE_ARRAY, + TYPE_ARRAY_DECLARATION, }; Type type; @@ -351,6 +354,40 @@ public: datatype(TYPE_VOID) {} }; + struct ArrayNode : public Node { + DataType datatype_cache; + StringName name; + Node *index_expression; + Node *call_expression; + + virtual DataType get_datatype() const { return datatype_cache; } + + ArrayNode() : + Node(TYPE_ARRAY), + datatype_cache(TYPE_VOID), + index_expression(NULL), + call_expression(NULL) {} + }; + + struct ArrayDeclarationNode : public Node { + DataPrecision precision; + DataType datatype; + + struct Declaration { + StringName name; + uint32_t size; + Vector<Node *> initializer; + }; + + Vector<Declaration> declarations; + virtual DataType get_datatype() const { return datatype; } + + ArrayDeclarationNode() : + Node(TYPE_ARRAY_DECLARATION), + precision(PRECISION_DEFAULT), + datatype(TYPE_VOID) {} + }; + struct ConstantNode : public Node { DataType datatype; @@ -379,6 +416,7 @@ public: DataType type; DataPrecision precision; int line; //for completion + int array_size; }; Map<StringName, Variable> variables; @@ -551,6 +589,7 @@ public: static DataInterpolation get_token_interpolation(TokenType p_type); static bool is_token_precision(TokenType p_type); static DataPrecision get_token_precision(TokenType p_type); + static String get_precision_name(DataPrecision p_type); static String get_datatype_name(DataType p_type); static bool is_token_nonvoid_datatype(TokenType p_type); static bool is_token_operator(TokenType p_type); @@ -644,16 +683,22 @@ private: IDENTIFIER_CONSTANT, }; - bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL); + bool _find_identifier(const BlockNode *p_block, const Map<StringName, BuiltInInfo> &p_builtin_types, const StringName &p_identifier, DataType *r_data_type = NULL, IdentifierType *r_type = NULL, int *r_array_size = NULL); bool _is_operator_assign(Operator p_op) const; bool _validate_assign(Node *p_node, const Map<StringName, BuiltInInfo> &p_builtin_types, String *r_message = NULL); bool _validate_operator(OperatorNode *p_op, DataType *r_ret_type = NULL); + enum SubClassTag { + TAG_GLOBAL, + TAG_ARRAY + }; + struct BuiltinFuncDef { enum { MAX_ARGS = 5 }; const char *name; DataType rettype; const DataType args[MAX_ARGS]; + SubClassTag tag; }; struct BuiltinFuncOutArgs { //arguments used as out in built in functions @@ -665,6 +710,7 @@ private: int completion_line; BlockNode *completion_block; DataType completion_base; + SubClassTag completion_class; StringName completion_function; int completion_argument; @@ -689,7 +735,7 @@ public: static String get_shader_type(const String &p_code); Error compile(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types); - Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<String> *r_options, String &r_call_hint); + Error complete(const String &p_code, const Map<StringName, FunctionInfo> &p_functions, const Vector<StringName> &p_render_modes, const Set<String> &p_shader_types, List<ScriptCodeCompletionOption> *r_options, String &r_call_hint); String get_error_text(); int get_error_line(); diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp index 66e2429bd0..fc75fda583 100644 --- a/servers/visual/visual_server_canvas.cpp +++ b/servers/visual/visual_server_canvas.cpp @@ -49,13 +49,14 @@ void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Tra } } -void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item *p_material_owner, VisualServerCanvas::Item **r_items, int &r_index) { +void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2D p_transform, VisualServerCanvas::Item *p_material_owner, const Color p_modulate, VisualServerCanvas::Item **r_items, int &r_index) { int child_item_count = p_canvas_item->child_items.size(); VisualServerCanvas::Item **child_items = p_canvas_item->child_items.ptrw(); for (int i = 0; i < child_item_count; i++) { if (child_items[i]->visible) { if (r_items) { r_items[r_index] = child_items[i]; + child_items[i]->ysort_modulate = p_modulate; child_items[i]->ysort_xform = p_transform; child_items[i]->ysort_pos = p_transform.xform(child_items[i]->xform.elements[2]); child_items[i]->material_owner = child_items[i]->use_parent_material ? p_material_owner : NULL; @@ -64,7 +65,11 @@ void _collect_ysort_children(VisualServerCanvas::Item *p_canvas_item, Transform2 r_index++; if (child_items[i]->sort_y) - _collect_ysort_children(child_items[i], p_transform * child_items[i]->xform, child_items[i]->use_parent_material ? p_material_owner : child_items[i], r_items, r_index); + _collect_ysort_children(child_items[i], + p_transform * child_items[i]->xform, + child_items[i]->use_parent_material ? p_material_owner : child_items[i], + p_modulate * child_items[i]->modulate, + r_items, r_index); } } } @@ -125,14 +130,14 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor if (ci->ysort_children_count == -1) { ci->ysort_children_count = 0; - _collect_ysort_children(ci, Transform2D(), p_material_owner, NULL, ci->ysort_children_count); + _collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), NULL, ci->ysort_children_count); } child_item_count = ci->ysort_children_count; child_items = (Item **)alloca(child_item_count * sizeof(Item *)); int i = 0; - _collect_ysort_children(ci, Transform2D(), p_material_owner, child_items, i); + _collect_ysort_children(ci, Transform2D(), p_material_owner, Color(1, 1, 1, 1), child_items, i); SortArray<Item *, ItemPtrSort> sorter; sorter.sort(child_items, child_item_count); @@ -148,7 +153,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor if (!child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) continue; if (ci->sort_y) { - _render_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner); + _render_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner); } else { _render_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner); } @@ -190,7 +195,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor if (child_items[i]->behind || (ci->sort_y && child_items[i]->sort_y)) continue; if (ci->sort_y) { - _render_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner); + _render_canvas_item(child_items[i], xform * child_items[i]->ysort_xform, p_clip_rect, modulate * child_items[i]->ysort_modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, (Item *)child_items[i]->material_owner); } else { _render_canvas_item(child_items[i], xform, p_clip_rect, modulate, p_z, z_list, z_last_list, (Item *)ci->final_clip_owner, p_material_owner); } diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h index 28a8770c90..822e3f8ce3 100644 --- a/servers/visual/visual_server_canvas.h +++ b/servers/visual/visual_server_canvas.h @@ -49,6 +49,7 @@ public: int index; bool children_order_dirty; int ysort_children_count; + Color ysort_modulate; Transform2D ysort_xform; Vector2 ysort_pos; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index d45bda72b7..7aded4e816 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -77,6 +77,8 @@ void VisualServerRaster::free(RID p_rid) { return; if (VSG::scene->free(p_rid)) return; + if (VSG::scene_render->free(p_rid)) + return; } /* EVENT QUEUING */ diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index faf5a1f8fa..7c100be0f2 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -2396,7 +2396,7 @@ void VisualServerScene::_setup_gi_probe(Instance *p_instance) { mipmap.resize(size); PoolVector<uint8_t>::Write w = mipmap.write(); zeromem(w.ptr(), size); - w = PoolVector<uint8_t>::Write(); + w.release(); probe->dynamic.mipmaps_3d.push_back(mipmap); diff --git a/thirdparty/README.md b/thirdparty/README.md index b003ae6e8a..c6817e2389 100644 --- a/thirdparty/README.md +++ b/thirdparty/README.md @@ -122,20 +122,20 @@ Use UI font variant if available, because it has tight vertical metrics and good ## freetype - Upstream: https://www.freetype.org -- Version: 2.10.0 +- Version: 2.10.1 - License: FreeType License (BSD-like) Files extracted from upstream source: -- the src/ folder, stripped of the `Jamfile` files -- the include/ folder +- the `src/` folder, stripped of the `Jamfile` files and the `tools` subfolder +- the `include/` folder - `docs/{FTL.TXT,LICENSE.TXT}` ## glad - Upstream: https://github.com/Dav1dde/glad -- Version: 0.1.29 +- Version: 0.1.31 - License: MIT The files we package are automatically generated. @@ -262,40 +262,25 @@ changes to ensure they build for Javascript/HTML5. Those changes are marked with `// -- GODOT --` comments. -## libwebsockets +## wslay -- Upstream: https://github.com/warmcat/libwebsockets -- Version: 3.0.1 -- License: LGPLv2.1 + static linking exception - -File extracted from upstream source: -- From `lib/` into `thirdparty/libwebsockets`: - - Everything from `core` - - From `event-libs` only the `poll` subfolder - - From `misc` only `base64-decode.c`, `getifaddrs.c`, `getifaddrs.h`, `lejp.c`, and `sha-1.c` - - From `plat` only `lws-plat-unix.c` and `lws-plat-win.c` - - From `roles` only `private.h`, `h1`, `http`, `listen`, `pipe`, `raw`, `ws` - - From `roles/http` exclude `minilex.c` - - From `roles/http/server` exclude `access-log.c`, `lws-spa.c`, `ranges.c`, and `rewrite.c` - - From `roles/ws` exclude `ext` folder. - - From `tls` exclude `openssl` folder. -- Also copy `win32helpers/` from `win32port/` inside `thirdparty/libwebsockets` -- A fix has been added to allow building for 32-bits UWP, replacing `GetFileSize[Ex]` and `CreateFileW` with supported functions. - There is a diff for this change in `thirdparty/libwebsockets/uwp_fixes.diff` -- A fix to disable V6ONLY flag from IPv6 sockets (on by default on some systems) has been also applied. - The diff for this change can be found in `thirdparty/libwebsockets/ipv6_fixes.diff` +- Upstream: https://github.com/tatsuhiro-t/wslay +- Version: 1.1.0 +- License: MIT -Important: `lws_config.h` and `lws_config_private.h` contains custom -Godot build configurations, check them out when updating. +File extracted from upstream release tarball: +- All `*.c` and `*.h` in `lib/` and `lib/includes/` +- `wslay.h` has a small Godot addition to fix MSVC build. + See `thirdparty/wslay/msvcfix.diff` ## mbedtls - Upstream: https://tls.mbed.org/ -- Version: 2.16.0 +- Version: 2.16.2 - License: Apache 2.0 -File extracted from upstream release tarball `mbedtls-2.16.0-apache.tgz`: +File extracted from upstream release tarball (`-apache.tgz` variant): - All `*.h` from `include/mbedtls/` to `thirdparty/mbedtls/include/mbedtls/` - All `*.c` from `library/` to `thirdparty/mbedtls/library/` - Applied the patch in `thirdparty/mbedtls/1453.diff` (PR 1453). @@ -303,6 +288,8 @@ File extracted from upstream release tarball `mbedtls-2.16.0-apache.tgz`: - Applied the patch in `thirdparty/mbedtls/padlock.diff`. This disables VIA padlock support which defines a symbol `unsupported` which clashes with a symbol in libwebsockets. +- Added 2 files `godot_core_mbedtls_platform.{c,h}` providing configuration + for light bundling with core. ## miniupnpc @@ -340,15 +327,7 @@ Collection of single-file libraries used in Godot components. ### core -- `aes256.{cpp,h}` - * Upstream: http://www.literatecode.com/aes256 - * Version: latest, as of April 2017 - * License: ISC -- `base64.{c,h}` - * Upstream: http://episec.com/people/edelkind/c.html - * Version: latest, as of April 2017 - * License: Public Domain - - `clipper.{cpp,hpp}` +- `clipper.{cpp,hpp}` * Upstream: https://sourceforge.net/projects/polyclipping * Version: 6.4.2 + Godot changes (added optional exceptions handling) * License: BSL-1.0 @@ -360,10 +339,6 @@ Collection of single-file libraries used in Godot components. * Upstream: https://github.com/brunexgeek/hqx * Version: TBD, file structure differs * License: Apache 2.0 -- `md5.{cpp,h}` - * Upstream: http://www.efgh.com/software/md5.htm - * Version: TBD, might not be latest from above URL - * License: RSA Message-Digest License - `open-simplex-noise.{c,h}` * Upstream: https://github.com/smcameron/open-simplex-noise-in-c * Version: git (0d555e7, 2015) @@ -372,10 +347,6 @@ Collection of single-file libraries used in Godot components. * Upstream: http://www.pcg-random.org * Version: minimal C implementation, http://www.pcg-random.org/download.html * License: Apache 2.0 -- `sha256.{c,h}` - * Upstream: https://github.com/ilvn/SHA256 - * Version: git (35ff823, 2015) - * License: ISC - `smaz.{c,h}` * Upstream: https://github.com/antirez/smaz * Version: git (150e125, 2009) @@ -420,7 +391,7 @@ Collection of single-file libraries used in Godot components. * License: Public Domain (Unlicense) or MIT - `stb_vorbis.c` * Upstream: https://github.com/nothings/stb - * Version: 1.15 + * Version: 1.16 * License: Public Domain (Unlicense) or MIT @@ -455,8 +426,8 @@ Files extracted from upstream source: ## pcre2 -- Upstream: http://www.pcre.org/ -- Version: 10.32 +- Upstream: http://www.pcre.org +- Version: 10.33 - License: BSD-3-Clause Files extracted from upstream source: @@ -540,7 +511,7 @@ folder. ## xatlas - Upstream: https://github.com/jpcy/xatlas -- Version: git (b8ec29b, 2018) +- Version: git (f65a664, 2019) - License: MIT Files extracted from upstream source: diff --git a/thirdparty/assimp/include/assimp/types.h b/thirdparty/assimp/include/assimp/types.h index 748e4851f3..331b8cd03f 100644 --- a/thirdparty/assimp/include/assimp/types.h +++ b/thirdparty/assimp/include/assimp/types.h @@ -161,7 +161,14 @@ struct aiColor3D explicit aiColor3D (ai_real _r) : r(_r), g(_r), b(_r) {} aiColor3D (const aiColor3D& o) : r(o.r), g(o.g), b(o.b) {} - /** Component-wise comparison */ + aiColor3D &operator=(const aiColor3D &o) { + r = o.r; + g = o.g; + b = o.b; + return *this; + } + + /** Component-wise comparison */ // TODO: add epsilon? bool operator == (const aiColor3D& other) const {return r == other.r && g == other.g && b == other.b;} diff --git a/thirdparty/freetype/include/freetype/freetype.h b/thirdparty/freetype/include/freetype/freetype.h index 4f2eaca691..a6bb667e3a 100644 --- a/thirdparty/freetype/include/freetype/freetype.h +++ b/thirdparty/freetype/include/freetype/freetype.h @@ -645,7 +645,7 @@ FT_BEGIN_HEADER * FT_ENCODING_MS_SYMBOL :: * Microsoft Symbol encoding, used to encode mathematical symbols and * wingdings. For more information, see - * 'https://www.microsoft.com/typography/otspec/recom.htm', + * 'https://www.microsoft.com/typography/otspec/recom.htm#non-standard-symbol-fonts', * 'http://www.kostis.net/charsets/symbol.htm', and * 'http://www.kostis.net/charsets/wingding.htm'. * @@ -1766,6 +1766,13 @@ FT_BEGIN_HEADER * transformed, distorted, emboldened, etc. However, it must not be * freed. * + * [Since 2.10.1] If @FT_LOAD_NO_SCALE is set, outline coordinates of + * OpenType variation fonts for a selected instance are internally + * handled as 26.6 fractional font units but returned as (rounded) + * integers, as expected. To get unrounded font units, don't use + * @FT_LOAD_NO_SCALE but load the glyph with @FT_LOAD_NO_HINTING and + * scale it, using the font's `units_per_EM` value as the ppem. + * * num_subglyphs :: * The number of subglyphs in a composite glyph. This field is only * valid for the composite glyph format that should normally only be @@ -3932,8 +3939,8 @@ FT_BEGIN_HEADER * The glyph index. 0~means 'undefined character code'. */ FT_EXPORT( FT_UInt ) - FT_Get_Name_Index( FT_Face face, - FT_String* glyph_name ); + FT_Get_Name_Index( FT_Face face, + const FT_String* glyph_name ); /************************************************************************** @@ -4774,7 +4781,7 @@ FT_BEGIN_HEADER */ #define FREETYPE_MAJOR 2 #define FREETYPE_MINOR 10 -#define FREETYPE_PATCH 0 +#define FREETYPE_PATCH 1 /************************************************************************** diff --git a/thirdparty/freetype/include/freetype/fterrors.h b/thirdparty/freetype/include/freetype/fterrors.h index 58f5a3ead1..2b47eb2096 100644 --- a/thirdparty/freetype/include/freetype/fterrors.h +++ b/thirdparty/freetype/include/freetype/fterrors.h @@ -244,6 +244,8 @@ #define FT_ERR_PROTOS_DEFINED +FT_BEGIN_HEADER + /************************************************************************** * * @function: @@ -274,6 +276,8 @@ FT_EXPORT( const char* ) FT_Error_String( FT_Error error_code ); +FT_END_HEADER + #endif /* FT_ERR_PROTOS_DEFINED */ diff --git a/thirdparty/freetype/include/freetype/ftglyph.h b/thirdparty/freetype/include/freetype/ftglyph.h index 4067c2e62f..fedab8491e 100644 --- a/thirdparty/freetype/include/freetype/ftglyph.h +++ b/thirdparty/freetype/include/freetype/ftglyph.h @@ -210,7 +210,7 @@ FT_BEGIN_HEADER * * As the outline is extracted from a glyph slot, its coordinates are * expressed normally in 26.6 pixels, unless the flag @FT_LOAD_NO_SCALE - * was used in @FT_Load_Glyph() or @FT_Load_Char(). + * was used in @FT_Load_Glyph or @FT_Load_Char. * * The outline's tables are always owned by the object and are destroyed * with it. diff --git a/thirdparty/freetype/include/freetype/ftimage.h b/thirdparty/freetype/include/freetype/ftimage.h index d640b0b0aa..face34fe49 100644 --- a/thirdparty/freetype/include/freetype/ftimage.h +++ b/thirdparty/freetype/include/freetype/ftimage.h @@ -869,7 +869,7 @@ FT_BEGIN_HEADER * * @input: * y :: - * The scanline's y~coordinate. + * The scanline's upward y~coordinate. * * count :: * The number of spans to draw on this scanline. @@ -945,19 +945,16 @@ FT_BEGIN_HEADER * This flag is set to indicate direct rendering. In this mode, client * applications must provide their own span callback. This lets them * directly draw or compose over an existing bitmap. If this bit is - * not set, the target pixmap's buffer _must_ be zeroed before - * rendering. + * _not_ set, the target pixmap's buffer _must_ be zeroed before + * rendering and the output will be clipped to its size. * * Direct rendering is only possible with anti-aliased glyphs. * * FT_RASTER_FLAG_CLIP :: * This flag is only used in direct rendering mode. If set, the output * will be clipped to a box specified in the `clip_box` field of the - * @FT_Raster_Params structure. - * - * Note that by default, the glyph bitmap is clipped to the target - * pixmap, except in direct rendering mode where all spans are - * generated if no clipping box is set. + * @FT_Raster_Params structure. Otherwise, the `clip_box` is + * effectively set to the bounding box and all spans are generated. */ #define FT_RASTER_FLAG_DEFAULT 0x0 #define FT_RASTER_FLAG_AA 0x1 @@ -978,7 +975,8 @@ FT_BEGIN_HEADER * FT_Raster_Params * * @description: - * A structure to hold the arguments used by a raster's render function. + * A structure to hold the parameters used by a raster's render function, + * passed as an argument to @FT_Outline_Render. * * @fields: * target :: diff --git a/thirdparty/freetype/include/freetype/ftmodapi.h b/thirdparty/freetype/include/freetype/ftmodapi.h index 88488bfe89..8d039c4f3a 100644 --- a/thirdparty/freetype/include/freetype/ftmodapi.h +++ b/thirdparty/freetype/include/freetype/ftmodapi.h @@ -623,7 +623,7 @@ FT_BEGIN_HEADER * it is bytecode interpreter's execution context, `TT_ExecContext`, * which is declared in FreeType's internal header file `tttypes.h`. */ - typedef void + typedef FT_Error (*FT_DebugHook_Func)( void* arg ); diff --git a/thirdparty/freetype/include/freetype/ftoutln.h b/thirdparty/freetype/include/freetype/ftoutln.h index 75c3d01596..b72327b703 100644 --- a/thirdparty/freetype/include/freetype/ftoutln.h +++ b/thirdparty/freetype/include/freetype/ftoutln.h @@ -466,8 +466,6 @@ FT_BEGIN_HEADER * * @description: * Render an outline within a bitmap using the current scan-convert. - * This function uses an @FT_Raster_Params structure as an argument, - * allowing advanced features like direct composition, translucency, etc. * * @input: * library :: @@ -485,8 +483,10 @@ FT_BEGIN_HEADER * FreeType error code. 0~means success. * * @note: - * You should know what you are doing and how @FT_Raster_Params works to - * use this function. + * This advanced function uses @FT_Raster_Params as an argument, + * allowing FreeType rasterizer to be used for direct composition, + * translucency, etc. You should know how to set up @FT_Raster_Params + * for this function to work. * * The field `params.source` will be set to `outline` before the scan * converter is called, which means that the value you give to it is diff --git a/thirdparty/freetype/include/freetype/ftwinfnt.h b/thirdparty/freetype/include/freetype/ftwinfnt.h index 3437913d53..a2fba903d2 100644 --- a/thirdparty/freetype/include/freetype/ftwinfnt.h +++ b/thirdparty/freetype/include/freetype/ftwinfnt.h @@ -58,7 +58,7 @@ FT_BEGIN_HEADER * @description: * A list of valid values for the `charset` byte in @FT_WinFNT_HeaderRec. * Exact mapping tables for the various 'cpXXXX' encodings (except for - * 'cp1361') can be found at 'ftp://ftp.unicode.org/Public' in the + * 'cp1361') can be found at 'ftp://ftp.unicode.org/Public/' in the * `MAPPINGS/VENDORS/MICSFT/WINDOWS` subdirectory. 'cp1361' is roughly a * superset of `MAPPINGS/OBSOLETE/EASTASIA/KSC/JOHAB.TXT`. * diff --git a/thirdparty/freetype/include/freetype/internal/ftcalc.h b/thirdparty/freetype/include/freetype/internal/ftcalc.h index 2986ec359b..1811fcd1ea 100644 --- a/thirdparty/freetype/include/freetype/internal/ftcalc.h +++ b/thirdparty/freetype/include/freetype/internal/ftcalc.h @@ -378,6 +378,7 @@ FT_BEGIN_HEADER #if FT_SIZEOF_INT == 4 #include <intrin.h> +#pragma intrinsic( _BitScanReverse ) static __inline FT_Int32 FT_MSB_i386( FT_UInt32 x ) @@ -385,7 +386,6 @@ FT_BEGIN_HEADER unsigned long where; - /* not available in older VC versions */ _BitScanReverse( &where, x ); return (FT_Int32)where; diff --git a/thirdparty/freetype/include/freetype/internal/ftobjs.h b/thirdparty/freetype/include/freetype/internal/ftobjs.h index f3a41b35ab..0c1d3e5bf2 100644 --- a/thirdparty/freetype/include/freetype/internal/ftobjs.h +++ b/thirdparty/freetype/include/freetype/internal/ftobjs.h @@ -278,14 +278,12 @@ FT_BEGIN_HEADER #ifdef FT_CONFIG_OPTION_SUBPIXEL_RENDERING typedef void (*FT_Bitmap_LcdFilterFunc)( FT_Bitmap* bitmap, - FT_Render_Mode render_mode, FT_Byte* weights ); /* This is the default LCD filter, an in-place, 5-tap FIR filter. */ FT_BASE( void ) ft_lcd_filter_fir( FT_Bitmap* bitmap, - FT_Render_Mode mode, FT_LcdFiveTapFilter weights ); #endif /* FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ @@ -941,8 +939,8 @@ FT_BEGIN_HEADER FT_UInt buffer_max ); typedef FT_UInt - (*FT_Face_GetGlyphNameIndexFunc)( FT_Face face, - FT_String* glyph_name ); + (*FT_Face_GetGlyphNameIndexFunc)( FT_Face face, + const FT_String* glyph_name ); #ifndef FT_CONFIG_OPTION_NO_DEFAULT_SYSTEM diff --git a/thirdparty/freetype/include/freetype/internal/ftstream.h b/thirdparty/freetype/include/freetype/internal/ftstream.h index e4dca0b0a5..a579a039b9 100644 --- a/thirdparty/freetype/include/freetype/internal/ftstream.h +++ b/thirdparty/freetype/include/freetype/internal/ftstream.h @@ -166,6 +166,17 @@ FT_BEGIN_HEADER /* + * function acts on increases does range for emits + * pointer checking frames error + * ------------------------------------------------------------------- + * FT_PEEK_XXX buffer pointer no no no no + * FT_NEXT_XXX buffer pointer yes no no no + * FT_GET_XXX stream->cursor yes yes yes no + * FT_READ_XXX stream->pos yes yes no yes + */ + + + /* * `FT_PEEK_XXX' are generic macros to get data from a buffer position. No * safety checks are performed. */ diff --git a/thirdparty/freetype/include/freetype/internal/fttrace.h b/thirdparty/freetype/include/freetype/internal/fttrace.h index 8089babfb6..f5f9598046 100644 --- a/thirdparty/freetype/include/freetype/internal/fttrace.h +++ b/thirdparty/freetype/include/freetype/internal/fttrace.h @@ -48,6 +48,7 @@ FT_TRACE_DEF( cache ) /* cache sub-system (ftcache.c, etc.) */ /* SFNT driver components */ FT_TRACE_DEF( sfdriver ) /* SFNT font driver (sfdriver.c) */ FT_TRACE_DEF( sfobjs ) /* SFNT object handler (sfobjs.c) */ +FT_TRACE_DEF( sfwoff ) /* WOFF format handler (sfwoff.c) */ FT_TRACE_DEF( ttbdf ) /* TrueType embedded BDF (ttbdf.c) */ FT_TRACE_DEF( ttcmap ) /* charmap handler (ttcmap.c) */ FT_TRACE_DEF( ttcolr ) /* glyph layer table (ttcolr.c) */ diff --git a/thirdparty/freetype/include/freetype/internal/internal.h b/thirdparty/freetype/include/freetype/internal/internal.h index 173d8ad906..3c8830f7e4 100644 --- a/thirdparty/freetype/include/freetype/internal/internal.h +++ b/thirdparty/freetype/include/freetype/internal/internal.h @@ -40,6 +40,7 @@ #define FT_INTERNAL_TRUETYPE_TYPES_H <freetype/internal/tttypes.h> #define FT_INTERNAL_TYPE1_TYPES_H <freetype/internal/t1types.h> +#define FT_INTERNAL_WOFF_TYPES_H <freetype/internal/wofftypes.h> #define FT_INTERNAL_POSTSCRIPT_AUX_H <freetype/internal/psaux.h> #define FT_INTERNAL_POSTSCRIPT_HINTS_H <freetype/internal/pshints.h> diff --git a/thirdparty/freetype/include/freetype/internal/psaux.h b/thirdparty/freetype/include/freetype/internal/psaux.h index 3ab01c3e68..f962a973de 100644 --- a/thirdparty/freetype/include/freetype/internal/psaux.h +++ b/thirdparty/freetype/include/freetype/internal/psaux.h @@ -96,10 +96,10 @@ FT_BEGIN_HEADER (*done)( PS_Table table ); FT_Error - (*add)( PS_Table table, - FT_Int idx, - void* object, - FT_UInt length ); + (*add)( PS_Table table, + FT_Int idx, + const void* object, + FT_UInt length ); void (*release)( PS_Table table ); diff --git a/thirdparty/freetype/include/freetype/internal/services/svgldict.h b/thirdparty/freetype/include/freetype/internal/services/svgldict.h index ca8edf0eb5..0949621835 100644 --- a/thirdparty/freetype/include/freetype/internal/services/svgldict.h +++ b/thirdparty/freetype/include/freetype/internal/services/svgldict.h @@ -41,8 +41,8 @@ FT_BEGIN_HEADER FT_UInt buffer_max ); typedef FT_UInt - (*FT_GlyphDict_NameIndexFunc)( FT_Face face, - FT_String* glyph_name ); + (*FT_GlyphDict_NameIndexFunc)( FT_Face face, + const FT_String* glyph_name ); FT_DEFINE_SERVICE( GlyphDict ) diff --git a/thirdparty/freetype/include/freetype/internal/sfnt.h b/thirdparty/freetype/include/freetype/internal/sfnt.h index 225f40df6e..b19241c306 100644 --- a/thirdparty/freetype/include/freetype/internal/sfnt.h +++ b/thirdparty/freetype/include/freetype/internal/sfnt.h @@ -23,6 +23,7 @@ #include <ft2build.h> #include FT_INTERNAL_DRIVER_H #include FT_INTERNAL_TRUETYPE_TYPES_H +#include FT_INTERNAL_WOFF_TYPES_H FT_BEGIN_HEADER diff --git a/thirdparty/freetype/include/freetype/internal/t1types.h b/thirdparty/freetype/include/freetype/internal/t1types.h index e197a1afca..d94c8c1284 100644 --- a/thirdparty/freetype/include/freetype/internal/t1types.h +++ b/thirdparty/freetype/include/freetype/internal/t1types.h @@ -76,8 +76,8 @@ FT_BEGIN_HEADER FT_Int code_first; FT_Int code_last; - FT_UShort* char_index; - FT_String** char_name; + FT_UShort* char_index; + const FT_String** char_name; } T1_EncodingRec, *T1_Encoding; diff --git a/thirdparty/freetype/include/freetype/internal/tttypes.h b/thirdparty/freetype/include/freetype/internal/tttypes.h index 5e9f40ec3f..23db240e7c 100644 --- a/thirdparty/freetype/include/freetype/internal/tttypes.h +++ b/thirdparty/freetype/include/freetype/internal/tttypes.h @@ -153,81 +153,6 @@ FT_BEGIN_HEADER /************************************************************************** * * @struct: - * WOFF_HeaderRec - * - * @description: - * WOFF file format header. - * - * @fields: - * See - * - * https://www.w3.org/TR/WOFF/#WOFFHeader - */ - typedef struct WOFF_HeaderRec_ - { - FT_ULong signature; - FT_ULong flavor; - FT_ULong length; - FT_UShort num_tables; - FT_UShort reserved; - FT_ULong totalSfntSize; - FT_UShort majorVersion; - FT_UShort minorVersion; - FT_ULong metaOffset; - FT_ULong metaLength; - FT_ULong metaOrigLength; - FT_ULong privOffset; - FT_ULong privLength; - - } WOFF_HeaderRec, *WOFF_Header; - - - /************************************************************************** - * - * @struct: - * WOFF_TableRec - * - * @description: - * This structure describes a given table of a WOFF font. - * - * @fields: - * Tag :: - * A four-bytes tag describing the table. - * - * Offset :: - * The offset of the table from the start of the WOFF font in its - * resource. - * - * CompLength :: - * Compressed table length (in bytes). - * - * OrigLength :: - * Uncompressed table length (in bytes). - * - * CheckSum :: - * The table checksum. This value can be ignored. - * - * OrigOffset :: - * The uncompressed table file offset. This value gets computed while - * constructing the (uncompressed) SFNT header. It is not contained in - * the WOFF file. - */ - typedef struct WOFF_TableRec_ - { - FT_ULong Tag; /* table ID */ - FT_ULong Offset; /* table file offset */ - FT_ULong CompLength; /* compressed table length */ - FT_ULong OrigLength; /* uncompressed table length */ - FT_ULong CheckSum; /* uncompressed checksum */ - - FT_ULong OrigOffset; /* uncompressed table file offset */ - /* (not in the WOFF file) */ - } WOFF_TableRec, *WOFF_Table; - - - /************************************************************************** - * - * @struct: * TT_LongMetricsRec * * @description: @@ -1395,8 +1320,10 @@ FT_BEGIN_HEADER * * cvt :: * The face's original control value table. Coordinates are expressed - * in unscaled font units. Comes from the 'cvt~' table. Ignored for - * Type 2 fonts. + * in unscaled font units (in 26.6 format). Comes from the 'cvt~' + * table. Ignored for Type 2 fonts. + * + * If varied by the `CVAR' table, non-integer values are possible. * * interpreter :: * A pointer to the TrueType bytecode interpreters field is also used @@ -1633,7 +1560,7 @@ FT_BEGIN_HEADER /* the original, unscaled, control value table */ FT_ULong cvt_size; - FT_Short* cvt; + FT_Int32* cvt; /* A pointer to the bytecode interpreter to use. This is also */ /* used to hook the debugger for the `ttdebug' utility. */ diff --git a/thirdparty/freetype/include/freetype/internal/wofftypes.h b/thirdparty/freetype/include/freetype/internal/wofftypes.h new file mode 100644 index 0000000000..ba55bf883e --- /dev/null +++ b/thirdparty/freetype/include/freetype/internal/wofftypes.h @@ -0,0 +1,112 @@ +/**************************************************************************** + * + * wofftypes.h + * + * Basic WOFF/WOFF2 type definitions and interface (specification + * only). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#ifndef WOFFTYPES_H_ +#define WOFFTYPES_H_ + + +#include <ft2build.h> +#include FT_TRUETYPE_TABLES_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + /************************************************************************** + * + * @struct: + * WOFF_HeaderRec + * + * @description: + * WOFF file format header. + * + * @fields: + * See + * + * https://www.w3.org/TR/WOFF/#WOFFHeader + */ + typedef struct WOFF_HeaderRec_ + { + FT_ULong signature; + FT_ULong flavor; + FT_ULong length; + FT_UShort num_tables; + FT_UShort reserved; + FT_ULong totalSfntSize; + FT_UShort majorVersion; + FT_UShort minorVersion; + FT_ULong metaOffset; + FT_ULong metaLength; + FT_ULong metaOrigLength; + FT_ULong privOffset; + FT_ULong privLength; + + } WOFF_HeaderRec, *WOFF_Header; + + + /************************************************************************** + * + * @struct: + * WOFF_TableRec + * + * @description: + * This structure describes a given table of a WOFF font. + * + * @fields: + * Tag :: + * A four-bytes tag describing the table. + * + * Offset :: + * The offset of the table from the start of the WOFF font in its + * resource. + * + * CompLength :: + * Compressed table length (in bytes). + * + * OrigLength :: + * Uncompressed table length (in bytes). + * + * CheckSum :: + * The table checksum. This value can be ignored. + * + * OrigOffset :: + * The uncompressed table file offset. This value gets computed while + * constructing the (uncompressed) SFNT header. It is not contained in + * the WOFF file. + */ + typedef struct WOFF_TableRec_ + { + FT_ULong Tag; /* table ID */ + FT_ULong Offset; /* table file offset */ + FT_ULong CompLength; /* compressed table length */ + FT_ULong OrigLength; /* uncompressed table length */ + FT_ULong CheckSum; /* uncompressed checksum */ + + FT_ULong OrigOffset; /* uncompressed table file offset */ + /* (not in the WOFF file) */ + } WOFF_TableRec, *WOFF_Table; + + +FT_END_HEADER + +#endif /* WOFFTYPES_H_ */ + + +/* END */ diff --git a/thirdparty/freetype/src/autofit/afblue.c b/thirdparty/freetype/src/autofit/afblue.c index 28da159008..b99dbeb19c 100644 --- a/thirdparty/freetype/src/autofit/afblue.c +++ b/thirdparty/freetype/src/autofit/afblue.c @@ -296,6 +296,10 @@ '\0', '\xE0', '\xB4', '\x9F', ' ', '\xE0', '\xB4', '\xA0', ' ', '\xE0', '\xB4', '\xA7', ' ', '\xE0', '\xB4', '\xB6', ' ', '\xE0', '\xB4', '\x98', ' ', '\xE0', '\xB4', '\x9A', ' ', '\xE0', '\xB4', '\xA5', ' ', '\xE0', '\xB4', '\xB2', /* à´Ÿ à´ à´§ à´¶ à´˜ à´š à´¥ à´² */ '\0', + '\xE1', '\xA0', '\xB3', ' ', '\xE1', '\xA0', '\xB4', ' ', '\xE1', '\xA0', '\xB6', ' ', '\xE1', '\xA0', '\xBD', ' ', '\xE1', '\xA1', '\x82', ' ', '\xE1', '\xA1', '\x8A', ' ', '\xE2', '\x80', '\x8D', '\xE1', '\xA1', '\xA1', '\xE2', '\x80', '\x8D', ' ', '\xE2', '\x80', '\x8D', '\xE1', '\xA1', '\xB3', '\xE2', '\x80', '\x8D', /* á ³ á ´ á ¶ á ½ á¡‚ ᡊ â€á¡¡â€ â€á¡³â€ */ + '\0', + '\xE1', '\xA1', '\x83', /* ᡃ */ + '\0', '\xE1', '\x80', '\x81', ' ', '\xE1', '\x80', '\x82', ' ', '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\xA5', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* ဠဂ င ဒ ဠᥠአዠ*/ '\0', '\xE1', '\x80', '\x84', ' ', '\xE1', '\x80', '\x8E', ' ', '\xE1', '\x80', '\x92', ' ', '\xE1', '\x80', '\x95', ' ', '\xE1', '\x80', '\x97', ' ', '\xE1', '\x80', '\x9D', ' ', '\xE1', '\x81', '\x8A', ' ', '\xE1', '\x81', '\x8B', /* င ဎ ဒ ပ ဗ ဠአዠ*/ @@ -649,6 +653,9 @@ { AF_BLUE_STRING_MALAYALAM_TOP, AF_BLUE_PROPERTY_LATIN_TOP }, { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 }, { AF_BLUE_STRING_MAX, 0 }, + { AF_BLUE_STRING_MONGOLIAN_TOP_BASE, AF_BLUE_PROPERTY_LATIN_TOP }, + { AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE, 0 }, + { AF_BLUE_STRING_MAX, 0 }, { AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT }, { AF_BLUE_STRING_MYANMAR_BOTTOM, 0 }, diff --git a/thirdparty/freetype/src/autofit/afblue.dat b/thirdparty/freetype/src/autofit/afblue.dat index 14a0993b61..46db43fe22 100644 --- a/thirdparty/freetype/src/autofit/afblue.dat +++ b/thirdparty/freetype/src/autofit/afblue.dat @@ -392,6 +392,11 @@ AF_BLUE_STRING_ENUM AF_BLUE_STRINGS_ARRAY AF_BLUE_STRING_MAX_LEN: AF_BLUE_STRING_MALAYALAM_BOTTOM "à´Ÿ à´ à´§ à´¶ à´˜ à´š à´¥ à´²" + AF_BLUE_STRING_MONGOLIAN_TOP_BASE + "á ³ á ´ á ¶ á ½ á¡‚ ᡊ â€á¡¡â€ â€á¡³â€" + AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE + "ᡃ" + AF_BLUE_STRING_MYANMAR_TOP "ဠဂ င ဒ ဠᥠአá‹" AF_BLUE_STRING_MYANMAR_BOTTOM @@ -947,6 +952,11 @@ AF_BLUE_STRINGSET_ENUM AF_BLUE_STRINGSETS_ARRAY AF_BLUE_STRINGSET_MAX_LEN: { AF_BLUE_STRING_MALAYALAM_BOTTOM, 0 } { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_MONG + { AF_BLUE_STRING_MONGOLIAN_TOP_BASE, AF_BLUE_PROPERTY_LATIN_TOP } + { AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE, 0 } + { AF_BLUE_STRING_MAX, 0 } + AF_BLUE_STRINGSET_MYMR { AF_BLUE_STRING_MYANMAR_TOP, AF_BLUE_PROPERTY_LATIN_TOP | AF_BLUE_PROPERTY_LATIN_X_HEIGHT } diff --git a/thirdparty/freetype/src/autofit/afblue.h b/thirdparty/freetype/src/autofit/afblue.h index a2ff597b8e..b69b1df521 100644 --- a/thirdparty/freetype/src/autofit/afblue.h +++ b/thirdparty/freetype/src/autofit/afblue.h @@ -212,56 +212,58 @@ FT_BEGIN_HEADER AF_BLUE_STRING_LISU_BOTTOM = 3506, AF_BLUE_STRING_MALAYALAM_TOP = 3538, AF_BLUE_STRING_MALAYALAM_BOTTOM = 3582, - AF_BLUE_STRING_MYANMAR_TOP = 3614, - AF_BLUE_STRING_MYANMAR_BOTTOM = 3646, - AF_BLUE_STRING_MYANMAR_ASCENDER = 3678, - AF_BLUE_STRING_MYANMAR_DESCENDER = 3706, - AF_BLUE_STRING_NKO_TOP = 3738, - AF_BLUE_STRING_NKO_BOTTOM = 3762, - AF_BLUE_STRING_NKO_SMALL_TOP = 3777, - AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3786, - AF_BLUE_STRING_OL_CHIKI = 3798, - AF_BLUE_STRING_OLD_TURKIC_TOP = 3822, - AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3837, - AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3857, - AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3897, - AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3927, - AF_BLUE_STRING_OSAGE_SMALL_TOP = 3942, - AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 3982, - AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4022, - AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4047, - AF_BLUE_STRING_OSMANYA_TOP = 4062, - AF_BLUE_STRING_OSMANYA_BOTTOM = 4102, - AF_BLUE_STRING_SAURASHTRA_TOP = 4142, - AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4174, - AF_BLUE_STRING_SHAVIAN_TOP = 4194, - AF_BLUE_STRING_SHAVIAN_BOTTOM = 4204, - AF_BLUE_STRING_SHAVIAN_DESCENDER = 4229, - AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4239, - AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4274, - AF_BLUE_STRING_SINHALA_TOP = 4289, - AF_BLUE_STRING_SINHALA_BOTTOM = 4321, - AF_BLUE_STRING_SINHALA_DESCENDER = 4353, - AF_BLUE_STRING_SUNDANESE_TOP = 4397, - AF_BLUE_STRING_SUNDANESE_BOTTOM = 4421, - AF_BLUE_STRING_SUNDANESE_DESCENDER = 4453, - AF_BLUE_STRING_TAI_VIET_TOP = 4461, - AF_BLUE_STRING_TAI_VIET_BOTTOM = 4481, - AF_BLUE_STRING_TAMIL_TOP = 4493, - AF_BLUE_STRING_TAMIL_BOTTOM = 4525, - AF_BLUE_STRING_TELUGU_TOP = 4557, - AF_BLUE_STRING_TELUGU_BOTTOM = 4585, - AF_BLUE_STRING_THAI_TOP = 4613, - AF_BLUE_STRING_THAI_BOTTOM = 4637, - AF_BLUE_STRING_THAI_ASCENDER = 4665, - AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4677, - AF_BLUE_STRING_THAI_DESCENDER = 4689, - AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4705, - AF_BLUE_STRING_THAI_DIGIT_TOP = 4713, - AF_BLUE_STRING_TIFINAGH = 4725, - AF_BLUE_STRING_VAI_TOP = 4757, - AF_BLUE_STRING_VAI_BOTTOM = 4789, - af_blue_1_1 = 4820, + AF_BLUE_STRING_MONGOLIAN_TOP_BASE = 3614, + AF_BLUE_STRING_MONGOLIAN_BOTTOM_BASE = 3658, + AF_BLUE_STRING_MYANMAR_TOP = 3662, + AF_BLUE_STRING_MYANMAR_BOTTOM = 3694, + AF_BLUE_STRING_MYANMAR_ASCENDER = 3726, + AF_BLUE_STRING_MYANMAR_DESCENDER = 3754, + AF_BLUE_STRING_NKO_TOP = 3786, + AF_BLUE_STRING_NKO_BOTTOM = 3810, + AF_BLUE_STRING_NKO_SMALL_TOP = 3825, + AF_BLUE_STRING_NKO_SMALL_BOTTOM = 3834, + AF_BLUE_STRING_OL_CHIKI = 3846, + AF_BLUE_STRING_OLD_TURKIC_TOP = 3870, + AF_BLUE_STRING_OLD_TURKIC_BOTTOM = 3885, + AF_BLUE_STRING_OSAGE_CAPITAL_TOP = 3905, + AF_BLUE_STRING_OSAGE_CAPITAL_BOTTOM = 3945, + AF_BLUE_STRING_OSAGE_CAPITAL_DESCENDER = 3975, + AF_BLUE_STRING_OSAGE_SMALL_TOP = 3990, + AF_BLUE_STRING_OSAGE_SMALL_BOTTOM = 4030, + AF_BLUE_STRING_OSAGE_SMALL_ASCENDER = 4070, + AF_BLUE_STRING_OSAGE_SMALL_DESCENDER = 4095, + AF_BLUE_STRING_OSMANYA_TOP = 4110, + AF_BLUE_STRING_OSMANYA_BOTTOM = 4150, + AF_BLUE_STRING_SAURASHTRA_TOP = 4190, + AF_BLUE_STRING_SAURASHTRA_BOTTOM = 4222, + AF_BLUE_STRING_SHAVIAN_TOP = 4242, + AF_BLUE_STRING_SHAVIAN_BOTTOM = 4252, + AF_BLUE_STRING_SHAVIAN_DESCENDER = 4277, + AF_BLUE_STRING_SHAVIAN_SMALL_TOP = 4287, + AF_BLUE_STRING_SHAVIAN_SMALL_BOTTOM = 4322, + AF_BLUE_STRING_SINHALA_TOP = 4337, + AF_BLUE_STRING_SINHALA_BOTTOM = 4369, + AF_BLUE_STRING_SINHALA_DESCENDER = 4401, + AF_BLUE_STRING_SUNDANESE_TOP = 4445, + AF_BLUE_STRING_SUNDANESE_BOTTOM = 4469, + AF_BLUE_STRING_SUNDANESE_DESCENDER = 4501, + AF_BLUE_STRING_TAI_VIET_TOP = 4509, + AF_BLUE_STRING_TAI_VIET_BOTTOM = 4529, + AF_BLUE_STRING_TAMIL_TOP = 4541, + AF_BLUE_STRING_TAMIL_BOTTOM = 4573, + AF_BLUE_STRING_TELUGU_TOP = 4605, + AF_BLUE_STRING_TELUGU_BOTTOM = 4633, + AF_BLUE_STRING_THAI_TOP = 4661, + AF_BLUE_STRING_THAI_BOTTOM = 4685, + AF_BLUE_STRING_THAI_ASCENDER = 4713, + AF_BLUE_STRING_THAI_LARGE_ASCENDER = 4725, + AF_BLUE_STRING_THAI_DESCENDER = 4737, + AF_BLUE_STRING_THAI_LARGE_DESCENDER = 4753, + AF_BLUE_STRING_THAI_DIGIT_TOP = 4761, + AF_BLUE_STRING_TIFINAGH = 4773, + AF_BLUE_STRING_VAI_TOP = 4805, + AF_BLUE_STRING_VAI_BOTTOM = 4837, + af_blue_1_1 = 4868, #ifdef AF_CONFIG_OPTION_CJK AF_BLUE_STRING_CJK_TOP = af_blue_1_1 + 1, AF_BLUE_STRING_CJK_BOTTOM = af_blue_1_1 + 203, @@ -355,24 +357,25 @@ FT_BEGIN_HEADER AF_BLUE_STRINGSET_LATP = 166, AF_BLUE_STRINGSET_LISU = 173, AF_BLUE_STRINGSET_MLYM = 176, - AF_BLUE_STRINGSET_MYMR = 179, - AF_BLUE_STRINGSET_NKOO = 184, - AF_BLUE_STRINGSET_NONE = 189, - AF_BLUE_STRINGSET_OLCK = 190, - AF_BLUE_STRINGSET_ORKH = 193, - AF_BLUE_STRINGSET_OSGE = 196, - AF_BLUE_STRINGSET_OSMA = 204, - AF_BLUE_STRINGSET_SAUR = 207, - AF_BLUE_STRINGSET_SHAW = 210, - AF_BLUE_STRINGSET_SINH = 216, - AF_BLUE_STRINGSET_SUND = 220, - AF_BLUE_STRINGSET_TAML = 224, - AF_BLUE_STRINGSET_TAVT = 227, - AF_BLUE_STRINGSET_TELU = 230, - AF_BLUE_STRINGSET_TFNG = 233, - AF_BLUE_STRINGSET_THAI = 236, - AF_BLUE_STRINGSET_VAII = 244, - af_blue_2_1 = 247, + AF_BLUE_STRINGSET_MONG = 179, + AF_BLUE_STRINGSET_MYMR = 182, + AF_BLUE_STRINGSET_NKOO = 187, + AF_BLUE_STRINGSET_NONE = 192, + AF_BLUE_STRINGSET_OLCK = 193, + AF_BLUE_STRINGSET_ORKH = 196, + AF_BLUE_STRINGSET_OSGE = 199, + AF_BLUE_STRINGSET_OSMA = 207, + AF_BLUE_STRINGSET_SAUR = 210, + AF_BLUE_STRINGSET_SHAW = 213, + AF_BLUE_STRINGSET_SINH = 219, + AF_BLUE_STRINGSET_SUND = 223, + AF_BLUE_STRINGSET_TAML = 227, + AF_BLUE_STRINGSET_TAVT = 230, + AF_BLUE_STRINGSET_TELU = 233, + AF_BLUE_STRINGSET_TFNG = 236, + AF_BLUE_STRINGSET_THAI = 239, + AF_BLUE_STRINGSET_VAII = 247, + af_blue_2_1 = 250, #ifdef AF_CONFIG_OPTION_CJK AF_BLUE_STRINGSET_HANI = af_blue_2_1 + 0, af_blue_2_1_1 = af_blue_2_1 + 2, diff --git a/thirdparty/freetype/src/autofit/afcjk.c b/thirdparty/freetype/src/autofit/afcjk.c index 3b2b1cf24c..a61689bee3 100644 --- a/thirdparty/freetype/src/autofit/afcjk.c +++ b/thirdparty/freetype/src/autofit/afcjk.c @@ -1184,6 +1184,8 @@ seg = edge->first; + if ( !seg ) + goto Skip_Loop; do { @@ -1239,13 +1241,14 @@ edge2->flags |= AF_EDGE_SERIF; } else - edge->link = edge2; + edge->link = edge2; } seg = seg->edge_next; } while ( seg != edge->first ); + Skip_Loop: /* set the round/straight flags */ edge->flags = AF_EDGE_NORMAL; diff --git a/thirdparty/freetype/src/autofit/afglobal.c b/thirdparty/freetype/src/autofit/afglobal.c index 7183ce4a78..6a9a1e5aaa 100644 --- a/thirdparty/freetype/src/autofit/afglobal.c +++ b/thirdparty/freetype/src/autofit/afglobal.c @@ -443,6 +443,7 @@ style = (AF_Style)( globals->glyph_styles[gindex] & AF_STYLE_UNASSIGNED ); + Again: style_class = af_style_classes[style]; writing_system_class = af_writing_system_classes [style_class->writing_system]; @@ -470,6 +471,16 @@ writing_system_class->style_metrics_done( metrics ); FT_FREE( metrics ); + + /* internal error code -1 indicates */ + /* that no blue zones have been found */ + if ( error == -1 ) + { + style = (AF_Style)( globals->glyph_styles[gindex] & + AF_STYLE_UNASSIGNED ); + goto Again; + } + goto Exit; } } diff --git a/thirdparty/freetype/src/autofit/aflatin.c b/thirdparty/freetype/src/autofit/aflatin.c index dccdcaf345..27d4024882 100644 --- a/thirdparty/freetype/src/autofit/aflatin.c +++ b/thirdparty/freetype/src/autofit/aflatin.c @@ -149,7 +149,11 @@ af_shaper_buf_destroy( face, shaper_buf ); if ( !glyph_index ) + { + FT_TRACE5(( "standard character missing;" + " using fallback stem widths\n" )); goto Exit; + } FT_TRACE5(( "standard character: U+%04lX (glyph index %d)\n", ch, glyph_index )); @@ -312,7 +316,7 @@ /* Find all blue zones. Flat segments give the reference points, */ /* round segments the overshoot positions. */ - static void + static int af_latin_metrics_init_blues( AF_LatinMetrics metrics, FT_Face face ) { @@ -981,10 +985,11 @@ af_shaper_buf_destroy( face, shaper_buf ); - /* we finally check whether blue zones are ordered; */ - /* `ref' and `shoot' values of two blue zones must not overlap */ if ( axis->blue_count ) { + /* we finally check whether blue zones are ordered; */ + /* `ref' and `shoot' values of two blue zones must not overlap */ + FT_UInt i; AF_LatinBlue blue_sorted[AF_BLUE_STRINGSET_MAX_LEN + 2]; @@ -1033,11 +1038,34 @@ *a )); } } + + FT_TRACE5(( "\n" )); + + return 0; } + else + { + /* disable hinting for the current style if there are no blue zones */ - FT_TRACE5(( "\n" )); + AF_FaceGlobals globals = metrics->root.globals; + FT_UShort* gstyles = globals->glyph_styles; + + FT_Long i; + + + FT_TRACE5(( "no blue zones found:" + " hinting disabled for this style\n" )); - return; + for ( i = 0; i < globals->glyph_count; i++ ) + { + if ( ( gstyles[i] & AF_STYLE_MASK ) == sc->style ) + gstyles[i] = AF_STYLE_NONE_DFLT; + } + + FT_TRACE5(( "\n" )); + + return 1; + } } @@ -1116,6 +1144,8 @@ af_latin_metrics_init( AF_LatinMetrics metrics, FT_Face face ) { + FT_Error error = FT_Err_Ok; + FT_CharMap oldmap = face->charmap; @@ -1124,12 +1154,18 @@ if ( !FT_Select_Charmap( face, FT_ENCODING_UNICODE ) ) { af_latin_metrics_init_widths( metrics, face ); - af_latin_metrics_init_blues( metrics, face ); + if ( af_latin_metrics_init_blues( metrics, face ) ) + { + /* use internal error code to indicate missing blue zones */ + error = -1; + goto Exit; + } af_latin_metrics_check_digits( metrics, face ); } + Exit: FT_Set_Charmap( face, oldmap ); - return FT_Err_Ok; + return error; } @@ -1443,13 +1479,13 @@ nn, blue->ref.org, blue->ref.fit / 64.0, - blue->flags & AF_LATIN_BLUE_ACTIVE ? "" - : " (inactive)", + ( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? "" + : " (inactive)", nn, blue->shoot.org, blue->shoot.fit / 64.0, - blue->flags & AF_LATIN_BLUE_ACTIVE ? "" - : " (inactive)" )); + ( blue->flags & AF_LATIN_BLUE_ACTIVE ) ? "" + : " (inactive)" )); } #endif } diff --git a/thirdparty/freetype/src/autofit/afranges.c b/thirdparty/freetype/src/autofit/afranges.c index c0dba818a1..45c8bbfc95 100644 --- a/thirdparty/freetype/src/autofit/afranges.c +++ b/thirdparty/freetype/src/autofit/afranges.c @@ -664,6 +664,21 @@ }; + const AF_Script_UniRangeRec af_mong_uniranges[] = + { + AF_UNIRANGE_REC( 0x1800, 0x18AF ), /* Mongolian */ + AF_UNIRANGE_REC( 0x11660, 0x1167F ), /* Mongolian Supplement */ + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_mong_nonbase_uniranges[] = + { + AF_UNIRANGE_REC( 0x1885, 0x1886 ), + AF_UNIRANGE_REC( 0x18A9, 0x18A9 ), + AF_UNIRANGE_REC( 0, 0 ) + }; + + const AF_Script_UniRangeRec af_mymr_uniranges[] = { AF_UNIRANGE_REC( 0x1000, 0x109F ), /* Myanmar */ diff --git a/thirdparty/freetype/src/autofit/afscript.h b/thirdparty/freetype/src/autofit/afscript.h index c2f0c7ac60..2da8c70183 100644 --- a/thirdparty/freetype/src/autofit/afscript.h +++ b/thirdparty/freetype/src/autofit/afscript.h @@ -243,6 +243,12 @@ HINTING_BOTTOM_TO_TOP, "\xE0\xB4\xA0 \xE0\xB4\xB1" ) /* à´ à´± */ + SCRIPT( mong, MONG, + "Mongolian", + HB_SCRIPT_MONGOLIAN, + HINTING_TOP_TO_BOTTOM, + "\xE1\xA1\x82 \xE1\xA0\xAA" ) /* á¡‚ á ª */ + SCRIPT( mymr, MYMR, "Myanmar", HB_SCRIPT_MYANMAR, diff --git a/thirdparty/freetype/src/autofit/afstyles.h b/thirdparty/freetype/src/autofit/afstyles.h index edf4f54edd..8d1d70812f 100644 --- a/thirdparty/freetype/src/autofit/afstyles.h +++ b/thirdparty/freetype/src/autofit/afstyles.h @@ -322,6 +322,13 @@ AF_BLUE_STRINGSET_MLYM, AF_COVERAGE_DEFAULT ) + STYLE( mong_dflt, MONG_DFLT, + "Mongolian default style", + AF_WRITING_SYSTEM_LATIN, + AF_SCRIPT_MONG, + AF_BLUE_STRINGSET_MONG, + AF_COVERAGE_DEFAULT ) + STYLE( mymr_dflt, MYMR_DFLT, "Myanmar default style", AF_WRITING_SYSTEM_LATIN, diff --git a/thirdparty/freetype/src/base/ftbbox.c b/thirdparty/freetype/src/base/ftbbox.c index 0b04fde635..a0b2c46f7b 100644 --- a/thirdparty/freetype/src/base/ftbbox.c +++ b/thirdparty/freetype/src/base/ftbbox.c @@ -319,9 +319,9 @@ q2 = q2 + q1; q4 = q4 + q3; q3 = q3 + q2; - q4 = ( q4 + q3 ) / 8; - q3 = q3 / 4; - q2 = q2 / 2; + q4 = ( q4 + q3 ) >> 3; + q3 = q3 >> 2; + q2 = q2 >> 1; } else /* second half */ { @@ -330,9 +330,9 @@ q3 = q3 + q4; q1 = q1 + q2; q2 = q2 + q3; - q1 = ( q1 + q2 ) / 8; - q2 = q2 / 4; - q3 = q3 / 2; + q1 = ( q1 + q2 ) >> 3; + q2 = q2 >> 2; + q3 = q3 >> 1; } /* check whether either end reached the maximum */ diff --git a/thirdparty/freetype/src/base/ftbitmap.c b/thirdparty/freetype/src/base/ftbitmap.c index 1bdcd9eff3..0e0a76fe40 100644 --- a/thirdparty/freetype/src/base/ftbitmap.c +++ b/thirdparty/freetype/src/base/ftbitmap.c @@ -922,12 +922,18 @@ else FT_TRACE5(( " target bitmap: empty\n" )); - FT_TRACE5(( " final bitmap: (%d, %d) -- (%d, %d); %d x %d\n", - final_llx / 64, final_lly / 64, - final_urx / 64, final_ury / 64, - final_width, final_rows )); + if ( final_width && final_rows ) + FT_TRACE5(( " final bitmap: (%d, %d) -- (%d, %d); %d x %d\n", + final_llx / 64, final_lly / 64, + final_urx / 64, final_ury / 64, + final_width, final_rows )); + else + FT_TRACE5(( " final bitmap: empty\n" )); #endif /* FT_DEBUG_LEVEL_TRACE */ + if ( !( final_width && final_rows ) ) + return FT_Err_Ok; /* nothing to do */ + /* for blending, set offset vector of final bitmap */ /* temporarily to (0,0) */ source_llx -= final_llx; @@ -971,6 +977,7 @@ pitch = target->pitch; + if ( pitch < 0 ) pitch = -pitch; diff --git a/thirdparty/freetype/src/base/fterrors.c b/thirdparty/freetype/src/base/fterrors.c index 4ef326d8e2..84fe590289 100644 --- a/thirdparty/freetype/src/base/fterrors.c +++ b/thirdparty/freetype/src/base/fterrors.c @@ -17,6 +17,7 @@ #include <ft2build.h> +#include FT_INTERNAL_DEBUG_H #include FT_ERRORS_H diff --git a/thirdparty/freetype/src/base/ftinit.c b/thirdparty/freetype/src/base/ftinit.c index 9d524effa9..c73cd78b83 100644 --- a/thirdparty/freetype/src/base/ftinit.c +++ b/thirdparty/freetype/src/base/ftinit.c @@ -176,6 +176,9 @@ module_name, property_name, property_value ); + + if ( !*p ) + break; } } diff --git a/thirdparty/freetype/src/base/ftlcdfil.c b/thirdparty/freetype/src/base/ftlcdfil.c index 9fb49ba116..d9f4af4293 100644 --- a/thirdparty/freetype/src/base/ftlcdfil.c +++ b/thirdparty/freetype/src/base/ftlcdfil.c @@ -77,13 +77,13 @@ /* FIR filter used by the default and light filters */ FT_BASE_DEF( void ) ft_lcd_filter_fir( FT_Bitmap* bitmap, - FT_Render_Mode mode, FT_LcdFiveTapFilter weights ) { FT_UInt width = (FT_UInt)bitmap->width; FT_UInt height = (FT_UInt)bitmap->rows; FT_Int pitch = bitmap->pitch; FT_Byte* origin = bitmap->buffer; + FT_Byte mode = bitmap->pixel_mode; /* take care of bitmap flow */ @@ -91,7 +91,7 @@ origin += pitch * (FT_Int)( height - 1 ); /* horizontal in-place FIR filter */ - if ( mode == FT_RENDER_MODE_LCD && width >= 2 ) + if ( mode == FT_PIXEL_MODE_LCD && width >= 2 ) { FT_Byte* line = origin; @@ -134,7 +134,7 @@ } /* vertical in-place FIR filter */ - else if ( mode == FT_RENDER_MODE_LCD_V && height >= 2 ) + else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 2 ) { FT_Byte* column = origin; @@ -183,13 +183,13 @@ /* intra-pixel filter used by the legacy filter */ static void _ft_lcd_filter_legacy( FT_Bitmap* bitmap, - FT_Render_Mode mode, FT_Byte* weights ) { FT_UInt width = (FT_UInt)bitmap->width; FT_UInt height = (FT_UInt)bitmap->rows; FT_Int pitch = bitmap->pitch; FT_Byte* origin = bitmap->buffer; + FT_Byte mode = bitmap->pixel_mode; static const unsigned int filters[3][3] = { @@ -206,7 +206,7 @@ origin += pitch * (FT_Int)( height - 1 ); /* horizontal in-place intra-pixel filter */ - if ( mode == FT_RENDER_MODE_LCD && width >= 3 ) + if ( mode == FT_PIXEL_MODE_LCD && width >= 3 ) { FT_Byte* line = origin; @@ -243,7 +243,7 @@ } } } - else if ( mode == FT_RENDER_MODE_LCD_V && height >= 3 ) + else if ( mode == FT_PIXEL_MODE_LCD_V && height >= 3 ) { FT_Byte* column = origin; diff --git a/thirdparty/freetype/src/base/ftobjs.c b/thirdparty/freetype/src/base/ftobjs.c index 3f8619d3b3..e301f8f11a 100644 --- a/thirdparty/freetype/src/base/ftobjs.c +++ b/thirdparty/freetype/src/base/ftobjs.c @@ -4059,8 +4059,8 @@ /* documentation is in freetype.h */ FT_EXPORT_DEF( FT_UInt ) - FT_Get_Name_Index( FT_Face face, - FT_String* glyph_name ) + FT_Get_Name_Index( FT_Face face, + const FT_String* glyph_name ) { FT_UInt result = 0; diff --git a/thirdparty/freetype/src/base/ftoutln.c b/thirdparty/freetype/src/base/ftoutln.c index 00329b46c6..0e2ba3475d 100644 --- a/thirdparty/freetype/src/base/ftoutln.c +++ b/thirdparty/freetype/src/base/ftoutln.c @@ -46,8 +46,7 @@ void* user ) { #undef SCALED -#define SCALED( x ) ( ( (x) < 0 ? -( -(x) << shift ) \ - : ( (x) << shift ) ) - delta ) +#define SCALED( x ) ( (x) * ( 1L << shift ) - delta ) FT_Vector v_last; FT_Vector v_control; @@ -621,6 +620,16 @@ params->source = (void*)outline; + /* preset clip_box for direct mode */ + if ( params->flags & FT_RASTER_FLAG_DIRECT && + !( params->flags & FT_RASTER_FLAG_CLIP ) ) + { + params->clip_box.xMin = cbox.xMin >> 6; + params->clip_box.yMin = cbox.yMin >> 6; + params->clip_box.xMax = ( cbox.xMax + 63 ) >> 6; + params->clip_box.yMax = ( cbox.yMax + 63 ) >> 6; + } + error = FT_ERR( Cannot_Render_Glyph ); while ( renderer ) { diff --git a/thirdparty/freetype/src/base/ftstroke.c b/thirdparty/freetype/src/base/ftstroke.c index 826062c94e..1b2c0f657c 100644 --- a/thirdparty/freetype/src/base/ftstroke.c +++ b/thirdparty/freetype/src/base/ftstroke.c @@ -86,16 +86,18 @@ base[4].x = base[2].x; - b = base[1].x; - a = base[3].x = ( base[2].x + b ) / 2; - b = base[1].x = ( base[0].x + b ) / 2; - base[2].x = ( a + b ) / 2; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + base[3].x = b >> 1; + base[2].x = ( a + b ) >> 2; + base[1].x = a >> 1; base[4].y = base[2].y; - b = base[1].y; - a = base[3].y = ( base[2].y + b ) / 2; - b = base[1].y = ( base[0].y + b ) / 2; - base[2].y = ( a + b ) / 2; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + base[3].y = b >> 1; + base[2].y = ( a + b ) >> 2; + base[1].y = a >> 1; } @@ -153,28 +155,32 @@ static void ft_cubic_split( FT_Vector* base ) { - FT_Pos a, b, c, d; + FT_Pos a, b, c; base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c ) / 2; - base[5].x = b = ( base[3].x + d ) / 2; - c = ( c + d ) / 2; - base[2].x = a = ( a + c ) / 2; - base[4].x = b = ( b + c ) / 2; - base[3].x = ( a + b ) / 2; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + c = base[2].x + base[3].x; + base[5].x = c >> 1; + c += b; + base[4].x = c >> 2; + base[1].x = a >> 1; + a += b; + base[2].x = a >> 2; + base[3].x = ( a + c ) >> 3; base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c ) / 2; - base[5].y = b = ( base[3].y + d ) / 2; - c = ( c + d ) / 2; - base[2].y = a = ( a + c ) / 2; - base[4].y = b = ( b + c ) / 2; - base[3].y = ( a + b ) / 2; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + c = base[2].y + base[3].y; + base[5].y = c >> 1; + c += b; + base[4].y = c >> 2; + base[1].y = a >> 1; + a += b; + base[2].y = a >> 2; + base[3].y = ( a + c ) >> 3; } diff --git a/thirdparty/freetype/src/base/ftver.rc b/thirdparty/freetype/src/base/ftver.rc index e02a88652c..1354497423 100644 --- a/thirdparty/freetype/src/base/ftver.rc +++ b/thirdparty/freetype/src/base/ftver.rc @@ -18,8 +18,8 @@ #include<windows.h> -#define FT_VERSION 2,10,0,0 -#define FT_VERSION_STR "2.10.0" +#define FT_VERSION 2,10,1,0 +#define FT_VERSION_STR "2.10.1" VS_VERSION_INFO VERSIONINFO FILEVERSION FT_VERSION diff --git a/thirdparty/freetype/src/bdf/bdf.h b/thirdparty/freetype/src/bdf/bdf.h index 4018756f72..d9abd2378f 100644 --- a/thirdparty/freetype/src/bdf/bdf.h +++ b/thirdparty/freetype/src/bdf/bdf.h @@ -109,9 +109,9 @@ FT_BEGIN_HEADER /* There are a set of defaults and each font has their own. */ typedef struct bdf_property_t_ { - char* name; /* Name of the property. */ - int format; /* Format of the property. */ - int builtin; /* A builtin property. */ + const char* name; /* Name of the property. */ + int format; /* Format of the property. */ + int builtin; /* A builtin property. */ union { char* atom; diff --git a/thirdparty/freetype/src/bdf/bdfdrivr.c b/thirdparty/freetype/src/bdf/bdfdrivr.c index 4a11843a1c..60eb93305e 100644 --- a/thirdparty/freetype/src/bdf/bdfdrivr.c +++ b/thirdparty/freetype/src/bdf/bdfdrivr.c @@ -106,7 +106,7 @@ THE SOFTWARE. FT_ULong code; - if ( mid > max || mid < min ) + if ( mid >= max || mid < min ) mid = ( min + max ) >> 1; code = encodings[mid].enc; @@ -152,7 +152,7 @@ THE SOFTWARE. FT_ULong code; /* same as BDF_encoding_el.enc */ - if ( mid > max || mid < min ) + if ( mid >= max || mid < min ) mid = ( min + max ) >> 1; code = encodings[mid].enc; @@ -216,13 +216,13 @@ THE SOFTWARE. bdf_font_t* font = bdf->bdffont; bdf_property_t* prop; - char* strings[4] = { NULL, NULL, NULL, NULL }; - size_t nn, len, lengths[4]; + const char* strings[4] = { NULL, NULL, NULL, NULL }; + size_t lengths[4], nn, len; face->style_flags = 0; - prop = bdf_get_font_property( font, (char *)"SLANT" ); + prop = bdf_get_font_property( font, "SLANT" ); if ( prop && prop->format == BDF_ATOM && prop->value.atom && ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' || @@ -230,30 +230,30 @@ THE SOFTWARE. { face->style_flags |= FT_STYLE_FLAG_ITALIC; strings[2] = ( *(prop->value.atom) == 'O' || *(prop->value.atom) == 'o' ) - ? (char *)"Oblique" - : (char *)"Italic"; + ? "Oblique" + : "Italic"; } - prop = bdf_get_font_property( font, (char *)"WEIGHT_NAME" ); + prop = bdf_get_font_property( font, "WEIGHT_NAME" ); if ( prop && prop->format == BDF_ATOM && prop->value.atom && ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) { face->style_flags |= FT_STYLE_FLAG_BOLD; - strings[1] = (char *)"Bold"; + strings[1] = "Bold"; } - prop = bdf_get_font_property( font, (char *)"SETWIDTH_NAME" ); + prop = bdf_get_font_property( font, "SETWIDTH_NAME" ); if ( prop && prop->format == BDF_ATOM && prop->value.atom && *(prop->value.atom) && !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) - strings[3] = (char *)(prop->value.atom); + strings[3] = (const char *)(prop->value.atom); - prop = bdf_get_font_property( font, (char *)"ADD_STYLE_NAME" ); + prop = bdf_get_font_property( font, "ADD_STYLE_NAME" ); if ( prop && prop->format == BDF_ATOM && prop->value.atom && *(prop->value.atom) && !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) - strings[0] = (char *)(prop->value.atom); + strings[0] = (const char *)(prop->value.atom); for ( len = 0, nn = 0; nn < 4; nn++ ) { @@ -267,7 +267,7 @@ THE SOFTWARE. if ( len == 0 ) { - strings[0] = (char *)"Regular"; + strings[0] = "Regular"; lengths[0] = ft_strlen( strings[0] ); len = lengths[0] + 1; } @@ -283,7 +283,7 @@ THE SOFTWARE. for ( nn = 0; nn < 4; nn++ ) { - char* src = strings[nn]; + const char* src = strings[nn]; len = lengths[nn]; diff --git a/thirdparty/freetype/src/bdf/bdflib.c b/thirdparty/freetype/src/bdf/bdflib.c index 0898b0d470..63813f7edc 100644 --- a/thirdparty/freetype/src/bdf/bdflib.c +++ b/thirdparty/freetype/src/bdf/bdflib.c @@ -79,89 +79,89 @@ static const bdf_property_t _bdf_properties[] = { - { (char *)"ADD_STYLE_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, - { (char *)"CHARSET_COLLECTIONS", BDF_ATOM, 1, { 0 } }, - { (char *)"CHARSET_ENCODING", BDF_ATOM, 1, { 0 } }, - { (char *)"CHARSET_REGISTRY", BDF_ATOM, 1, { 0 } }, - { (char *)"COMMENT", BDF_ATOM, 1, { 0 } }, - { (char *)"COPYRIGHT", BDF_ATOM, 1, { 0 } }, - { (char *)"DEFAULT_CHAR", BDF_CARDINAL, 1, { 0 } }, - { (char *)"DESTINATION", BDF_CARDINAL, 1, { 0 } }, - { (char *)"DEVICE_FONT_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"END_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"FACE_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"FAMILY_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"FONT", BDF_ATOM, 1, { 0 } }, - { (char *)"FONTNAME_REGISTRY", BDF_ATOM, 1, { 0 } }, - { (char *)"FONT_ASCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"FONT_DESCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"FOUNDRY", BDF_ATOM, 1, { 0 } }, - { (char *)"FULL_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"ITALIC_ANGLE", BDF_INTEGER, 1, { 0 } }, - { (char *)"MAX_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"MIN_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"NORM_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"NOTICE", BDF_ATOM, 1, { 0 } }, - { (char *)"PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"POINT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_ASCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_DESCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_END_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_MAX_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_MIN_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_NORM_SPACE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_POINT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_PIXELSIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_POINTSIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, - { (char *)"RAW_X_HEIGHT", BDF_INTEGER, 1, { 0 } }, - { (char *)"RELATIVE_SETWIDTH", BDF_CARDINAL, 1, { 0 } }, - { (char *)"RELATIVE_WEIGHT", BDF_CARDINAL, 1, { 0 } }, - { (char *)"RESOLUTION", BDF_INTEGER, 1, { 0 } }, - { (char *)"RESOLUTION_X", BDF_CARDINAL, 1, { 0 } }, - { (char *)"RESOLUTION_Y", BDF_CARDINAL, 1, { 0 } }, - { (char *)"SETWIDTH_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"SLANT", BDF_ATOM, 1, { 0 } }, - { (char *)"SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"SPACING", BDF_ATOM, 1, { 0 } }, - { (char *)"STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, - { (char *)"SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, - { (char *)"UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, - { (char *)"UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, - { (char *)"WEIGHT", BDF_CARDINAL, 1, { 0 } }, - { (char *)"WEIGHT_NAME", BDF_ATOM, 1, { 0 } }, - { (char *)"X_HEIGHT", BDF_INTEGER, 1, { 0 } }, - { (char *)"_MULE_BASELINE_OFFSET", BDF_INTEGER, 1, { 0 } }, - { (char *)"_MULE_RELATIVE_COMPOSE", BDF_INTEGER, 1, { 0 } }, + { "ADD_STYLE_NAME", BDF_ATOM, 1, { 0 } }, + { "AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { "AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, + { "AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { "CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { "CHARSET_COLLECTIONS", BDF_ATOM, 1, { 0 } }, + { "CHARSET_ENCODING", BDF_ATOM, 1, { 0 } }, + { "CHARSET_REGISTRY", BDF_ATOM, 1, { 0 } }, + { "COMMENT", BDF_ATOM, 1, { 0 } }, + { "COPYRIGHT", BDF_ATOM, 1, { 0 } }, + { "DEFAULT_CHAR", BDF_CARDINAL, 1, { 0 } }, + { "DESTINATION", BDF_CARDINAL, 1, { 0 } }, + { "DEVICE_FONT_NAME", BDF_ATOM, 1, { 0 } }, + { "END_SPACE", BDF_INTEGER, 1, { 0 } }, + { "FACE_NAME", BDF_ATOM, 1, { 0 } }, + { "FAMILY_NAME", BDF_ATOM, 1, { 0 } }, + { "FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { "FONT", BDF_ATOM, 1, { 0 } }, + { "FONTNAME_REGISTRY", BDF_ATOM, 1, { 0 } }, + { "FONT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { "FONT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { "FOUNDRY", BDF_ATOM, 1, { 0 } }, + { "FULL_NAME", BDF_ATOM, 1, { 0 } }, + { "ITALIC_ANGLE", BDF_INTEGER, 1, { 0 } }, + { "MAX_SPACE", BDF_INTEGER, 1, { 0 } }, + { "MIN_SPACE", BDF_INTEGER, 1, { 0 } }, + { "NORM_SPACE", BDF_INTEGER, 1, { 0 } }, + { "NOTICE", BDF_ATOM, 1, { 0 } }, + { "PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, + { "POINT_SIZE", BDF_INTEGER, 1, { 0 } }, + { "QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, + { "RAW_ASCENT", BDF_INTEGER, 1, { 0 } }, + { "RAW_AVERAGE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { "RAW_AVG_CAPITAL_WIDTH", BDF_INTEGER, 1, { 0 } }, + { "RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { "RAW_CAP_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { "RAW_DESCENT", BDF_INTEGER, 1, { 0 } }, + { "RAW_END_SPACE", BDF_INTEGER, 1, { 0 } }, + { "RAW_FIGURE_WIDTH", BDF_INTEGER, 1, { 0 } }, + { "RAW_MAX_SPACE", BDF_INTEGER, 1, { 0 } }, + { "RAW_MIN_SPACE", BDF_INTEGER, 1, { 0 } }, + { "RAW_NORM_SPACE", BDF_INTEGER, 1, { 0 } }, + { "RAW_PIXEL_SIZE", BDF_INTEGER, 1, { 0 } }, + { "RAW_POINT_SIZE", BDF_INTEGER, 1, { 0 } }, + { "RAW_PIXELSIZE", BDF_INTEGER, 1, { 0 } }, + { "RAW_POINTSIZE", BDF_INTEGER, 1, { 0 } }, + { "RAW_QUAD_WIDTH", BDF_INTEGER, 1, { 0 } }, + { "RAW_SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, + { "RAW_STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { "RAW_STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { "RAW_SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { "RAW_SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { "RAW_SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { "RAW_SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { "RAW_SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { "RAW_SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { "RAW_UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, + { "RAW_UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, + { "RAW_X_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { "RELATIVE_SETWIDTH", BDF_CARDINAL, 1, { 0 } }, + { "RELATIVE_WEIGHT", BDF_CARDINAL, 1, { 0 } }, + { "RESOLUTION", BDF_INTEGER, 1, { 0 } }, + { "RESOLUTION_X", BDF_CARDINAL, 1, { 0 } }, + { "RESOLUTION_Y", BDF_CARDINAL, 1, { 0 } }, + { "SETWIDTH_NAME", BDF_ATOM, 1, { 0 } }, + { "SLANT", BDF_ATOM, 1, { 0 } }, + { "SMALL_CAP_SIZE", BDF_INTEGER, 1, { 0 } }, + { "SPACING", BDF_ATOM, 1, { 0 } }, + { "STRIKEOUT_ASCENT", BDF_INTEGER, 1, { 0 } }, + { "STRIKEOUT_DESCENT", BDF_INTEGER, 1, { 0 } }, + { "SUBSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { "SUBSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { "SUBSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { "SUPERSCRIPT_SIZE", BDF_INTEGER, 1, { 0 } }, + { "SUPERSCRIPT_X", BDF_INTEGER, 1, { 0 } }, + { "SUPERSCRIPT_Y", BDF_INTEGER, 1, { 0 } }, + { "UNDERLINE_POSITION", BDF_INTEGER, 1, { 0 } }, + { "UNDERLINE_THICKNESS", BDF_INTEGER, 1, { 0 } }, + { "WEIGHT", BDF_CARDINAL, 1, { 0 } }, + { "WEIGHT_NAME", BDF_ATOM, 1, { 0 } }, + { "X_HEIGHT", BDF_INTEGER, 1, { 0 } }, + { "_MULE_BASELINE_OFFSET", BDF_INTEGER, 1, { 0 } }, + { "_MULE_RELATIVE_COMPOSE", BDF_INTEGER, 1, { 0 } }, }; static const unsigned long @@ -364,7 +364,7 @@ /* An empty string for empty fields. */ - static const char empty[1] = { 0 }; /* XXX eliminate this */ + static const char empty[] = ""; /* XXX eliminate this */ static char * @@ -407,13 +407,14 @@ static FT_Error _bdf_list_split( _bdf_list_t* list, - char* separators, + const char* separators, char* line, unsigned long linelen ) { unsigned long final_empty; int mult; - char *sp, *ep, *end; + const char *sp, *end; + char *ep; char seps[32]; FT_Error error = FT_Err_Ok; @@ -473,7 +474,7 @@ } /* Assign the field appropriately. */ - list->field[list->used++] = ( ep > sp ) ? sp : (char*)empty; + list->field[list->used++] = ( ep > sp ) ? (char*)sp : (char*)empty; sp = ep; @@ -692,7 +693,7 @@ /* Routine to convert a decimal ASCII string to an unsigned long integer. */ static unsigned long - _bdf_atoul( char* s ) + _bdf_atoul( const char* s ) { unsigned long v; @@ -717,7 +718,7 @@ /* Routine to convert a decimal ASCII string to a signed long integer. */ static long - _bdf_atol( char* s ) + _bdf_atol( const char* s ) { long v, neg; @@ -750,7 +751,7 @@ /* Routine to convert a decimal ASCII string to an unsigned short integer. */ static unsigned short - _bdf_atous( char* s ) + _bdf_atous( const char* s ) { unsigned short v; @@ -775,7 +776,7 @@ /* Routine to convert a decimal ASCII string to a signed short integer. */ static short - _bdf_atos( char* s ) + _bdf_atos( const char* s ) { short v, neg; @@ -828,7 +829,7 @@ static FT_Error - bdf_create_property( char* name, + bdf_create_property( const char* name, int format, bdf_font_t* font ) { @@ -998,7 +999,7 @@ FT_MEM_COPY( name, font->name, len ); - error = _bdf_list_split( &list, (char *)"-", name, (unsigned long)len ); + error = _bdf_list_split( &list, "-", name, (unsigned long)len ); if ( error ) goto Fail; @@ -1097,7 +1098,7 @@ static FT_Error _bdf_add_property( bdf_font_t* font, - char* name, + const char* name, char* value, unsigned long lineno ) { @@ -1336,7 +1337,7 @@ goto Exit; } - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; p->cnt = font->glyphs_size = _bdf_atoul( p->list.field[1] ); @@ -1423,7 +1424,7 @@ /* encoding can be checked for an unencoded character. */ FT_FREE( p->glyph_name ); - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; @@ -1461,7 +1462,7 @@ goto Exit; } - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; @@ -1615,7 +1616,7 @@ /* Expect the SWIDTH (scalable width) field next. */ if ( _bdf_strncmp( line, "SWIDTH", 6 ) == 0 ) { - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; @@ -1628,7 +1629,7 @@ /* Expect the DWIDTH (scalable width) field next. */ if ( _bdf_strncmp( line, "DWIDTH", 6 ) == 0 ) { - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; @@ -1653,7 +1654,7 @@ /* Expect the BBX field next. */ if ( _bdf_strncmp( line, "BBX", 3 ) == 0 ) { - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; @@ -1796,7 +1797,7 @@ { p->font->font_ascent = p->font->bbx.ascent; ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); - error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", + error = _bdf_add_property( p->font, "FONT_ASCENT", nbuf, lineno ); if ( error ) goto Exit; @@ -1808,7 +1809,7 @@ { p->font->font_descent = p->font->bbx.descent; ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); - error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", + error = _bdf_add_property( p->font, "FONT_DESCENT", nbuf, lineno ); if ( error ) goto Exit; @@ -1846,7 +1847,7 @@ } else { - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; name = p->list.field[0]; @@ -1976,7 +1977,7 @@ goto Exit; } - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; @@ -2015,7 +2016,7 @@ goto Exit; } - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; @@ -2038,7 +2039,7 @@ /* The next thing to check for is the FONT field. */ if ( _bdf_strncmp( line, "FONT", 4 ) == 0 ) { - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; _bdf_list_shift( &p->list, 1 ); @@ -2081,7 +2082,7 @@ goto Exit; } - error = _bdf_list_split( &p->list, (char *)" +", line, linelen ); + error = _bdf_list_split( &p->list, " +", line, linelen ); if ( error ) goto Exit; @@ -2136,7 +2137,7 @@ /* for compiling fonts. */ p->font->font_ascent = p->font->bbx.ascent; ft_sprintf( nbuf, "%hd", p->font->bbx.ascent ); - error = _bdf_add_property( p->font, (char *)"FONT_ASCENT", + error = _bdf_add_property( p->font, "FONT_ASCENT", nbuf, lineno ); if ( error ) goto Exit; @@ -2144,7 +2145,7 @@ p->font->font_descent = p->font->bbx.descent; ft_sprintf( nbuf, "%hd", p->font->bbx.descent ); - error = _bdf_add_property( p->font, (char *)"FONT_DESCENT", + error = _bdf_add_property( p->font, "FONT_DESCENT", nbuf, lineno ); if ( error ) goto Exit; diff --git a/thirdparty/freetype/src/cache/rules.mk b/thirdparty/freetype/src/cache/rules.mk index abcb242239..1618d98303 100644 --- a/thirdparty/freetype/src/cache/rules.mk +++ b/thirdparty/freetype/src/cache/rules.mk @@ -15,7 +15,7 @@ # Cache driver directory # -CACHE_DIR := $(SRC_DIR)/cache +CACHE_DIR := $(SRC_DIR)/cache # compilation flags for the driver diff --git a/thirdparty/freetype/src/cff/cffdrivr.c b/thirdparty/freetype/src/cff/cffdrivr.c index bbd5c40329..2324989811 100644 --- a/thirdparty/freetype/src/cff/cffdrivr.c +++ b/thirdparty/freetype/src/cff/cffdrivr.c @@ -381,8 +381,8 @@ static FT_UInt - cff_get_name_index( CFF_Face face, - FT_String* glyph_name ) + cff_get_name_index( CFF_Face face, + const FT_String* glyph_name ) { CFF_Font cff; CFF_Charset charset; diff --git a/thirdparty/freetype/src/cff/cffobjs.c b/thirdparty/freetype/src/cff/cffobjs.c index 1a1030c065..f76245f30b 100644 --- a/thirdparty/freetype/src/cff/cffobjs.c +++ b/thirdparty/freetype/src/cff/cffobjs.c @@ -962,7 +962,7 @@ cffface->style_name = style_name; else /* assume "Regular" style if we don't know better */ - cffface->style_name = cff_strcpy( memory, (char *)"Regular" ); + cffface->style_name = cff_strcpy( memory, "Regular" ); /******************************************************************** * diff --git a/thirdparty/freetype/src/cff/cffparse.c b/thirdparty/freetype/src/cff/cffparse.c index fa806f1a90..008752c3ae 100644 --- a/thirdparty/freetype/src/cff/cffparse.c +++ b/thirdparty/freetype/src/cff/cffparse.c @@ -77,6 +77,23 @@ } +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + static void + finalize_t2_strings( FT_Memory memory, + void* data, + void* user ) + { + CFF_T2_String t2 = (CFF_T2_String)data; + + + FT_UNUSED( user ); + + memory->free( memory, t2->start ); + memory->free( memory, data ); + } +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ + + FT_LOCAL_DEF( void ) cff_parser_done( CFF_Parser parser ) { @@ -84,13 +101,65 @@ FT_FREE( parser->stack ); + +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + FT_List_Finalize( &parser->t2_strings, + finalize_t2_strings, + memory, + NULL ); +#endif + } + + + /* Assuming `first >= last'. */ + + static FT_Error + cff_parser_within_limits( CFF_Parser parser, + FT_Byte* first, + FT_Byte* last ) + { +#ifndef CFF_CONFIG_OPTION_OLD_ENGINE + + /* Fast path for regular FreeType builds with the "new" engine; */ + /* `first >= parser->start' can be assumed. */ + + FT_UNUSED( first ); + + return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument ); + +#else /* CFF_CONFIG_OPTION_OLD_ENGINE */ + + FT_ListNode node; + + + if ( first >= parser->start && + last < parser->limit ) + return FT_Err_Ok; + + node = parser->t2_strings.head; + + while ( node ) + { + CFF_T2_String t2 = (CFF_T2_String)node->data; + + + if ( first >= t2->start && + last < t2->limit ) + return FT_Err_Ok; + + node = node->next; + } + + return FT_THROW( Invalid_Argument ); + +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ } /* read an integer */ static FT_Long - cff_parse_integer( FT_Byte* start, - FT_Byte* limit ) + cff_parse_integer( CFF_Parser parser, + FT_Byte* start ) { FT_Byte* p = start; FT_Int v = *p++; @@ -99,14 +168,14 @@ if ( v == 28 ) { - if ( p + 2 > limit ) + if ( cff_parser_within_limits( parser, p, p + 1 ) ) goto Bad; val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] ); } else if ( v == 29 ) { - if ( p + 4 > limit ) + if ( cff_parser_within_limits( parser, p, p + 3 ) ) goto Bad; val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) | @@ -120,14 +189,14 @@ } else if ( v < 251 ) { - if ( p + 1 > limit ) + if ( cff_parser_within_limits( parser, p, p ) ) goto Bad; val = ( v - 247 ) * 256 + p[0] + 108; } else { - if ( p + 1 > limit ) + if ( cff_parser_within_limits( parser, p, p ) ) goto Bad; val = -( v - 251 ) * 256 - p[0] - 108; @@ -176,10 +245,10 @@ /* read a real */ static FT_Fixed - cff_parse_real( FT_Byte* start, - FT_Byte* limit, - FT_Long power_ten, - FT_Long* scaling ) + cff_parse_real( CFF_Parser parser, + FT_Byte* start, + FT_Long power_ten, + FT_Long* scaling ) { FT_Byte* p = start; FT_Int nib; @@ -214,7 +283,7 @@ p++; /* Make sure we don't read past the end. */ - if ( p >= limit ) + if ( cff_parser_within_limits( parser, p, p ) ) goto Bad; } @@ -251,7 +320,7 @@ p++; /* Make sure we don't read past the end. */ - if ( p >= limit ) + if ( cff_parser_within_limits( parser, p, p ) ) goto Bad; } @@ -290,7 +359,7 @@ p++; /* Make sure we don't read past the end. */ - if ( p >= limit ) + if ( cff_parser_within_limits( parser, p, p ) ) goto Bad; } @@ -457,7 +526,7 @@ if ( **d == 30 ) { /* binary-coded decimal is truncated to integer */ - return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16; + return cff_parse_real( parser, *d, 0, NULL ) >> 16; } else if ( **d == 255 ) @@ -483,7 +552,7 @@ } else - return cff_parse_integer( *d, parser->limit ); + return cff_parse_integer( parser, *d ); } @@ -494,10 +563,10 @@ FT_Long scaling ) { if ( **d == 30 ) - return cff_parse_real( *d, parser->limit, scaling, NULL ); + return cff_parse_real( parser, *d, scaling, NULL ); else { - FT_Long val = cff_parse_integer( *d, parser->limit ); + FT_Long val = cff_parse_integer( parser, *d ); if ( scaling ) @@ -562,14 +631,14 @@ FT_ASSERT( scaling ); if ( **d == 30 ) - return cff_parse_real( *d, parser->limit, 0, scaling ); + return cff_parse_real( parser, *d, 0, scaling ); else { FT_Long number; FT_Int integer_length; - number = cff_parse_integer( d[0], d[1] ); + number = cff_parse_integer( parser, d[0] ); if ( number > 0x7FFFL ) { @@ -1122,18 +1191,6 @@ #endif /* FT_DEBUG_LEVEL_TRACE */ -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - static void - destruct_t2s_item( FT_Memory memory, - void* data, - void* user ) - { - FT_UNUSED( user ); - memory->free( memory, data ); - } -#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ - - FT_LOCAL_DEF( FT_Error ) cff_parser_run( CFF_Parser parser, FT_Byte* start, @@ -1147,11 +1204,6 @@ FT_Library library = parser->library; FT_Memory memory = library->memory; - - FT_ListRec t2s; - - - FT_ZERO( &t2s ); #endif parser->top = parser->stack; @@ -1212,9 +1264,11 @@ FT_Byte* charstring_base; FT_ULong charstring_len; - FT_Fixed* stack; - FT_ListNode node; - FT_Byte* q; + FT_Fixed* stack; + FT_ListNode node; + CFF_T2_String t2; + size_t t2_size; + FT_Byte* q; charstring_base = ++p; @@ -1261,16 +1315,26 @@ if ( !node ) goto Out_Of_Memory_Error; + FT_List_Add( &parser->t2_strings, node ); + + t2 = (CFF_T2_String)memory->alloc( memory, + sizeof ( CFF_T2_StringRec ) ); + if ( !t2 ) + goto Out_Of_Memory_Error; + + node->data = t2; + /* `5' is the conservative upper bound of required bytes per stack */ /* element. */ - q = (FT_Byte*)memory->alloc( memory, - 5 * ( decoder.top - decoder.stack ) ); + + t2_size = 5 * ( decoder.top - decoder.stack ); + + q = (FT_Byte*)memory->alloc( memory, t2_size ); if ( !q ) goto Out_Of_Memory_Error; - node->data = q; - - FT_List_Add( &t2s, node ); + t2->start = q; + t2->limit = q + t2_size; stack = decoder.stack; @@ -1531,9 +1595,6 @@ } /* while ( p < limit ) */ Exit: -#ifdef CFF_CONFIG_OPTION_OLD_ENGINE - FT_List_Finalize( &t2s, destruct_t2s_item, memory, NULL ); -#endif return error; #ifdef CFF_CONFIG_OPTION_OLD_ENGINE diff --git a/thirdparty/freetype/src/cff/cffparse.h b/thirdparty/freetype/src/cff/cffparse.h index bac32f9449..4e74709a2d 100644 --- a/thirdparty/freetype/src/cff/cffparse.h +++ b/thirdparty/freetype/src/cff/cffparse.h @@ -60,6 +60,10 @@ FT_BEGIN_HEADER FT_Byte** top; FT_UInt stackSize; /* allocated size */ +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + FT_ListRec t2_strings; +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ + FT_UInt object_code; void* object; @@ -130,6 +134,15 @@ FT_BEGIN_HEADER FT_END_HEADER +#ifdef CFF_CONFIG_OPTION_OLD_ENGINE + typedef struct CFF_T2_String_ + { + FT_Byte* start; + FT_Byte* limit; + + } CFF_T2_StringRec, *CFF_T2_String; +#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */ + #endif /* CFFPARSE_H_ */ diff --git a/thirdparty/freetype/src/gzip/ftgzip.c b/thirdparty/freetype/src/gzip/ftgzip.c index a5206307f4..5e78bc6f8d 100644 --- a/thirdparty/freetype/src/gzip/ftgzip.c +++ b/thirdparty/freetype/src/gzip/ftgzip.c @@ -746,7 +746,7 @@ stream.zfree = (free_func) ft_gzip_free; stream.opaque = memory; - err = inflateInit2( &stream, MAX_WBITS ); + err = inflateInit2( &stream, MAX_WBITS|32 ); if ( err != Z_OK ) return FT_THROW( Invalid_Argument ); diff --git a/thirdparty/freetype/src/gzip/infblock.c b/thirdparty/freetype/src/gzip/infblock.c index d6e2dc297d..2b4f0c2b53 100644 --- a/thirdparty/freetype/src/gzip/infblock.c +++ b/thirdparty/freetype/src/gzip/infblock.c @@ -235,6 +235,7 @@ int r ) s->sub.trees.index = 0; Tracev((stderr, "inflate: table sizes ok\n")); s->mode = BTREE; + /* fall through */ case BTREE: while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) { @@ -260,6 +261,7 @@ int r ) s->sub.trees.index = 0; Tracev((stderr, "inflate: bits tree ok\n")); s->mode = DTREE; + /* fall through */ case DTREE: while (t = s->sub.trees.table, s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) @@ -335,6 +337,7 @@ int r ) } ZFREE(z, s->sub.trees.blens); s->mode = CODES; + /* fall through */ case CODES: UPDATE if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) @@ -351,11 +354,13 @@ int r ) break; } s->mode = DRY; + /* fall through */ case DRY: FLUSH if (s->read != s->write) LEAVE s->mode = DONE; + /* fall through */ case DONE: r = Z_STREAM_END; LEAVE diff --git a/thirdparty/freetype/src/gzip/infcodes.c b/thirdparty/freetype/src/gzip/infcodes.c index f7bfd58c4f..ba30654990 100644 --- a/thirdparty/freetype/src/gzip/infcodes.c +++ b/thirdparty/freetype/src/gzip/infcodes.c @@ -117,6 +117,7 @@ int r ) c->sub.code.need = c->lbits; c->sub.code.tree = c->ltree; c->mode = LEN; + /* fall through */ case LEN: /* i: get length/literal/eob next */ j = c->sub.code.need; NEEDBITS(j) @@ -164,6 +165,7 @@ int r ) c->sub.code.tree = c->dtree; Tracevv((stderr, "inflate: length %u\n", c->len)); c->mode = DIST; + /* fall through */ case DIST: /* i: get distance next */ j = c->sub.code.need; NEEDBITS(j) @@ -194,6 +196,7 @@ int r ) DUMPBITS(j) Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); c->mode = COPY; + /* fall through */ case COPY: /* o: copying bytes in window, waiting for space */ f = q - c->sub.copy.dist; while (f < s->window) /* modulo window size-"while" instead */ @@ -225,6 +228,7 @@ int r ) if (s->read != s->write) LEAVE c->mode = END; + /* fall through */ case END: r = Z_STREAM_END; LEAVE diff --git a/thirdparty/freetype/src/gzip/inflate.c b/thirdparty/freetype/src/gzip/inflate.c index 8877fa3eb2..95e2653662 100644 --- a/thirdparty/freetype/src/gzip/inflate.c +++ b/thirdparty/freetype/src/gzip/inflate.c @@ -174,6 +174,7 @@ int f ) break; } z->state->mode = FLAG; + /* fall through */ case FLAG: NEEDBYTE b = NEXTBYTE; @@ -191,18 +192,22 @@ int f ) break; } z->state->mode = DICT4; + /* fall through */ case DICT4: NEEDBYTE z->state->sub.check.need = (uLong)NEXTBYTE << 24; z->state->mode = DICT3; + /* fall through */ case DICT3: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 16; z->state->mode = DICT2; + /* fall through */ case DICT2: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 8; z->state->mode = DICT1; + /* fall through */ case DICT1: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE; @@ -234,18 +239,22 @@ int f ) break; } z->state->mode = CHECK4; + /* fall through */ case CHECK4: NEEDBYTE z->state->sub.check.need = (uLong)NEXTBYTE << 24; z->state->mode = CHECK3; + /* fall through */ case CHECK3: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 16; z->state->mode = CHECK2; + /* fall through */ case CHECK2: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE << 8; z->state->mode = CHECK1; + /* fall through */ case CHECK1: NEEDBYTE z->state->sub.check.need += (uLong)NEXTBYTE; @@ -259,6 +268,7 @@ int f ) } Tracev((stderr, "inflate: zlib check ok\n")); z->state->mode = DONE; + /* fall through */ case DONE: return Z_STREAM_END; case BAD: diff --git a/thirdparty/freetype/src/pcf/pcf.h b/thirdparty/freetype/src/pcf/pcf.h index 529dd3adf8..33be4bcd85 100644 --- a/thirdparty/freetype/src/pcf/pcf.h +++ b/thirdparty/freetype/src/pcf/pcf.h @@ -99,7 +99,8 @@ FT_BEGIN_HEADER FT_Short ascent; FT_Short descent; FT_Short attributes; - FT_ULong bits; + + FT_ULong bits; /* offset into the PCF_BITMAPS table */ } PCF_MetricRec, *PCF_Metric; diff --git a/thirdparty/freetype/src/pcf/pcfdrivr.c b/thirdparty/freetype/src/pcf/pcfdrivr.c index 54bbb9d119..b39592c794 100644 --- a/thirdparty/freetype/src/pcf/pcfdrivr.c +++ b/thirdparty/freetype/src/pcf/pcfdrivr.c @@ -122,9 +122,9 @@ THE SOFTWARE. charcodeCol > enc->lastCol ) return 0; - return (FT_UInt)enc->offset[ ( charcodeRow - enc->firstRow ) * - ( enc->lastCol - enc->firstCol + 1 ) + - charcodeCol - enc->firstCol ]; + return (FT_UInt)enc->offset[( charcodeRow - enc->firstRow ) * + ( enc->lastCol - enc->firstCol + 1 ) + + charcodeCol - enc->firstCol]; } @@ -160,9 +160,9 @@ THE SOFTWARE. charcode = (FT_UInt32)( charcodeRow * 256 + charcodeCol ); - result = (FT_UInt)enc->offset[ ( charcodeRow - enc->firstRow ) * - ( enc->lastCol - enc->firstCol + 1 ) + - charcodeCol - enc->firstCol ]; + result = (FT_UInt)enc->offset[( charcodeRow - enc->firstRow ) * + ( enc->lastCol - enc->firstCol + 1 ) + + charcodeCol - enc->firstCol]; if ( result != 0xFFFFU ) break; } diff --git a/thirdparty/freetype/src/pcf/pcfread.c b/thirdparty/freetype/src/pcf/pcfread.c index 71143ecfb5..2ffe22d71c 100644 --- a/thirdparty/freetype/src/pcf/pcfread.c +++ b/thirdparty/freetype/src/pcf/pcfread.c @@ -743,33 +743,39 @@ THE SOFTWARE. if ( !orig_nmetrics ) return FT_THROW( Invalid_Table ); - /* PCF is a format from ancient times; Unicode was in its */ - /* infancy, and widely used two-byte character sets for CJK */ - /* scripts (Big 5, GB 2312, JIS X 0208, etc.) did have at most */ - /* 15000 characters. Even the more exotic CNS 11643 and CCCII */ - /* standards, which were essentially three-byte character sets, */ - /* provided less then 65536 assigned characters. */ - /* */ - /* While technically possible to have a larger number of glyphs */ - /* in PCF files, we thus limit the number to 65536. */ - if ( orig_nmetrics > 65536 ) + /* + * PCF is a format from ancient times; Unicode was in its infancy, and + * widely used two-byte character sets for CJK scripts (Big 5, GB 2312, + * JIS X 0208, etc.) did have at most 15000 characters. Even the more + * exotic CNS 11643 and CCCII standards, which were essentially + * three-byte character sets, provided less then 65536 assigned + * characters. + * + * While technically possible to have a larger number of glyphs in PCF + * files, we thus limit the number to 65535, taking into account that we + * synthesize the metrics of glyph 0 to be a copy of the `default + * character', and that 0xFFFF in the encodings array indicates a + * missing glyph. + */ + if ( orig_nmetrics > 65534 ) { FT_TRACE0(( "pcf_get_metrics:" - " only loading first 65536 metrics\n" )); - nmetrics = 65536; + " only loading first 65534 metrics\n" )); + nmetrics = 65534; } else nmetrics = orig_nmetrics; - face->nmetrics = nmetrics; + face->nmetrics = nmetrics + 1; - if ( FT_NEW_ARRAY( face->metrics, nmetrics ) ) + if ( FT_NEW_ARRAY( face->metrics, face->nmetrics ) ) return error; - metrics = face->metrics; + /* we handle glyph index 0 later on */ + metrics = face->metrics + 1; FT_TRACE4(( "\n" )); - for ( i = 0; i < nmetrics; i++, metrics++ ) + for ( i = 1; i < face->nmetrics; i++, metrics++ ) { FT_TRACE5(( " idx %ld:", i )); error = pcf_get_metric( stream, format, metrics ); @@ -808,12 +814,10 @@ THE SOFTWARE. pcf_get_bitmaps( FT_Stream stream, PCF_Face face ) { - FT_Error error; - FT_Memory memory = FT_FACE( face )->memory; - FT_ULong* offsets = NULL; - FT_ULong bitmapSizes[GLYPHPADOPTIONS]; - FT_ULong format, size; - FT_ULong nbitmaps, orig_nbitmaps, i, sizebitmaps = 0; + FT_Error error; + FT_ULong bitmapSizes[GLYPHPADOPTIONS]; + FT_ULong format, size, pos; + FT_ULong nbitmaps, orig_nbitmaps, i, sizebitmaps = 0; error = pcf_seek_to_table_type( stream, @@ -859,31 +863,46 @@ THE SOFTWARE. FT_TRACE4(( " number of bitmaps: %ld\n", orig_nbitmaps )); /* see comment in `pcf_get_metrics' */ - if ( orig_nbitmaps > 65536 ) + if ( orig_nbitmaps > 65534 ) { FT_TRACE0(( "pcf_get_bitmaps:" - " only loading first 65536 bitmaps\n" )); - nbitmaps = 65536; + " only loading first 65534 bitmaps\n" )); + nbitmaps = 65534; } else nbitmaps = orig_nbitmaps; - if ( nbitmaps != face->nmetrics ) + /* no extra bitmap for glyph 0 */ + if ( nbitmaps != face->nmetrics - 1 ) return FT_THROW( Invalid_File_Format ); - if ( FT_NEW_ARRAY( offsets, nbitmaps ) ) - return error; + /* start position of bitmap data */ + pos = stream->pos + nbitmaps * 4 + 4 * 4; FT_TRACE5(( "\n" )); - for ( i = 0; i < nbitmaps; i++ ) + for ( i = 1; i <= nbitmaps; i++ ) { + FT_ULong offset; + + if ( PCF_BYTE_ORDER( format ) == MSBFirst ) - (void)FT_READ_ULONG( offsets[i] ); + (void)FT_READ_ULONG( offset ); else - (void)FT_READ_ULONG_LE( offsets[i] ); + (void)FT_READ_ULONG_LE( offset ); FT_TRACE5(( " bitmap %lu: offset %lu (0x%lX)\n", - i, offsets[i], offsets[i] )); + i, offset, offset )); + + /* right now, we only check the offset with a rough estimate; */ + /* actual bitmaps are only loaded on demand */ + if ( offset > size ) + { + FT_TRACE0(( "pcf_get_bitmaps:" + " invalid offset to bitmap data of glyph %lu\n", i )); + face->metrics[i].bits = pos; + } + else + face->metrics[i].bits = pos + offset; } if ( error ) goto Bail; @@ -910,24 +929,9 @@ THE SOFTWARE. FT_UNUSED( sizebitmaps ); /* only used for debugging */ - /* right now, we only check the bitmap offsets; */ - /* actual bitmaps are only loaded on demand */ - for ( i = 0; i < nbitmaps; i++ ) - { - /* rough estimate */ - if ( offsets[i] > size ) - { - FT_TRACE0(( "pcf_get_bitmaps:" - " invalid offset to bitmap data of glyph %lu\n", i )); - } - else - face->metrics[i].bits = stream->pos + offsets[i]; - } - face->bitmapsFormat = format; Bail: - FT_FREE( offsets ); return error; } @@ -1062,41 +1066,52 @@ THE SOFTWARE. defaultCharCol = enc->firstCol; } - /* FreeType mandates that glyph index 0 is the `undefined glyph', */ - /* which PCF calls the `default character'. For this reason, we */ - /* swap the positions of glyph index 0 and the index corresponding */ - /* to `defaultChar' in case they are different. */ - - /* `stream->cursor' still points at the beginning of the frame; */ - /* we can thus easily get the offset to the default character */ + /* + * FreeType mandates that glyph index 0 is the `undefined glyph', which + * PCF calls the `default character'. However, FreeType needs glyph + * index 0 to be used for the undefined glyph only, which is is not the + * case for PCF. For this reason, we add one slot for glyph index 0 and + * simply copy the default character to it. + * + * `stream->cursor' still points to the beginning of the frame; we can + * thus easily get the offset to the default character. + */ pos = stream->cursor + 2 * ( ( defaultCharRow - enc->firstRow ) * - ( enc->lastCol - enc->firstCol + 1 ) + - defaultCharCol - enc->firstCol ); + ( enc->lastCol - enc->firstCol + 1 ) + + defaultCharCol - enc->firstCol ); if ( PCF_BYTE_ORDER( format ) == MSBFirst ) defaultCharEncodingOffset = FT_PEEK_USHORT( pos ); else defaultCharEncodingOffset = FT_PEEK_USHORT_LE( pos ); - if ( defaultCharEncodingOffset >= face->nmetrics ) + if ( defaultCharEncodingOffset == 0xFFFF ) { FT_TRACE0(( "pcf_get_encodings:" - " Invalid glyph index for default character," - " setting to zero\n" )); - defaultCharEncodingOffset = 0; + " No glyph for default character,\n" + " " + " setting it to the first glyph of the font\n" )); + defaultCharEncodingOffset = 1; } - - if ( defaultCharEncodingOffset ) + else { - /* do the swapping */ - PCF_MetricRec tmp = face->metrics[defaultCharEncodingOffset]; - + defaultCharEncodingOffset++; - face->metrics[defaultCharEncodingOffset] = face->metrics[0]; - face->metrics[0] = tmp; + if ( defaultCharEncodingOffset >= face->nmetrics ) + { + FT_TRACE0(( "pcf_get_encodings:" + " Invalid glyph index for default character,\n" + " " + " setting it to the first glyph of the font\n" )); + defaultCharEncodingOffset = 1; + } } + /* copy metrics of default character to index 0 */ + face->metrics[0] = face->metrics[defaultCharEncodingOffset]; + + /* now loop over all values */ offset = enc->offset; for ( i = enc->firstRow; i <= enc->lastRow; i++ ) { @@ -1111,15 +1126,9 @@ THE SOFTWARE. else encodingOffset = FT_GET_USHORT_LE(); - if ( encodingOffset != 0xFFFFU ) - { - if ( encodingOffset == defaultCharEncodingOffset ) - encodingOffset = 0; - else if ( encodingOffset == 0 ) - encodingOffset = defaultCharEncodingOffset; - } - - *offset++ = encodingOffset; + /* everything is off by 1 due to the artificial glyph 0 */ + *offset++ = encodingOffset == 0xFFFF ? 0xFFFF + : encodingOffset + 1; } } FT_Stream_ExitFrame( stream ); @@ -1303,9 +1312,8 @@ THE SOFTWARE. PCF_Property prop; - size_t nn, len; - char* strings[4] = { NULL, NULL, NULL, NULL }; - size_t lengths[4]; + const char* strings[4] = { NULL, NULL, NULL, NULL }; + size_t lengths[4], nn, len; face->style_flags = 0; @@ -1317,8 +1325,8 @@ THE SOFTWARE. { face->style_flags |= FT_STYLE_FLAG_ITALIC; strings[2] = ( *(prop->value.atom) == 'O' || - *(prop->value.atom) == 'o' ) ? (char *)"Oblique" - : (char *)"Italic"; + *(prop->value.atom) == 'o' ) ? "Oblique" + : "Italic"; } prop = pcf_find_property( pcf, "WEIGHT_NAME" ); @@ -1326,20 +1334,20 @@ THE SOFTWARE. ( *(prop->value.atom) == 'B' || *(prop->value.atom) == 'b' ) ) { face->style_flags |= FT_STYLE_FLAG_BOLD; - strings[1] = (char*)"Bold"; + strings[1] = "Bold"; } prop = pcf_find_property( pcf, "SETWIDTH_NAME" ); if ( prop && prop->isString && *(prop->value.atom) && !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) - strings[3] = (char*)( prop->value.atom ); + strings[3] = (const char*)( prop->value.atom ); prop = pcf_find_property( pcf, "ADD_STYLE_NAME" ); if ( prop && prop->isString && *(prop->value.atom) && !( *(prop->value.atom) == 'N' || *(prop->value.atom) == 'n' ) ) - strings[0] = (char*)( prop->value.atom ); + strings[0] = (const char*)( prop->value.atom ); for ( len = 0, nn = 0; nn < 4; nn++ ) { @@ -1353,7 +1361,7 @@ THE SOFTWARE. if ( len == 0 ) { - strings[0] = (char*)"Regular"; + strings[0] = "Regular"; lengths[0] = ft_strlen( strings[0] ); len = lengths[0] + 1; } @@ -1369,7 +1377,7 @@ THE SOFTWARE. for ( nn = 0; nn < 4; nn++ ) { - char* src = strings[nn]; + const char* src = strings[nn]; len = lengths[nn]; diff --git a/thirdparty/freetype/src/pfr/pfrobjs.c b/thirdparty/freetype/src/pfr/pfrobjs.c index e103a3f6f2..9765f95c2f 100644 --- a/thirdparty/freetype/src/pfr/pfrobjs.c +++ b/thirdparty/freetype/src/pfr/pfrobjs.c @@ -378,7 +378,7 @@ outline->flags &= ~FT_OUTLINE_OWNER; outline->flags |= FT_OUTLINE_REVERSE_FILL; - if ( size && pfrsize->metrics.y_ppem < 24 ) + if ( pfrsize->metrics.y_ppem < 24 ) outline->flags |= FT_OUTLINE_HIGH_PRECISION; /* compute the advance vector */ diff --git a/thirdparty/freetype/src/psaux/afmparse.c b/thirdparty/freetype/src/psaux/afmparse.c index 49225a9f78..f78adbba3d 100644 --- a/thirdparty/freetype/src/psaux/afmparse.c +++ b/thirdparty/freetype/src/psaux/afmparse.c @@ -953,7 +953,8 @@ error = afm_parse_kern_data( parser ); if ( error ) goto Fail; - /* fall through since we only support kern data */ + /* we only support kern data, so ... */ + /* fall through */ case AFM_TOKEN_ENDFONTMETRICS: return FT_Err_Ok; diff --git a/thirdparty/freetype/src/psaux/psfixed.h b/thirdparty/freetype/src/psaux/psfixed.h index fd3460f34a..7dff9ef1bd 100644 --- a/thirdparty/freetype/src/psaux/psfixed.h +++ b/thirdparty/freetype/src/psaux/psfixed.h @@ -72,8 +72,7 @@ FT_BEGIN_HEADER #define cf2_fixedFraction( x ) \ ( (x) - cf2_fixedFloor( x ) ) #define cf2_fracToFixed( x ) \ - ( (x) < 0 ? -( ( -(x) + 0x2000 ) >> 14 ) \ - : ( ( (x) + 0x2000 ) >> 14 ) ) + ( ( (x) + 0x2000 - ( (x) < 0 ) ) >> 14 ) /* signed numeric types */ diff --git a/thirdparty/freetype/src/psaux/psfont.c b/thirdparty/freetype/src/psaux/psfont.c index bb5faa38f5..00e4210819 100644 --- a/thirdparty/freetype/src/psaux/psfont.c +++ b/thirdparty/freetype/src/psaux/psfont.c @@ -274,9 +274,6 @@ if ( !font->isT1 ) { - FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)font->cffload; - - /* check for variation vectors */ vstore = cf2_getVStore( decoder ); hasVariations = ( vstore->dataCount != 0 ); @@ -284,6 +281,9 @@ if ( hasVariations ) { #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Service_CFFLoad cffload = (FT_Service_CFFLoad)font->cffload; + + /* check whether Private DICT in this subfont needs to be reparsed */ font->error = cf2_getNormalizedVector( decoder, &lenNormalizedV, diff --git a/thirdparty/freetype/src/psaux/psobjs.c b/thirdparty/freetype/src/psaux/psobjs.c index e2168a3324..8bfdb92332 100644 --- a/thirdparty/freetype/src/psaux/psobjs.c +++ b/thirdparty/freetype/src/psaux/psobjs.c @@ -174,10 +174,10 @@ * reallocation fails. */ FT_LOCAL_DEF( FT_Error ) - ps_table_add( PS_Table table, - FT_Int idx, - void* object, - FT_UInt length ) + ps_table_add( PS_Table table, + FT_Int idx, + const void* object, + FT_UInt length ) { if ( idx < 0 || idx >= table->max_elems ) { diff --git a/thirdparty/freetype/src/psaux/psobjs.h b/thirdparty/freetype/src/psaux/psobjs.h index 9466a1d075..c44dc450ec 100644 --- a/thirdparty/freetype/src/psaux/psobjs.h +++ b/thirdparty/freetype/src/psaux/psobjs.h @@ -53,10 +53,10 @@ FT_BEGIN_HEADER FT_Memory memory ); FT_LOCAL( FT_Error ) - ps_table_add( PS_Table table, - FT_Int idx, - void* object, - FT_UInt length ); + ps_table_add( PS_Table table, + FT_Int idx, + const void* object, + FT_UInt length ); FT_LOCAL( void ) ps_table_done( PS_Table table ); diff --git a/thirdparty/freetype/src/raster/ftraster.c b/thirdparty/freetype/src/raster/ftraster.c index 798a72d02a..023b6c1eff 100644 --- a/thirdparty/freetype/src/raster/ftraster.c +++ b/thirdparty/freetype/src/raster/ftraster.c @@ -399,7 +399,7 @@ #define RAS_ARGS /* void */ -#define RAS_ARG /* void */ +#define RAS_ARG void #define RAS_VARS /* void */ #define RAS_VAR /* void */ @@ -546,8 +546,7 @@ #ifdef FT_STATIC_RASTER - static black_TWorker cur_ras; -#define ras cur_ras + static black_TWorker ras; #else /* !FT_STATIC_RASTER */ @@ -661,7 +660,6 @@ return FAILURE; } - ras.cProfile->flags = 0; ras.cProfile->start = 0; ras.cProfile->height = 0; ras.cProfile->offset = ras.top; @@ -914,16 +912,18 @@ base[4].x = base[2].x; - b = base[1].x; - a = base[3].x = ( base[2].x + b ) / 2; - b = base[1].x = ( base[0].x + b ) / 2; - base[2].x = ( a + b ) / 2; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + base[3].x = b >> 1; + base[2].x = ( a + b ) >> 2; + base[1].x = a >> 1; base[4].y = base[2].y; - b = base[1].y; - a = base[3].y = ( base[2].y + b ) / 2; - b = base[1].y = ( base[0].y + b ) / 2; - base[2].y = ( a + b ) / 2; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + base[3].y = b >> 1; + base[2].y = ( a + b ) >> 2; + base[1].y = a >> 1; /* hand optimized. gcc doesn't seem to be too good at common */ /* expression substitution and instruction scheduling ;-) */ @@ -947,28 +947,32 @@ static void Split_Cubic( TPoint* base ) { - Long a, b, c, d; + Long a, b, c; base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c + 1 ) >> 1; - base[5].x = b = ( base[3].x + d + 1 ) >> 1; - c = ( c + d + 1 ) >> 1; - base[2].x = a = ( a + c + 1 ) >> 1; - base[4].x = b = ( b + c + 1 ) >> 1; - base[3].x = ( a + b + 1 ) >> 1; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + c = base[2].x + base[3].x; + base[5].x = c >> 1; + c += b; + base[4].x = c >> 2; + base[1].x = a >> 1; + a += b; + base[2].x = a >> 2; + base[3].x = ( a + c ) >> 3; base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c + 1 ) >> 1; - base[5].y = b = ( base[3].y + d + 1 ) >> 1; - c = ( c + d + 1 ) >> 1; - base[2].y = a = ( a + c + 1 ) >> 1; - base[4].y = b = ( b + c + 1 ) >> 1; - base[3].y = ( a + b + 1 ) >> 1; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + c = base[2].y + base[3].y; + base[5].y = c >> 1; + c += b; + base[4].y = c >> 2; + base[1].y = a >> 1; + a += b; + base[2].y = a >> 2; + base[3].y = ( a + c ) >> 3; } @@ -2784,7 +2788,7 @@ P_Left = draw_left; P_Right = draw_right; - while ( P_Left ) + while ( P_Left && P_Right ) { x1 = P_Left ->X; x2 = P_Right->X; @@ -2885,7 +2889,7 @@ P_Left = draw_left; P_Right = draw_right; - while ( P_Left ) + while ( P_Left && P_Right ) { if ( P_Left->countL ) { @@ -3257,7 +3261,9 @@ const FT_Outline* outline = (const FT_Outline*)params->source; const FT_Bitmap* target_map = params->target; +#ifndef FT_STATIC_RASTER black_TWorker worker[1]; +#endif Long buffer[FT_MAX_BLACK_POOL]; @@ -3299,8 +3305,8 @@ ras.outline = *outline; ras.target = *target_map; - worker->buff = buffer; - worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ + ras.buff = buffer; + ras.sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ return Render_Glyph( RAS_VAR ); } diff --git a/thirdparty/freetype/src/sfnt/rules.mk b/thirdparty/freetype/src/sfnt/rules.mk index ff9e7c6117..ee3314eac3 100644 --- a/thirdparty/freetype/src/sfnt/rules.mk +++ b/thirdparty/freetype/src/sfnt/rules.mk @@ -31,6 +31,7 @@ SFNT_COMPILE := $(CC) $(ANSIFLAGS) \ SFNT_DRV_SRC := $(SFNT_DIR)/pngshim.c \ $(SFNT_DIR)/sfdriver.c \ $(SFNT_DIR)/sfobjs.c \ + $(SFNT_DIR)/sfwoff.c \ $(SFNT_DIR)/ttbdf.c \ $(SFNT_DIR)/ttcmap.c \ $(SFNT_DIR)/ttcolr.c \ diff --git a/thirdparty/freetype/src/sfnt/sfdriver.c b/thirdparty/freetype/src/sfnt/sfdriver.c index c467ff4d37..2611685284 100644 --- a/thirdparty/freetype/src/sfnt/sfdriver.c +++ b/thirdparty/freetype/src/sfnt/sfdriver.c @@ -182,8 +182,8 @@ static FT_UInt - sfnt_get_name_index( FT_Face face, - FT_String* glyph_name ) + sfnt_get_name_index( FT_Face face, + const FT_String* glyph_name ) { TT_Face ttface = (TT_Face)face; @@ -375,47 +375,61 @@ { case 15: k4 ^= (FT_UInt32)tail[14] << 16; + /* fall through */ case 14: k4 ^= (FT_UInt32)tail[13] << 8; + /* fall through */ case 13: k4 ^= (FT_UInt32)tail[12]; k4 *= c4; k4 = ROTL32( k4, 18 ); k4 *= c1; h4 ^= k4; + /* fall through */ case 12: k3 ^= (FT_UInt32)tail[11] << 24; + /* fall through */ case 11: k3 ^= (FT_UInt32)tail[10] << 16; + /* fall through */ case 10: k3 ^= (FT_UInt32)tail[9] << 8; + /* fall through */ case 9: k3 ^= (FT_UInt32)tail[8]; k3 *= c3; k3 = ROTL32( k3, 17 ); k3 *= c4; h3 ^= k3; + /* fall through */ case 8: k2 ^= (FT_UInt32)tail[7] << 24; + /* fall through */ case 7: k2 ^= (FT_UInt32)tail[6] << 16; + /* fall through */ case 6: k2 ^= (FT_UInt32)tail[5] << 8; + /* fall through */ case 5: k2 ^= (FT_UInt32)tail[4]; k2 *= c2; k2 = ROTL32( k2, 16 ); k2 *= c3; h2 ^= k2; + /* fall through */ case 4: k1 ^= (FT_UInt32)tail[3] << 24; + /* fall through */ case 3: k1 ^= (FT_UInt32)tail[2] << 16; + /* fall through */ case 2: k1 ^= (FT_UInt32)tail[1] << 8; + /* fall through */ case 1: k1 ^= (FT_UInt32)tail[0]; k1 *= c1; diff --git a/thirdparty/freetype/src/sfnt/sfnt.c b/thirdparty/freetype/src/sfnt/sfnt.c index 5a503f30c5..b4faf34a3a 100644 --- a/thirdparty/freetype/src/sfnt/sfnt.c +++ b/thirdparty/freetype/src/sfnt/sfnt.c @@ -22,6 +22,7 @@ #include "pngshim.c" #include "sfdriver.c" #include "sfobjs.c" +#include "sfwoff.c" #include "ttbdf.c" #include "ttcmap.c" #include "ttcolr.c" diff --git a/thirdparty/freetype/src/sfnt/sfobjs.c b/thirdparty/freetype/src/sfnt/sfobjs.c index 0b43d251b8..6edf3ae1de 100644 --- a/thirdparty/freetype/src/sfnt/sfobjs.c +++ b/thirdparty/freetype/src/sfnt/sfobjs.c @@ -21,13 +21,13 @@ #include "ttload.h" #include "ttcmap.h" #include "ttkern.h" +#include "sfwoff.h" #include FT_INTERNAL_SFNT_H #include FT_INTERNAL_DEBUG_H #include FT_TRUETYPE_IDS_H #include FT_TRUETYPE_TAGS_H #include FT_SERVICE_POSTSCRIPT_CMAPS_H #include FT_SFNT_NAMES_H -#include FT_GZIP_H #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT #include FT_SERVICE_MULTIPLE_MASTERS_H @@ -337,403 +337,6 @@ } -#define WRITE_USHORT( p, v ) \ - do \ - { \ - *(p)++ = (FT_Byte)( (v) >> 8 ); \ - *(p)++ = (FT_Byte)( (v) >> 0 ); \ - \ - } while ( 0 ) - -#define WRITE_ULONG( p, v ) \ - do \ - { \ - *(p)++ = (FT_Byte)( (v) >> 24 ); \ - *(p)++ = (FT_Byte)( (v) >> 16 ); \ - *(p)++ = (FT_Byte)( (v) >> 8 ); \ - *(p)++ = (FT_Byte)( (v) >> 0 ); \ - \ - } while ( 0 ) - - - static void - sfnt_stream_close( FT_Stream stream ) - { - FT_Memory memory = stream->memory; - - - FT_FREE( stream->base ); - - stream->size = 0; - stream->base = NULL; - stream->close = NULL; - } - - - FT_CALLBACK_DEF( int ) - compare_offsets( const void* a, - const void* b ) - { - WOFF_Table table1 = *(WOFF_Table*)a; - WOFF_Table table2 = *(WOFF_Table*)b; - - FT_ULong offset1 = table1->Offset; - FT_ULong offset2 = table2->Offset; - - - if ( offset1 > offset2 ) - return 1; - else if ( offset1 < offset2 ) - return -1; - else - return 0; - } - - - /* Replace `face->root.stream' with a stream containing the extracted */ - /* SFNT of a WOFF font. */ - - static FT_Error - woff_open_font( FT_Stream stream, - TT_Face face ) - { - FT_Memory memory = stream->memory; - FT_Error error = FT_Err_Ok; - - WOFF_HeaderRec woff; - WOFF_Table tables = NULL; - WOFF_Table* indices = NULL; - - FT_ULong woff_offset; - - FT_Byte* sfnt = NULL; - FT_Stream sfnt_stream = NULL; - - FT_Byte* sfnt_header; - FT_ULong sfnt_offset; - - FT_Int nn; - FT_ULong old_tag = 0; - - static const FT_Frame_Field woff_header_fields[] = - { -#undef FT_STRUCTURE -#define FT_STRUCTURE WOFF_HeaderRec - - FT_FRAME_START( 44 ), - FT_FRAME_ULONG ( signature ), - FT_FRAME_ULONG ( flavor ), - FT_FRAME_ULONG ( length ), - FT_FRAME_USHORT( num_tables ), - FT_FRAME_USHORT( reserved ), - FT_FRAME_ULONG ( totalSfntSize ), - FT_FRAME_USHORT( majorVersion ), - FT_FRAME_USHORT( minorVersion ), - FT_FRAME_ULONG ( metaOffset ), - FT_FRAME_ULONG ( metaLength ), - FT_FRAME_ULONG ( metaOrigLength ), - FT_FRAME_ULONG ( privOffset ), - FT_FRAME_ULONG ( privLength ), - FT_FRAME_END - }; - - - FT_ASSERT( stream == face->root.stream ); - FT_ASSERT( FT_STREAM_POS() == 0 ); - - if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) ) - return error; - - /* Make sure we don't recurse back here or hit TTC code. */ - if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf ) - return FT_THROW( Invalid_Table ); - - /* Miscellaneous checks. */ - if ( woff.length != stream->size || - woff.num_tables == 0 || - 44 + woff.num_tables * 20UL >= woff.length || - 12 + woff.num_tables * 16UL >= woff.totalSfntSize || - ( woff.totalSfntSize & 3 ) != 0 || - ( woff.metaOffset == 0 && ( woff.metaLength != 0 || - woff.metaOrigLength != 0 ) ) || - ( woff.metaLength != 0 && woff.metaOrigLength == 0 ) || - ( woff.privOffset == 0 && woff.privLength != 0 ) ) - { - FT_ERROR(( "woff_font_open: invalid WOFF header\n" )); - return FT_THROW( Invalid_Table ); - } - - /* Don't trust `totalSfntSize' before thorough checks. */ - if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) || - FT_NEW( sfnt_stream ) ) - goto Exit; - - sfnt_header = sfnt; - - /* Write sfnt header. */ - { - FT_UInt searchRange, entrySelector, rangeShift, x; - - - x = woff.num_tables; - entrySelector = 0; - while ( x ) - { - x >>= 1; - entrySelector += 1; - } - entrySelector--; - - searchRange = ( 1 << entrySelector ) * 16; - rangeShift = woff.num_tables * 16 - searchRange; - - WRITE_ULONG ( sfnt_header, woff.flavor ); - WRITE_USHORT( sfnt_header, woff.num_tables ); - WRITE_USHORT( sfnt_header, searchRange ); - WRITE_USHORT( sfnt_header, entrySelector ); - WRITE_USHORT( sfnt_header, rangeShift ); - } - - /* While the entries in the sfnt header must be sorted by the */ - /* tag value, the tables themselves are not. We thus have to */ - /* sort them by offset and check that they don't overlap. */ - - if ( FT_NEW_ARRAY( tables, woff.num_tables ) || - FT_NEW_ARRAY( indices, woff.num_tables ) ) - goto Exit; - - FT_TRACE2(( "\n" - " tag offset compLen origLen checksum\n" - " -------------------------------------------\n" )); - - if ( FT_FRAME_ENTER( 20L * woff.num_tables ) ) - goto Exit; - - for ( nn = 0; nn < woff.num_tables; nn++ ) - { - WOFF_Table table = tables + nn; - - table->Tag = FT_GET_TAG4(); - table->Offset = FT_GET_ULONG(); - table->CompLength = FT_GET_ULONG(); - table->OrigLength = FT_GET_ULONG(); - table->CheckSum = FT_GET_ULONG(); - - FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx %08lx\n", - (FT_Char)( table->Tag >> 24 ), - (FT_Char)( table->Tag >> 16 ), - (FT_Char)( table->Tag >> 8 ), - (FT_Char)( table->Tag ), - table->Offset, - table->CompLength, - table->OrigLength, - table->CheckSum )); - - if ( table->Tag <= old_tag ) - { - FT_FRAME_EXIT(); - - FT_ERROR(( "woff_font_open: table tags are not sorted\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - old_tag = table->Tag; - indices[nn] = table; - } - - FT_FRAME_EXIT(); - - /* Sort by offset. */ - - ft_qsort( indices, - woff.num_tables, - sizeof ( WOFF_Table ), - compare_offsets ); - - /* Check offsets and lengths. */ - - woff_offset = 44 + woff.num_tables * 20L; - sfnt_offset = 12 + woff.num_tables * 16L; - - for ( nn = 0; nn < woff.num_tables; nn++ ) - { - WOFF_Table table = indices[nn]; - - - if ( table->Offset != woff_offset || - table->CompLength > woff.length || - table->Offset > woff.length - table->CompLength || - table->OrigLength > woff.totalSfntSize || - sfnt_offset > woff.totalSfntSize - table->OrigLength || - table->CompLength > table->OrigLength ) - { - FT_ERROR(( "woff_font_open: invalid table offsets\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - table->OrigOffset = sfnt_offset; - - /* The offsets must be multiples of 4. */ - woff_offset += ( table->CompLength + 3 ) & ~3U; - sfnt_offset += ( table->OrigLength + 3 ) & ~3U; - } - - /* - * Final checks! - * - * We don't decode and check the metadata block. - * We don't check table checksums either. - * But other than those, I think we implement all - * `MUST' checks from the spec. - */ - - if ( woff.metaOffset ) - { - if ( woff.metaOffset != woff_offset || - woff.metaOffset + woff.metaLength > woff.length ) - { - FT_ERROR(( "woff_font_open:" - " invalid `metadata' offset or length\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - /* We have padding only ... */ - woff_offset += woff.metaLength; - } - - if ( woff.privOffset ) - { - /* ... if it isn't the last block. */ - woff_offset = ( woff_offset + 3 ) & ~3U; - - if ( woff.privOffset != woff_offset || - woff.privOffset + woff.privLength > woff.length ) - { - FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - /* No padding for the last block. */ - woff_offset += woff.privLength; - } - - if ( sfnt_offset != woff.totalSfntSize || - woff_offset != woff.length ) - { - FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - - /* Now use `totalSfntSize'. */ - if ( FT_REALLOC( sfnt, - 12 + woff.num_tables * 16UL, - woff.totalSfntSize ) ) - goto Exit; - - sfnt_header = sfnt + 12; - - /* Write the tables. */ - - for ( nn = 0; nn < woff.num_tables; nn++ ) - { - WOFF_Table table = tables + nn; - - - /* Write SFNT table entry. */ - WRITE_ULONG( sfnt_header, table->Tag ); - WRITE_ULONG( sfnt_header, table->CheckSum ); - WRITE_ULONG( sfnt_header, table->OrigOffset ); - WRITE_ULONG( sfnt_header, table->OrigLength ); - - /* Write table data. */ - if ( FT_STREAM_SEEK( table->Offset ) || - FT_FRAME_ENTER( table->CompLength ) ) - goto Exit; - - if ( table->CompLength == table->OrigLength ) - { - /* Uncompressed data; just copy. */ - ft_memcpy( sfnt + table->OrigOffset, - stream->cursor, - table->OrigLength ); - } - else - { -#ifdef FT_CONFIG_OPTION_USE_ZLIB - - /* Uncompress with zlib. */ - FT_ULong output_len = table->OrigLength; - - - error = FT_Gzip_Uncompress( memory, - sfnt + table->OrigOffset, &output_len, - stream->cursor, table->CompLength ); - if ( error ) - goto Exit; - if ( output_len != table->OrigLength ) - { - FT_ERROR(( "woff_font_open: compressed table length mismatch\n" )); - error = FT_THROW( Invalid_Table ); - goto Exit; - } - -#else /* !FT_CONFIG_OPTION_USE_ZLIB */ - - error = FT_THROW( Unimplemented_Feature ); - goto Exit; - -#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ - } - - FT_FRAME_EXIT(); - - /* We don't check whether the padding bytes in the WOFF file are */ - /* actually '\0'. For the output, however, we do set them properly. */ - sfnt_offset = table->OrigOffset + table->OrigLength; - while ( sfnt_offset & 3 ) - { - sfnt[sfnt_offset] = '\0'; - sfnt_offset++; - } - } - - /* Ok! Finally ready. Swap out stream and return. */ - FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize ); - sfnt_stream->memory = stream->memory; - sfnt_stream->close = sfnt_stream_close; - - FT_Stream_Free( - face->root.stream, - ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); - - face->root.stream = sfnt_stream; - - face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; - - Exit: - FT_FREE( tables ); - FT_FREE( indices ); - - if ( error ) - { - FT_FREE( sfnt ); - FT_Stream_Close( sfnt_stream ); - FT_FREE( sfnt_stream ); - } - - return error; - } - - -#undef WRITE_USHORT -#undef WRITE_ULONG - - /* Fill in face->ttc_header. If the font is not a TTC, it is */ /* synthesized into a TTC with one offset table. */ static FT_Error diff --git a/thirdparty/freetype/src/sfnt/sfobjs.h b/thirdparty/freetype/src/sfnt/sfobjs.h index 17b0d50105..3fbf2dd6bd 100644 --- a/thirdparty/freetype/src/sfnt/sfobjs.h +++ b/thirdparty/freetype/src/sfnt/sfobjs.h @@ -53,7 +53,7 @@ FT_BEGIN_HEADER FT_END_HEADER -#endif /* SFDRIVER_H_ */ +#endif /* SFOBJS_H_ */ /* END */ diff --git a/thirdparty/freetype/src/sfnt/sfwoff.c b/thirdparty/freetype/src/sfnt/sfwoff.c new file mode 100644 index 0000000000..ca4821a20a --- /dev/null +++ b/thirdparty/freetype/src/sfnt/sfwoff.c @@ -0,0 +1,434 @@ +/**************************************************************************** + * + * sfwoff.c + * + * WOFF format management (base). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#include <ft2build.h> +#include "sfwoff.h" +#include FT_TRUETYPE_TAGS_H +#include FT_INTERNAL_DEBUG_H +#include FT_INTERNAL_STREAM_H +#include FT_GZIP_H + + + /************************************************************************** + * + * The macro FT_COMPONENT is used in trace mode. It is an implicit + * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log + * messages during execution. + */ +#undef FT_COMPONENT +#define FT_COMPONENT sfwoff + + +#define WRITE_USHORT( p, v ) \ + do \ + { \ + *(p)++ = (FT_Byte)( (v) >> 8 ); \ + *(p)++ = (FT_Byte)( (v) >> 0 ); \ + \ + } while ( 0 ) + +#define WRITE_ULONG( p, v ) \ + do \ + { \ + *(p)++ = (FT_Byte)( (v) >> 24 ); \ + *(p)++ = (FT_Byte)( (v) >> 16 ); \ + *(p)++ = (FT_Byte)( (v) >> 8 ); \ + *(p)++ = (FT_Byte)( (v) >> 0 ); \ + \ + } while ( 0 ) + + + static void + sfnt_stream_close( FT_Stream stream ) + { + FT_Memory memory = stream->memory; + + + FT_FREE( stream->base ); + + stream->size = 0; + stream->base = NULL; + stream->close = NULL; + } + + + FT_CALLBACK_DEF( int ) + compare_offsets( const void* a, + const void* b ) + { + WOFF_Table table1 = *(WOFF_Table*)a; + WOFF_Table table2 = *(WOFF_Table*)b; + + FT_ULong offset1 = table1->Offset; + FT_ULong offset2 = table2->Offset; + + + if ( offset1 > offset2 ) + return 1; + else if ( offset1 < offset2 ) + return -1; + else + return 0; + } + + + /* Replace `face->root.stream' with a stream containing the extracted */ + /* SFNT of a WOFF font. */ + + FT_LOCAL_DEF( FT_Error ) + woff_open_font( FT_Stream stream, + TT_Face face ) + { + FT_Memory memory = stream->memory; + FT_Error error = FT_Err_Ok; + + WOFF_HeaderRec woff; + WOFF_Table tables = NULL; + WOFF_Table* indices = NULL; + + FT_ULong woff_offset; + + FT_Byte* sfnt = NULL; + FT_Stream sfnt_stream = NULL; + + FT_Byte* sfnt_header; + FT_ULong sfnt_offset; + + FT_Int nn; + FT_ULong old_tag = 0; + + static const FT_Frame_Field woff_header_fields[] = + { +#undef FT_STRUCTURE +#define FT_STRUCTURE WOFF_HeaderRec + + FT_FRAME_START( 44 ), + FT_FRAME_ULONG ( signature ), + FT_FRAME_ULONG ( flavor ), + FT_FRAME_ULONG ( length ), + FT_FRAME_USHORT( num_tables ), + FT_FRAME_USHORT( reserved ), + FT_FRAME_ULONG ( totalSfntSize ), + FT_FRAME_USHORT( majorVersion ), + FT_FRAME_USHORT( minorVersion ), + FT_FRAME_ULONG ( metaOffset ), + FT_FRAME_ULONG ( metaLength ), + FT_FRAME_ULONG ( metaOrigLength ), + FT_FRAME_ULONG ( privOffset ), + FT_FRAME_ULONG ( privLength ), + FT_FRAME_END + }; + + + FT_ASSERT( stream == face->root.stream ); + FT_ASSERT( FT_STREAM_POS() == 0 ); + + if ( FT_STREAM_READ_FIELDS( woff_header_fields, &woff ) ) + return error; + + /* Make sure we don't recurse back here or hit TTC code. */ + if ( woff.flavor == TTAG_wOFF || woff.flavor == TTAG_ttcf ) + return FT_THROW( Invalid_Table ); + + /* Miscellaneous checks. */ + if ( woff.length != stream->size || + woff.num_tables == 0 || + 44 + woff.num_tables * 20UL >= woff.length || + 12 + woff.num_tables * 16UL >= woff.totalSfntSize || + ( woff.totalSfntSize & 3 ) != 0 || + ( woff.metaOffset == 0 && ( woff.metaLength != 0 || + woff.metaOrigLength != 0 ) ) || + ( woff.metaLength != 0 && woff.metaOrigLength == 0 ) || + ( woff.privOffset == 0 && woff.privLength != 0 ) ) + { + FT_ERROR(( "woff_font_open: invalid WOFF header\n" )); + return FT_THROW( Invalid_Table ); + } + + /* Don't trust `totalSfntSize' before thorough checks. */ + if ( FT_ALLOC( sfnt, 12 + woff.num_tables * 16UL ) || + FT_NEW( sfnt_stream ) ) + goto Exit; + + sfnt_header = sfnt; + + /* Write sfnt header. */ + { + FT_UInt searchRange, entrySelector, rangeShift, x; + + + x = woff.num_tables; + entrySelector = 0; + while ( x ) + { + x >>= 1; + entrySelector += 1; + } + entrySelector--; + + searchRange = ( 1 << entrySelector ) * 16; + rangeShift = woff.num_tables * 16 - searchRange; + + WRITE_ULONG ( sfnt_header, woff.flavor ); + WRITE_USHORT( sfnt_header, woff.num_tables ); + WRITE_USHORT( sfnt_header, searchRange ); + WRITE_USHORT( sfnt_header, entrySelector ); + WRITE_USHORT( sfnt_header, rangeShift ); + } + + /* While the entries in the sfnt header must be sorted by the */ + /* tag value, the tables themselves are not. We thus have to */ + /* sort them by offset and check that they don't overlap. */ + + if ( FT_NEW_ARRAY( tables, woff.num_tables ) || + FT_NEW_ARRAY( indices, woff.num_tables ) ) + goto Exit; + + FT_TRACE2(( "\n" + " tag offset compLen origLen checksum\n" + " -------------------------------------------\n" )); + + if ( FT_FRAME_ENTER( 20L * woff.num_tables ) ) + goto Exit; + + for ( nn = 0; nn < woff.num_tables; nn++ ) + { + WOFF_Table table = tables + nn; + + table->Tag = FT_GET_TAG4(); + table->Offset = FT_GET_ULONG(); + table->CompLength = FT_GET_ULONG(); + table->OrigLength = FT_GET_ULONG(); + table->CheckSum = FT_GET_ULONG(); + + FT_TRACE2(( " %c%c%c%c %08lx %08lx %08lx %08lx\n", + (FT_Char)( table->Tag >> 24 ), + (FT_Char)( table->Tag >> 16 ), + (FT_Char)( table->Tag >> 8 ), + (FT_Char)( table->Tag ), + table->Offset, + table->CompLength, + table->OrigLength, + table->CheckSum )); + + if ( table->Tag <= old_tag ) + { + FT_FRAME_EXIT(); + + FT_ERROR(( "woff_font_open: table tags are not sorted\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + old_tag = table->Tag; + indices[nn] = table; + } + + FT_FRAME_EXIT(); + + /* Sort by offset. */ + + ft_qsort( indices, + woff.num_tables, + sizeof ( WOFF_Table ), + compare_offsets ); + + /* Check offsets and lengths. */ + + woff_offset = 44 + woff.num_tables * 20L; + sfnt_offset = 12 + woff.num_tables * 16L; + + for ( nn = 0; nn < woff.num_tables; nn++ ) + { + WOFF_Table table = indices[nn]; + + + if ( table->Offset != woff_offset || + table->CompLength > woff.length || + table->Offset > woff.length - table->CompLength || + table->OrigLength > woff.totalSfntSize || + sfnt_offset > woff.totalSfntSize - table->OrigLength || + table->CompLength > table->OrigLength ) + { + FT_ERROR(( "woff_font_open: invalid table offsets\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + table->OrigOffset = sfnt_offset; + + /* The offsets must be multiples of 4. */ + woff_offset += ( table->CompLength + 3 ) & ~3U; + sfnt_offset += ( table->OrigLength + 3 ) & ~3U; + } + + /* + * Final checks! + * + * We don't decode and check the metadata block. + * We don't check table checksums either. + * But other than those, I think we implement all + * `MUST' checks from the spec. + */ + + if ( woff.metaOffset ) + { + if ( woff.metaOffset != woff_offset || + woff.metaOffset + woff.metaLength > woff.length ) + { + FT_ERROR(( "woff_font_open:" + " invalid `metadata' offset or length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* We have padding only ... */ + woff_offset += woff.metaLength; + } + + if ( woff.privOffset ) + { + /* ... if it isn't the last block. */ + woff_offset = ( woff_offset + 3 ) & ~3U; + + if ( woff.privOffset != woff_offset || + woff.privOffset + woff.privLength > woff.length ) + { + FT_ERROR(( "woff_font_open: invalid `private' offset or length\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* No padding for the last block. */ + woff_offset += woff.privLength; + } + + if ( sfnt_offset != woff.totalSfntSize || + woff_offset != woff.length ) + { + FT_ERROR(( "woff_font_open: invalid `sfnt' table structure\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + + /* Now use `totalSfntSize'. */ + if ( FT_REALLOC( sfnt, + 12 + woff.num_tables * 16UL, + woff.totalSfntSize ) ) + goto Exit; + + sfnt_header = sfnt + 12; + + /* Write the tables. */ + + for ( nn = 0; nn < woff.num_tables; nn++ ) + { + WOFF_Table table = tables + nn; + + + /* Write SFNT table entry. */ + WRITE_ULONG( sfnt_header, table->Tag ); + WRITE_ULONG( sfnt_header, table->CheckSum ); + WRITE_ULONG( sfnt_header, table->OrigOffset ); + WRITE_ULONG( sfnt_header, table->OrigLength ); + + /* Write table data. */ + if ( FT_STREAM_SEEK( table->Offset ) || + FT_FRAME_ENTER( table->CompLength ) ) + goto Exit; + + if ( table->CompLength == table->OrigLength ) + { + /* Uncompressed data; just copy. */ + ft_memcpy( sfnt + table->OrigOffset, + stream->cursor, + table->OrigLength ); + } + else + { +#ifdef FT_CONFIG_OPTION_USE_ZLIB + + /* Uncompress with zlib. */ + FT_ULong output_len = table->OrigLength; + + + error = FT_Gzip_Uncompress( memory, + sfnt + table->OrigOffset, &output_len, + stream->cursor, table->CompLength ); + if ( error ) + goto Exit; + if ( output_len != table->OrigLength ) + { + FT_ERROR(( "woff_font_open: compressed table length mismatch\n" )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + +#else /* !FT_CONFIG_OPTION_USE_ZLIB */ + + error = FT_THROW( Unimplemented_Feature ); + goto Exit; + +#endif /* !FT_CONFIG_OPTION_USE_ZLIB */ + } + + FT_FRAME_EXIT(); + + /* We don't check whether the padding bytes in the WOFF file are */ + /* actually '\0'. For the output, however, we do set them properly. */ + sfnt_offset = table->OrigOffset + table->OrigLength; + while ( sfnt_offset & 3 ) + { + sfnt[sfnt_offset] = '\0'; + sfnt_offset++; + } + } + + /* Ok! Finally ready. Swap out stream and return. */ + FT_Stream_OpenMemory( sfnt_stream, sfnt, woff.totalSfntSize ); + sfnt_stream->memory = stream->memory; + sfnt_stream->close = sfnt_stream_close; + + FT_Stream_Free( + face->root.stream, + ( face->root.face_flags & FT_FACE_FLAG_EXTERNAL_STREAM ) != 0 ); + + face->root.stream = sfnt_stream; + + face->root.face_flags &= ~FT_FACE_FLAG_EXTERNAL_STREAM; + + Exit: + FT_FREE( tables ); + FT_FREE( indices ); + + if ( error ) + { + FT_FREE( sfnt ); + FT_Stream_Close( sfnt_stream ); + FT_FREE( sfnt_stream ); + } + + return error; + } + + +#undef WRITE_USHORT +#undef WRITE_ULONG + + +/* END */ diff --git a/thirdparty/freetype/src/sfnt/sfwoff.h b/thirdparty/freetype/src/sfnt/sfwoff.h new file mode 100644 index 0000000000..15495c32a2 --- /dev/null +++ b/thirdparty/freetype/src/sfnt/sfwoff.h @@ -0,0 +1,41 @@ +/**************************************************************************** + * + * sfwoff.h + * + * WOFFF format management (specification). + * + * Copyright (C) 1996-2019 by + * David Turner, Robert Wilhelm, and Werner Lemberg. + * + * This file is part of the FreeType project, and may only be used, + * modified, and distributed under the terms of the FreeType project + * license, LICENSE.TXT. By continuing to use, modify, or distribute + * this file you indicate that you have read the license and + * understand and accept it fully. + * + */ + + +#ifndef SFWOFF_H_ +#define SFWOFF_H_ + + +#include <ft2build.h> +#include FT_INTERNAL_SFNT_H +#include FT_INTERNAL_OBJECTS_H + + +FT_BEGIN_HEADER + + + FT_LOCAL( FT_Error ) + woff_open_font( FT_Stream stream, + TT_Face face ); + + +FT_END_HEADER + +#endif /* SFWOFF_H_ */ + + +/* END */ diff --git a/thirdparty/freetype/src/sfnt/ttcmap.c b/thirdparty/freetype/src/sfnt/ttcmap.c index 8d9737310c..683f3b1818 100644 --- a/thirdparty/freetype/src/sfnt/ttcmap.c +++ b/thirdparty/freetype/src/sfnt/ttcmap.c @@ -2368,10 +2368,7 @@ /* if `gindex' is invalid, the remaining values */ /* in this group are invalid, too */ if ( gindex >= (FT_UInt)face->num_glyphs ) - { - gindex = 0; continue; - } cmap->cur_charcode = char_code; cmap->cur_gindex = gindex; @@ -3661,7 +3658,7 @@ tt_get_glyph_name( TT_Face face, FT_UInt idx ) { - FT_String* PSname; + FT_String* PSname = NULL; tt_face_get_ps_name( face, idx, &PSname ); diff --git a/thirdparty/freetype/src/sfnt/ttmtx.c b/thirdparty/freetype/src/sfnt/ttmtx.c index 7a4d2be2cb..b6725c962f 100644 --- a/thirdparty/freetype/src/sfnt/ttmtx.c +++ b/thirdparty/freetype/src/sfnt/ttmtx.c @@ -280,7 +280,7 @@ else { table_pos += 4 * ( k - 1 ); - if ( table_pos + 4 > table_end ) + if ( table_pos + 2 > table_end ) goto NoData; if ( FT_STREAM_SEEK( table_pos ) || @@ -292,7 +292,9 @@ *abearing = 0; else { - if ( !FT_STREAM_SEEK( table_pos ) ) + if ( FT_STREAM_SEEK( table_pos ) ) + *abearing = 0; + else (void)FT_READ_SHORT( *abearing ); } } diff --git a/thirdparty/freetype/src/smooth/ftgrays.c b/thirdparty/freetype/src/smooth/ftgrays.c index 91293ac946..fd357a50fc 100644 --- a/thirdparty/freetype/src/smooth/ftgrays.c +++ b/thirdparty/freetype/src/smooth/ftgrays.c @@ -45,7 +45,7 @@ * This is a new anti-aliasing scan-converter for FreeType 2. The * algorithm used here is _very_ different from the one in the standard * `ftraster' module. Actually, `ftgrays' computes the _exact_ - * coverage of the outline on each pixel cell. + * coverage of the outline on each pixel cell by straight segments. * * It is based on ideas that I initially found in Raph Levien's * excellent LibArt graphics library (see https://www.levien.com/libart @@ -58,6 +58,14 @@ * different way, and I don't use sorted vector paths. Also, it doesn't * use floating point values. * + * Bézier segments are flattened by splitting them until their deviation + * from straight line becomes much smaller than a pixel. Therefore, the + * pixel coverage by a Bézier curve is calculated approximately. To + * estimate the deviation, we use the distance from the control point + * to the conic chord centre or the cubic chord trisection. These + * distances vanish fast after each split. In the conic case, they vanish + * predictably and the number of necessary splits can be calculated. + * * This renderer has the following advantages: * * - It doesn't need an intermediate bitmap. Instead, one can supply a @@ -67,7 +75,7 @@ * callback. * * - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on - * each pixel cell. + * each pixel cell by straight segments. * * - It performs a single pass on the outline (the `standard' FT2 * renderer makes two passes). @@ -75,7 +83,7 @@ * - It can easily be modified to render to _any_ number of gray levels * cheaply. * - * - For small (< 20) pixel sizes, it is faster than the standard + * - For small (< 80) pixel sizes, it is faster than the standard * renderer. * */ @@ -327,17 +335,9 @@ typedef ptrdiff_t FT_PtrDist; /* must be at least 6 bits! */ #define PIXEL_BITS 8 -#undef FLOOR -#undef CEILING -#undef TRUNC -#undef SCALED - #define ONE_PIXEL ( 1 << PIXEL_BITS ) -#define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) -#define SUBPIXELS( x ) ( (TPos)(x) * ONE_PIXEL ) -#define FLOOR( x ) ( (x) & -ONE_PIXEL ) -#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) -#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) +#define TRUNC( x ) (TCoord)( (x) >> PIXEL_BITS ) +#define FRACT( x ) (TCoord)( (x) & ( ONE_PIXEL - 1 ) ) #if PIXEL_BITS >= 6 #define UPSCALE( x ) ( (x) * ( ONE_PIXEL >> 6 ) ) @@ -388,9 +388,9 @@ typedef ptrdiff_t FT_PtrDist; #define FT_UDIVPREP( c, b ) \ long b ## _r = c ? (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) \ : 0 -#define FT_UDIV( a, b ) \ - ( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \ - ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) ) +#define FT_UDIV( a, b ) \ + (TCoord)( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >> \ + ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) ) /************************************************************************** @@ -432,6 +432,9 @@ typedef ptrdiff_t FT_PtrDist; #define FT_MAX_GRAY_POOL ( 2048 / sizeof ( TCell ) ) #endif + /* FT_Span buffer size for direct rendering only */ +#define FT_MAX_GRAY_SPANS 10 + #if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ /* We disable the warning `structure was padded due to */ @@ -465,6 +468,8 @@ typedef ptrdiff_t FT_PtrDist; FT_Raster_Span_Func render_span; void* render_span_data; + FT_Span spans[FT_MAX_GRAY_SPANS]; + int num_spans; } gray_TWorker, *gray_PWorker; @@ -516,7 +521,7 @@ typedef ptrdiff_t FT_PtrDist; /************************************************************************** * - * Record the current cell in the table. + * Record the current cell in the linked list. */ static void gray_record_cell( RAS_ARG ) @@ -526,10 +531,9 @@ typedef ptrdiff_t FT_PtrDist; pcell = &ras.ycells[ras.ey - ras.min_ey]; - for (;;) + while ( ( cell = *pcell ) ) { - cell = *pcell; - if ( !cell || cell->x > x ) + if ( cell->x > x ) break; if ( cell->x == x ) @@ -577,16 +581,13 @@ typedef ptrdiff_t FT_PtrDist; /* Note that if a cell is to the left of the clipping region, it is */ /* actually set to the (min_ex-1) horizontal position. */ - if ( ex < ras.min_ex ) - ex = ras.min_ex - 1; - /* record the current one if it is valid and substantial */ if ( !ras.invalid && ( ras.area || ras.cover ) ) gray_record_cell( RAS_VAR ); ras.area = 0; ras.cover = 0; - ras.ex = ex; + ras.ex = FT_MAX( ex, ras.min_ex - 1 ); ras.ey = ey; ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey || @@ -622,8 +623,8 @@ typedef ptrdiff_t FT_PtrDist; return; } - fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); - fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); + fx1 = FRACT( x1 ); + fx2 = FRACT( x2 ); /* everything is located in a single cell. That is easy! */ /* */ @@ -650,6 +651,9 @@ typedef ptrdiff_t FT_PtrDist; dx = -dx; } + /* the fractional part of y-delta is mod/dx. It is essential to */ + /* keep track of its accumulation for accurate rendering. */ + /* XXX: y-delta and x-delta below should be related. */ FT_DIV_MOD( TCoord, p, dx, delta, mod ); ras.area += (TArea)( ( fx1 + first ) * delta ); @@ -715,8 +719,8 @@ typedef ptrdiff_t FT_PtrDist; ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) goto End; - fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) ); - fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); + fy1 = FRACT( ras.y ); + fy2 = FRACT( to_y ); /* everything is on a single scanline */ if ( ey1 == ey2 ) @@ -732,7 +736,7 @@ typedef ptrdiff_t FT_PtrDist; if ( dx == 0 ) { TCoord ex = TRUNC( ras.x ); - TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 ); + TCoord two_fx = FRACT( ras.x ) << 1; TArea area; @@ -787,6 +791,8 @@ typedef ptrdiff_t FT_PtrDist; dy = -dy; } + /* the fractional part of x-delta is mod/dy. It is essential to */ + /* keep track of its accumulation for accurate rendering. */ FT_DIV_MOD( TCoord, p, dy, delta, mod ); x = ras.x + delta; @@ -843,8 +849,9 @@ typedef ptrdiff_t FT_PtrDist; gray_render_line( RAS_ARG_ TPos to_x, TPos to_y ) { - TPos dx, dy, fx1, fy1, fx2, fy2; - TCoord ex1, ex2, ey1, ey2; + TPos dx, dy; + TCoord fx1, fy1, fx2, fy2; + TCoord ex1, ey1, ex2, ey2; ey1 = TRUNC( ras.y ); @@ -858,8 +865,8 @@ typedef ptrdiff_t FT_PtrDist; ex1 = TRUNC( ras.x ); ex2 = TRUNC( to_x ); - fx1 = ras.x - SUBPIXELS( ex1 ); - fy1 = ras.y - SUBPIXELS( ey1 ); + fx1 = FRACT( ras.x ); + fy1 = FRACT( ras.y ); dx = to_x - ras.x; dy = to_y - ras.y; @@ -868,8 +875,8 @@ typedef ptrdiff_t FT_PtrDist; ; else if ( dy == 0 ) /* ex1 != ex2 */ /* any horizontal line */ { - ex1 = ex2; - gray_set_cell( RAS_VAR_ ex1, ey1 ); + gray_set_cell( RAS_VAR_ ex2, ey2 ); + goto End; } else if ( dx == 0 ) { @@ -896,7 +903,7 @@ typedef ptrdiff_t FT_PtrDist; } else /* any other line */ { - TPos prod = dx * fy1 - dy * fx1; + TPos prod = dx * (TPos)fy1 - dy * (TPos)fx1; FT_UDIVPREP( ex1 != ex2, dx ); FT_UDIVPREP( ey1 != ey2, dy ); @@ -910,7 +917,7 @@ typedef ptrdiff_t FT_PtrDist; prod - dx * ONE_PIXEL > 0 ) /* left */ { fx2 = 0; - fy2 = (TPos)FT_UDIV( -prod, -dx ); + fy2 = FT_UDIV( -prod, -dx ); prod -= dy * ONE_PIXEL; ras.cover += ( fy2 - fy1 ); ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); @@ -922,7 +929,7 @@ typedef ptrdiff_t FT_PtrDist; prod - dx * ONE_PIXEL + dy * ONE_PIXEL > 0 ) /* up */ { prod -= dx * ONE_PIXEL; - fx2 = (TPos)FT_UDIV( -prod, dy ); + fx2 = FT_UDIV( -prod, dy ); fy2 = ONE_PIXEL; ras.cover += ( fy2 - fy1 ); ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); @@ -935,7 +942,7 @@ typedef ptrdiff_t FT_PtrDist; { prod += dy * ONE_PIXEL; fx2 = ONE_PIXEL; - fy2 = (TPos)FT_UDIV( prod, dx ); + fy2 = FT_UDIV( prod, dx ); ras.cover += ( fy2 - fy1 ); ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); fx1 = 0; @@ -945,7 +952,7 @@ typedef ptrdiff_t FT_PtrDist; else /* ( prod + dy * ONE_PIXEL < 0 && prod > 0 ) down */ { - fx2 = (TPos)FT_UDIV( prod, -dy ); + fx2 = FT_UDIV( prod, -dy ); fy2 = 0; prod += dx * ONE_PIXEL; ras.cover += ( fy2 - fy1 ); @@ -959,8 +966,8 @@ typedef ptrdiff_t FT_PtrDist; } while ( ex1 != ex2 || ey1 != ey2 ); } - fx2 = to_x - SUBPIXELS( ex2 ); - fy2 = to_y - SUBPIXELS( ey2 ); + fx2 = FRACT( to_x ); + fy2 = FRACT( to_y ); ras.cover += ( fy2 - fy1 ); ras.area += ( fy2 - fy1 ) * ( fx1 + fx2 ); @@ -979,16 +986,18 @@ typedef ptrdiff_t FT_PtrDist; base[4].x = base[2].x; - b = base[1].x; - a = base[3].x = ( base[2].x + b ) / 2; - b = base[1].x = ( base[0].x + b ) / 2; - base[2].x = ( a + b ) / 2; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + base[3].x = b >> 1; + base[2].x = ( a + b ) >> 2; + base[1].x = a >> 1; base[4].y = base[2].y; - b = base[1].y; - a = base[3].y = ( base[2].y + b ) / 2; - b = base[1].y = ( base[0].y + b ) / 2; - base[2].y = ( a + b ) / 2; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + base[3].y = b >> 1; + base[2].y = ( a + b ) >> 2; + base[1].y = a >> 1; } @@ -1042,12 +1051,11 @@ typedef ptrdiff_t FT_PtrDist; /* many times as there are trailing zeros in the counter. */ do { - split = 1; - while ( ( draw & split ) == 0 ) + split = draw & ( -draw ); /* isolate the rightmost 1-bit */ + while ( ( split >>= 1 ) ) { gray_split_conic( arc ); arc += 2; - split <<= 1; } gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); @@ -1060,28 +1068,32 @@ typedef ptrdiff_t FT_PtrDist; static void gray_split_cubic( FT_Vector* base ) { - TPos a, b, c, d; + TPos a, b, c; base[6].x = base[3].x; - c = base[1].x; - d = base[2].x; - base[1].x = a = ( base[0].x + c ) / 2; - base[5].x = b = ( base[3].x + d ) / 2; - c = ( c + d ) / 2; - base[2].x = a = ( a + c ) / 2; - base[4].x = b = ( b + c ) / 2; - base[3].x = ( a + b ) / 2; + a = base[0].x + base[1].x; + b = base[1].x + base[2].x; + c = base[2].x + base[3].x; + base[5].x = c >> 1; + c += b; + base[4].x = c >> 2; + base[1].x = a >> 1; + a += b; + base[2].x = a >> 2; + base[3].x = ( a + c ) >> 3; base[6].y = base[3].y; - c = base[1].y; - d = base[2].y; - base[1].y = a = ( base[0].y + c ) / 2; - base[5].y = b = ( base[3].y + d ) / 2; - c = ( c + d ) / 2; - base[2].y = a = ( a + c ) / 2; - base[4].y = b = ( b + c ) / 2; - base[3].y = ( a + b ) / 2; + a = base[0].y + base[1].y; + b = base[1].y + base[2].y; + c = base[2].y + base[3].y; + base[5].y = c >> 1; + c += b; + base[4].y = c >> 2; + base[1].y = a >> 1; + a += b; + base[2].y = a >> 2; + base[3].y = ( a + c ) >> 3; } @@ -1092,9 +1104,6 @@ typedef ptrdiff_t FT_PtrDist; { FT_Vector bez_stack[16 * 3 + 1]; /* enough to accommodate bisections */ FT_Vector* arc = bez_stack; - TPos dx, dy, dx_, dy_; - TPos dx1, dy1, dx2, dy2; - TPos L, s, s_limit; arc[0].x = UPSCALE( to->x ); @@ -1123,45 +1132,13 @@ typedef ptrdiff_t FT_PtrDist; for (;;) { - /* Decide whether to split or draw. See `Rapid Termination */ - /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */ - /* F. Hain, at */ - /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */ - - /* dx and dy are x and y components of the P0-P3 chord vector. */ - dx = dx_ = arc[3].x - arc[0].x; - dy = dy_ = arc[3].y - arc[0].y; - - L = FT_HYPOT( dx_, dy_ ); - - /* Avoid possible arithmetic overflow below by splitting. */ - if ( L > 32767 ) - goto Split; - - /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ - s_limit = L * (TPos)( ONE_PIXEL / 6 ); - - /* s is L * the perpendicular distance from P1 to the line P0-P3. */ - dx1 = arc[1].x - arc[0].x; - dy1 = arc[1].y - arc[0].y; - s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx1 ), MUL_LONG( dx, dy1 ) ) ); - - if ( s > s_limit ) - goto Split; - - /* s is L * the perpendicular distance from P2 to the line P0-P3. */ - dx2 = arc[2].x - arc[0].x; - dy2 = arc[2].y - arc[0].y; - s = FT_ABS( SUB_LONG( MUL_LONG( dy, dx2 ), MUL_LONG( dx, dy2 ) ) ); - - if ( s > s_limit ) - goto Split; - - /* Split super curvy segments where the off points are so far - from the chord that the angles P0-P1-P3 or P0-P2-P3 become - acute as detected by appropriate dot products. */ - if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || - dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) + /* with each split, control points quickly converge towards */ + /* chord trisection points and the vanishing distances below */ + /* indicate when the segment is flat enough to draw */ + if ( FT_ABS( 2 * arc[0].x - 3 * arc[1].x + arc[3].x ) > ONE_PIXEL / 2 || + FT_ABS( 2 * arc[0].y - 3 * arc[1].y + arc[3].y ) > ONE_PIXEL / 2 || + FT_ABS( arc[0].x - 3 * arc[2].x + 2 * arc[3].x ) > ONE_PIXEL / 2 || + FT_ABS( arc[0].y - 3 * arc[2].y + 2 * arc[3].y ) > ONE_PIXEL / 2 ) goto Split; gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); @@ -1236,8 +1213,6 @@ typedef ptrdiff_t FT_PtrDist; { /* scale the coverage from 0..(ONE_PIXEL*ONE_PIXEL*2) to 0..256 */ coverage >>= PIXEL_BITS * 2 + 1 - 8; - if ( coverage < 0 ) - coverage = -coverage - 1; /* compute the line's coverage depending on the outline fill rule */ if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) @@ -1247,23 +1222,30 @@ typedef ptrdiff_t FT_PtrDist; if ( coverage >= 256 ) coverage = 511 - coverage; } - else + else /* default non-zero winding rule */ { - /* normal non-zero winding rule */ + if ( coverage < 0 ) + coverage = ~coverage; /* the same as -coverage - 1 */ + if ( coverage >= 256 ) coverage = 255; } - if ( ras.render_span ) /* for FT_RASTER_FLAG_DIRECT only */ + if ( ras.num_spans >= 0 ) /* for FT_RASTER_FLAG_DIRECT only */ { - FT_Span span; + FT_Span* span = ras.spans + ras.num_spans++; - span.x = (short)x; - span.len = (unsigned short)acount; - span.coverage = (unsigned char)coverage; + span->x = (short)x; + span->len = (unsigned short)acount; + span->coverage = (unsigned char)coverage; - ras.render_span( y, 1, &span, ras.render_span_data ); + if ( ras.num_spans == FT_MAX_GRAY_SPANS ) + { + /* flush the span buffer and reset the count */ + ras.render_span( y, ras.num_spans, ras.spans, ras.render_span_data ); + ras.num_spans = 0; + } } else { @@ -1277,14 +1259,29 @@ typedef ptrdiff_t FT_PtrDist; */ switch ( acount ) { - case 7: *q++ = c; - case 6: *q++ = c; - case 5: *q++ = c; - case 4: *q++ = c; - case 3: *q++ = c; - case 2: *q++ = c; - case 1: *q = c; - case 0: break; + case 7: + *q++ = c; + /* fall through */ + case 6: + *q++ = c; + /* fall through */ + case 5: + *q++ = c; + /* fall through */ + case 4: + *q++ = c; + /* fall through */ + case 3: + *q++ = c; + /* fall through */ + case 2: + *q++ = c; + /* fall through */ + case 1: + *q = c; + /* fall through */ + case 0: + break; default: FT_MEM_SET( q, c, acount ); } @@ -1322,6 +1319,13 @@ typedef ptrdiff_t FT_PtrDist; if ( cover != 0 ) gray_hline( RAS_VAR_ x, y, cover, ras.max_ex - x ); + + if ( ras.num_spans > 0 ) /* for FT_RASTER_FLAG_DIRECT only */ + { + /* flush the span buffer and reset the count */ + ras.render_span( y, ras.num_spans, ras.spans, ras.render_span_data ); + ras.num_spans = 0; + } } } @@ -1371,7 +1375,7 @@ typedef ptrdiff_t FT_PtrDist; void* user ) { #undef SCALED -#define SCALED( x ) ( ( (x) << shift ) - delta ) +#define SCALED( x ) ( (x) * ( 1L << shift ) - delta ) FT_Vector v_last; FT_Vector v_control; @@ -1631,7 +1635,7 @@ typedef ptrdiff_t FT_PtrDist; gray_convert_glyph_inner( RAS_ARG, int continued ) { - volatile int error = 0; + int error; if ( ft_setjmp( ras.jump_buffer ) == 0 ) @@ -1755,7 +1759,6 @@ typedef ptrdiff_t FT_PtrDist; { const FT_Outline* outline = (const FT_Outline*)params->source; const FT_Bitmap* target_map = params->target; - FT_BBox clip; #ifndef FT_STATIC_RASTER gray_TWorker worker[1]; @@ -1792,6 +1795,12 @@ typedef ptrdiff_t FT_PtrDist; ras.render_span = (FT_Raster_Span_Func)params->gray_spans; ras.render_span_data = params->user; + ras.num_spans = 0; + + ras.min_ex = params->clip_box.xMin; + ras.min_ey = params->clip_box.yMin; + ras.max_ex = params->clip_box.xMax; + ras.max_ey = params->clip_box.yMax; } else { @@ -1816,27 +1825,15 @@ typedef ptrdiff_t FT_PtrDist; ras.render_span = (FT_Raster_Span_Func)NULL; ras.render_span_data = NULL; - } + ras.num_spans = -1; /* invalid */ - /* compute clipping box */ - if ( params->flags & FT_RASTER_FLAG_DIRECT && - params->flags & FT_RASTER_FLAG_CLIP ) - clip = params->clip_box; - else - { - /* compute clip box from target pixmap */ - clip.xMin = 0; - clip.yMin = 0; - clip.xMax = (FT_Pos)target_map->width; - clip.yMax = (FT_Pos)target_map->rows; + ras.min_ex = 0; + ras.min_ey = 0; + ras.max_ex = (FT_Pos)target_map->width; + ras.max_ey = (FT_Pos)target_map->rows; } - /* clip to target bitmap, exit if nothing to do */ - ras.min_ex = clip.xMin; - ras.min_ey = clip.yMin; - ras.max_ex = clip.xMax; - ras.max_ey = clip.yMax; - + /* exit if nothing to do */ if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) return 0; diff --git a/thirdparty/freetype/src/smooth/ftsmooth.c b/thirdparty/freetype/src/smooth/ftsmooth.c index c8b6bb7518..cd034d2b40 100644 --- a/thirdparty/freetype/src/smooth/ftsmooth.c +++ b/thirdparty/freetype/src/smooth/ftsmooth.c @@ -243,7 +243,7 @@ } if ( lcd_filter_func ) - lcd_filter_func( bitmap, mode, lcd_weights ); + lcd_filter_func( bitmap, lcd_weights ); } #else /* !FT_CONFIG_OPTION_SUBPIXEL_RENDERING */ diff --git a/thirdparty/freetype/src/truetype/ttgload.c b/thirdparty/freetype/src/truetype/ttgload.c index cbee27aa69..a04684086b 100644 --- a/thirdparty/freetype/src/truetype/ttgload.c +++ b/thirdparty/freetype/src/truetype/ttgload.c @@ -82,6 +82,15 @@ #define UNSCALED_COMPONENT_OFFSET 0x1000 +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT +#define IS_DEFAULT_INSTANCE( _face ) \ + ( !( FT_IS_NAMED_INSTANCE( _face ) || \ + FT_IS_VARIATION( _face ) ) ) +#else +#define IS_DEFAULT_INSTANCE( _face ) 1 +#endif + + /************************************************************************** * * Return the horizontal metrics in font units for a given glyph. @@ -927,6 +936,11 @@ FT_Outline* outline; FT_Int n_points; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Memory memory = loader->face->root.memory; + FT_Vector* unrounded = NULL; +#endif + outline = &gloader->current.outline; n_points = outline->n_points; @@ -947,26 +961,32 @@ #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) || - FT_IS_VARIATION( FT_FACE( loader->face ) ) ) + if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) ) { + if ( FT_NEW_ARRAY( unrounded, n_points ) ) + goto Exit; + /* Deltas apply to the unscaled data. */ error = TT_Vary_Apply_Glyph_Deltas( loader->face, loader->glyph_index, outline, + unrounded, (FT_UInt)n_points ); /* recalculate linear horizontal and vertical advances */ /* if we don't have HVAR and VVAR, respectively */ + + /* XXX: change all FreeType modules to store `linear' and `vadvance' */ + /* in 26.6 format before the `base' module scales them to 16.16 */ if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) - loader->linear = outline->points[n_points - 3].x - - outline->points[n_points - 4].x; + loader->linear = FT_PIX_ROUND( unrounded[n_points - 3].x - + unrounded[n_points - 4].x ) / 64; if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) - loader->vadvance = outline->points[n_points - 1].x - - outline->points[n_points - 2].x; + loader->vadvance = FT_PIX_ROUND( unrounded[n_points - 1].x - + unrounded[n_points - 2].x ) / 64; if ( error ) - return error; + goto Exit; } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -1021,10 +1041,23 @@ /* compensate for any scaling by de/emboldening; */ /* the amount was determined via experimentation */ if ( x_scale_factor != 1000 && ppem > 11 ) + { +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + FT_Vector* orig_points = outline->points; + + + if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) ) + outline->points = unrounded; +#endif FT_Outline_EmboldenXY( outline, FT_MulFix( 1280 * ppem, 1000 - x_scale_factor ), 0 ); +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) ) + outline->points = orig_points; +#endif + } do_scale = TRUE; } } @@ -1045,10 +1078,26 @@ if ( do_scale ) { - for ( ; vec < limit; vec++ ) +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + if ( !IS_DEFAULT_INSTANCE( FT_FACE( loader->face ) ) ) { - vec->x = FT_MulFix( vec->x, x_scale ); - vec->y = FT_MulFix( vec->y, y_scale ); + FT_Vector* u = unrounded; + + + for ( ; vec < limit; vec++, u++ ) + { + vec->x = ( FT_MulFix( u->x, x_scale ) + 32 ) >> 6; + vec->y = ( FT_MulFix( u->y, y_scale ) + 32 ) >> 6; + } + } + else +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + { + for ( ; vec < limit; vec++ ) + { + vec->x = FT_MulFix( vec->x, x_scale ); + vec->y = FT_MulFix( vec->y, y_scale ); + } } } @@ -1080,6 +1129,11 @@ error = TT_Hint_Glyph( loader, 0 ); } +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + Exit: + FT_FREE( unrounded ); +#endif + return error; } @@ -1681,6 +1735,9 @@ short contours[4] = { 0, 1, 2, 3 }; FT_Outline outline; + /* unrounded values */ + FT_Vector unrounded[4] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} }; + points[0].x = loader->pp1.x; points[0].y = loader->pp1.y; @@ -1702,6 +1759,7 @@ error = TT_Vary_Apply_Glyph_Deltas( loader->face, glyph_index, &outline, + unrounded, (FT_UInt)outline.n_points ); if ( error ) goto Exit; @@ -1719,9 +1777,11 @@ /* recalculate linear horizontal and vertical advances */ /* if we don't have HVAR and VVAR, respectively */ if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) - loader->linear = loader->pp2.x - loader->pp1.x; + loader->linear = FT_PIX_ROUND( unrounded[1].x - + unrounded[0].x ) / 64; if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) - loader->vadvance = loader->pp4.x - loader->pp3.x; + loader->vadvance = FT_PIX_ROUND( unrounded[3].x - + unrounded[2].x ) / 64; } #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ @@ -1861,9 +1921,10 @@ FT_SubGlyph subglyph; FT_Outline outline; - FT_Vector* points = NULL; - char* tags = NULL; - short* contours = NULL; + FT_Vector* points = NULL; + char* tags = NULL; + short* contours = NULL; + FT_Vector* unrounded = NULL; limit = (short)gloader->current.num_subglyphs; @@ -1877,9 +1938,10 @@ outline.tags = NULL; outline.contours = NULL; - if ( FT_NEW_ARRAY( points, outline.n_points ) || - FT_NEW_ARRAY( tags, outline.n_points ) || - FT_NEW_ARRAY( contours, outline.n_points ) ) + if ( FT_NEW_ARRAY( points, outline.n_points ) || + FT_NEW_ARRAY( tags, outline.n_points ) || + FT_NEW_ARRAY( contours, outline.n_points ) || + FT_NEW_ARRAY( unrounded, outline.n_points ) ) goto Exit1; subglyph = gloader->current.subglyphs; @@ -1928,6 +1990,7 @@ face, glyph_index, &outline, + unrounded, (FT_UInt)outline.n_points ) ) ) goto Exit1; @@ -1955,14 +2018,19 @@ /* recalculate linear horizontal and vertical advances */ /* if we don't have HVAR and VVAR, respectively */ if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ) - loader->linear = loader->pp2.x - loader->pp1.x; + loader->linear = + FT_PIX_ROUND( unrounded[outline.n_points - 3].x - + unrounded[outline.n_points - 4].x ) / 64; if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ) - loader->vadvance = loader->pp4.x - loader->pp3.x; + loader->vadvance = + FT_PIX_ROUND( unrounded[outline.n_points - 1].x - + unrounded[outline.n_points - 2].x ) / 64; Exit1: FT_FREE( outline.points ); FT_FREE( outline.tags ); FT_FREE( outline.contours ); + FT_FREE( unrounded ); if ( error ) goto Exit; @@ -2088,6 +2156,7 @@ loader->ins_pos = ins_pos; if ( IS_HINTED( loader->load_flags ) && #ifdef TT_USE_BYTECODE_INTERPRETER + subglyph && subglyph->flags & WE_HAVE_INSTR && #endif num_points > start_point ) @@ -2611,11 +2680,6 @@ if ( reexecute ) { - FT_UInt i; - - - for ( i = 0; i < size->cvt_size; i++ ) - size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); error = tt_size_run_prep( size, pedantic ); if ( error ) return error; @@ -2718,13 +2782,6 @@ FT_Error error; TT_LoaderRec loader; -#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT -#define IS_DEFAULT_INSTANCE ( !( FT_IS_NAMED_INSTANCE( glyph->face ) || \ - FT_IS_VARIATION( glyph->face ) ) ) -#else -#define IS_DEFAULT_INSTANCE 1 -#endif - FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index )); @@ -2733,7 +2790,7 @@ /* try to load embedded bitmap (if any) */ if ( size->strike_index != 0xFFFFFFFFUL && ( load_flags & FT_LOAD_NO_BITMAP ) == 0 && - IS_DEFAULT_INSTANCE ) + IS_DEFAULT_INSTANCE( glyph->face ) ) { FT_Fixed x_scale = size->root.metrics.x_scale; FT_Fixed y_scale = size->root.metrics.y_scale; diff --git a/thirdparty/freetype/src/truetype/ttgxvar.c b/thirdparty/freetype/src/truetype/ttgxvar.c index 020918f533..78d87dc097 100644 --- a/thirdparty/freetype/src/truetype/ttgxvar.c +++ b/thirdparty/freetype/src/truetype/ttgxvar.c @@ -68,12 +68,16 @@ /* some macros we need */ -#define FT_fdot14ToFixed( x ) \ - ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) -#define FT_intToFixed( i ) \ - ( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) -#define FT_fixedToInt( x ) \ - ( (FT_Short)( ( (FT_UInt32)(x) + 0x8000U ) >> 16 ) ) +#define FT_fdot14ToFixed( x ) \ + ( (FT_Fixed)( (FT_ULong)(x) << 2 ) ) +#define FT_intToFixed( i ) \ + ( (FT_Fixed)( (FT_ULong)(i) << 16 ) ) +#define FT_fdot6ToFixed( i ) \ + ( (FT_Fixed)( (FT_ULong)(i) << 10 ) ) +#define FT_fixedToInt( x ) \ + ( (FT_Short)( ( (x) + 0x8000U ) >> 16 ) ) +#define FT_fixedToFdot6( x ) \ + ( (FT_Pos)( ( (x) + 0x200 ) >> 10 ) ) /************************************************************************** @@ -397,9 +401,10 @@ for ( j = 0; j < segment->pairCount; j++ ) { - /* convert to Fixed */ - segment->correspondence[j].fromCoord = FT_GET_SHORT() * 4; - segment->correspondence[j].toCoord = FT_GET_SHORT() * 4; + segment->correspondence[j].fromCoord = + FT_fdot14ToFixed( FT_GET_SHORT() ); + segment->correspondence[j].toCoord = + FT_fdot14ToFixed( FT_GET_SHORT() ); FT_TRACE5(( " mapping %.5f to %.5f\n", segment->correspondence[j].fromCoord / 65536.0, @@ -1616,7 +1621,7 @@ for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ ) { blend->tuplecoords[i * gvar_head.axisCount + j] = - FT_GET_SHORT() * 4; /* convert to FT_Fixed */ + FT_fdot14ToFixed( FT_GET_SHORT() ); FT_TRACE5(( "%.5f ", blend->tuplecoords[i * gvar_head.axisCount + j] / 65536.0 )); } @@ -3054,7 +3059,7 @@ if ( instance_index > num_instances ) goto Exit; - if ( instance_index > 0 && mmvar->namedstyle ) + if ( instance_index > 0 ) { FT_Memory memory = face->root.memory; SFNT_Service sfnt = (SFNT_Service)face->sfnt; @@ -3080,7 +3085,12 @@ mmvar->num_axis, named_style->coords ); if ( error ) + { + /* internal error code -1 means `no change' */ + if ( error == -1 ) + error = FT_Err_Ok; goto Exit; + } } else error = TT_Set_Var_Design( face, 0, NULL ); @@ -3103,6 +3113,21 @@ /*************************************************************************/ + static FT_Error + tt_cvt_ready_iterator( FT_ListNode node, + void* user ) + { + TT_Size size = (TT_Size)node->data; + + FT_UNUSED( user ); + + + size->cvt_ready = -1; + + return FT_Err_Ok; + } + + /************************************************************************** * * @Function: @@ -3133,6 +3158,8 @@ FT_Error error; FT_Memory memory = stream->memory; + FT_Face root = &face->root; + FT_ULong table_start; FT_ULong table_len; @@ -3261,8 +3288,7 @@ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; j++ ) - tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ - /* short frac to fixed */ + tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); } else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) { @@ -3293,9 +3319,9 @@ if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { for ( j = 0; j < blend->num_axis; j++ ) - im_start_coords[j] = FT_GET_SHORT() * 4; + im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); for ( j = 0; j < blend->num_axis; j++ ) - im_end_coords[j] = FT_GET_SHORT() * 4; + im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); } apply = ft_var_apply_tuple( blend, @@ -3360,9 +3386,9 @@ { FT_TRACE7(( " %d: %f -> %f\n", j, - ( FT_intToFixed( face->cvt[j] ) + + ( FT_fdot6ToFixed( face->cvt[j] ) + old_cvt_delta ) / 65536.0, - ( FT_intToFixed( face->cvt[j] ) + + ( FT_fdot6ToFixed( face->cvt[j] ) + cvt_deltas[j] ) / 65536.0 )); count++; } @@ -3402,9 +3428,9 @@ { FT_TRACE7(( " %d: %f -> %f\n", pindex, - ( FT_intToFixed( face->cvt[pindex] ) + + ( FT_fdot6ToFixed( face->cvt[pindex] ) + old_cvt_delta ) / 65536.0, - ( FT_intToFixed( face->cvt[pindex] ) + + ( FT_fdot6ToFixed( face->cvt[pindex] ) + cvt_deltas[pindex] ) / 65536.0 )); count++; } @@ -3429,7 +3455,7 @@ FT_TRACE5(( "\n" )); for ( i = 0; i < face->cvt_size; i++ ) - face->cvt[i] += FT_fixedToInt( cvt_deltas[i] ); + face->cvt[i] += FT_fixedToFdot6( cvt_deltas[i] ); FExit: FT_FRAME_EXIT(); @@ -3442,6 +3468,12 @@ FT_FREE( im_end_coords ); FT_FREE( cvt_deltas ); + /* iterate over all FT_Size objects and set `cvt_ready' to -1 */ + /* to trigger rescaling of all CVT values */ + FT_List_Iterate( &root->sizes_list, + tt_cvt_ready_iterator, + NULL ); + return error; } @@ -3669,6 +3701,11 @@ * outline :: * The outline to change. * + * @Output: + * unrounded :: + * An array with `n_points' elements that is filled with unrounded + * point coordinates (in 26.6 format). + * * @Return: * FreeType error code. 0 means success. */ @@ -3676,6 +3713,7 @@ TT_Vary_Apply_Glyph_Deltas( TT_Face face, FT_UInt glyph_index, FT_Outline* outline, + FT_Vector* unrounded, FT_UInt n_points ) { FT_Error error; @@ -3717,6 +3755,12 @@ if ( !face->doblend || !blend ) return FT_THROW( Invalid_Argument ); + for ( i = 0; i < n_points; i++ ) + { + unrounded[i].x = INT_TO_F26DOT6( outline->points[i].x ); + unrounded[i].y = INT_TO_F26DOT6( outline->points[i].y ); + } + if ( glyph_index >= blend->gv_glyphcnt || blend->glyphoffsets[glyph_index] == blend->glyphoffsets[glyph_index + 1] ) @@ -3807,8 +3851,7 @@ if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j = 0; j < blend->num_axis; j++ ) - tuple_coords[j] = FT_GET_SHORT() * 4; /* convert from */ - /* short frac to fixed */ + tuple_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); } else if ( ( tupleIndex & GX_TI_TUPLE_INDEX_MASK ) >= blend->tuplecount ) { @@ -3828,9 +3871,9 @@ if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { for ( j = 0; j < blend->num_axis; j++ ) - im_start_coords[j] = FT_GET_SHORT() * 4; + im_start_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); for ( j = 0; j < blend->num_axis; j++ ) - im_end_coords[j] = FT_GET_SHORT() * 4; + im_end_coords[j] = FT_fdot14ToFixed( FT_GET_SHORT() ); } apply = ft_var_apply_tuple( blend, @@ -4064,6 +4107,9 @@ for ( i = 0; i < n_points; i++ ) { + unrounded[i].x += FT_fixedToFdot6( point_deltas_x[i] ); + unrounded[i].y += FT_fixedToFdot6( point_deltas_y[i] ); + outline->points[i].x += FT_fixedToInt( point_deltas_x[i] ); outline->points[i].y += FT_fixedToInt( point_deltas_y[i] ); } diff --git a/thirdparty/freetype/src/truetype/ttgxvar.h b/thirdparty/freetype/src/truetype/ttgxvar.h index 7e8d9768a7..07c99b6403 100644 --- a/thirdparty/freetype/src/truetype/ttgxvar.h +++ b/thirdparty/freetype/src/truetype/ttgxvar.h @@ -416,6 +416,7 @@ FT_BEGIN_HEADER TT_Vary_Apply_Glyph_Deltas( TT_Face face, FT_UInt glyph_index, FT_Outline* outline, + FT_Vector* unrounded, FT_UInt n_points ); FT_LOCAL( FT_Error ) diff --git a/thirdparty/freetype/src/truetype/ttinterp.c b/thirdparty/freetype/src/truetype/ttinterp.c index 403f3753c7..70434e1729 100644 --- a/thirdparty/freetype/src/truetype/ttinterp.c +++ b/thirdparty/freetype/src/truetype/ttinterp.c @@ -654,23 +654,25 @@ /* opcodes are gathered in groups of 16 */ /* please keep the spaces as they are */ - /* SVTCA y */ PACK( 0, 0 ), - /* SVTCA x */ PACK( 0, 0 ), - /* SPvTCA y */ PACK( 0, 0 ), - /* SPvTCA x */ PACK( 0, 0 ), - /* SFvTCA y */ PACK( 0, 0 ), - /* SFvTCA x */ PACK( 0, 0 ), - /* SPvTL // */ PACK( 2, 0 ), - /* SPvTL + */ PACK( 2, 0 ), - /* SFvTL // */ PACK( 2, 0 ), - /* SFvTL + */ PACK( 2, 0 ), - /* SPvFS */ PACK( 2, 0 ), - /* SFvFS */ PACK( 2, 0 ), - /* GPv */ PACK( 0, 2 ), - /* GFv */ PACK( 0, 2 ), - /* SFvTPv */ PACK( 0, 0 ), + /* 0x00 */ + /* SVTCA[0] */ PACK( 0, 0 ), + /* SVTCA[1] */ PACK( 0, 0 ), + /* SPVTCA[0] */ PACK( 0, 0 ), + /* SPVTCA[1] */ PACK( 0, 0 ), + /* SFVTCA[0] */ PACK( 0, 0 ), + /* SFVTCA[1] */ PACK( 0, 0 ), + /* SPVTL[0] */ PACK( 2, 0 ), + /* SPVTL[1] */ PACK( 2, 0 ), + /* SFVTL[0] */ PACK( 2, 0 ), + /* SFVTL[1] */ PACK( 2, 0 ), + /* SPVFS */ PACK( 2, 0 ), + /* SFVFS */ PACK( 2, 0 ), + /* GPV */ PACK( 0, 2 ), + /* GFV */ PACK( 0, 2 ), + /* SFVTPV */ PACK( 0, 0 ), /* ISECT */ PACK( 5, 0 ), + /* 0x10 */ /* SRP0 */ PACK( 1, 0 ), /* SRP1 */ PACK( 1, 0 ), /* SRP2 */ PACK( 1, 0 ), @@ -684,10 +686,11 @@ /* SMD */ PACK( 1, 0 ), /* ELSE */ PACK( 0, 0 ), /* JMPR */ PACK( 1, 0 ), - /* SCvTCi */ PACK( 1, 0 ), - /* SSwCi */ PACK( 1, 0 ), + /* SCVTCI */ PACK( 1, 0 ), + /* SSWCI */ PACK( 1, 0 ), /* SSW */ PACK( 1, 0 ), + /* 0x20 */ /* DUP */ PACK( 1, 2 ), /* POP */ PACK( 1, 0 ), /* CLEAR */ PACK( 0, 0 ), @@ -695,7 +698,7 @@ /* DEPTH */ PACK( 0, 1 ), /* CINDEX */ PACK( 1, 1 ), /* MINDEX */ PACK( 1, 0 ), - /* AlignPTS */ PACK( 2, 0 ), + /* ALIGNPTS */ PACK( 2, 0 ), /* INS_$28 */ PACK( 0, 0 ), /* UTP */ PACK( 1, 0 ), /* LOOPCALL */ PACK( 2, 0 ), @@ -705,6 +708,7 @@ /* MDAP[0] */ PACK( 1, 0 ), /* MDAP[1] */ PACK( 1, 0 ), + /* 0x30 */ /* IUP[0] */ PACK( 0, 0 ), /* IUP[1] */ PACK( 0, 0 ), /* SHP[0] */ PACK( 0, 0 ), /* loops */ @@ -717,17 +721,18 @@ /* IP */ PACK( 0, 0 ), /* loops */ /* MSIRP[0] */ PACK( 2, 0 ), /* MSIRP[1] */ PACK( 2, 0 ), - /* AlignRP */ PACK( 0, 0 ), /* loops */ + /* ALIGNRP */ PACK( 0, 0 ), /* loops */ /* RTDG */ PACK( 0, 0 ), /* MIAP[0] */ PACK( 2, 0 ), /* MIAP[1] */ PACK( 2, 0 ), - /* NPushB */ PACK( 0, 0 ), - /* NPushW */ PACK( 0, 0 ), + /* 0x40 */ + /* NPUSHB */ PACK( 0, 0 ), + /* NPUSHW */ PACK( 0, 0 ), /* WS */ PACK( 2, 0 ), /* RS */ PACK( 1, 1 ), - /* WCvtP */ PACK( 2, 0 ), - /* RCvt */ PACK( 1, 1 ), + /* WCVTP */ PACK( 2, 0 ), + /* RCVT */ PACK( 1, 1 ), /* GC[0] */ PACK( 1, 1 ), /* GC[1] */ PACK( 1, 1 ), /* SCFS */ PACK( 2, 0 ), @@ -735,10 +740,11 @@ /* MD[1] */ PACK( 2, 1 ), /* MPPEM */ PACK( 0, 1 ), /* MPS */ PACK( 0, 1 ), - /* FlipON */ PACK( 0, 0 ), - /* FlipOFF */ PACK( 0, 0 ), + /* FLIPON */ PACK( 0, 0 ), + /* FLIPOFF */ PACK( 0, 0 ), /* DEBUG */ PACK( 1, 0 ), + /* 0x50 */ /* LT */ PACK( 2, 1 ), /* LTEQ */ PACK( 2, 1 ), /* GT */ PACK( 2, 1 ), @@ -752,10 +758,11 @@ /* AND */ PACK( 2, 1 ), /* OR */ PACK( 2, 1 ), /* NOT */ PACK( 1, 1 ), - /* DeltaP1 */ PACK( 1, 0 ), + /* DELTAP1 */ PACK( 1, 0 ), /* SDB */ PACK( 1, 0 ), /* SDS */ PACK( 1, 0 ), + /* 0x60 */ /* ADD */ PACK( 2, 1 ), /* SUB */ PACK( 2, 1 ), /* DIV */ PACK( 2, 1 ), @@ -773,14 +780,15 @@ /* NROUND[2] */ PACK( 1, 1 ), /* NROUND[3] */ PACK( 1, 1 ), - /* WCvtF */ PACK( 2, 0 ), - /* DeltaP2 */ PACK( 1, 0 ), - /* DeltaP3 */ PACK( 1, 0 ), - /* DeltaCn[0] */ PACK( 1, 0 ), - /* DeltaCn[1] */ PACK( 1, 0 ), - /* DeltaCn[2] */ PACK( 1, 0 ), + /* 0x70 */ + /* WCVTF */ PACK( 2, 0 ), + /* DELTAP2 */ PACK( 1, 0 ), + /* DELTAP3 */ PACK( 1, 0 ), + /* DELTAC1 */ PACK( 1, 0 ), + /* DELTAC2 */ PACK( 1, 0 ), + /* DELTAC3 */ PACK( 1, 0 ), /* SROUND */ PACK( 1, 0 ), - /* S45Round */ PACK( 1, 0 ), + /* S45ROUND */ PACK( 1, 0 ), /* JROT */ PACK( 2, 0 ), /* JROF */ PACK( 2, 0 ), /* ROFF */ PACK( 0, 0 ), @@ -790,23 +798,25 @@ /* SANGW */ PACK( 1, 0 ), /* AA */ PACK( 1, 0 ), - /* FlipPT */ PACK( 0, 0 ), /* loops */ - /* FlipRgON */ PACK( 2, 0 ), - /* FlipRgOFF */ PACK( 2, 0 ), + /* 0x80 */ + /* FLIPPT */ PACK( 0, 0 ), /* loops */ + /* FLIPRGON */ PACK( 2, 0 ), + /* FLIPRGOFF */ PACK( 2, 0 ), /* INS_$83 */ PACK( 0, 0 ), /* INS_$84 */ PACK( 0, 0 ), - /* ScanCTRL */ PACK( 1, 0 ), - /* SDPvTL[0] */ PACK( 2, 0 ), - /* SDPvTL[1] */ PACK( 2, 0 ), - /* GetINFO */ PACK( 1, 1 ), + /* SCANCTRL */ PACK( 1, 0 ), + /* SDPVTL[0] */ PACK( 2, 0 ), + /* SDPVTL[1] */ PACK( 2, 0 ), + /* GETINFO */ PACK( 1, 1 ), /* IDEF */ PACK( 1, 0 ), /* ROLL */ PACK( 3, 3 ), /* MAX */ PACK( 2, 1 ), /* MIN */ PACK( 2, 1 ), - /* ScanTYPE */ PACK( 1, 0 ), - /* InstCTRL */ PACK( 2, 0 ), + /* SCANTYPE */ PACK( 1, 0 ), + /* INSTCTRL */ PACK( 2, 0 ), /* INS_$8F */ PACK( 0, 0 ), + /* 0x90 */ /* INS_$90 */ PACK( 0, 0 ), /* GETVAR */ PACK( 0, 0 ), /* will be handled specially */ /* GETDATA */ PACK( 0, 1 ), @@ -824,6 +834,7 @@ /* INS_$9E */ PACK( 0, 0 ), /* INS_$9F */ PACK( 0, 0 ), + /* 0xA0 */ /* INS_$A0 */ PACK( 0, 0 ), /* INS_$A1 */ PACK( 0, 0 ), /* INS_$A2 */ PACK( 0, 0 ), @@ -841,23 +852,25 @@ /* INS_$AE */ PACK( 0, 0 ), /* INS_$AF */ PACK( 0, 0 ), - /* PushB[0] */ PACK( 0, 1 ), - /* PushB[1] */ PACK( 0, 2 ), - /* PushB[2] */ PACK( 0, 3 ), - /* PushB[3] */ PACK( 0, 4 ), - /* PushB[4] */ PACK( 0, 5 ), - /* PushB[5] */ PACK( 0, 6 ), - /* PushB[6] */ PACK( 0, 7 ), - /* PushB[7] */ PACK( 0, 8 ), - /* PushW[0] */ PACK( 0, 1 ), - /* PushW[1] */ PACK( 0, 2 ), - /* PushW[2] */ PACK( 0, 3 ), - /* PushW[3] */ PACK( 0, 4 ), - /* PushW[4] */ PACK( 0, 5 ), - /* PushW[5] */ PACK( 0, 6 ), - /* PushW[6] */ PACK( 0, 7 ), - /* PushW[7] */ PACK( 0, 8 ), - + /* 0xB0 */ + /* PUSHB[0] */ PACK( 0, 1 ), + /* PUSHB[1] */ PACK( 0, 2 ), + /* PUSHB[2] */ PACK( 0, 3 ), + /* PUSHB[3] */ PACK( 0, 4 ), + /* PUSHB[4] */ PACK( 0, 5 ), + /* PUSHB[5] */ PACK( 0, 6 ), + /* PUSHB[6] */ PACK( 0, 7 ), + /* PUSHB[7] */ PACK( 0, 8 ), + /* PUSHW[0] */ PACK( 0, 1 ), + /* PUSHW[1] */ PACK( 0, 2 ), + /* PUSHW[2] */ PACK( 0, 3 ), + /* PUSHW[3] */ PACK( 0, 4 ), + /* PUSHW[4] */ PACK( 0, 5 ), + /* PUSHW[5] */ PACK( 0, 6 ), + /* PUSHW[6] */ PACK( 0, 7 ), + /* PUSHW[7] */ PACK( 0, 8 ), + + /* 0xC0 */ /* MDRP[00] */ PACK( 1, 0 ), /* MDRP[01] */ PACK( 1, 0 ), /* MDRP[02] */ PACK( 1, 0 ), @@ -875,6 +888,7 @@ /* MDRP[14] */ PACK( 1, 0 ), /* MDRP[15] */ PACK( 1, 0 ), + /* 0xD0 */ /* MDRP[16] */ PACK( 1, 0 ), /* MDRP[17] */ PACK( 1, 0 ), /* MDRP[18] */ PACK( 1, 0 ), @@ -892,6 +906,7 @@ /* MDRP[30] */ PACK( 1, 0 ), /* MDRP[31] */ PACK( 1, 0 ), + /* 0xE0 */ /* MIRP[00] */ PACK( 2, 0 ), /* MIRP[01] */ PACK( 2, 0 ), /* MIRP[02] */ PACK( 2, 0 ), @@ -909,6 +924,7 @@ /* MIRP[14] */ PACK( 2, 0 ), /* MIRP[15] */ PACK( 2, 0 ), + /* 0xF0 */ /* MIRP[16] */ PACK( 2, 0 ), /* MIRP[17] */ PACK( 2, 0 ), /* MIRP[18] */ PACK( 2, 0 ), @@ -937,23 +953,25 @@ static const char* const opcode_name[256] = { - "7 SVTCA y", - "7 SVTCA x", - "8 SPvTCA y", - "8 SPvTCA x", - "8 SFvTCA y", - "8 SFvTCA x", - "8 SPvTL ||", - "7 SPvTL +", - "8 SFvTL ||", - "7 SFvTL +", - "5 SPvFS", - "5 SFvFS", - "3 GPv", - "3 GFv", - "6 SFvTPv", + /* 0x00 */ + "8 SVTCA[y]", + "8 SVTCA[x]", + "9 SPVTCA[y]", + "9 SPVTCA[x]", + "9 SFVTCA[y]", + "9 SFVTCA[x]", + "9 SPVTL[||]", + "8 SPVTL[+]", + "9 SFVTL[||]", + "8 SFVTL[+]", + "5 SPVFS", + "5 SFVFS", + "3 GPV", + "3 GFV", + "6 SFVTPV", "5 ISECT", + /* 0x10 */ "4 SRP0", "4 SRP1", "4 SRP2", @@ -967,10 +985,11 @@ "3 SMD", "4 ELSE", "4 JMPR", - "6 SCvTCi", - "5 SSwCi", + "6 SCVTCI", + "5 SSWCI", "3 SSW", + /* 0x20 */ "3 DUP", "3 POP", "5 CLEAR", @@ -978,50 +997,53 @@ "5 DEPTH", "6 CINDEX", "6 MINDEX", - "8 AlignPTS", + "8 ALIGNPTS", "7 INS_$28", "3 UTP", "8 LOOPCALL", "4 CALL", "4 FDEF", "4 ENDF", - "7 MDAP[0]", - "7 MDAP[1]", - - "6 IUP[0]", - "6 IUP[1]", - "6 SHP[0]", - "6 SHP[1]", - "6 SHC[0]", - "6 SHC[1]", - "6 SHZ[0]", - "6 SHZ[1]", + "6 MDAP[]", + "9 MDAP[rnd]", + + /* 0x30 */ + "6 IUP[y]", + "6 IUP[x]", + "8 SHP[rp2]", + "8 SHP[rp1]", + "8 SHC[rp2]", + "8 SHC[rp1]", + "8 SHZ[rp2]", + "8 SHZ[rp1]", "5 SHPIX", "2 IP", - "8 MSIRP[0]", - "8 MSIRP[1]", - "7 AlignRP", + "7 MSIRP[]", + "A MSIRP[rp0]", + "7 ALIGNRP", "4 RTDG", - "7 MIAP[0]", - "7 MIAP[1]", + "6 MIAP[]", + "9 MIAP[rnd]", - "6 NPushB", - "6 NPushW", + /* 0x40 */ + "6 NPUSHB", + "6 NPUSHW", "2 WS", "2 RS", - "5 WCvtP", - "4 RCvt", - "5 GC[0]", - "5 GC[1]", + "5 WCVTP", + "4 RCVT", + "8 GC[curr]", + "8 GC[orig]", "4 SCFS", - "5 MD[0]", - "5 MD[1]", + "8 MD[curr]", + "8 MD[orig]", "5 MPPEM", "3 MPS", - "6 FlipON", - "7 FlipOFF", + "6 FLIPON", + "7 FLIPOFF", "5 DEBUG", + /* 0x50 */ "2 LT", "4 LTEQ", "2 GT", @@ -1035,10 +1057,11 @@ "3 AND", "2 OR", "3 NOT", - "7 DeltaP1", + "7 DELTAP1", "3 SDB", "3 SDS", + /* 0x60 */ "3 ADD", "3 SUB", "3 DIV", @@ -1047,23 +1070,24 @@ "3 NEG", "5 FLOOR", "7 CEILING", - "8 ROUND[0]", - "8 ROUND[1]", - "8 ROUND[2]", - "8 ROUND[3]", - "9 NROUND[0]", - "9 NROUND[1]", - "9 NROUND[2]", - "9 NROUND[3]", - - "5 WCvtF", - "7 DeltaP2", - "7 DeltaP3", - "A DeltaCn[0]", - "A DeltaCn[1]", - "A DeltaCn[2]", + "8 ROUND[G]", + "8 ROUND[B]", + "8 ROUND[W]", + "7 ROUND[]", + "9 NROUND[G]", + "9 NROUND[B]", + "9 NROUND[W]", + "8 NROUND[]", + + /* 0x70 */ + "5 WCVTF", + "7 DELTAP2", + "7 DELTAP3", + "7 DELTAC1", + "7 DELTAC2", + "7 DELTAC3", "6 SROUND", - "8 S45Round", + "8 S45ROUND", "4 JROT", "4 JROF", "4 ROFF", @@ -1073,26 +1097,28 @@ "5 SANGW", "2 AA", - "6 FlipPT", - "8 FlipRgON", - "9 FlipRgOFF", + /* 0x80 */ + "6 FLIPPT", + "8 FLIPRGON", + "9 FLIPRGOFF", "7 INS_$83", "7 INS_$84", - "8 ScanCTRL", - "9 SDPvTL[0]", - "9 SDPvTL[1]", - "7 GetINFO", + "8 SCANCTRL", + "A SDPVTL[||]", + "9 SDPVTL[+]", + "7 GETINFO", "4 IDEF", "4 ROLL", "3 MAX", "3 MIN", - "8 ScanTYPE", - "8 InstCTRL", + "8 SCANTYPE", + "8 INSTCTRL", "7 INS_$8F", + /* 0x90 */ "7 INS_$90", #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT - "6 GETVAR", + "C GETVARIATION", "7 GETDATA", #else "7 INS_$91", @@ -1112,6 +1138,7 @@ "7 INS_$9E", "7 INS_$9F", + /* 0xA0 */ "7 INS_$A0", "7 INS_$A1", "7 INS_$A2", @@ -1129,90 +1156,95 @@ "7 INS_$AE", "7 INS_$AF", - "8 PushB[0]", - "8 PushB[1]", - "8 PushB[2]", - "8 PushB[3]", - "8 PushB[4]", - "8 PushB[5]", - "8 PushB[6]", - "8 PushB[7]", - "8 PushW[0]", - "8 PushW[1]", - "8 PushW[2]", - "8 PushW[3]", - "8 PushW[4]", - "8 PushW[5]", - "8 PushW[6]", - "8 PushW[7]", - + /* 0xB0 */ + "8 PUSHB[0]", + "8 PUSHB[1]", + "8 PUSHB[2]", + "8 PUSHB[3]", + "8 PUSHB[4]", + "8 PUSHB[5]", + "8 PUSHB[6]", + "8 PUSHB[7]", + "8 PUSHW[0]", + "8 PUSHW[1]", + "8 PUSHW[2]", + "8 PUSHW[3]", + "8 PUSHW[4]", + "8 PUSHW[5]", + "8 PUSHW[6]", + "8 PUSHW[7]", + + /* 0xC0 */ "7 MDRP[G]", "7 MDRP[B]", "7 MDRP[W]", - "7 MDRP[?]", + "6 MDRP[]", "8 MDRP[rG]", "8 MDRP[rB]", "8 MDRP[rW]", - "8 MDRP[r?]", + "7 MDRP[r]", "8 MDRP[mG]", "8 MDRP[mB]", "8 MDRP[mW]", - "8 MDRP[m?]", + "7 MDRP[m]", "9 MDRP[mrG]", "9 MDRP[mrB]", "9 MDRP[mrW]", - "9 MDRP[mr?]", + "8 MDRP[mr]", + /* 0xD0 */ "8 MDRP[pG]", "8 MDRP[pB]", "8 MDRP[pW]", - "8 MDRP[p?]", + "7 MDRP[p]", "9 MDRP[prG]", "9 MDRP[prB]", "9 MDRP[prW]", - "9 MDRP[pr?]", + "8 MDRP[pr]", "9 MDRP[pmG]", "9 MDRP[pmB]", "9 MDRP[pmW]", - "9 MDRP[pm?]", + "8 MDRP[pm]", "A MDRP[pmrG]", "A MDRP[pmrB]", "A MDRP[pmrW]", - "A MDRP[pmr?]", + "9 MDRP[pmr]", + /* 0xE0 */ "7 MIRP[G]", "7 MIRP[B]", "7 MIRP[W]", - "7 MIRP[?]", + "6 MIRP[]", "8 MIRP[rG]", "8 MIRP[rB]", "8 MIRP[rW]", - "8 MIRP[r?]", + "7 MIRP[r]", "8 MIRP[mG]", "8 MIRP[mB]", "8 MIRP[mW]", - "8 MIRP[m?]", + "7 MIRP[m]", "9 MIRP[mrG]", "9 MIRP[mrB]", "9 MIRP[mrW]", - "9 MIRP[mr?]", + "8 MIRP[mr]", + /* 0xF0 */ "8 MIRP[pG]", "8 MIRP[pB]", "8 MIRP[pW]", - "8 MIRP[p?]", + "7 MIRP[p]", "9 MIRP[prG]", "9 MIRP[prB]", "9 MIRP[prW]", - "9 MIRP[pr?]", + "8 MIRP[pr]", "9 MIRP[pmG]", "9 MIRP[pmB]", "9 MIRP[pmW]", - "9 MIRP[pm?]", + "8 MIRP[pm]", "A MIRP[pmrG]", "A MIRP[pmrB]", "A MIRP[pmrW]", - "A MIRP[pmr?]" + "9 MIRP[pmr]" }; #endif /* FT_DEBUG_LEVEL_TRACE */ @@ -1662,6 +1694,32 @@ } + /* + * + * Apple's TrueType specification at + * + * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM02/Chap2.html#order + * + * gives the following order of operations in instructions that move + * points. + * + * - check single width cut-in (MIRP, MDRP) + * + * - check control value cut-in (MIRP, MIAP) + * + * - apply engine compensation (MIRP, MDRP) + * + * - round distance (MIRP, MDRP) or value (MIAP, MDAP) + * + * - check minimum distance (MIRP,MDRP) + * + * - move point (MIRP, MDRP, MIAP, MSIRP, MDAP) + * + * For rounding instructions, engine compensation happens before rounding. + * + */ + + /************************************************************************** * * @Function: @@ -1886,7 +1944,6 @@ zone->org[point].y = ADD_LONG( zone->org[point].y, distance ); } - /************************************************************************** * * @Function: @@ -1904,12 +1961,6 @@ * * @Return: * The compensated distance. - * - * @Note: - * The TrueType specification says very few about the relationship - * between rounding and engine compensation. However, it seems from - * the description of super round that we should add the compensation - * before rounding. */ static FT_F26Dot6 Round_None( TT_ExecContext exc, diff --git a/thirdparty/freetype/src/truetype/ttobjs.c b/thirdparty/freetype/src/truetype/ttobjs.c index f3a432cedd..e4775a51ed 100644 --- a/thirdparty/freetype/src/truetype/ttobjs.c +++ b/thirdparty/freetype/src/truetype/ttobjs.c @@ -148,7 +148,7 @@ /* This list shall be expanded as we find more of them. */ static FT_Bool - tt_check_trickyness_family( FT_String* name ) + tt_check_trickyness_family( const FT_String* name ) { #define TRICK_NAMES_MAX_CHARACTERS 19 @@ -937,7 +937,22 @@ TT_Face face = (TT_Face)size->root.face; TT_ExecContext exec; FT_Error error; + FT_UInt i; + /* unscaled CVT values are already stored in 26.6 format */ + FT_Fixed scale = size->ttmetrics.scale >> 6; + + + /* Scale the cvt values to the new ppem. */ + /* By default, we use the y ppem value for scaling. */ + FT_TRACE6(( "CVT values:\n" )); + for ( i = 0; i < size->cvt_size; i++ ) + { + size->cvt[i] = FT_MulFix( face->cvt[i], scale ); + FT_TRACE6(( " %3d: %f (%f)\n", + i, face->cvt[i] / 64.0, size->cvt[i] / 64.0 )); + } + FT_TRACE6(( "\n" )); exec = size->context; @@ -1094,11 +1109,17 @@ tt_metrics->rotated = FALSE; tt_metrics->stretched = FALSE; - /* set default engine compensation */ - tt_metrics->compensations[0] = 0; /* gray */ - tt_metrics->compensations[1] = 0; /* black */ - tt_metrics->compensations[2] = 0; /* white */ - tt_metrics->compensations[3] = 0; /* reserved */ + /* Set default engine compensation. Value 3 is not described */ + /* in the OpenType specification (as of Mai 2019), but Greg */ + /* says that MS handles it the same as `gray'. */ + /* */ + /* The Apple specification says that the compensation for */ + /* `gray' is always zero. FreeType doesn't do any */ + /* compensation at all. */ + tt_metrics->compensations[0] = 0; /* gray */ + tt_metrics->compensations[1] = 0; /* black */ + tt_metrics->compensations[2] = 0; /* white */ + tt_metrics->compensations[3] = 0; /* the same as gray */ } /* allocate function defs, instruction defs, cvt, and storage area */ @@ -1171,20 +1192,8 @@ if ( size->cvt_ready < 0 ) { FT_UInt i; - TT_Face face = (TT_Face)size->root.face; - /* Scale the cvt values to the new ppem. */ - /* By default, we use the y ppem value for scaling. */ - FT_TRACE6(( "CVT values:\n" )); - for ( i = 0; i < size->cvt_size; i++ ) - { - size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale ); - FT_TRACE6(( " %3d: %d (%f)\n", - i, face->cvt[i], size->cvt[i] / 64.0 )); - } - FT_TRACE6(( "\n" )); - /* all twilight points are originally zero */ for ( i = 0; i < (FT_UInt)size->twilight.n_points; i++ ) { diff --git a/thirdparty/freetype/src/truetype/ttpload.c b/thirdparty/freetype/src/truetype/ttpload.c index e7718bf9b7..bc954c2dba 100644 --- a/thirdparty/freetype/src/truetype/ttpload.c +++ b/thirdparty/freetype/src/truetype/ttpload.c @@ -352,12 +352,12 @@ goto Exit; { - FT_Short* cur = face->cvt; - FT_Short* limit = cur + face->cvt_size; + FT_Int32* cur = face->cvt; + FT_Int32* limit = cur + face->cvt_size; for ( ; cur < limit; cur++ ) - *cur = FT_GET_SHORT(); + *cur = FT_GET_SHORT() * 64; } FT_FRAME_EXIT(); diff --git a/thirdparty/freetype/src/type1/t1driver.c b/thirdparty/freetype/src/type1/t1driver.c index 8625db5b01..557733da3b 100644 --- a/thirdparty/freetype/src/type1/t1driver.c +++ b/thirdparty/freetype/src/type1/t1driver.c @@ -70,8 +70,8 @@ static FT_UInt - t1_get_name_index( T1_Face face, - FT_String* glyph_name ) + t1_get_name_index( T1_Face face, + const FT_String* glyph_name ) { FT_Int i; diff --git a/thirdparty/freetype/src/type1/t1load.c b/thirdparty/freetype/src/type1/t1load.c index 3896af70ba..5cffdfaac4 100644 --- a/thirdparty/freetype/src/type1/t1load.c +++ b/thirdparty/freetype/src/type1/t1load.c @@ -1507,12 +1507,7 @@ /* We need to `zero' out encoding_table.elements */ for ( n = 0; n < array_size; n++ ) - { - char* notdef = (char *)".notdef"; - - - (void)T1_Add_Table( char_table, n, notdef, 8 ); - } + (void)T1_Add_Table( char_table, n, ".notdef", 8 ); /* Now we need to read records of the form */ /* */ @@ -2147,7 +2142,6 @@ /* 0 333 hsbw endchar */ FT_Byte notdef_glyph[] = { 0x8B, 0xF7, 0xE1, 0x0D, 0x0E }; - char* notdef_name = (char *)".notdef"; error = T1_Add_Table( swap_table, 0, @@ -2162,7 +2156,7 @@ if ( error ) goto Fail; - error = T1_Add_Table( name_table, 0, notdef_name, 8 ); + error = T1_Add_Table( name_table, 0, ".notdef", 8 ); if ( error ) goto Fail; @@ -2633,8 +2627,7 @@ /* we must now build type1.encoding when we have a custom array */ if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) { - FT_Int charcode, idx, min_char, max_char; - FT_Byte* glyph_name; + FT_Int charcode, idx, min_char, max_char; /* OK, we do the following: for each element in the encoding */ @@ -2648,27 +2641,27 @@ charcode = 0; for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) { - FT_Byte* char_name; + const FT_String* char_name = + (const FT_String*)loader.encoding_table.elements[charcode]; type1->encoding.char_index[charcode] = 0; - type1->encoding.char_name [charcode] = (char *)".notdef"; + type1->encoding.char_name [charcode] = ".notdef"; - char_name = loader.encoding_table.elements[charcode]; if ( char_name ) for ( idx = 0; idx < type1->num_glyphs; idx++ ) { - glyph_name = (FT_Byte*)type1->glyph_names[idx]; - if ( ft_strcmp( (const char*)char_name, - (const char*)glyph_name ) == 0 ) + const FT_String* glyph_name = type1->glyph_names[idx]; + + + if ( ft_strcmp( char_name, glyph_name ) == 0 ) { type1->encoding.char_index[charcode] = (FT_UShort)idx; - type1->encoding.char_name [charcode] = (char*)glyph_name; + type1->encoding.char_name [charcode] = glyph_name; /* Change min/max encoded char only if glyph name is */ /* not /.notdef */ - if ( ft_strcmp( (const char*)".notdef", - (const char*)glyph_name ) != 0 ) + if ( ft_strcmp( ".notdef", glyph_name ) != 0 ) { if ( charcode < min_char ) min_char = charcode; diff --git a/thirdparty/freetype/src/type42/t42drivr.c b/thirdparty/freetype/src/type42/t42drivr.c index 6d4e7a0955..09ad632e97 100644 --- a/thirdparty/freetype/src/type42/t42drivr.c +++ b/thirdparty/freetype/src/type42/t42drivr.c @@ -69,8 +69,8 @@ static FT_UInt - t42_get_name_index( T42_Face face, - FT_String* glyph_name ) + t42_get_name_index( T42_Face face, + const FT_String* glyph_name ) { FT_Int i; diff --git a/thirdparty/freetype/src/type42/t42objs.c b/thirdparty/freetype/src/type42/t42objs.c index 234c0a3e97..d31bace451 100644 --- a/thirdparty/freetype/src/type42/t42objs.c +++ b/thirdparty/freetype/src/type42/t42objs.c @@ -98,8 +98,7 @@ /* we must now build type1.encoding when we have a custom array */ if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY ) { - FT_Int charcode, idx, min_char, max_char; - FT_Byte* glyph_name; + FT_Int charcode, idx, min_char, max_char; /* OK, we do the following: for each element in the encoding */ @@ -114,27 +113,27 @@ charcode = 0; for ( ; charcode < loader.encoding_table.max_elems; charcode++ ) { - FT_Byte* char_name; + const FT_String* char_name = + (const FT_String*)loader.encoding_table.elements[charcode]; type1->encoding.char_index[charcode] = 0; - type1->encoding.char_name [charcode] = (char *)".notdef"; + type1->encoding.char_name [charcode] = ".notdef"; - char_name = loader.encoding_table.elements[charcode]; if ( char_name ) for ( idx = 0; idx < type1->num_glyphs; idx++ ) { - glyph_name = (FT_Byte*)type1->glyph_names[idx]; - if ( ft_strcmp( (const char*)char_name, - (const char*)glyph_name ) == 0 ) + const FT_String* glyph_name = type1->glyph_names[idx]; + + + if ( ft_strcmp( char_name, glyph_name ) == 0 ) { type1->encoding.char_index[charcode] = (FT_UShort)idx; - type1->encoding.char_name [charcode] = (char*)glyph_name; + type1->encoding.char_name [charcode] = glyph_name; /* Change min/max encoded char only if glyph name is */ /* not /.notdef */ - if ( ft_strcmp( (const char*)".notdef", - (const char*)glyph_name ) != 0 ) + if ( ft_strcmp( ".notdef", glyph_name ) != 0 ) { if ( charcode < min_char ) min_char = charcode; diff --git a/thirdparty/freetype/src/type42/t42parse.c b/thirdparty/freetype/src/type42/t42parse.c index b653a133a5..c47a77786d 100644 --- a/thirdparty/freetype/src/type42/t42parse.c +++ b/thirdparty/freetype/src/type42/t42parse.c @@ -226,7 +226,8 @@ if ( !parser->in_memory ) FT_FREE( parser->base_dict ); - parser->root.funcs.done( &parser->root ); + if ( parser->root.funcs.done ) + parser->root.funcs.done( &parser->root ); } @@ -373,12 +374,7 @@ /* We need to `zero' out encoding_table.elements */ for ( n = 0; n < count; n++ ) - { - char* notdef = (char *)".notdef"; - - - (void)T1_Add_Table( char_table, n, notdef, 8 ); - } + (void)T1_Add_Table( char_table, n, ".notdef", 8 ); /* Now we need to read records of the form */ /* */ @@ -1021,8 +1017,7 @@ } /* if /.notdef does not occupy index 0, do our magic. */ - if ( ft_strcmp( (const char*)".notdef", - (const char*)name_table->elements[0] ) ) + if ( ft_strcmp( ".notdef", (const char*)name_table->elements[0] ) ) { /* Swap glyph in index 0 with /.notdef glyph. First, add index 0 */ /* name and code entries to swap_table. Then place notdef_index */ diff --git a/thirdparty/glad/KHR/khrplatform.h b/thirdparty/glad/KHR/khrplatform.h index 975bbffed6..5b55ea2b98 100644 --- a/thirdparty/glad/KHR/khrplatform.h +++ b/thirdparty/glad/KHR/khrplatform.h @@ -90,12 +90,20 @@ * int arg2) KHRONOS_APIATTRIBUTES; */ +#if defined(__SCITECH_SNAP__) && !defined(KHRONOS_STATIC) +# define KHRONOS_STATIC 1 +#endif + /*------------------------------------------------------------------------- * Definition of KHRONOS_APICALL *------------------------------------------------------------------------- * This precedes the return type of the function in the function prototype. */ -#if defined(_WIN32) && !defined(__SCITECH_SNAP__) +#if defined(KHRONOS_STATIC) + /* If the preprocessor constant KHRONOS_STATIC is defined, make the + * header compatible with static linking. */ +# define KHRONOS_APICALL +#elif defined(_WIN32) # define KHRONOS_APICALL __declspec(dllimport) #elif defined (__SYMBIAN32__) # define KHRONOS_APICALL IMPORT_C @@ -111,7 +119,7 @@ * This follows the return type of the function and precedes the function * name in the function prototype. */ -#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) +#if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(KHRONOS_STATIC) /* Win32 but not WinCE */ # define KHRONOS_APIENTRY __stdcall #else diff --git a/thirdparty/glad/glad.c b/thirdparty/glad/glad.c index 9704c1079f..08c9c7e228 100644 --- a/thirdparty/glad/glad.c +++ b/thirdparty/glad/glad.c @@ -1,6 +1,6 @@ /* - OpenGL loader generated by glad 0.1.29 on Wed May 1 23:16:34 2019. + OpenGL loader generated by glad 0.1.31 on Thu Jul 11 10:09:18 2019. Language/Generator: C/C++ Specification: gl diff --git a/thirdparty/glad/glad/glad.h b/thirdparty/glad/glad/glad.h index b398faf627..acf96d8cd9 100644 --- a/thirdparty/glad/glad/glad.h +++ b/thirdparty/glad/glad/glad.h @@ -1,6 +1,6 @@ /* - OpenGL loader generated by glad 0.1.29 on Wed May 1 23:16:34 2019. + OpenGL loader generated by glad 0.1.31 on Thu Jul 11 10:09:18 2019. Language/Generator: C/C++ Specification: gl @@ -33,13 +33,7 @@ #define __gl_h_ #if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 -#endif -#ifndef NOMINMAX -#define NOMINMAX 1 -#endif -#include <windows.h> +#define APIENTRY __stdcall #endif #ifndef APIENTRY diff --git a/thirdparty/libwebsockets/LICENSE b/thirdparty/libwebsockets/LICENSE deleted file mode 100644 index 6c7cd90cdc..0000000000 --- a/thirdparty/libwebsockets/LICENSE +++ /dev/null @@ -1,556 +0,0 @@ -Libwebsockets and included programs are provided under the terms of the GNU -Library General Public License (LGPL) 2.1, with the following exceptions: - -1) Any reference, whether in these modifications or in the GNU -Library General Public License 2.1, to this License, these terms, the -GNU Lesser Public License, GNU Library General Public License, LGPL, or -any similar reference shall refer to the GNU Library General Public -License 2.1 as modified by these paragraphs 1) through 4). - -2) Static linking of programs with the libwebsockets library does not -constitute a derivative work and does not require the author to provide -source code for the program, use the shared libwebsockets libraries, or -link their program against a user-supplied version of libwebsockets. - -If you link the program to a modified version of libwebsockets, then the -changes to libwebsockets must be provided under the terms of the LGPL in -sections 1, 2, and 4. - -3) You do not have to provide a copy of the libwebsockets license with -programs that are linked to the libwebsockets library, nor do you have to -identify the libwebsockets license in your program or documentation as -required by section 6 of the LGPL. - -However, programs must still identify their use of libwebsockets. The -following example statement can be included in user documentation to -satisfy this requirement: - -"[program] is based in part on the work of the libwebsockets project -(https://libwebsockets.org)" - -4) Some sources included have their own, more liberal licenses, or options -to get original sources with the liberal terms. - -Original liberal license retained - - - lib/misc/sha-1.c - 3-clause BSD license retained, link to original - - win32port/zlib - ZLIB license (see zlib.h) - - lib/tls/mbedtls/wrapper - Apache 2.0 (only built if linked against mbedtls) - -Relicensed to libwebsocket license - - - lib/misc/base64-decode.c - relicensed to LGPL2.1+SLE, link to original - - lib/misc/daemonize.c - relicensed from Public Domain to LGPL2.1+SLE, - link to original Public Domain version - -Public Domain (CC-zero) to simplify reuse - - - test-apps/*.c - - test-apps/*.h - - minimal-examples/* - - lwsws/* - ------- end of exceptions - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - <one line to give the library's name and a brief idea of what it does.> - Copyright (C) <year> <name of author> - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - <signature of Ty Coon>, 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/thirdparty/libwebsockets/core/alloc.c b/thirdparty/libwebsockets/core/alloc.c deleted file mode 100644 index f169fc3767..0000000000 --- a/thirdparty/libwebsockets/core/alloc.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "core/private.h" - -#if defined(LWS_PLAT_OPTEE) - -#define TEE_USER_MEM_HINT_NO_FILL_ZERO 0x80000000 - -void *__attribute__((weak)) - TEE_Malloc(uint32_t size, uint32_t hint) -{ - return NULL; -} -void *__attribute__((weak)) - TEE_Realloc(void *buffer, uint32_t newSize) -{ - return NULL; -} -void __attribute__((weak)) - TEE_Free(void *buffer) -{ -} - -void *lws_realloc(void *ptr, size_t size, const char *reason) -{ - return TEE_Realloc(ptr, size); -} - -void *lws_malloc(size_t size, const char *reason) -{ - return TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO); -} - -void lws_free(void *p) -{ - TEE_Free(p); -} - -void *lws_zalloc(size_t size, const char *reason) -{ - void *ptr = TEE_Malloc(size, TEE_USER_MEM_HINT_NO_FILL_ZERO); - if (ptr) - memset(ptr, 0, size); - return ptr; -} - -void lws_set_allocator(void *(*cb)(void *ptr, size_t size, const char *reason)) -{ - (void)cb; -} -#else - -static void *_realloc(void *ptr, size_t size, const char *reason) -{ - if (size) { -#if defined(LWS_WITH_ESP32) - lwsl_notice("%s: size %lu: %s (free heap %d)\n", __func__, - (unsigned long)size, reason, (unsigned int)esp_get_free_heap_size() - (int)size); -#else - lwsl_debug("%s: size %lu: %s\n", __func__, - (unsigned long)size, reason); -#endif -#if defined(LWS_PLAT_OPTEE) - return (void *)TEE_Realloc(ptr, size); -#else - return (void *)realloc(ptr, size); -#endif - } - if (ptr) - free(ptr); - - return NULL; -} - -void *(*_lws_realloc)(void *ptr, size_t size, const char *reason) = _realloc; - -void *lws_realloc(void *ptr, size_t size, const char *reason) -{ - return _lws_realloc(ptr, size, reason); -} - -void *lws_zalloc(size_t size, const char *reason) -{ - void *ptr = _lws_realloc(NULL, size, reason); - if (ptr) - memset(ptr, 0, size); - return ptr; -} - -void lws_set_allocator(void *(*cb)(void *ptr, size_t size, const char *reason)) -{ - _lws_realloc = cb; -} -#endif diff --git a/thirdparty/libwebsockets/core/context.c b/thirdparty/libwebsockets/core/context.c deleted file mode 100644 index 7be004df33..0000000000 --- a/thirdparty/libwebsockets/core/context.c +++ /dev/null @@ -1,1962 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -#ifndef LWS_BUILD_HASH -#define LWS_BUILD_HASH "unknown-build-hash" -#endif - -const struct lws_role_ops *available_roles[] = { -#if defined(LWS_ROLE_H2) - &role_ops_h2, -#endif -#if defined(LWS_ROLE_H1) - &role_ops_h1, -#endif -#if defined(LWS_ROLE_WS) - &role_ops_ws, -#endif - NULL -}; - -const struct lws_event_loop_ops *available_event_libs[] = { -#if defined(LWS_WITH_POLL) - &event_loop_ops_poll, -#endif -#if defined(LWS_WITH_LIBUV) - &event_loop_ops_uv, -#endif -#if defined(LWS_WITH_LIBEVENT) - &event_loop_ops_event, -#endif -#if defined(LWS_WITH_LIBEV) - &event_loop_ops_ev, -#endif - NULL -}; - -static const char *library_version = LWS_LIBRARY_VERSION " " LWS_BUILD_HASH; - -/** - * lws_get_library_version: get version and git hash library built from - * - * returns a const char * to a string like "1.1 178d78c" - * representing the library version followed by the git head hash it - * was built from - */ -LWS_VISIBLE const char * -lws_get_library_version(void) -{ - return library_version; -} - -int -lws_role_call_alpn_negotiated(struct lws *wsi, const char *alpn) -{ -#if defined(LWS_WITH_TLS) - if (!alpn) - return 0; - - lwsl_info("%s: '%s'\n", __func__, alpn); - - LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) - if (ar->alpn && !strcmp(ar->alpn, alpn) && ar->alpn_negotiated) - return ar->alpn_negotiated(wsi, alpn); - LWS_FOR_EVERY_AVAILABLE_ROLE_END; -#endif - return 0; -} - -static const char * const mount_protocols[] = { - "http://", - "https://", - "file://", - "cgi://", - ">http://", - ">https://", - "callback://" -}; - -LWS_VISIBLE void * -lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, - const struct lws_protocols *prot, int size) -{ - int n = 0; - - /* allocate the vh priv array only on demand */ - if (!vhost->protocol_vh_privs) { - vhost->protocol_vh_privs = (void **)lws_zalloc( - vhost->count_protocols * sizeof(void *), - "protocol_vh_privs"); - if (!vhost->protocol_vh_privs) - return NULL; - } - - while (n < vhost->count_protocols && &vhost->protocols[n] != prot) - n++; - - if (n == vhost->count_protocols) { - n = 0; - while (n < vhost->count_protocols && - strcmp(vhost->protocols[n].name, prot->name)) - n++; - - if (n == vhost->count_protocols) - return NULL; - } - - vhost->protocol_vh_privs[n] = lws_zalloc(size, "vh priv"); - return vhost->protocol_vh_privs[n]; -} - -LWS_VISIBLE void * -lws_protocol_vh_priv_get(struct lws_vhost *vhost, - const struct lws_protocols *prot) -{ - int n = 0; - - if (!vhost || !vhost->protocol_vh_privs || !prot) - return NULL; - - while (n < vhost->count_protocols && &vhost->protocols[n] != prot) - n++; - - if (n == vhost->count_protocols) { - n = 0; - while (n < vhost->count_protocols && - strcmp(vhost->protocols[n].name, prot->name)) - n++; - - if (n == vhost->count_protocols) { - lwsl_err("%s: unknown protocol %p\n", __func__, prot); - return NULL; - } - } - - return vhost->protocol_vh_privs[n]; -} - -static const struct lws_protocol_vhost_options * -lws_vhost_protocol_options(struct lws_vhost *vh, const char *name) -{ - const struct lws_protocol_vhost_options *pvo = vh->pvo; - - if (!name) - return NULL; - - while (pvo) { - if (!strcmp(pvo->name, name)) - return pvo; - pvo = pvo->next; - } - - return NULL; -} - -/* - * inform every vhost that hasn't already done it, that - * his protocols are initializing - */ -LWS_VISIBLE int -lws_protocol_init(struct lws_context *context) -{ - struct lws_vhost *vh = context->vhost_list; - const struct lws_protocol_vhost_options *pvo, *pvo1; - struct lws wsi; - int n, any = 0; - - if (context->doing_protocol_init) - return 0; - - context->doing_protocol_init = 1; - - memset(&wsi, 0, sizeof(wsi)); - wsi.context = context; - - lwsl_info("%s\n", __func__); - - while (vh) { - wsi.vhost = vh; - - /* only do the protocol init once for a given vhost */ - if (vh->created_vhost_protocols || - (vh->options & LWS_SERVER_OPTION_SKIP_PROTOCOL_INIT)) - goto next; - - /* initialize supported protocols on this vhost */ - - for (n = 0; n < vh->count_protocols; n++) { - wsi.protocol = &vh->protocols[n]; - if (!vh->protocols[n].name) - continue; - pvo = lws_vhost_protocol_options(vh, - vh->protocols[n].name); - if (pvo) { - /* - * linked list of options specific to - * vh + protocol - */ - pvo1 = pvo; - pvo = pvo1->options; - - while (pvo) { - lwsl_debug( - " vhost \"%s\", " - "protocol \"%s\", " - "option \"%s\"\n", - vh->name, - vh->protocols[n].name, - pvo->name); - - if (!strcmp(pvo->name, "default")) { - lwsl_info("Setting default " - "protocol for vh %s to %s\n", - vh->name, - vh->protocols[n].name); - vh->default_protocol_index = n; - } - if (!strcmp(pvo->name, "raw")) { - lwsl_info("Setting raw " - "protocol for vh %s to %s\n", - vh->name, - vh->protocols[n].name); - vh->raw_protocol_index = n; - } - pvo = pvo->next; - } - - pvo = pvo1->options; - } - -#if defined(LWS_WITH_TLS) - any |= !!vh->tls.ssl_ctx; -#endif - - /* - * inform all the protocols that they are doing their - * one-time initialization if they want to. - * - * NOTE the wsi is all zeros except for the context, vh - * + protocol ptrs so lws_get_context(wsi) etc can work - */ - if (vh->protocols[n].callback(&wsi, - LWS_CALLBACK_PROTOCOL_INIT, NULL, - (void *)pvo, 0)) { - lws_free(vh->protocol_vh_privs[n]); - vh->protocol_vh_privs[n] = NULL; - lwsl_err("%s: protocol %s failed init\n", __func__, - vh->protocols[n].name); - } - } - - vh->created_vhost_protocols = 1; -next: - vh = vh->vhost_next; - } - - context->doing_protocol_init = 0; - - if (!context->protocol_init_done) - lws_finalize_startup(context); - - context->protocol_init_done = 1; - - if (any) - lws_tls_check_all_cert_lifetimes(context); - - return 0; -} - -LWS_VISIBLE int -lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len) -{ - struct lws_ssl_info *si; -#ifdef LWS_WITH_CGI - struct lws_cgi_args *args; -#endif -#if defined(LWS_WITH_CGI) || defined(LWS_WITH_HTTP_PROXY) - char buf[512]; - int n; -#endif - - switch (reason) { -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - case LWS_CALLBACK_HTTP: -#ifndef LWS_NO_SERVER - if (lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL)) - return -1; - - if (lws_http_transaction_completed(wsi)) -#endif - return -1; - break; -#if !defined(LWS_NO_SERVER) - case LWS_CALLBACK_HTTP_FILE_COMPLETION: - if (lws_http_transaction_completed(wsi)) - return -1; - break; -#endif - - case LWS_CALLBACK_HTTP_WRITEABLE: -#ifdef LWS_WITH_CGI - if (wsi->reason_bf & (LWS_CB_REASON_AUX_BF__CGI_HEADERS | - LWS_CB_REASON_AUX_BF__CGI)) { - n = lws_cgi_write_split_stdout_headers(wsi); - if (n < 0) { - lwsl_debug("AUX_BF__CGI forcing close\n"); - return -1; - } - if (!n) - lws_rx_flow_control( - wsi->http.cgi->stdwsi[LWS_STDOUT], 1); - - if (wsi->reason_bf & LWS_CB_REASON_AUX_BF__CGI_HEADERS) - wsi->reason_bf &= - ~LWS_CB_REASON_AUX_BF__CGI_HEADERS; - else - wsi->reason_bf &= ~LWS_CB_REASON_AUX_BF__CGI; - break; - } - - if (wsi->reason_bf & LWS_CB_REASON_AUX_BF__CGI_CHUNK_END) { - if (!wsi->http2_substream) { - memcpy(buf + LWS_PRE, "0\x0d\x0a\x0d\x0a", 5); - lwsl_debug("writing chunk term and exiting\n"); - n = lws_write(wsi, (unsigned char *)buf + - LWS_PRE, 5, LWS_WRITE_HTTP); - } else - n = lws_write(wsi, (unsigned char *)buf + - LWS_PRE, 0, - LWS_WRITE_HTTP_FINAL); - - /* always close after sending it */ - return -1; - } -#endif -#if defined(LWS_WITH_HTTP_PROXY) - if (wsi->reason_bf & LWS_CB_REASON_AUX_BF__PROXY) { - char *px = buf + LWS_PRE; - int lenx = sizeof(buf) - LWS_PRE; - - /* - * our sink is writeable and our source has something - * to read. So read a lump of source material of - * suitable size to send or what's available, whichever - * is the smaller. - */ - wsi->reason_bf &= ~LWS_CB_REASON_AUX_BF__PROXY; - if (!lws_get_child(wsi)) - break; - if (lws_http_client_read(lws_get_child(wsi), &px, - &lenx) < 0) - return -1; - break; - } -#endif - break; - -#if defined(LWS_WITH_HTTP_PROXY) - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP: - assert(lws_get_parent(wsi)); - if (!lws_get_parent(wsi)) - break; - lws_get_parent(wsi)->reason_bf |= LWS_CB_REASON_AUX_BF__PROXY; - lws_callback_on_writable(lws_get_parent(wsi)); - break; - - case LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ: - assert(lws_get_parent(wsi)); - n = lws_write(lws_get_parent(wsi), (unsigned char *)in, - len, LWS_WRITE_HTTP); - if (n < 0) - return -1; - break; - - case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP: { - unsigned char *p, *end; - char ctype[64], ctlen = 0; - - p = (unsigned char *)buf + LWS_PRE; - end = p + sizeof(buf) - LWS_PRE; - - if (lws_add_http_header_status(lws_get_parent(wsi), - HTTP_STATUS_OK, &p, end)) - return 1; - if (lws_add_http_header_by_token(lws_get_parent(wsi), - WSI_TOKEN_HTTP_SERVER, - (unsigned char *)"libwebsockets", - 13, &p, end)) - return 1; - - ctlen = lws_hdr_copy(wsi, ctype, sizeof(ctype), - WSI_TOKEN_HTTP_CONTENT_TYPE); - if (ctlen > 0) { - if (lws_add_http_header_by_token(lws_get_parent(wsi), - WSI_TOKEN_HTTP_CONTENT_TYPE, - (unsigned char *)ctype, ctlen, &p, end)) - return 1; - } - - if (lws_finalize_http_header(lws_get_parent(wsi), &p, end)) - return 1; - - *p = '\0'; - n = lws_write(lws_get_parent(wsi), - (unsigned char *)buf + LWS_PRE, - p - ((unsigned char *)buf + LWS_PRE), - LWS_WRITE_HTTP_HEADERS); - if (n < 0) - return -1; - - break; } - -#endif - -#ifdef LWS_WITH_CGI - /* CGI IO events (POLLIN/OUT) appear here, our default policy is: - * - * - POST data goes on subprocess stdin - * - subprocess stdout goes on http via writeable callback - * - subprocess stderr goes to the logs - */ - case LWS_CALLBACK_CGI: - args = (struct lws_cgi_args *)in; - switch (args->ch) { /* which of stdin/out/err ? */ - case LWS_STDIN: - /* TBD stdin rx flow control */ - break; - case LWS_STDOUT: - /* quench POLLIN on STDOUT until MASTER got writeable */ - lws_rx_flow_control(args->stdwsi[LWS_STDOUT], 0); - wsi->reason_bf |= LWS_CB_REASON_AUX_BF__CGI; - /* when writing to MASTER would not block */ - lws_callback_on_writable(wsi); - break; - case LWS_STDERR: - n = lws_get_socket_fd(args->stdwsi[LWS_STDERR]); - if (n < 0) - break; - n = read(n, buf, sizeof(buf) - 2); - if (n > 0) { - if (buf[n - 1] != '\n') - buf[n++] = '\n'; - buf[n] = '\0'; - lwsl_notice("CGI-stderr: %s\n", buf); - } - break; - } - break; - - case LWS_CALLBACK_CGI_TERMINATED: - lwsl_debug("LWS_CALLBACK_CGI_TERMINATED: %d %" PRIu64 "\n", - wsi->http.cgi->explicitly_chunked, - (uint64_t)wsi->http.cgi->content_length); - if (!wsi->http.cgi->explicitly_chunked && - !wsi->http.cgi->content_length) { - /* send terminating chunk */ - lwsl_debug("LWS_CALLBACK_CGI_TERMINATED: ending\n"); - wsi->reason_bf |= LWS_CB_REASON_AUX_BF__CGI_CHUNK_END; - lws_callback_on_writable(wsi); - lws_set_timeout(wsi, PENDING_TIMEOUT_CGI, 3); - break; - } - return -1; - - case LWS_CALLBACK_CGI_STDIN_DATA: /* POST body for stdin */ - args = (struct lws_cgi_args *)in; - args->data[args->len] = '\0'; - n = lws_get_socket_fd(args->stdwsi[LWS_STDIN]); - if (n < 0) - return -1; - n = write(n, args->data, args->len); - if (n < args->len) - lwsl_notice("LWS_CALLBACK_CGI_STDIN_DATA: " - "sent %d only %d went", n, args->len); - return n; -#endif -#endif - case LWS_CALLBACK_SSL_INFO: - si = in; - - (void)si; - lwsl_notice("LWS_CALLBACK_SSL_INFO: where: 0x%x, ret: 0x%x\n", - si->where, si->ret); - break; - - default: - break; - } - - return 0; -} - -/* list of supported protocols and callbacks */ - -static const struct lws_protocols protocols_dummy[] = { - /* first protocol must always be HTTP handler */ - - { - "http-only", /* name */ - lws_callback_http_dummy, /* callback */ - 0, /* per_session_data_size */ - 0, /* rx_buffer_size */ - 0, /* id */ - NULL, /* user */ - 0 /* tx_packet_size */ - }, - /* - * the other protocols are provided by lws plugins - */ - { NULL, NULL, 0, 0, 0, NULL, 0} /* terminator */ -}; - -#ifdef LWS_PLAT_OPTEE -#undef LWS_HAVE_GETENV -#endif - -static void -lws_vhost_destroy2(struct lws_vhost *vh); - -LWS_VISIBLE struct lws_vhost * -lws_create_vhost(struct lws_context *context, - const struct lws_context_creation_info *info) -{ - struct lws_vhost *vh = lws_zalloc(sizeof(*vh), "create vhost"), - **vh1 = &context->vhost_list; - const struct lws_http_mount *mounts; - const struct lws_protocols *pcols = info->protocols; - const struct lws_protocol_vhost_options *pvo; -#ifdef LWS_WITH_PLUGINS - struct lws_plugin *plugin = context->plugin_list; -#endif - struct lws_protocols *lwsp; - int m, f = !info->pvo; - char buf[20]; -#if !defined(LWS_WITHOUT_CLIENT) && defined(LWS_HAVE_GETENV) - char *p; -#endif - int n; - - if (!vh) - return NULL; - -#if LWS_MAX_SMP > 1 - pthread_mutex_init(&vh->lock, NULL); -#endif - - if (!pcols) - pcols = &protocols_dummy[0]; - - vh->context = context; - if (!info->vhost_name) - vh->name = "default"; - else - vh->name = info->vhost_name; - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - vh->http.error_document_404 = info->error_document_404; -#endif - - if (info->options & LWS_SERVER_OPTION_ONLY_RAW) - lwsl_info("%s set to only support RAW\n", vh->name); - - vh->iface = info->iface; -#if !defined(LWS_WITH_ESP32) && \ - !defined(OPTEE_TA) && !defined(WIN32) - vh->bind_iface = info->bind_iface; -#endif - - for (vh->count_protocols = 0; - pcols[vh->count_protocols].callback; - vh->count_protocols++) - ; - - vh->options = info->options; - vh->pvo = info->pvo; - vh->headers = info->headers; - vh->user = info->user; - - LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) - if (ar->init_vhost) - if (ar->init_vhost(vh, info)) - return NULL; - LWS_FOR_EVERY_AVAILABLE_ROLE_END; - - - if (info->keepalive_timeout) - vh->keepalive_timeout = info->keepalive_timeout; - else - vh->keepalive_timeout = 5; - - if (info->timeout_secs_ah_idle) - vh->timeout_secs_ah_idle = info->timeout_secs_ah_idle; - else - vh->timeout_secs_ah_idle = 10; - -#if defined(LWS_WITH_TLS) - - vh->tls.alpn = info->alpn; - vh->tls.ssl_info_event_mask = info->ssl_info_event_mask; - - if (info->ecdh_curve) - lws_strncpy(vh->tls.ecdh_curve, info->ecdh_curve, - sizeof(vh->tls.ecdh_curve)); - - /* carefully allocate and take a copy of cert + key paths if present */ - n = 0; - if (info->ssl_cert_filepath) - n += (int)strlen(info->ssl_cert_filepath) + 1; - if (info->ssl_private_key_filepath) - n += (int)strlen(info->ssl_private_key_filepath) + 1; - - if (n) { - vh->tls.key_path = vh->tls.alloc_cert_path = lws_malloc(n, "vh paths"); - if (info->ssl_cert_filepath) { - n = (int)strlen(info->ssl_cert_filepath) + 1; - memcpy(vh->tls.alloc_cert_path, info->ssl_cert_filepath, n); - vh->tls.key_path += n; - } - if (info->ssl_private_key_filepath) - memcpy(vh->tls.key_path, info->ssl_private_key_filepath, - strlen(info->ssl_private_key_filepath) + 1); - } -#endif - - /* - * give the vhost a unified list of protocols including the - * ones that came from plugins - */ - lwsp = lws_zalloc(sizeof(struct lws_protocols) * (vh->count_protocols + - context->plugin_protocol_count + 1), - "vhost-specific plugin table"); - if (!lwsp) { - lwsl_err("OOM\n"); - return NULL; - } - - m = vh->count_protocols; - memcpy(lwsp, pcols, sizeof(struct lws_protocols) * m); - - /* for compatibility, all protocols enabled on vhost if only - * the default vhost exists. Otherwise only vhosts who ask - * for a protocol get it enabled. - */ - - if (context->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS) - f = 0; - (void)f; -#ifdef LWS_WITH_PLUGINS - if (plugin) { - - while (plugin) { - for (n = 0; n < plugin->caps.count_protocols; n++) { - /* - * for compatibility's sake, no pvo implies - * allow all protocols - */ - if (f || lws_vhost_protocol_options(vh, - plugin->caps.protocols[n].name)) { - memcpy(&lwsp[m], - &plugin->caps.protocols[n], - sizeof(struct lws_protocols)); - m++; - vh->count_protocols++; - } - } - plugin = plugin->list; - } - } -#endif - - if ( -#ifdef LWS_WITH_PLUGINS - (context->plugin_list) || -#endif - context->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS) - vh->protocols = lwsp; - else { - vh->protocols = pcols; - lws_free(lwsp); - } - - vh->same_vh_protocol_list = (struct lws **) - lws_zalloc(sizeof(struct lws *) * vh->count_protocols, - "same vh list"); -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - vh->http.mount_list = info->mounts; -#endif - -#ifdef LWS_WITH_UNIX_SOCK - if (LWS_UNIX_SOCK_ENABLED(context)) { - lwsl_notice("Creating Vhost '%s' path \"%s\", %d protocols\n", - vh->name, vh->iface, vh->count_protocols); - } else -#endif - { - switch(info->port) { - case CONTEXT_PORT_NO_LISTEN: - strcpy(buf, "(serving disabled)"); - break; - case CONTEXT_PORT_NO_LISTEN_SERVER: - strcpy(buf, "(no listener)"); - break; - default: - lws_snprintf(buf, sizeof(buf), "port %u", info->port); - break; - } - lwsl_notice("Creating Vhost '%s' %s, %d protocols, IPv6 %s\n", - vh->name, buf, vh->count_protocols, - LWS_IPV6_ENABLED(vh) ? "on" : "off"); - } - mounts = info->mounts; - while (mounts) { - (void)mount_protocols[0]; - lwsl_info(" mounting %s%s to %s\n", - mount_protocols[mounts->origin_protocol], - mounts->origin, mounts->mountpoint); - - /* convert interpreter protocol names to pointers */ - pvo = mounts->interpret; - while (pvo) { - for (n = 0; n < vh->count_protocols; n++) { - if (strcmp(pvo->value, vh->protocols[n].name)) - continue; - ((struct lws_protocol_vhost_options *)pvo)-> - value = (const char *)(lws_intptr_t)n; - break; - } - if (n == vh->count_protocols) - lwsl_err("ignoring unknown interp pr %s\n", - pvo->value); - pvo = pvo->next; - } - - mounts = mounts->mount_next; - } - - vh->listen_port = info->port; -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - vh->http.http_proxy_port = 0; - vh->http.http_proxy_address[0] = '\0'; -#endif -#if defined(LWS_WITH_SOCKS5) - vh->socks_proxy_port = 0; - vh->socks_proxy_address[0] = '\0'; -#endif - -#if !defined(LWS_WITHOUT_CLIENT) - /* either use proxy from info, or try get it from env var */ -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - /* http proxy */ - if (info->http_proxy_address) { - /* override for backwards compatibility */ - if (info->http_proxy_port) - vh->http.http_proxy_port = info->http_proxy_port; - lws_set_proxy(vh, info->http_proxy_address); - } else -#endif - { -#ifdef LWS_HAVE_GETENV - p = getenv("http_proxy"); - if (p) - lws_set_proxy(vh, p); -#endif - } -#endif -#if defined(LWS_WITH_SOCKS5) - /* socks proxy */ - if (info->socks_proxy_address) { - /* override for backwards compatibility */ - if (info->socks_proxy_port) - vh->socks_proxy_port = info->socks_proxy_port; - lws_set_socks(vh, info->socks_proxy_address); - } else { -#ifdef LWS_HAVE_GETENV - p = getenv("socks_proxy"); - if (p) - lws_set_socks(vh, p); -#endif - } -#endif - - vh->ka_time = info->ka_time; - vh->ka_interval = info->ka_interval; - vh->ka_probes = info->ka_probes; - - if (vh->options & LWS_SERVER_OPTION_STS) - lwsl_notice(" STS enabled\n"); - -#ifdef LWS_WITH_ACCESS_LOG - if (info->log_filepath) { - vh->log_fd = lws_open(info->log_filepath, - O_CREAT | O_APPEND | O_RDWR, 0600); - if (vh->log_fd == (int)LWS_INVALID_FILE) { - lwsl_err("unable to open log filepath %s\n", - info->log_filepath); - goto bail; - } -#ifndef WIN32 - if (context->uid != -1) - if (chown(info->log_filepath, context->uid, - context->gid) == -1) - lwsl_err("unable to chown log file %s\n", - info->log_filepath); -#endif - } else - vh->log_fd = (int)LWS_INVALID_FILE; -#endif - if (lws_context_init_server_ssl(info, vh)) { - lwsl_err("%s: lws_context_init_server_ssl failed\n", __func__); - goto bail1; - } - if (lws_context_init_client_ssl(info, vh)) { - lwsl_err("%s: lws_context_init_client_ssl failed\n", __func__); - goto bail1; - } - lws_context_lock(context); - n = _lws_vhost_init_server(info, vh); - lws_context_unlock(context); - if (n < 0) { - lwsl_err("init server failed\n"); - goto bail1; - } - - - while (1) { - if (!(*vh1)) { - *vh1 = vh; - break; - } - vh1 = &(*vh1)->vhost_next; - }; - - /* for the case we are adding a vhost much later, after server init */ - - if (context->protocol_init_done) - if (lws_protocol_init(context)) { - lwsl_err("%s: lws_protocol_init failed\n", __func__); - goto bail1; - } - - return vh; - -bail1: - lws_vhost_destroy(vh); - lws_vhost_destroy2(vh); - - return NULL; - -#ifdef LWS_WITH_ACCESS_LOG -bail: - lws_free(vh); -#endif - - return NULL; -} - -LWS_VISIBLE int -lws_init_vhost_client_ssl(const struct lws_context_creation_info *info, - struct lws_vhost *vhost) -{ - struct lws_context_creation_info i; - - memcpy(&i, info, sizeof(i)); - i.port = CONTEXT_PORT_NO_LISTEN; - - return lws_context_init_client_ssl(&i, vhost); -} - -LWS_VISIBLE void -lws_cancel_service_pt(struct lws *wsi) -{ - lws_plat_pipe_signal(wsi); -} - -LWS_VISIBLE void -lws_cancel_service(struct lws_context *context) -{ - struct lws_context_per_thread *pt = &context->pt[0]; - short m = context->count_threads; - - if (context->being_destroyed1) - return; - - lwsl_info("%s\n", __func__); - - while (m--) { - if (pt->pipe_wsi) - lws_plat_pipe_signal(pt->pipe_wsi); - pt++; - } -} - -int -lws_create_event_pipes(struct lws_context *context) -{ - struct lws *wsi; - int n; - - /* - * Create the pt event pipes... these are unique in that they are - * not bound to a vhost or protocol (both are NULL) - */ - - for (n = 0; n < context->count_threads; n++) { - if (context->pt[n].pipe_wsi) - continue; - - wsi = lws_zalloc(sizeof(*wsi), "event pipe wsi"); - if (!wsi) { - lwsl_err("Out of mem\n"); - return 1; - } - wsi->context = context; - lws_role_transition(wsi, 0, LRS_UNCONNECTED, &role_ops_pipe); - wsi->protocol = NULL; - wsi->tsi = n; - wsi->vhost = NULL; - wsi->event_pipe = 1; - wsi->desc.sockfd = LWS_SOCK_INVALID; - context->pt[n].pipe_wsi = wsi; - context->count_wsi_allocated++; - - if (lws_plat_pipe_create(wsi)) - /* - * platform code returns 0 if it actually created pipes - * and initialized pt->dummy_pipe_fds[]. If it used - * some other mechanism outside of signaling in the - * normal event loop, we skip treating the pipe as - * related to dummy_pipe_fds[], adding it to the fds, - * etc. - */ - continue; - - wsi->desc.sockfd = context->pt[n].dummy_pipe_fds[0]; - lwsl_debug("event pipe fd %d\n", wsi->desc.sockfd); - - if (context->event_loop_ops->accept) - context->event_loop_ops->accept(wsi); - - if (__insert_wsi_socket_into_fds(context, wsi)) - return 1; - } - - return 0; -} - -void -lws_destroy_event_pipe(struct lws *wsi) -{ - lwsl_info("%s\n", __func__); - __remove_wsi_socket_from_fds(wsi); - - if (wsi->context->event_loop_ops->wsi_logical_close) { - wsi->context->event_loop_ops->wsi_logical_close(wsi); - lws_plat_pipe_close(wsi); - return; - } - - if (wsi->context->event_loop_ops->destroy_wsi) - wsi->context->event_loop_ops->destroy_wsi(wsi); - lws_plat_pipe_close(wsi); - wsi->context->count_wsi_allocated--; - lws_free(wsi); -} - -LWS_VISIBLE struct lws_context * -lws_create_context(const struct lws_context_creation_info *info) -{ - struct lws_context *context = NULL; - struct lws_plat_file_ops *prev; -#ifndef LWS_NO_DAEMONIZE - int pid_daemon = get_daemonize_pid(); -#endif - int n; -#if defined(__ANDROID__) - struct rlimit rt; -#endif - - - - lwsl_info("Initial logging level %d\n", log_level); - lwsl_info("Libwebsockets version: %s\n", library_version); -#if defined(GCC_VER) - lwsl_info("Compiled with %s\n", GCC_VER); -#endif - -#ifdef LWS_WITH_IPV6 - if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DISABLE_IPV6)) - lwsl_info("IPV6 compiled in and enabled\n"); - else - lwsl_info("IPV6 compiled in but disabled\n"); -#else - lwsl_info("IPV6 not compiled in\n"); -#endif - - lwsl_info(" LWS_DEF_HEADER_LEN : %u\n", LWS_DEF_HEADER_LEN); - lwsl_info(" LWS_MAX_PROTOCOLS : %u\n", LWS_MAX_PROTOCOLS); - lwsl_info(" LWS_MAX_SMP : %u\n", LWS_MAX_SMP); - lwsl_info(" sizeof (*info) : %ld\n", (long)sizeof(*info)); -#if defined(LWS_WITH_STATS) - lwsl_info(" LWS_WITH_STATS : on\n"); -#endif - lwsl_info(" SYSTEM_RANDOM_FILEPATH: '%s'\n", SYSTEM_RANDOM_FILEPATH); -#if defined(LWS_WITH_HTTP2) - lwsl_info(" HTTP2 support : available\n"); -#else - lwsl_info(" HTTP2 support : not configured\n"); -#endif - if (lws_plat_context_early_init()) - return NULL; - - context = lws_zalloc(sizeof(struct lws_context), "context"); - if (!context) { - lwsl_err("No memory for websocket context\n"); - return NULL; - } - -#if defined(LWS_WITH_TLS) -#if defined(LWS_WITH_MBEDTLS) - context->tls_ops = &tls_ops_mbedtls; -#else - context->tls_ops = &tls_ops_openssl; -#endif -#endif - - if (info->pt_serv_buf_size) - context->pt_serv_buf_size = info->pt_serv_buf_size; - else - context->pt_serv_buf_size = 4096; - -#if defined(LWS_ROLE_H2) - role_ops_h2.init_context(context, info); -#endif - -#if LWS_MAX_SMP > 1 - pthread_mutex_init(&context->lock, NULL); -#endif - -#if defined(LWS_WITH_ESP32) - context->last_free_heap = esp_get_free_heap_size(); -#endif - - /* default to just the platform fops implementation */ - - context->fops_platform.LWS_FOP_OPEN = _lws_plat_file_open; - context->fops_platform.LWS_FOP_CLOSE = _lws_plat_file_close; - context->fops_platform.LWS_FOP_SEEK_CUR = _lws_plat_file_seek_cur; - context->fops_platform.LWS_FOP_READ = _lws_plat_file_read; - context->fops_platform.LWS_FOP_WRITE = _lws_plat_file_write; - context->fops_platform.fi[0].sig = NULL; - - /* - * arrange a linear linked-list of fops starting from context->fops - * - * platform fops - * [ -> fops_zip (copied into context so .next settable) ] - * [ -> info->fops ] - */ - - context->fops = &context->fops_platform; - prev = (struct lws_plat_file_ops *)context->fops; - -#if defined(LWS_WITH_ZIP_FOPS) - /* make a soft copy so we can set .next */ - context->fops_zip = fops_zip; - prev->next = &context->fops_zip; - prev = (struct lws_plat_file_ops *)prev->next; -#endif - - /* if user provided fops, tack them on the end of the list */ - if (info->fops) - prev->next = info->fops; - - context->reject_service_keywords = info->reject_service_keywords; - if (info->external_baggage_free_on_destroy) - context->external_baggage_free_on_destroy = - info->external_baggage_free_on_destroy; - - context->time_up = time(NULL); - context->pcontext_finalize = info->pcontext; - - context->simultaneous_ssl_restriction = - info->simultaneous_ssl_restriction; - -#ifndef LWS_NO_DAEMONIZE - if (pid_daemon) { - context->started_with_parent = pid_daemon; - lwsl_info(" Started with daemon pid %d\n", pid_daemon); - } -#endif -#if defined(__ANDROID__) - n = getrlimit ( RLIMIT_NOFILE,&rt); - if (-1 == n) { - lwsl_err("Get RLIMIT_NOFILE failed!\n"); - return NULL; - } - context->max_fds = rt.rlim_cur; -#else - context->max_fds = getdtablesize(); -#endif - - if (info->count_threads) - context->count_threads = info->count_threads; - else - context->count_threads = 1; - - if (context->count_threads > LWS_MAX_SMP) - context->count_threads = LWS_MAX_SMP; - - context->token_limits = info->token_limits; - - context->options = info->options; - - /* - * set the context event loops ops struct - * - * after this, all event_loop actions use the generic ops - */ - -#if defined(LWS_WITH_POLL) - context->event_loop_ops = &event_loop_ops_poll; -#endif - - if (lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV)) -#if defined(LWS_WITH_LIBUV) - context->event_loop_ops = &event_loop_ops_uv; -#else - goto fail_event_libs; -#endif - - if (lws_check_opt(context->options, LWS_SERVER_OPTION_LIBEV)) -#if defined(LWS_WITH_LIBEV) - context->event_loop_ops = &event_loop_ops_ev; -#else - goto fail_event_libs; -#endif - - if (lws_check_opt(context->options, LWS_SERVER_OPTION_LIBEVENT)) -#if defined(LWS_WITH_LIBEVENT) - context->event_loop_ops = &event_loop_ops_event; -#else - goto fail_event_libs; -#endif - - if (!context->event_loop_ops) - goto fail_event_libs; - - lwsl_info("Using event loop: %s\n", context->event_loop_ops->name); - -#if defined(LWS_WITH_TLS) - time(&context->tls.last_cert_check_s); - if (info->alpn) - context->tls.alpn_default = info->alpn; - else { - char *p = context->tls.alpn_discovered, first = 1; - - LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) { - if (ar->alpn) { - if (!first) - *p++ = ','; - p += lws_snprintf(p, - context->tls.alpn_discovered + - sizeof(context->tls.alpn_discovered) - - 2 - p, "%s", ar->alpn); - first = 0; - } - } LWS_FOR_EVERY_AVAILABLE_ROLE_END; - - context->tls.alpn_default = context->tls.alpn_discovered; - } - - lwsl_info("Default ALPN advertisment: %s\n", context->tls.alpn_default); -#endif - - if (info->timeout_secs) - context->timeout_secs = info->timeout_secs; - else - context->timeout_secs = AWAITING_TIMEOUT; - - context->ws_ping_pong_interval = info->ws_ping_pong_interval; - - lwsl_info(" default timeout (secs): %u\n", context->timeout_secs); - - if (info->max_http_header_data) - context->max_http_header_data = info->max_http_header_data; - else - if (info->max_http_header_data2) - context->max_http_header_data = - info->max_http_header_data2; - else - context->max_http_header_data = LWS_DEF_HEADER_LEN; - - if (info->max_http_header_pool) - context->max_http_header_pool = info->max_http_header_pool; - else - context->max_http_header_pool = context->max_fds; - - if (info->fd_limit_per_thread) - context->fd_limit_per_thread = info->fd_limit_per_thread; - else - context->fd_limit_per_thread = context->max_fds / - context->count_threads; - - /* - * Allocate the per-thread storage for scratchpad buffers, - * and header data pool - */ - for (n = 0; n < context->count_threads; n++) { - context->pt[n].serv_buf = lws_malloc(context->pt_serv_buf_size, - "pt_serv_buf"); - if (!context->pt[n].serv_buf) { - lwsl_err("OOM\n"); - return NULL; - } - - context->pt[n].context = context; - context->pt[n].tid = n; - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - context->pt[n].http.ah_list = NULL; - context->pt[n].http.ah_pool_length = 0; -#endif - lws_pt_mutex_init(&context->pt[n]); - } - - lwsl_info(" Threads: %d each %d fds\n", context->count_threads, - context->fd_limit_per_thread); - - if (!info->ka_interval && info->ka_time > 0) { - lwsl_err("info->ka_interval can't be 0 if ka_time used\n"); - return NULL; - } - - -#if defined(LWS_WITH_PEER_LIMITS) - /* scale the peer hash table according to the max fds for the process, - * so that the max list depth averages 16. Eg, 1024 fd -> 64, - * 102400 fd -> 6400 - */ - context->pl_hash_elements = - (context->count_threads * context->fd_limit_per_thread) / 16; - context->pl_hash_table = lws_zalloc(sizeof(struct lws_peer *) * - context->pl_hash_elements, "peer limits hash table"); - context->ip_limit_ah = info->ip_limit_ah; - context->ip_limit_wsi = info->ip_limit_wsi; -#endif - - lwsl_info(" mem: context: %5lu B (%ld ctx + (%ld thr x %d))\n", - (long)sizeof(struct lws_context) + - (context->count_threads * context->pt_serv_buf_size), - (long)sizeof(struct lws_context), - (long)context->count_threads, - context->pt_serv_buf_size); -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - lwsl_info(" mem: http hdr rsvd: %5lu B (%u thr x (%u + %lu) x %u))\n", - (long)(context->max_http_header_data + - sizeof(struct allocated_headers)) * - context->max_http_header_pool * context->count_threads, - context->count_threads, - context->max_http_header_data, - (long)sizeof(struct allocated_headers), - context->max_http_header_pool); -#endif - n = sizeof(struct lws_pollfd) * context->count_threads * - context->fd_limit_per_thread; - context->pt[0].fds = lws_zalloc(n, "fds table"); - if (context->pt[0].fds == NULL) { - lwsl_err("OOM allocating %d fds\n", context->max_fds); - goto bail; - } - lwsl_info(" mem: pollfd map: %5u\n", n); - - if (info->server_string) { - context->server_string = info->server_string; - context->server_string_len = (short) - strlen(context->server_string); - } - -#if LWS_MAX_SMP > 1 - /* each thread serves his own chunk of fds */ - for (n = 1; n < (int)info->count_threads; n++) - context->pt[n].fds = context->pt[n - 1].fds + - context->fd_limit_per_thread; -#endif - - if (lws_plat_init(context, info)) - goto bail; - - if (context->event_loop_ops->init_context) - if (context->event_loop_ops->init_context(context, info)) - goto bail; - - - if (context->event_loop_ops->init_pt) - for (n = 0; n < context->count_threads; n++) { - void *lp = NULL; - - if (info->foreign_loops) - lp = info->foreign_loops[n]; - - if (context->event_loop_ops->init_pt(context, lp, n)) - goto bail; - } - - if (lws_create_event_pipes(context)) - goto bail; - - lws_context_init_ssl_library(info); - - context->user_space = info->user; - - /* - * if he's not saying he'll make his own vhosts later then act - * compatibly and make a default vhost using the data in the info - */ - if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) - if (!lws_create_vhost(context, info)) { - lwsl_err("Failed to create default vhost\n"); - for (n = 0; n < context->count_threads; n++) - lws_free_set_NULL(context->pt[n].serv_buf); -#if defined(LWS_WITH_PEER_LIMITS) - lws_free_set_NULL(context->pl_hash_table); -#endif - lws_free_set_NULL(context->pt[0].fds); - lws_plat_context_late_destroy(context); - lws_free_set_NULL(context); - return NULL; - } - - lws_context_init_extensions(info, context); - - lwsl_info(" mem: per-conn: %5lu bytes + protocol rx buf\n", - (unsigned long)sizeof(struct lws)); - - strcpy(context->canonical_hostname, "unknown"); - lws_server_get_canonical_hostname(context, info); - - context->uid = info->uid; - context->gid = info->gid; - -#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) - memcpy(context->caps, info->caps, sizeof(context->caps)); - context->count_caps = info->count_caps; -#endif - - /* - * drop any root privs for this process - * to listen on port < 1023 we would have needed root, but now we are - * listening, we don't want the power for anything else - */ - if (!lws_check_opt(info->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) - lws_plat_drop_app_privileges(info); - - /* expedite post-context init (eg, protocols) */ - lws_cancel_service(context); - -#if defined(LWS_WITH_SELFTESTS) - lws_jws_selftest(); -#endif - - return context; - -bail: - lws_context_destroy(context); - - return NULL; - -fail_event_libs: - lwsl_err("Requested event library support not configured, available:\n"); - { - const struct lws_event_loop_ops **elops = available_event_libs; - - while (*elops) { - lwsl_err(" - %s\n", (*elops)->name); - elops++; - } - } - lws_free(context); - - return NULL; -} - -LWS_VISIBLE LWS_EXTERN void -lws_context_deprecate(struct lws_context *context, lws_reload_func cb) -{ - struct lws_vhost *vh = context->vhost_list, *vh1; - struct lws *wsi; - - /* - * "deprecation" means disable the context from accepting any new - * connections and free up listen sockets to be used by a replacement - * context. - * - * Otherwise the deprecated context remains operational, until its - * number of connected sockets falls to zero, when it is deleted. - */ - - /* for each vhost, close his listen socket */ - - while (vh) { - wsi = vh->lserv_wsi; - if (wsi) { - wsi->socket_is_permanently_unusable = 1; - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "ctx deprecate"); - wsi->context->deprecation_pending_listen_close_count++; - /* - * other vhosts can share the listen port, they - * point to the same wsi. So zap those too. - */ - vh1 = context->vhost_list; - while (vh1) { - if (vh1->lserv_wsi == wsi) - vh1->lserv_wsi = NULL; - vh1 = vh1->vhost_next; - } - } - vh = vh->vhost_next; - } - - context->deprecated = 1; - context->deprecation_cb = cb; -} - -LWS_VISIBLE LWS_EXTERN int -lws_context_is_deprecated(struct lws_context *context) -{ - return context->deprecated; -} - -void -lws_vhost_destroy1(struct lws_vhost *vh) -{ - const struct lws_protocols *protocol = NULL; - struct lws_context_per_thread *pt; - int n, m = vh->context->count_threads; - struct lws_context *context = vh->context; - struct lws wsi; - - lwsl_info("%s\n", __func__); - - if (vh->being_destroyed) - return; - - vh->being_destroyed = 1; - - /* - * Are there other vhosts that are piggybacking on our listen socket? - * If so we need to hand the listen socket off to one of the others - * so it will remain open. If not, leave it attached to the closing - * vhost and it will get closed. - */ - - if (vh->lserv_wsi) - lws_start_foreach_ll(struct lws_vhost *, v, - context->vhost_list) { - if (v != vh && - !v->being_destroyed && - v->listen_port == vh->listen_port && - ((!v->iface && !vh->iface) || - (v->iface && vh->iface && - !strcmp(v->iface, vh->iface)))) { - /* - * this can only be a listen wsi, which is - * restricted... it has no protocol or other - * bindings or states. So we can simply - * swap it to a vhost that has the same - * iface + port, but is not closing. - */ - assert(v->lserv_wsi == NULL); - v->lserv_wsi = vh->lserv_wsi; - vh->lserv_wsi = NULL; - if (v->lserv_wsi) - v->lserv_wsi->vhost = v; - - lwsl_notice("%s: listen skt from %s to %s\n", - __func__, vh->name, v->name); - break; - } - } lws_end_foreach_ll(v, vhost_next); - - /* - * Forcibly close every wsi assoicated with this vhost. That will - * include the listen socket if it is still associated with the closing - * vhost. - */ - - while (m--) { - pt = &context->pt[m]; - - for (n = 0; (unsigned int)n < context->pt[m].fds_count; n++) { - struct lws *wsi = wsi_from_fd(context, pt->fds[n].fd); - if (!wsi) - continue; - if (wsi->vhost != vh) - continue; - - lws_close_free_wsi(wsi, - LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY, - "vh destroy" - /* no protocol close */); - n--; - } - } - - /* - * destroy any pending timed events - */ - - while (vh->timed_vh_protocol_list) - lws_timed_callback_remove(vh, vh->timed_vh_protocol_list); - - /* - * let the protocols destroy the per-vhost protocol objects - */ - - memset(&wsi, 0, sizeof(wsi)); - wsi.context = vh->context; - wsi.vhost = vh; - protocol = vh->protocols; - if (protocol && vh->created_vhost_protocols) { - n = 0; - while (n < vh->count_protocols) { - wsi.protocol = protocol; - protocol->callback(&wsi, LWS_CALLBACK_PROTOCOL_DESTROY, - NULL, NULL, 0); - protocol++; - n++; - } - } - - /* - * remove vhost from context list of vhosts - */ - - lws_start_foreach_llp(struct lws_vhost **, pv, context->vhost_list) { - if (*pv == vh) { - *pv = vh->vhost_next; - break; - } - } lws_end_foreach_llp(pv, vhost_next); - - /* add ourselves to the pending destruction list */ - - vh->vhost_next = vh->context->vhost_pending_destruction_list; - vh->context->vhost_pending_destruction_list = vh; -} - -static void -lws_vhost_destroy2(struct lws_vhost *vh) -{ - const struct lws_protocols *protocol = NULL; - struct lws_context *context = vh->context; - struct lws_deferred_free *df; - int n; - - lwsl_info("%s: %p\n", __func__, vh); - - /* if we are still on deferred free list, remove ourselves */ - - lws_start_foreach_llp(struct lws_deferred_free **, pdf, - context->deferred_free_list) { - if ((*pdf)->payload == vh) { - df = *pdf; - *pdf = df->next; - lws_free(df); - break; - } - } lws_end_foreach_llp(pdf, next); - - /* remove ourselves from the pending destruction list */ - - lws_start_foreach_llp(struct lws_vhost **, pv, - context->vhost_pending_destruction_list) { - if ((*pv) == vh) { - *pv = (*pv)->vhost_next; - break; - } - } lws_end_foreach_llp(pv, vhost_next); - - /* - * Free all the allocations associated with the vhost - */ - - protocol = vh->protocols; - if (protocol) { - n = 0; - while (n < vh->count_protocols) { - if (vh->protocol_vh_privs && - vh->protocol_vh_privs[n]) { - lws_free(vh->protocol_vh_privs[n]); - vh->protocol_vh_privs[n] = NULL; - } - protocol++; - n++; - } - } - if (vh->protocol_vh_privs) - lws_free(vh->protocol_vh_privs); - lws_ssl_SSL_CTX_destroy(vh); - lws_free(vh->same_vh_protocol_list); - - if (context->plugin_list || - (context->options & LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) - lws_free((void *)vh->protocols); - - LWS_FOR_EVERY_AVAILABLE_ROLE_START(ar) - if (ar->destroy_vhost) - ar->destroy_vhost(vh); - LWS_FOR_EVERY_AVAILABLE_ROLE_END; - -#ifdef LWS_WITH_ACCESS_LOG - if (vh->log_fd != (int)LWS_INVALID_FILE) - close(vh->log_fd); -#endif - -#if defined (LWS_WITH_TLS) - lws_free_set_NULL(vh->tls.alloc_cert_path); -#endif - -#if LWS_MAX_SMP > 1 - pthread_mutex_destroy(&vh->lock); -#endif - -#if defined(LWS_WITH_UNIX_SOCK) - if (LWS_UNIX_SOCK_ENABLED(context)) { - n = unlink(vh->iface); - if (n) - lwsl_info("Closing unix socket %s: errno %d\n", - vh->iface, errno); - } -#endif - /* - * although async event callbacks may still come for wsi handles with - * pending close in the case of asycn event library like libuv, - * they do not refer to the vhost. So it's safe to free. - */ - - lwsl_info(" %s: Freeing vhost %p\n", __func__, vh); - - memset(vh, 0, sizeof(*vh)); - lws_free(vh); -} - -int -lws_check_deferred_free(struct lws_context *context, int force) -{ - struct lws_deferred_free *df; - time_t now = lws_now_secs(); - - lws_start_foreach_llp(struct lws_deferred_free **, pdf, - context->deferred_free_list) { - if (force || - lws_compare_time_t(context, now, (*pdf)->deadline) > 5) { - df = *pdf; - *pdf = df->next; - /* finalize vh destruction */ - lwsl_notice("deferred vh %p destroy\n", df->payload); - lws_vhost_destroy2(df->payload); - lws_free(df); - continue; /* after deletion we already point to next */ - } - } lws_end_foreach_llp(pdf, next); - - return 0; -} - -LWS_VISIBLE void -lws_vhost_destroy(struct lws_vhost *vh) -{ - struct lws_deferred_free *df = lws_malloc(sizeof(*df), "deferred free"); - - if (!df) - return; - - lws_vhost_destroy1(vh); - - /* part 2 is deferred to allow all the handle closes to complete */ - - df->next = vh->context->deferred_free_list; - df->deadline = lws_now_secs(); - df->payload = vh; - vh->context->deferred_free_list = df; -} - -/* - * When using an event loop, the context destruction is in three separate - * parts. This is to cover both internal and foreign event loops cleanly. - * - * - lws_context_destroy() simply starts a soft close of all wsi and - * related allocations. The event loop continues. - * - * As the closes complete in the event loop, reference counting is used - * to determine when everything is closed. It then calls - * lws_context_destroy2(). - * - * - lws_context_destroy2() cleans up the rest of the higher-level logical - * lws pieces like vhosts. If the loop was foreign, it then proceeds to - * lws_context_destroy3(). If it the loop is internal, it stops the - * internal loops and waits for lws_context_destroy() to be called again - * outside the event loop (since we cannot destroy the loop from - * within the loop). That will cause lws_context_destroy3() to run - * directly. - * - * - lws_context_destroy3() destroys any internal event loops and then - * destroys the context itself, setting what was info.pcontext to NULL. - */ - -/* - * destroy the actual context itself - */ - -static void -lws_context_destroy3(struct lws_context *context) -{ - struct lws_context **pcontext_finalize = context->pcontext_finalize; - struct lws_context_per_thread *pt; - int n; - - for (n = 0; n < context->count_threads; n++) { - pt = &context->pt[n]; - - if (context->event_loop_ops->destroy_pt) - context->event_loop_ops->destroy_pt(context, n); - - lws_free_set_NULL(context->pt[n].serv_buf); - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - while (pt->http.ah_list) - _lws_destroy_ah(pt, pt->http.ah_list); -#endif - } - - lws_free(context); - lwsl_info("%s: ctx %p freed\n", __func__, context); - - if (pcontext_finalize) - *pcontext_finalize = NULL; -} - -/* - * really start destroying things - */ - -void -lws_context_destroy2(struct lws_context *context) -{ - struct lws_vhost *vh = NULL, *vh1; -#if defined(LWS_WITH_PEER_LIMITS) - uint32_t nu; -#endif - int n; - - lwsl_info("%s: ctx %p\n", __func__, context); - - context->being_destroyed2 = 1; - - if (context->pt[0].fds) - lws_free_set_NULL(context->pt[0].fds); - - /* - * free all the per-vhost allocations - */ - - vh = context->vhost_list; - while (vh) { - vh1 = vh->vhost_next; - lws_vhost_destroy2(vh); - vh = vh1; - } - - /* remove ourselves from the pending destruction list */ - - while (context->vhost_pending_destruction_list) - /* removes itself from list */ - lws_vhost_destroy2(context->vhost_pending_destruction_list); - - - lws_stats_log_dump(context); - - lws_ssl_context_destroy(context); - lws_plat_context_late_destroy(context); - -#if defined(LWS_WITH_PEER_LIMITS) - for (nu = 0; nu < context->pl_hash_elements; nu++) { - lws_start_foreach_llp(struct lws_peer **, peer, - context->pl_hash_table[nu]) { - struct lws_peer *df = *peer; - *peer = df->next; - lws_free(df); - continue; - } lws_end_foreach_llp(peer, next); - } - lws_free(context->pl_hash_table); -#endif - - if (context->external_baggage_free_on_destroy) - free(context->external_baggage_free_on_destroy); - - lws_check_deferred_free(context, 1); - -#if LWS_MAX_SMP > 1 - pthread_mutex_destroy(&context->lock); -#endif - - if (context->event_loop_ops->destroy_context2) - if (context->event_loop_ops->destroy_context2(context)) { - context->finalize_destroy_after_internal_loops_stopped = 1; - return; - } - - if (!context->pt[0].event_loop_foreign) - for (n = 0; n < context->count_threads; n++) - if (context->pt[n].inside_service) - return; - - lws_context_destroy3(context); -} - -/* - * Begin the context takedown - */ - -LWS_VISIBLE void -lws_context_destroy(struct lws_context *context) -{ - volatile struct lws_foreign_thread_pollfd *ftp, *next; - volatile struct lws_context_per_thread *vpt; - struct lws_context_per_thread *pt; - struct lws_vhost *vh = NULL; - struct lws wsi; - int n, m; - - if (!context) - return; - - if (context->finalize_destroy_after_internal_loops_stopped) { - if (context->event_loop_ops->destroy_context2) - context->event_loop_ops->destroy_context2(context); - - lws_context_destroy3(context); - - return; - } - - if (context->being_destroyed1) { - if (!context->being_destroyed2) { - lws_context_destroy2(context); - - return; - } - lwsl_info("%s: ctx %p: already being destroyed\n", - __func__, context); - - lws_context_destroy3(context); - return; - } - - lwsl_info("%s: ctx %p\n", __func__, context); - - m = context->count_threads; - context->being_destroyed = 1; - context->being_destroyed1 = 1; - context->requested_kill = 1; - - memset(&wsi, 0, sizeof(wsi)); - wsi.context = context; - -#ifdef LWS_LATENCY - if (context->worst_latency_info[0]) - lwsl_notice("Worst latency: %s\n", context->worst_latency_info); -#endif - - while (m--) { - pt = &context->pt[m]; - vpt = (volatile struct lws_context_per_thread *)pt; - - ftp = vpt->foreign_pfd_list; - while (ftp) { - next = ftp->next; - lws_free((void *)ftp); - ftp = next; - } - vpt->foreign_pfd_list = NULL; - - for (n = 0; (unsigned int)n < context->pt[m].fds_count; n++) { - struct lws *wsi = wsi_from_fd(context, pt->fds[n].fd); - if (!wsi) - continue; - - if (wsi->event_pipe) - lws_destroy_event_pipe(wsi); - else - lws_close_free_wsi(wsi, - LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY, - "ctx destroy" - /* no protocol close */); - n--; - } - lws_pt_mutex_destroy(pt); - } - - /* - * inform all the protocols that they are done and will have no more - * callbacks. - * - * We can't free things until after the event loop shuts down. - */ - if (context->protocol_init_done) - vh = context->vhost_list; - while (vh) { - struct lws_vhost *vhn = vh->vhost_next; - lws_vhost_destroy1(vh); - vh = vhn; - } - - lws_plat_context_early_destroy(context); - - /* - * We face two different needs depending if foreign loop or not. - * - * 1) If foreign loop, we really want to advance the destroy_context() - * past here, and block only for libuv-style async close completion. - * - * 2a) If poll, and we exited by ourselves and are calling a final - * destroy_context() outside of any service already, we want to - * advance all the way in one step. - * - * 2b) If poll, and we are reacting to a SIGINT, service thread(s) may - * be in poll wait or servicing. We can't advance the - * destroy_context() to the point it's freeing things; we have to - * leave that for the final destroy_context() after the service - * thread(s) are finished calling for service. - */ - - if (context->event_loop_ops->destroy_context1) { - context->event_loop_ops->destroy_context1(context); - - return; - } - - lws_context_destroy2(context); -} diff --git a/thirdparty/libwebsockets/core/libwebsockets.c b/thirdparty/libwebsockets/core/libwebsockets.c deleted file mode 100644 index 58f00226f6..0000000000 --- a/thirdparty/libwebsockets/core/libwebsockets.c +++ /dev/null @@ -1,3479 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -#ifdef LWS_HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -#ifdef LWS_WITH_IPV6 -#if defined(WIN32) || defined(_WIN32) -#include <wincrypt.h> -#include <iphlpapi.h> -#else -#include <net/if.h> -#endif -#endif - -int log_level = LLL_ERR | LLL_WARN | LLL_NOTICE; -static void (*lwsl_emit)(int level, const char *line) -#ifndef LWS_PLAT_OPTEE - = lwsl_emit_stderr -#endif - ; -#ifndef LWS_PLAT_OPTEE -static const char * const log_level_names[] = { - "ERR", - "WARN", - "NOTICE", - "INFO", - "DEBUG", - "PARSER", - "HEADER", - "EXTENSION", - "CLIENT", - "LATENCY", - "USER", - "?", - "?" -}; -#endif - -int lws_open(const char *__file, int __oflag, ...) -{ - va_list ap; - int n; - - va_start(ap, __oflag); - if (((__oflag & O_CREAT) == O_CREAT) -#if defined(O_TMPFILE) - || ((__oflag & O_TMPFILE) == O_TMPFILE) -#endif - ) - /* last arg is really a mode_t. But windows... */ - n = open(__file, __oflag, va_arg(ap, uint32_t)); - else - n = open(__file, __oflag); - va_end(ap); - - lws_plat_apply_FD_CLOEXEC(n); - - return n; -} - -#if defined (_DEBUG) -void lwsi_set_role(struct lws *wsi, lws_wsi_state_t role) -{ - wsi->wsistate = (wsi->wsistate & (~LWSI_ROLE_MASK)) | role; - - lwsl_debug("lwsi_set_role(%p, 0x%x)\n", wsi, wsi->wsistate); -} - -void lwsi_set_state(struct lws *wsi, lws_wsi_state_t lrs) -{ - wsi->wsistate = (wsi->wsistate & (~LRS_MASK)) | lrs; - - lwsl_debug("lwsi_set_state(%p, 0x%x)\n", wsi, wsi->wsistate); -} -#endif - -signed char char_to_hex(const char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - - return -1; -} - -void -__lws_free_wsi(struct lws *wsi) -{ - if (!wsi) - return; - - /* - * Protocol user data may be allocated either internally by lws - * or by specified the user. We should only free what we allocated. - */ - if (wsi->protocol && wsi->protocol->per_session_data_size && - wsi->user_space && !wsi->user_space_externally_allocated) - lws_free(wsi->user_space); - - lws_buflist_destroy_all_segments(&wsi->buflist); - lws_free_set_NULL(wsi->trunc_alloc); - lws_free_set_NULL(wsi->udp); - - if (wsi->vhost && wsi->vhost->lserv_wsi == wsi) - wsi->vhost->lserv_wsi = NULL; - - // lws_peer_dump_from_wsi(wsi); - - if (wsi->role_ops->destroy_role) - wsi->role_ops->destroy_role(wsi); - -#if defined(LWS_WITH_PEER_LIMITS) - lws_peer_track_wsi_close(wsi->context, wsi->peer); - wsi->peer = NULL; -#endif - - /* since we will destroy the wsi, make absolutely sure now */ - -#if defined(LWS_WITH_OPENSSL) - __lws_ssl_remove_wsi_from_buffered_list(wsi); -#endif - __lws_remove_from_timeout_list(wsi); - - if (wsi->context->event_loop_ops->destroy_wsi) - wsi->context->event_loop_ops->destroy_wsi(wsi); - - wsi->context->count_wsi_allocated--; - lwsl_debug("%s: %p, remaining wsi %d\n", __func__, wsi, - wsi->context->count_wsi_allocated); - - lws_free(wsi); -} - -void -lws_dll_add_front(struct lws_dll *d, struct lws_dll *phead) -{ - if (d->prev) - return; - - /* our next guy is current first guy */ - d->next = phead->next; - /* if there is a next guy, set his prev ptr to our next ptr */ - if (d->next) - d->next->prev = d; - /* our prev ptr is first ptr */ - d->prev = phead; - /* set the first guy to be us */ - phead->next = d; -} - -/* situation is: - * - * HEAD: struct lws_dll * = &entry1 - * - * Entry 1: struct lws_dll .pprev = &HEAD , .next = Entry 2 - * Entry 2: struct lws_dll .pprev = &entry1 , .next = &entry2 - * Entry 3: struct lws_dll .pprev = &entry2 , .next = NULL - * - * Delete Entry1: - * - * - HEAD = &entry2 - * - Entry2: .pprev = &HEAD, .next = &entry3 - * - Entry3: .pprev = &entry2, .next = NULL - * - * Delete Entry2: - * - * - HEAD = &entry1 - * - Entry1: .pprev = &HEAD, .next = &entry3 - * - Entry3: .pprev = &entry1, .next = NULL - * - * Delete Entry3: - * - * - HEAD = &entry1 - * - Entry1: .pprev = &HEAD, .next = &entry2 - * - Entry2: .pprev = &entry1, .next = NULL - * - */ - -void -lws_dll_remove(struct lws_dll *d) -{ - if (!d->prev) /* ie, not part of the list */ - return; - - /* - * remove us - * - * USp <-> us <-> USn --> USp <-> USn - */ - - /* if we have a next guy, set his prev to our prev */ - if (d->next) - d->next->prev = d->prev; - - /* set our prev guy to our next guy instead of us */ - if (d->prev) - d->prev->next = d->next; - - /* we're out of the list, we should not point anywhere any more */ - d->prev = NULL; - d->next = NULL; -} - -void -__lws_remove_from_timeout_list(struct lws *wsi) -{ - lws_dll_lws_remove(&wsi->dll_timeout); -} - -void -lws_remove_from_timeout_list(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - - lws_pt_lock(pt, __func__); - __lws_remove_from_timeout_list(wsi); - lws_pt_unlock(pt); -} - -void -lws_dll_dump(struct lws_dll_lws *head, const char *title) -{ - int n = 0; - - (void)n; - lwsl_notice("%s: %s (head.next %p)\n", __func__, title, head->next); - - lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, head->next) { - struct lws *wsi = lws_container_of(d, struct lws, dll_hrtimer); - - (void)wsi; - - lwsl_notice(" %d: wsi %p: %llu\n", n++, wsi, - (unsigned long long)wsi->pending_timer); - } lws_end_foreach_dll_safe(d, d1); -} - -void -__lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - struct lws_dll_lws *dd = &pt->dll_head_hrtimer; - struct timeval now; - struct lws *wsi1; - int bef = 0; - - lws_dll_lws_remove(&wsi->dll_hrtimer); - - if (usecs == LWS_SET_TIMER_USEC_CANCEL) - return; - - gettimeofday(&now, NULL); - wsi->pending_timer = ((now.tv_sec * 1000000ll) + now.tv_usec) + usecs; - - /* - * we sort the hrtimer list with the earliest timeout first - */ - - lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, - pt->dll_head_hrtimer.next) { - dd = d; - wsi1 = lws_container_of(d, struct lws, dll_hrtimer); - - if (wsi1->pending_timer >= wsi->pending_timer) { - /* d, dprev's next, is >= our time */ - bef = 1; - break; - } - } lws_end_foreach_dll_safe(d, d1); - - if (bef) { - /* - * we go before dd - * DDp <-> DD <-> DDn --> DDp <-> us <-> DD <-> DDn - */ - /* we point forward to dd */ - wsi->dll_hrtimer.next = dd; - /* we point back to what dd used to point back to */ - wsi->dll_hrtimer.prev = dd->prev; - /* DDp points forward to us now */ - dd->prev->next = &wsi->dll_hrtimer; - /* DD points back to us now */ - dd->prev = &wsi->dll_hrtimer; - } else { - /* - * we go after dd - * DDp <-> DD <-> DDn --> DDp <-> DD <-> us <-> DDn - */ - /* we point forward to what dd used to point forward to */ - wsi->dll_hrtimer.next = dd->next; - /* we point back to dd */ - wsi->dll_hrtimer.prev = dd; - /* DDn points back to us */ - if (dd->next) - dd->next->prev = &wsi->dll_hrtimer; - /* DD points forward to us */ - dd->next = &wsi->dll_hrtimer; - } - -// lws_dll_dump(&pt->dll_head_hrtimer, "after set_timer_usec"); -} - -LWS_VISIBLE void -lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs) -{ - __lws_set_timer_usecs(wsi, usecs); -} - -lws_usec_t -__lws_hrtimer_service(struct lws_context_per_thread *pt) -{ - struct timeval now; - struct lws *wsi; - lws_usec_t t; - - gettimeofday(&now, NULL); - t = (now.tv_sec * 1000000ll) + now.tv_usec; - - lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, - pt->dll_head_hrtimer.next) { - wsi = lws_container_of(d, struct lws, dll_hrtimer); - - /* - * if we met one in the future, we are done, because the list - * is sorted by time in the future. - */ - if (wsi->pending_timer > t) - break; - - lws_set_timer_usecs(wsi, LWS_SET_TIMER_USEC_CANCEL); - - /* it's time for the timer to be serviced */ - - if (wsi->protocol && - wsi->protocol->callback(wsi, LWS_CALLBACK_TIMER, - wsi->user_space, NULL, 0)) - __lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, - "timer cb errored"); - } lws_end_foreach_dll_safe(d, d1); - - /* return an estimate how many us until next timer hit */ - - if (!pt->dll_head_hrtimer.next) - return LWS_HRTIMER_NOWAIT; - - wsi = lws_container_of(pt->dll_head_hrtimer.next, struct lws, dll_hrtimer); - - gettimeofday(&now, NULL); - t = (now.tv_sec * 1000000ll) + now.tv_usec; - - if (wsi->pending_timer < t) - return 0; - - return wsi->pending_timer - t; -} - -void -__lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - time_t now; - - time(&now); - - lwsl_debug("%s: %p: %d secs\n", __func__, wsi, secs); - wsi->pending_timeout_limit = secs; - wsi->pending_timeout_set = now; - wsi->pending_timeout = reason; - - if (!reason) - lws_dll_lws_remove(&wsi->dll_timeout); - else - lws_dll_lws_add_front(&wsi->dll_timeout, &pt->dll_head_timeout); -} - -LWS_VISIBLE void -lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - - if (secs == LWS_TO_KILL_SYNC) { - lws_remove_from_timeout_list(wsi); - lwsl_debug("synchronously killing %p\n", wsi); - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "to sync kill"); - return; - } - - if (secs == LWS_TO_KILL_ASYNC) - secs = 0; - - lws_pt_lock(pt, __func__); - __lws_set_timeout(wsi, reason, secs); - lws_pt_unlock(pt); -} - -int -lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p) -{ - lws_start_foreach_llp(struct lws_timed_vh_protocol **, pt, - vh->timed_vh_protocol_list) { - if (*pt == p) { - *pt = p->next; - lws_free(p); - - return 0; - } - } lws_end_foreach_llp(pt, next); - - return 1; -} - -LWS_VISIBLE LWS_EXTERN int -lws_timed_callback_vh_protocol(struct lws_vhost *vh, const struct lws_protocols *prot, - int reason, int secs) -{ - struct lws_timed_vh_protocol *p = (struct lws_timed_vh_protocol *) - lws_malloc(sizeof(*p), "timed_vh"); - - if (!p) - return 1; - - p->protocol = prot; - p->reason = reason; - p->time = lws_now_secs() + secs; - p->next = vh->timed_vh_protocol_list; - - vh->timed_vh_protocol_list = p; - - return 0; -} - -static void -lws_remove_child_from_any_parent(struct lws *wsi) -{ - struct lws **pwsi; - int seen = 0; - - if (!wsi->parent) - return; - - /* detach ourselves from parent's child list */ - pwsi = &wsi->parent->child_list; - while (*pwsi) { - if (*pwsi == wsi) { - lwsl_info("%s: detach %p from parent %p\n", __func__, - wsi, wsi->parent); - - if (wsi->parent->protocol) - wsi->parent->protocol->callback(wsi, - LWS_CALLBACK_CHILD_CLOSING, - wsi->parent->user_space, wsi, 0); - - *pwsi = wsi->sibling_list; - seen = 1; - break; - } - pwsi = &(*pwsi)->sibling_list; - } - if (!seen) - lwsl_err("%s: failed to detach from parent\n", __func__); - - wsi->parent = NULL; -} - -int -lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p) -{ -// if (wsi->protocol == p) -// return 0; - const struct lws_protocols *vp = wsi->vhost->protocols, *vpo; - - if (wsi->protocol && wsi->protocol_bind_balance) { - wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL, - wsi->user_space, NULL, 0); - wsi->protocol_bind_balance = 0; - } - if (!wsi->user_space_externally_allocated) - lws_free_set_NULL(wsi->user_space); - - lws_same_vh_protocol_remove(wsi); - - wsi->protocol = p; - if (!p) - return 0; - - if (lws_ensure_user_space(wsi)) - return 1; - - if (p > vp && p < &vp[wsi->vhost->count_protocols]) - lws_same_vh_protocol_insert(wsi, (int)(p - vp)); - else { - int n = wsi->vhost->count_protocols; - int hit = 0; - - vpo = vp; - - while (n--) { - if (p->name && vp->name && !strcmp(p->name, vp->name)) { - hit = 1; - lws_same_vh_protocol_insert(wsi, (int)(vp - vpo)); - break; - } - vp++; - } - if (!hit) - lwsl_err("%s: %p is not in vhost '%s' protocols list\n", - __func__, p, wsi->vhost->name); - } - - if (wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_BIND_PROTOCOL, - wsi->user_space, NULL, 0)) - return 1; - - wsi->protocol_bind_balance = 1; - - return 0; -} - -void -__lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, const char *caller) -{ - struct lws_context_per_thread *pt; - struct lws *wsi1, *wsi2; - struct lws_context *context; - int n; - - lwsl_info("%s: %p: caller: %s\n", __func__, wsi, caller); - - if (!wsi) - return; - - lws_access_log(wsi); - - context = wsi->context; - pt = &context->pt[(int)wsi->tsi]; - lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_API_CLOSE, 1); - -#if !defined(LWS_NO_CLIENT) - - lws_free_set_NULL(wsi->client_hostname_copy); - /* we are no longer an active client connection that can piggyback */ - lws_dll_lws_remove(&wsi->dll_active_client_conns); - - /* - * if we have wsi in our transaction queue, if we are closing we - * must go through and close all those first - */ - if (wsi->vhost) { - if ((int)reason != -1) - lws_vhost_lock(wsi->vhost); - lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, - wsi->dll_client_transaction_queue_head.next) { - struct lws *w = lws_container_of(d, struct lws, - dll_client_transaction_queue); - - __lws_close_free_wsi(w, -1, "trans q leader closing"); - } lws_end_foreach_dll_safe(d, d1); - - /* - * !!! If we are closing, but we have pending pipelined transaction - * results we already sent headers for, that's going to destroy sync - * for HTTP/1 and leave H2 stream with no live swsi. - * - * However this is normal if we are being closed because the transaction - * queue leader is closing. - */ - lws_dll_lws_remove(&wsi->dll_client_transaction_queue); - if ((int)reason !=-1) - lws_vhost_unlock(wsi->vhost); - } -#endif - - /* if we have children, close them first */ - if (wsi->child_list) { - wsi2 = wsi->child_list; - while (wsi2) { - wsi1 = wsi2->sibling_list; - wsi2->parent = NULL; - /* stop it doing shutdown processing */ - wsi2->socket_is_permanently_unusable = 1; - __lws_close_free_wsi(wsi2, reason, "general child recurse"); - wsi2 = wsi1; - } - wsi->child_list = NULL; - } - - if (wsi->role_ops == &role_ops_raw_file) { - lws_remove_child_from_any_parent(wsi); - __remove_wsi_socket_from_fds(wsi); - wsi->protocol->callback(wsi, wsi->role_ops->close_cb[0], - wsi->user_space, NULL, 0); - goto async_close; - } - - wsi->wsistate_pre_close = wsi->wsistate; - -#ifdef LWS_WITH_CGI - if (wsi->role_ops == &role_ops_cgi) { - /* we are not a network connection, but a handler for CGI io */ - if (wsi->parent && wsi->parent->http.cgi) { - - if (wsi->cgi_channel == LWS_STDOUT) - lws_cgi_remove_and_kill(wsi->parent); - - /* end the binding between us and master */ - wsi->parent->http.cgi->stdwsi[(int)wsi->cgi_channel] = NULL; - } - wsi->socket_is_permanently_unusable = 1; - - goto just_kill_connection; - } - - if (wsi->http.cgi) - lws_cgi_remove_and_kill(wsi); -#endif - -#if !defined(LWS_NO_CLIENT) - lws_client_stash_destroy(wsi); -#endif - - if (wsi->role_ops == &role_ops_raw_skt) { - wsi->socket_is_permanently_unusable = 1; - goto just_kill_connection; - } -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - if (lwsi_role_http(wsi) && lwsi_role_server(wsi) && - wsi->http.fop_fd != NULL) - lws_vfs_file_close(&wsi->http.fop_fd); -#endif - - if (lwsi_state(wsi) == LRS_DEAD_SOCKET) - return; - - if (wsi->socket_is_permanently_unusable || - reason == LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY || - lwsi_state(wsi) == LRS_SHUTDOWN) - goto just_kill_connection; - - switch (lwsi_state_PRE_CLOSE(wsi)) { - case LRS_DEAD_SOCKET: - return; - - /* we tried the polite way... */ - case LRS_WAITING_TO_SEND_CLOSE: - case LRS_AWAITING_CLOSE_ACK: - case LRS_RETURNED_CLOSE: - goto just_kill_connection; - - case LRS_FLUSHING_BEFORE_CLOSE: - if (wsi->trunc_len) { - lws_callback_on_writable(wsi); - return; - } - lwsl_info("%p: end LRS_FLUSHING_BEFORE_CLOSE\n", wsi); - goto just_kill_connection; - default: - if (wsi->trunc_len) { - lwsl_info("%p: LRS_FLUSHING_BEFORE_CLOSE\n", wsi); - lwsi_set_state(wsi, LRS_FLUSHING_BEFORE_CLOSE); - __lws_set_timeout(wsi, - PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE, 5); - return; - } - break; - } - - if (lwsi_state(wsi) == LRS_WAITING_CONNECT || - lwsi_state(wsi) == LRS_H1C_ISSUE_HANDSHAKE) - goto just_kill_connection; - - if (!wsi->told_user_closed && lwsi_role_http(wsi) && - lwsi_role_server(wsi)) { - if (wsi->user_space && wsi->protocol && - wsi->protocol_bind_balance) { - wsi->protocol->callback(wsi, - LWS_CALLBACK_HTTP_DROP_PROTOCOL, - wsi->user_space, NULL, 0); - wsi->protocol_bind_balance = 0; - } - } - - /* - * signal we are closing, lws_write will - * add any necessary version-specific stuff. If the write fails, - * no worries we are closing anyway. If we didn't initiate this - * close, then our state has been changed to - * LRS_RETURNED_CLOSE and we will skip this. - * - * Likewise if it's a second call to close this connection after we - * sent the close indication to the peer already, we are in state - * LRS_AWAITING_CLOSE_ACK and will skip doing this a second time. - */ - - if (wsi->role_ops->close_via_role_protocol && - wsi->role_ops->close_via_role_protocol(wsi, reason)) - return; - -just_kill_connection: - - if (wsi->role_ops->close_kill_connection) - wsi->role_ops->close_kill_connection(wsi, reason); - - lws_remove_child_from_any_parent(wsi); - n = 0; - - if (!wsi->told_user_closed && wsi->user_space && - wsi->protocol_bind_balance) { - lwsl_debug("%s: %p: DROP_PROTOCOL %s\n", __func__, wsi, - wsi->protocol->name); - wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_DROP_PROTOCOL, - wsi->user_space, NULL, 0); - wsi->protocol_bind_balance = 0; - } - - if ((lwsi_state(wsi) == LRS_WAITING_SERVER_REPLY || - lwsi_state(wsi) == LRS_WAITING_CONNECT) && !wsi->already_did_cce) - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, NULL, 0); - - /* - * Testing with ab shows that we have to stage the socket close when - * the system is under stress... shutdown any further TX, change the - * state to one that won't emit anything more, and wait with a timeout - * for the POLLIN to show a zero-size rx before coming back and doing - * the actual close. - */ - if (wsi->role_ops != &role_ops_raw_skt && !lwsi_role_client(wsi) && - lwsi_state(wsi) != LRS_SHUTDOWN && - lwsi_state(wsi) != LRS_UNCONNECTED && - reason != LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY && - !wsi->socket_is_permanently_unusable) { - -#if defined(LWS_WITH_TLS) - if (lws_is_ssl(wsi) && wsi->tls.ssl) { - n = 0; - switch (__lws_tls_shutdown(wsi)) { - case LWS_SSL_CAPABLE_DONE: - case LWS_SSL_CAPABLE_ERROR: - case LWS_SSL_CAPABLE_MORE_SERVICE_READ: - case LWS_SSL_CAPABLE_MORE_SERVICE_WRITE: - case LWS_SSL_CAPABLE_MORE_SERVICE: - break; - } - } else -#endif - { - lwsl_info("%s: shutdown conn: %p (sock %d, state 0x%x)\n", - __func__, wsi, (int)(long)wsi->desc.sockfd, - lwsi_state(wsi)); - if (!wsi->socket_is_permanently_unusable && - lws_socket_is_valid(wsi->desc.sockfd)) { - wsi->socket_is_permanently_unusable = 1; - n = shutdown(wsi->desc.sockfd, SHUT_WR); - } - } - if (n) - lwsl_debug("closing: shutdown (state 0x%x) ret %d\n", - lwsi_state(wsi), LWS_ERRNO); - - /* - * This causes problems on WINCE / ESP32 with disconnection - * when the events are half closing connection - */ -#if !defined(_WIN32_WCE) && !defined(LWS_WITH_ESP32) - /* libuv: no event available to guarantee completion */ - if (!wsi->socket_is_permanently_unusable && - lws_socket_is_valid(wsi->desc.sockfd) && - lwsi_state(wsi) != LRS_SHUTDOWN && - context->event_loop_ops->periodic_events_available) { - __lws_change_pollfd(wsi, LWS_POLLOUT, LWS_POLLIN); - lwsi_set_state(wsi, LRS_SHUTDOWN); - __lws_set_timeout(wsi, PENDING_TIMEOUT_SHUTDOWN_FLUSH, - context->timeout_secs); - - return; - } -#endif - } - - lwsl_debug("%s: real just_kill_connection: %p (sockfd %d)\n", __func__, - wsi, wsi->desc.sockfd); - -#ifdef LWS_WITH_HTTP_PROXY - if (wsi->http.rw) { - lws_rewrite_destroy(wsi->http.rw); - wsi->http.rw = NULL; - } -#endif - /* - * we won't be servicing or receiving anything further from this guy - * delete socket from the internal poll list if still present - */ - __lws_ssl_remove_wsi_from_buffered_list(wsi); - __lws_remove_from_timeout_list(wsi); - lws_dll_lws_remove(&wsi->dll_hrtimer); - - /* don't repeat event loop stuff */ - if (wsi->told_event_loop_closed) - return; - - /* checking return redundant since we anyway close */ - if (wsi->desc.sockfd != LWS_SOCK_INVALID) - __remove_wsi_socket_from_fds(wsi); - else - lws_same_vh_protocol_remove(wsi); - - lwsi_set_state(wsi, LRS_DEAD_SOCKET); - lws_buflist_destroy_all_segments(&wsi->buflist); - lws_dll_lws_remove(&wsi->dll_buflist); - - if (wsi->role_ops->close_role) - wsi->role_ops->close_role(pt, wsi); - - /* tell the user it's all over for this guy */ - - if (lwsi_state_est_PRE_CLOSE(wsi) && !wsi->told_user_closed && - wsi->role_ops->close_cb[lwsi_role_server(wsi)]) { - const struct lws_protocols *pro = wsi->protocol; - - if (!wsi->protocol) - pro = &wsi->vhost->protocols[0]; - - if (!wsi->upgraded_to_http2 || !lwsi_role_client(wsi)) - /* - * The network wsi for a client h2 connection shouldn't - * call back for its role: the child stream connections - * own the role. Otherwise h2 will call back closed - * one too many times as the children do it and then - * the closing network stream. - */ - pro->callback(wsi, - wsi->role_ops->close_cb[lwsi_role_server(wsi)], - wsi->user_space, NULL, 0); - wsi->told_user_closed = 1; - } - -async_close: - wsi->socket_is_permanently_unusable = 1; - - if (wsi->context->event_loop_ops->wsi_logical_close) - if (wsi->context->event_loop_ops->wsi_logical_close(wsi)) - return; - - __lws_close_free_wsi_final(wsi); -} - -void -__lws_close_free_wsi_final(struct lws *wsi) -{ - int n; - - if (lws_socket_is_valid(wsi->desc.sockfd) && !lws_ssl_close(wsi)) { - n = compatible_close(wsi->desc.sockfd); - if (n) - lwsl_debug("closing: close ret %d\n", LWS_ERRNO); - - wsi->desc.sockfd = LWS_SOCK_INVALID; - } - - /* outermost destroy notification for wsi (user_space still intact) */ - if (wsi->vhost) - wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_WSI_DESTROY, - wsi->user_space, NULL, 0); - -#ifdef LWS_WITH_CGI - if (wsi->http.cgi) { - - for (n = 0; n < 3; n++) { - if (wsi->http.cgi->pipe_fds[n][!!(n == 0)] == 0) - lwsl_err("ZERO FD IN CGI CLOSE"); - - if (wsi->http.cgi->pipe_fds[n][!!(n == 0)] >= 0) - close(wsi->http.cgi->pipe_fds[n][!!(n == 0)]); - } - - lws_free(wsi->http.cgi); - } -#endif - - __lws_free_wsi(wsi); -} - - -void -lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason, const char *caller) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - - lws_pt_lock(pt, __func__); - __lws_close_free_wsi(wsi, reason, caller); - lws_pt_unlock(pt); -} - -/* lws_buflist */ - -int -lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf, - size_t len) -{ - struct lws_buflist *nbuf; - int first = !*head; - void *p = *head; - int sanity = 1024; - - assert(buf); - assert(len); - - /* append at the tail */ - while (*head) { - if (!--sanity || head == &((*head)->next)) { - lwsl_err("%s: corrupt list points to self\n", __func__); - return -1; - } - head = &((*head)->next); - } - - lwsl_info("%s: len %u first %d %p\n", __func__, (uint32_t)len, first, p); - - nbuf = (struct lws_buflist *) - lws_malloc(sizeof(**head) + len, __func__); - if (!nbuf) { - lwsl_err("%s: OOM\n", __func__); - return -1; - } - - nbuf->len = len; - nbuf->pos = 0; - nbuf->next = NULL; - - p = (void *)nbuf->buf; - memcpy(p, buf, len); - - *head = nbuf; - - return first; /* returns 1 if first segment just created */ -} - -static int -lws_buflist_destroy_segment(struct lws_buflist **head) -{ - struct lws_buflist *old = *head; - - assert(*head); - *head = (*head)->next; - old->next = NULL; - lws_free(old); - - return !*head; /* returns 1 if last segment just destroyed */ -} - -void -lws_buflist_destroy_all_segments(struct lws_buflist **head) -{ - struct lws_buflist *p = *head, *p1; - - while (p) { - p1 = p->next; - p->next = NULL; - lws_free(p); - p = p1; - } - - *head = NULL; -} - -size_t -lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf) -{ - if (!*head) { - if (buf) - *buf = NULL; - - return 0; - } - - if (!(*head)->len && (*head)->next) - lws_buflist_destroy_segment(head); - - if (!*head) { - if (buf) - *buf = NULL; - - return 0; - } - - assert((*head)->pos < (*head)->len); - - if (buf) - *buf = (*head)->buf + (*head)->pos; - - return (*head)->len - (*head)->pos; -} - -int -lws_buflist_use_segment(struct lws_buflist **head, size_t len) -{ - assert(*head); - assert(len); - assert((*head)->pos + len <= (*head)->len); - - (*head)->pos += len; - if ((*head)->pos == (*head)->len) - lws_buflist_destroy_segment(head); - - if (!*head) - return 0; - - return (int)((*head)->len - (*head)->pos); -} - -void -lws_buflist_describe(struct lws_buflist **head, void *id) -{ - struct lws_buflist *old; - int n = 0; - - if (*head == NULL) - lwsl_notice("%p: buflist empty\n", id); - - while (*head) { - lwsl_notice("%p: %d: %llu / %llu (%llu left)\n", id, n, - (unsigned long long)(*head)->pos, - (unsigned long long)(*head)->len, - (unsigned long long)(*head)->len - (*head)->pos); - old = *head; - head = &((*head)->next); - if (*head == old) { - lwsl_err("%s: next points to self\n", __func__); - break; - } - n++; - } -} - -/* ... */ - -LWS_VISIBLE LWS_EXTERN const char * -lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len) -{ - int n = 0, sl = (int)strlen(name); - - while (lws_hdr_copy_fragment(wsi, buf, len, - WSI_TOKEN_HTTP_URI_ARGS, n) >= 0) { - - if (!strncmp(buf, name, sl)) - return buf + sl; - - n++; - } - - return NULL; -} - -#if !defined(LWS_WITH_ESP32) -LWS_VISIBLE int -interface_to_sa(struct lws_vhost *vh, const char *ifname, - struct sockaddr_in *addr, size_t addrlen) -{ - int ipv6 = 0; -#ifdef LWS_WITH_IPV6 - ipv6 = LWS_IPV6_ENABLED(vh); -#endif - (void)vh; - - return lws_interface_to_sa(ipv6, ifname, addr, addrlen); -} -#endif - -#ifndef LWS_PLAT_OPTEE -static int -lws_get_addresses(struct lws_vhost *vh, void *ads, char *name, - int name_len, char *rip, int rip_len) -{ - struct addrinfo ai, *res; - struct sockaddr_in addr4; - - rip[0] = '\0'; - name[0] = '\0'; - addr4.sin_family = AF_UNSPEC; - -#ifdef LWS_WITH_IPV6 - if (LWS_IPV6_ENABLED(vh)) { - if (!lws_plat_inet_ntop(AF_INET6, - &((struct sockaddr_in6 *)ads)->sin6_addr, - rip, rip_len)) { - lwsl_err("inet_ntop: %s", strerror(LWS_ERRNO)); - return -1; - } - - // Strip off the IPv4 to IPv6 header if one exists - if (strncmp(rip, "::ffff:", 7) == 0) - memmove(rip, rip + 7, strlen(rip) - 6); - - getnameinfo((struct sockaddr *)ads, sizeof(struct sockaddr_in6), - name, name_len, NULL, 0, 0); - - return 0; - } else -#endif - { - struct addrinfo *result; - - memset(&ai, 0, sizeof ai); - ai.ai_family = PF_UNSPEC; - ai.ai_socktype = SOCK_STREAM; -#if !defined(LWS_WITH_ESP32) - if (getnameinfo((struct sockaddr *)ads, - sizeof(struct sockaddr_in), - name, name_len, NULL, 0, 0)) - return -1; -#endif - - if (getaddrinfo(name, NULL, &ai, &result)) - return -1; - - res = result; - while (addr4.sin_family == AF_UNSPEC && res) { - switch (res->ai_family) { - case AF_INET: - addr4.sin_addr = - ((struct sockaddr_in *)res->ai_addr)->sin_addr; - addr4.sin_family = AF_INET; - break; - } - - res = res->ai_next; - } - freeaddrinfo(result); - } - - if (addr4.sin_family == AF_UNSPEC) - return -1; - - if (lws_plat_inet_ntop(AF_INET, &addr4.sin_addr, rip, rip_len) == NULL) - return -1; - - return 0; -} - - -LWS_VISIBLE const char * -lws_get_peer_simple(struct lws *wsi, char *name, int namelen) -{ - socklen_t len, olen; -#ifdef LWS_WITH_IPV6 - struct sockaddr_in6 sin6; -#endif - struct sockaddr_in sin4; - int af = AF_INET; - void *p, *q; - - wsi = lws_get_network_wsi(wsi); - - if (wsi->parent_carries_io) - wsi = wsi->parent; - -#ifdef LWS_WITH_IPV6 - if (LWS_IPV6_ENABLED(wsi->vhost)) { - len = sizeof(sin6); - p = &sin6; - af = AF_INET6; - q = &sin6.sin6_addr; - } else -#endif - { - len = sizeof(sin4); - p = &sin4; - q = &sin4.sin_addr; - } - - olen = len; - if (getpeername(wsi->desc.sockfd, p, &len) < 0 || len > olen) { - lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO)); - return NULL; - } - - return lws_plat_inet_ntop(af, q, name, namelen); -} -#endif - -LWS_VISIBLE void -lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name, - int name_len, char *rip, int rip_len) -{ -#ifndef LWS_PLAT_OPTEE - socklen_t len; -#ifdef LWS_WITH_IPV6 - struct sockaddr_in6 sin6; -#endif - struct sockaddr_in sin4; - struct lws_context *context = wsi->context; - int ret = -1; - void *p; - - rip[0] = '\0'; - name[0] = '\0'; - - lws_latency_pre(context, wsi); - -#ifdef LWS_WITH_IPV6 - if (LWS_IPV6_ENABLED(wsi->vhost)) { - len = sizeof(sin6); - p = &sin6; - } else -#endif - { - len = sizeof(sin4); - p = &sin4; - } - - if (getpeername(fd, p, &len) < 0) { - lwsl_warn("getpeername: %s\n", strerror(LWS_ERRNO)); - goto bail; - } - - ret = lws_get_addresses(wsi->vhost, p, name, name_len, rip, rip_len); - -bail: - lws_latency(context, wsi, "lws_get_peer_addresses", ret, 1); -#endif - (void)wsi; - (void)fd; - (void)name; - (void)name_len; - (void)rip; - (void)rip_len; - -} - -LWS_EXTERN void * -lws_vhost_user(struct lws_vhost *vhost) -{ - return vhost->user; -} - -LWS_EXTERN void * -lws_context_user(struct lws_context *context) -{ - return context->user_space; -} - -LWS_VISIBLE struct lws_vhost * -lws_vhost_get(struct lws *wsi) -{ - return wsi->vhost; -} - -LWS_VISIBLE struct lws_vhost * -lws_get_vhost(struct lws *wsi) -{ - return wsi->vhost; -} - -LWS_VISIBLE const struct lws_protocols * -lws_protocol_get(struct lws *wsi) -{ - return wsi->protocol; -} - -LWS_VISIBLE const struct lws_udp * -lws_get_udp(const struct lws *wsi) -{ - return wsi->udp; -} - -LWS_VISIBLE struct lws * -lws_get_network_wsi(struct lws *wsi) -{ - if (!wsi) - return NULL; - -#if defined(LWS_WITH_HTTP2) - if (!wsi->http2_substream && !wsi->client_h2_substream) - return wsi; - - while (wsi->h2.parent_wsi) - wsi = wsi->h2.parent_wsi; -#endif - - return wsi; -} - -LWS_VISIBLE LWS_EXTERN const struct lws_protocols * -lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name) -{ - int n; - - for (n = 0; n < vh->count_protocols; n++) - if (!strcmp(name, vh->protocols[n].name)) - return &vh->protocols[n]; - - return NULL; -} - -LWS_VISIBLE int -lws_callback_all_protocol(struct lws_context *context, - const struct lws_protocols *protocol, int reason) -{ - struct lws_context_per_thread *pt = &context->pt[0]; - unsigned int n, m = context->count_threads; - struct lws *wsi; - - while (m--) { - for (n = 0; n < pt->fds_count; n++) { - wsi = wsi_from_fd(context, pt->fds[n].fd); - if (!wsi) - continue; - if (wsi->protocol == protocol) - protocol->callback(wsi, reason, wsi->user_space, - NULL, 0); - } - pt++; - } - - return 0; -} - -LWS_VISIBLE int -lws_callback_all_protocol_vhost_args(struct lws_vhost *vh, - const struct lws_protocols *protocol, int reason, - void *argp, size_t len) -{ - struct lws_context *context = vh->context; - struct lws_context_per_thread *pt = &context->pt[0]; - unsigned int n, m = context->count_threads; - struct lws *wsi; - - while (m--) { - for (n = 0; n < pt->fds_count; n++) { - wsi = wsi_from_fd(context, pt->fds[n].fd); - if (!wsi) - continue; - if (wsi->vhost == vh && (wsi->protocol == protocol || - !protocol)) - wsi->protocol->callback(wsi, reason, - wsi->user_space, argp, len); - } - pt++; - } - - return 0; -} - -LWS_VISIBLE int -lws_callback_all_protocol_vhost(struct lws_vhost *vh, - const struct lws_protocols *protocol, int reason) -{ - return lws_callback_all_protocol_vhost_args(vh, protocol, reason, NULL, 0); -} - -LWS_VISIBLE LWS_EXTERN int -lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len) -{ - int n; - - for (n = 0; n < wsi->vhost->count_protocols; n++) - if (wsi->vhost->protocols[n].callback(wsi, reason, NULL, in, len)) - return 1; - - return 0; -} - -LWS_VISIBLE LWS_EXTERN int -lws_callback_vhost_protocols_vhost(struct lws_vhost *vh, int reason, void *in, - size_t len) -{ - int n; - struct lws *wsi = lws_zalloc(sizeof(*wsi), "fake wsi"); - - wsi->context = vh->context; - wsi->vhost = vh; - - for (n = 0; n < wsi->vhost->count_protocols; n++) { - wsi->protocol = &vh->protocols[n]; - if (wsi->protocol->callback(wsi, reason, NULL, in, len)) { - lws_free(wsi); - return 1; - } - } - - lws_free(wsi); - - return 0; -} - -LWS_VISIBLE LWS_EXTERN void -lws_set_fops(struct lws_context *context, const struct lws_plat_file_ops *fops) -{ - context->fops = fops; -} - -LWS_VISIBLE LWS_EXTERN lws_filepos_t -lws_vfs_tell(lws_fop_fd_t fop_fd) -{ - return fop_fd->pos; -} - -LWS_VISIBLE LWS_EXTERN lws_filepos_t -lws_vfs_get_length(lws_fop_fd_t fop_fd) -{ - return fop_fd->len; -} - -LWS_VISIBLE LWS_EXTERN uint32_t -lws_vfs_get_mod_time(lws_fop_fd_t fop_fd) -{ - return fop_fd->mod_time; -} - -LWS_VISIBLE lws_fileofs_t -lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset) -{ - lws_fileofs_t ofs; - - ofs = fop_fd->fops->LWS_FOP_SEEK_CUR(fop_fd, offset - fop_fd->pos); - - return ofs; -} - - -LWS_VISIBLE lws_fileofs_t -lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset) -{ - return fop_fd->fops->LWS_FOP_SEEK_CUR(fop_fd, fop_fd->len + - fop_fd->pos + offset); -} - - -const struct lws_plat_file_ops * -lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path, - const char **vpath) -{ - const struct lws_plat_file_ops *pf; - const char *p = vfs_path; - int n; - - *vpath = NULL; - - /* no non-platform fops, just use that */ - - if (!fops->next) - return fops; - - /* - * scan the vfs path looking for indications we are to be - * handled by a specific fops - */ - - while (p && *p) { - if (*p != '/') { - p++; - continue; - } - /* the first one is always platform fops, so skip */ - pf = fops->next; - while (pf) { - n = 0; - while (n < (int)LWS_ARRAY_SIZE(pf->fi) && pf->fi[n].sig) { - if (p >= vfs_path + pf->fi[n].len) - if (!strncmp(p - (pf->fi[n].len - 1), - pf->fi[n].sig, - pf->fi[n].len - 1)) { - *vpath = p + 1; - return pf; - } - - n++; - } - pf = pf->next; - } - p++; - } - - return fops; -} - -LWS_VISIBLE LWS_EXTERN lws_fop_fd_t LWS_WARN_UNUSED_RESULT -lws_vfs_file_open(const struct lws_plat_file_ops *fops, const char *vfs_path, - lws_fop_flags_t *flags) -{ - const char *vpath = ""; - const struct lws_plat_file_ops *selected; - - selected = lws_vfs_select_fops(fops, vfs_path, &vpath); - - return selected->LWS_FOP_OPEN(fops, vfs_path, vpath, flags); -} - - -/** - * lws_now_secs() - seconds since 1970-1-1 - * - */ -LWS_VISIBLE LWS_EXTERN unsigned long -lws_now_secs(void) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - - return tv.tv_sec; -} - -LWS_VISIBLE LWS_EXTERN int -lws_compare_time_t(struct lws_context *context, time_t t1, time_t t2) -{ - if (t1 < context->time_discontiguity) - t1 += context->time_fixup; - - if (t2 < context->time_discontiguity) - t2 += context->time_fixup; - - return (int)(t1 - t2); -} - -LWS_VISIBLE lws_sockfd_type -lws_get_socket_fd(struct lws *wsi) -{ - if (!wsi) - return -1; - return wsi->desc.sockfd; -} - -#ifdef LWS_LATENCY -void -lws_latency(struct lws_context *context, struct lws *wsi, const char *action, - int ret, int completed) -{ - unsigned long long u; - char buf[256]; - - u = time_in_microseconds(); - - if (!action) { - wsi->latency_start = u; - if (!wsi->action_start) - wsi->action_start = u; - return; - } - if (completed) { - if (wsi->action_start == wsi->latency_start) - sprintf(buf, - "Completion first try lat %lluus: %p: ret %d: %s\n", - u - wsi->latency_start, - (void *)wsi, ret, action); - else - sprintf(buf, - "Completion %lluus: lat %lluus: %p: ret %d: %s\n", - u - wsi->action_start, - u - wsi->latency_start, - (void *)wsi, ret, action); - wsi->action_start = 0; - } else - sprintf(buf, "lat %lluus: %p: ret %d: %s\n", - u - wsi->latency_start, (void *)wsi, ret, action); - - if (u - wsi->latency_start > context->worst_latency) { - context->worst_latency = u - wsi->latency_start; - strcpy(context->worst_latency_info, buf); - } - lwsl_latency("%s", buf); -} -#endif - -LWS_VISIBLE int -lws_rx_flow_control(struct lws *wsi, int _enable) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - int en = _enable; - - // h2 ignores rx flow control atm - if (lwsi_role_h2(wsi) || wsi->http2_substream || - lwsi_role_h2_ENCAPSULATION(wsi)) - return 0; // !!! - - lwsl_info("%s: %p 0x%x\n", __func__, wsi, _enable); - - if (!(_enable & LWS_RXFLOW_REASON_APPLIES)) { - /* - * convert user bool style to bitmap style... in user simple - * bool style _enable = 0 = flow control it, = 1 = allow rx - */ - en = LWS_RXFLOW_REASON_APPLIES | LWS_RXFLOW_REASON_USER_BOOL; - if (_enable & 1) - en |= LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT; - } - - lws_pt_lock(pt, __func__); - - /* any bit set in rxflow_bitmap DISABLEs rxflow control */ - if (en & LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT) - wsi->rxflow_bitmap &= ~(en & 0xff); - else - wsi->rxflow_bitmap |= en & 0xff; - - if ((LWS_RXFLOW_PENDING_CHANGE | (!wsi->rxflow_bitmap)) == - wsi->rxflow_change_to) - goto skip; - - wsi->rxflow_change_to = LWS_RXFLOW_PENDING_CHANGE | !wsi->rxflow_bitmap; - - lwsl_info("%s: %p: bitmap 0x%x: en 0x%x, ch 0x%x\n", __func__, wsi, - wsi->rxflow_bitmap, en, wsi->rxflow_change_to); - - if (_enable & LWS_RXFLOW_REASON_FLAG_PROCESS_NOW || - !wsi->rxflow_will_be_applied) { - en = __lws_rx_flow_control(wsi); - lws_pt_unlock(pt); - - return en; - } - -skip: - lws_pt_unlock(pt); - - return 0; -} - -LWS_VISIBLE void -lws_rx_flow_allow_all_protocol(const struct lws_context *context, - const struct lws_protocols *protocol) -{ - const struct lws_context_per_thread *pt = &context->pt[0]; - struct lws *wsi; - unsigned int n, m = context->count_threads; - - while (m--) { - for (n = 0; n < pt->fds_count; n++) { - wsi = wsi_from_fd(context, pt->fds[n].fd); - if (!wsi) - continue; - if (wsi->protocol == protocol) - lws_rx_flow_control(wsi, LWS_RXFLOW_ALLOW); - } - pt++; - } -} - -int -lws_broadcast(struct lws_context *context, int reason, void *in, size_t len) -{ - struct lws_vhost *v = context->vhost_list; - struct lws wsi; - int n, ret = 0; - - memset(&wsi, 0, sizeof(wsi)); - wsi.context = context; - - while (v) { - const struct lws_protocols *p = v->protocols; - wsi.vhost = v; - - for (n = 0; n < v->count_protocols; n++) { - wsi.protocol = p; - if (p->callback && - p->callback(&wsi, reason, NULL, in, len)) - ret |= 1; - p++; - } - v = v->vhost_next; - } - - return ret; -} - -LWS_VISIBLE extern const char * -lws_canonical_hostname(struct lws_context *context) -{ - return (const char *)context->canonical_hostname; -} - -LWS_VISIBLE LWS_EXTERN const char * -lws_get_vhost_name(struct lws_vhost *vhost) -{ - return vhost->name; -} - -LWS_VISIBLE LWS_EXTERN int -lws_get_vhost_port(struct lws_vhost *vhost) -{ - return vhost->listen_port; -} - -LWS_VISIBLE LWS_EXTERN void * -lws_get_vhost_user(struct lws_vhost *vhost) -{ - return vhost->user; -} - -LWS_VISIBLE LWS_EXTERN const char * -lws_get_vhost_iface(struct lws_vhost *vhost) -{ - return vhost->iface; -} - -int user_callback_handle_rxflow(lws_callback_function callback_function, - struct lws *wsi, - enum lws_callback_reasons reason, void *user, - void *in, size_t len) -{ - int n; - - wsi->rxflow_will_be_applied = 1; - n = callback_function(wsi, reason, user, in, len); - wsi->rxflow_will_be_applied = 0; - if (!n) - n = __lws_rx_flow_control(wsi); - - return n; -} - -#if !defined(LWS_WITHOUT_CLIENT) -LWS_VISIBLE int -lws_set_proxy(struct lws_vhost *vhost, const char *proxy) -{ - char *p; - char authstring[96]; - - if (!proxy) - return -1; - - /* we have to deal with a possible redundant leading http:// */ - if (!strncmp(proxy, "http://", 7)) - proxy += 7; - - p = strrchr(proxy, '@'); - if (p) { /* auth is around */ - - if ((unsigned int)(p - proxy) > sizeof(authstring) - 1) - goto auth_too_long; - - lws_strncpy(authstring, proxy, p - proxy + 1); - // null termination not needed on input - if (lws_b64_encode_string(authstring, lws_ptr_diff(p, proxy), - vhost->proxy_basic_auth_token, - sizeof vhost->proxy_basic_auth_token) < 0) - goto auth_too_long; - - lwsl_info(" Proxy auth in use\n"); - - proxy = p + 1; - } else - vhost->proxy_basic_auth_token[0] = '\0'; - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - lws_strncpy(vhost->http.http_proxy_address, proxy, - sizeof(vhost->http.http_proxy_address)); - - p = strchr(vhost->http.http_proxy_address, ':'); - if (!p && !vhost->http.http_proxy_port) { - lwsl_err("http_proxy needs to be ads:port\n"); - - return -1; - } else { - if (p) { - *p = '\0'; - vhost->http.http_proxy_port = atoi(p + 1); - } - } - - lwsl_info(" Proxy %s:%u\n", vhost->http.http_proxy_address, - vhost->http.http_proxy_port); -#endif - return 0; - -auth_too_long: - lwsl_err("proxy auth too long\n"); - - return -1; -} -#endif - -#if defined(LWS_WITH_SOCKS5) -LWS_VISIBLE int -lws_set_socks(struct lws_vhost *vhost, const char *socks) -{ - char *p_at, *p_colon; - char user[96]; - char password[96]; - - if (!socks) - return -1; - - vhost->socks_user[0] = '\0'; - vhost->socks_password[0] = '\0'; - - p_at = strrchr(socks, '@'); - if (p_at) { /* auth is around */ - if ((unsigned int)(p_at - socks) > (sizeof(user) - + sizeof(password) - 2)) { - lwsl_err("Socks auth too long\n"); - goto bail; - } - - p_colon = strchr(socks, ':'); - if (p_colon) { - if ((unsigned int)(p_colon - socks) > (sizeof(user) - - 1) ) { - lwsl_err("Socks user too long\n"); - goto bail; - } - if ((unsigned int)(p_at - p_colon) > (sizeof(password) - - 1) ) { - lwsl_err("Socks password too long\n"); - goto bail; - } - - lws_strncpy(vhost->socks_user, socks, p_colon - socks + 1); - lws_strncpy(vhost->socks_password, p_colon + 1, - p_at - (p_colon + 1) + 1); - } - - lwsl_info(" Socks auth, user: %s, password: %s\n", - vhost->socks_user, vhost->socks_password ); - - socks = p_at + 1; - } - - lws_strncpy(vhost->socks_proxy_address, socks, - sizeof(vhost->socks_proxy_address)); - - p_colon = strchr(vhost->socks_proxy_address, ':'); - if (!p_colon && !vhost->socks_proxy_port) { - lwsl_err("socks_proxy needs to be address:port\n"); - return -1; - } else { - if (p_colon) { - *p_colon = '\0'; - vhost->socks_proxy_port = atoi(p_colon + 1); - } - } - - lwsl_info(" Socks %s:%u\n", vhost->socks_proxy_address, - vhost->socks_proxy_port); - - return 0; - -bail: - return -1; -} -#endif - -LWS_VISIBLE const struct lws_protocols * -lws_get_protocol(struct lws *wsi) -{ - return wsi->protocol; -} - - -int -lws_ensure_user_space(struct lws *wsi) -{ - if (!wsi->protocol) - return 0; - - /* allocate the per-connection user memory (if any) */ - - if (wsi->protocol->per_session_data_size && !wsi->user_space) { - wsi->user_space = lws_zalloc( - wsi->protocol->per_session_data_size, "user space"); - if (wsi->user_space == NULL) { - lwsl_err("%s: OOM\n", __func__); - return 1; - } - } else - lwsl_debug("%s: %p protocol pss %lu, user_space=%p\n", __func__, - wsi, (long)wsi->protocol->per_session_data_size, - wsi->user_space); - return 0; -} - -LWS_VISIBLE void * -lws_adjust_protocol_psds(struct lws *wsi, size_t new_size) -{ - ((struct lws_protocols *)lws_get_protocol(wsi))->per_session_data_size = - new_size; - - if (lws_ensure_user_space(wsi)) - return NULL; - - return wsi->user_space; -} - -LWS_VISIBLE int -lwsl_timestamp(int level, char *p, int len) -{ -#ifndef LWS_PLAT_OPTEE - time_t o_now = time(NULL); - unsigned long long now; - struct tm *ptm = NULL; -#ifndef WIN32 - struct tm tm; -#endif - int n; - -#ifndef _WIN32_WCE -#ifdef WIN32 - ptm = localtime(&o_now); -#else - if (localtime_r(&o_now, &tm)) - ptm = &tm; -#endif -#endif - p[0] = '\0'; - for (n = 0; n < LLL_COUNT; n++) { - if (level != (1 << n)) - continue; - now = time_in_microseconds() / 100; - if (ptm) - n = lws_snprintf(p, len, - "[%04d/%02d/%02d %02d:%02d:%02d:%04d] %s: ", - ptm->tm_year + 1900, - ptm->tm_mon + 1, - ptm->tm_mday, - ptm->tm_hour, - ptm->tm_min, - ptm->tm_sec, - (int)(now % 10000), log_level_names[n]); - else - n = lws_snprintf(p, len, "[%llu:%04d] %s: ", - (unsigned long long) now / 10000, - (int)(now % 10000), log_level_names[n]); - return n; - } -#else - p[0] = '\0'; -#endif - - return 0; -} - -#ifndef LWS_PLAT_OPTEE -static const char * const colours[] = { - "[31;1m", /* LLL_ERR */ - "[36;1m", /* LLL_WARN */ - "[35;1m", /* LLL_NOTICE */ - "[32;1m", /* LLL_INFO */ - "[34;1m", /* LLL_DEBUG */ - "[33;1m", /* LLL_PARSER */ - "[33m", /* LLL_HEADER */ - "[33m", /* LLL_EXT */ - "[33m", /* LLL_CLIENT */ - "[33;1m", /* LLL_LATENCY */ - "[30;1m", /* LLL_USER */ -}; - -LWS_VISIBLE void lwsl_emit_stderr(int level, const char *line) -{ - char buf[50]; - static char tty = 3; - int n, m = LWS_ARRAY_SIZE(colours) - 1; - - if (!tty) - tty = isatty(2) | 2; - lwsl_timestamp(level, buf, sizeof(buf)); - - if (tty == 3) { - n = 1 << (LWS_ARRAY_SIZE(colours) - 1); - while (n) { - if (level & n) - break; - m--; - n >>= 1; - } - fprintf(stderr, "%c%s%s%s%c[0m", 27, colours[m], buf, line, 27); - } else - fprintf(stderr, "%s%s", buf, line); -} -#endif - -LWS_VISIBLE void _lws_logv(int filter, const char *format, va_list vl) -{ - char buf[256]; - int n; - - if (!(log_level & filter)) - return; - - n = vsnprintf(buf, sizeof(buf) - 1, format, vl); - (void)n; - /* vnsprintf returns what it would have written, even if truncated */ - if (n > (int)sizeof(buf) - 1) - n = sizeof(buf) - 1; - if (n > 0) - buf[n] = '\0'; - - lwsl_emit(filter, buf); -} - -LWS_VISIBLE void _lws_log(int filter, const char *format, ...) -{ - va_list ap; - - va_start(ap, format); - _lws_logv(filter, format, ap); - va_end(ap); -} - -LWS_VISIBLE void lws_set_log_level(int level, - void (*func)(int level, const char *line)) -{ - log_level = level; - if (func) - lwsl_emit = func; -} - -LWS_VISIBLE int lwsl_visible(int level) -{ - return log_level & level; -} - -LWS_VISIBLE void -lwsl_hexdump_level(int hexdump_level, const void *vbuf, size_t len) -{ - unsigned char *buf = (unsigned char *)vbuf; - unsigned int n, m, start; - char line[80]; - char *p; - - if (!lwsl_visible(hexdump_level)) - return; - - if (!len) - return; - - if (!vbuf) - return; - - _lws_log(hexdump_level, "\n"); - - for (n = 0; n < len;) { - start = n; - p = line; - - p += sprintf(p, "%04X: ", start); - - for (m = 0; m < 16 && n < len; m++) - p += sprintf(p, "%02X ", buf[n++]); - while (m++ < 16) - p += sprintf(p, " "); - - p += sprintf(p, " "); - - for (m = 0; m < 16 && (start + m) < len; m++) { - if (buf[start + m] >= ' ' && buf[start + m] < 127) - *p++ = buf[start + m]; - else - *p++ = '.'; - } - while (m++ < 16) - *p++ = ' '; - - *p++ = '\n'; - *p = '\0'; - _lws_log(hexdump_level, "%s", line); - (void)line; - } - - _lws_log(hexdump_level, "\n"); -} - -LWS_VISIBLE void -lwsl_hexdump(const void *vbuf, size_t len) -{ -#if defined(_DEBUG) - lwsl_hexdump_level(LLL_DEBUG, vbuf, len); -#endif -} - -LWS_VISIBLE int -lws_is_ssl(struct lws *wsi) -{ -#if defined(LWS_WITH_TLS) - return wsi->tls.use_ssl & LCCSCF_USE_SSL; -#else - (void)wsi; - return 0; -#endif -} - -#if defined(LWS_WITH_TLS) && !defined(LWS_WITH_MBEDTLS) -LWS_VISIBLE lws_tls_conn* -lws_get_ssl(struct lws *wsi) -{ - return wsi->tls.ssl; -} -#endif - -LWS_VISIBLE int -lws_partial_buffered(struct lws *wsi) -{ - return !!wsi->trunc_len; -} - -LWS_VISIBLE lws_fileofs_t -lws_get_peer_write_allowance(struct lws *wsi) -{ - if (!wsi->role_ops->tx_credit) - return -1; - return wsi->role_ops->tx_credit(wsi); -} - -LWS_VISIBLE void -lws_role_transition(struct lws *wsi, enum lwsi_role role, enum lwsi_state state, - struct lws_role_ops *ops) -{ -#if defined(_DEBUG) - const char *name = "(unset)"; -#endif - wsi->wsistate = role | state; - if (ops) - wsi->role_ops = ops; -#if defined(_DEBUG) - if (wsi->role_ops) - name = wsi->role_ops->name; - lwsl_debug("%s: %p: wsistate 0x%x, ops %s\n", __func__, wsi, - wsi->wsistate, name); -#endif -} - -LWS_VISIBLE struct lws_plat_file_ops * -lws_get_fops(struct lws_context *context) -{ - return (struct lws_plat_file_ops *)context->fops; -} - -LWS_VISIBLE LWS_EXTERN struct lws_context * -lws_get_context(const struct lws *wsi) -{ - return wsi->context; -} - -LWS_VISIBLE LWS_EXTERN int -lws_get_count_threads(struct lws_context *context) -{ - return context->count_threads; -} - -LWS_VISIBLE LWS_EXTERN void * -lws_wsi_user(struct lws *wsi) -{ - return wsi->user_space; -} - -LWS_VISIBLE LWS_EXTERN void -lws_set_wsi_user(struct lws *wsi, void *data) -{ - if (wsi->user_space_externally_allocated) - wsi->user_space = data; - else - lwsl_err("%s: Cannot set internally-allocated user_space\n", - __func__); -} - -LWS_VISIBLE LWS_EXTERN struct lws * -lws_get_parent(const struct lws *wsi) -{ - return wsi->parent; -} - -LWS_VISIBLE LWS_EXTERN struct lws * -lws_get_child(const struct lws *wsi) -{ - return wsi->child_list; -} - -LWS_VISIBLE LWS_EXTERN void -lws_set_parent_carries_io(struct lws *wsi) -{ - wsi->parent_carries_io = 1; -} - -LWS_VISIBLE LWS_EXTERN void * -lws_get_opaque_parent_data(const struct lws *wsi) -{ - return wsi->opaque_parent_data; -} - -LWS_VISIBLE LWS_EXTERN void -lws_set_opaque_parent_data(struct lws *wsi, void *data) -{ - wsi->opaque_parent_data = data; -} - -LWS_VISIBLE LWS_EXTERN int -lws_get_child_pending_on_writable(const struct lws *wsi) -{ - return wsi->parent_pending_cb_on_writable; -} - -LWS_VISIBLE LWS_EXTERN void -lws_clear_child_pending_on_writable(struct lws *wsi) -{ - wsi->parent_pending_cb_on_writable = 0; -} - - -LWS_EXTERN int -__lws_rx_flow_control(struct lws *wsi) -{ - struct lws *wsic = wsi->child_list; - - // h2 ignores rx flow control atm - if (lwsi_role_h2(wsi) || wsi->http2_substream || - lwsi_role_h2_ENCAPSULATION(wsi)) - return 0; // !!! - - /* if he has children, do those if they were changed */ - while (wsic) { - if (wsic->rxflow_change_to & LWS_RXFLOW_PENDING_CHANGE) - __lws_rx_flow_control(wsic); - - wsic = wsic->sibling_list; - } - - /* there is no pending change */ - if (!(wsi->rxflow_change_to & LWS_RXFLOW_PENDING_CHANGE)) - return 0; - - /* stuff is still buffered, not ready to really accept new input */ - if (lws_buflist_next_segment_len(&wsi->buflist, NULL)) { - /* get ourselves called back to deal with stashed buffer */ - lws_callback_on_writable(wsi); - return 0; - } - - /* now the pending is cleared, we can change rxflow state */ - - wsi->rxflow_change_to &= ~LWS_RXFLOW_PENDING_CHANGE; - - lwsl_info("rxflow: wsi %p change_to %d\n", wsi, - wsi->rxflow_change_to & LWS_RXFLOW_ALLOW); - - /* adjust the pollfd for this wsi */ - - if (wsi->rxflow_change_to & LWS_RXFLOW_ALLOW) { - if (__lws_change_pollfd(wsi, 0, LWS_POLLIN)) { - lwsl_info("%s: fail\n", __func__); - return -1; - } - } else - if (__lws_change_pollfd(wsi, LWS_POLLIN, 0)) - return -1; - - return 0; -} - -LWS_EXTERN int -lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len) -{ - static const unsigned char e0f4[] = { - 0xa0 | ((2 - 1) << 2) | 1, /* e0 */ - 0x80 | ((4 - 1) << 2) | 1, /* e1 */ - 0x80 | ((4 - 1) << 2) | 1, /* e2 */ - 0x80 | ((4 - 1) << 2) | 1, /* e3 */ - 0x80 | ((4 - 1) << 2) | 1, /* e4 */ - 0x80 | ((4 - 1) << 2) | 1, /* e5 */ - 0x80 | ((4 - 1) << 2) | 1, /* e6 */ - 0x80 | ((4 - 1) << 2) | 1, /* e7 */ - 0x80 | ((4 - 1) << 2) | 1, /* e8 */ - 0x80 | ((4 - 1) << 2) | 1, /* e9 */ - 0x80 | ((4 - 1) << 2) | 1, /* ea */ - 0x80 | ((4 - 1) << 2) | 1, /* eb */ - 0x80 | ((4 - 1) << 2) | 1, /* ec */ - 0x80 | ((2 - 1) << 2) | 1, /* ed */ - 0x80 | ((4 - 1) << 2) | 1, /* ee */ - 0x80 | ((4 - 1) << 2) | 1, /* ef */ - 0x90 | ((3 - 1) << 2) | 2, /* f0 */ - 0x80 | ((4 - 1) << 2) | 2, /* f1 */ - 0x80 | ((4 - 1) << 2) | 2, /* f2 */ - 0x80 | ((4 - 1) << 2) | 2, /* f3 */ - 0x80 | ((1 - 1) << 2) | 2, /* f4 */ - - 0, /* s0 */ - 0x80 | ((4 - 1) << 2) | 0, /* s2 */ - 0x80 | ((4 - 1) << 2) | 1, /* s3 */ - }; - unsigned char s = *state; - - while (len--) { - unsigned char c = *buf++; - - if (!s) { - if (c >= 0x80) { - if (c < 0xc2 || c > 0xf4) - return 1; - if (c < 0xe0) - s = 0x80 | ((4 - 1) << 2); - else - s = e0f4[c - 0xe0]; - } - } else { - if (c < (s & 0xf0) || - c >= (s & 0xf0) + 0x10 + ((s << 2) & 0x30)) - return 1; - s = e0f4[21 + (s & 3)]; - } - } - - *state = s; - - return 0; -} - -LWS_VISIBLE LWS_EXTERN int -lws_parse_uri(char *p, const char **prot, const char **ads, int *port, - const char **path) -{ - const char *end; - static const char *slash = "/"; - - /* cut up the location into address, port and path */ - *prot = p; - while (*p && (*p != ':' || p[1] != '/' || p[2] != '/')) - p++; - if (!*p) { - end = p; - p = (char *)*prot; - *prot = end; - } else { - *p = '\0'; - p += 3; - } - *ads = p; - if (!strcmp(*prot, "http") || !strcmp(*prot, "ws")) - *port = 80; - else if (!strcmp(*prot, "https") || !strcmp(*prot, "wss")) - *port = 443; - - if (*p == '[') - { - ++(*ads); - while (*p && *p != ']') - p++; - if (*p) - *p++ = '\0'; - } - else - { - while (*p && *p != ':' && *p != '/') - p++; - } - if (*p == ':') { - *p++ = '\0'; - *port = atoi(p); - while (*p && *p != '/') - p++; - } - *path = slash; - if (*p) { - *p++ = '\0'; - if (*p) - *path = p; - } - - return 0; -} - -#if defined(LWS_WITHOUT_EXTENSIONS) - -/* we need to provide dummy callbacks for internal exts - * so user code runs when faced with a lib compiled with - * extensions disabled. - */ - -LWS_VISIBLE int -lws_extension_callback_pm_deflate(struct lws_context *context, - const struct lws_extension *ext, - struct lws *wsi, - enum lws_extension_callback_reasons reason, - void *user, void *in, size_t len) -{ - (void)context; - (void)ext; - (void)wsi; - (void)reason; - (void)user; - (void)in; - (void)len; - - return 0; -} - -LWS_EXTERN int -lws_set_extension_option(struct lws *wsi, const char *ext_name, - const char *opt_name, const char *opt_val) -{ - return -1; -} -#endif - -LWS_EXTERN int -lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port, - const char *iface) -{ -#ifdef LWS_WITH_UNIX_SOCK - struct sockaddr_un serv_unix; -#endif -#ifdef LWS_WITH_IPV6 - struct sockaddr_in6 serv_addr6; -#endif - struct sockaddr_in serv_addr4; -#ifndef LWS_PLAT_OPTEE - socklen_t len = sizeof(struct sockaddr_storage); -#endif - int n; -#if !defined(LWS_WITH_ESP32) - int m; -#endif - struct sockaddr_storage sin; - struct sockaddr *v; - -#ifdef LWS_WITH_UNIX_SOCK - if (LWS_UNIX_SOCK_ENABLED(vhost)) { - v = (struct sockaddr *)&serv_unix; - n = sizeof(struct sockaddr_un); - bzero((char *) &serv_unix, sizeof(serv_unix)); - serv_unix.sun_family = AF_UNIX; - if (!iface) - return -1; - if (sizeof(serv_unix.sun_path) <= strlen(iface)) { - lwsl_err("\"%s\" too long for UNIX domain socket\n", - iface); - return -1; - } - strcpy(serv_unix.sun_path, iface); - if (serv_unix.sun_path[0] == '@') - serv_unix.sun_path[0] = '\0'; - - } else -#endif -#if defined(LWS_WITH_IPV6) && !defined(LWS_WITH_ESP32) - if (LWS_IPV6_ENABLED(vhost)) { - v = (struct sockaddr *)&serv_addr6; - n = sizeof(struct sockaddr_in6); - bzero((char *) &serv_addr6, sizeof(serv_addr6)); - if (iface) { - m = interface_to_sa(vhost, iface, - (struct sockaddr_in *)v, n); - if (m == LWS_ITOSA_NOT_USABLE) { - lwsl_info("%s: netif %s: Not usable\n", - __func__, iface); - return m; - } - if (m == LWS_ITOSA_NOT_EXIST) { - lwsl_info("%s: netif %s: Does not exist\n", - __func__, iface); - return m; - } - serv_addr6.sin6_scope_id = lws_get_addr_scope(iface); - } - - serv_addr6.sin6_family = AF_INET6; - serv_addr6.sin6_port = htons(port); - } else -#endif - { - v = (struct sockaddr *)&serv_addr4; - n = sizeof(serv_addr4); - bzero((char *) &serv_addr4, sizeof(serv_addr4)); - serv_addr4.sin_addr.s_addr = INADDR_ANY; - serv_addr4.sin_family = AF_INET; -#if !defined(LWS_WITH_ESP32) - - if (iface) { - m = interface_to_sa(vhost, iface, - (struct sockaddr_in *)v, n); - if (m == LWS_ITOSA_NOT_USABLE) { - lwsl_info("%s: netif %s: Not usable\n", - __func__, iface); - return m; - } - if (m == LWS_ITOSA_NOT_EXIST) { - lwsl_info("%s: netif %s: Does not exist\n", - __func__, iface); - return m; - } - } -#endif - serv_addr4.sin_port = htons(port); - } /* ipv4 */ - - /* just checking for the interface extant */ - if (sockfd == LWS_SOCK_INVALID) - return 0; - - n = bind(sockfd, v, n); -#ifdef LWS_WITH_UNIX_SOCK - if (n < 0 && LWS_UNIX_SOCK_ENABLED(vhost)) { - lwsl_err("ERROR on binding fd %d to \"%s\" (%d %d)\n", - sockfd, iface, n, LWS_ERRNO); - return -1; - } else -#endif - if (n < 0) { - lwsl_err("ERROR on binding fd %d to port %d (%d %d)\n", - sockfd, port, n, LWS_ERRNO); - return -1; - } - -#ifndef LWS_PLAT_OPTEE - if (getsockname(sockfd, (struct sockaddr *)&sin, &len) == -1) - lwsl_warn("getsockname: %s\n", strerror(LWS_ERRNO)); - else -#endif -#if defined(LWS_WITH_IPV6) - port = (sin.ss_family == AF_INET6) ? - ntohs(((struct sockaddr_in6 *) &sin)->sin6_port) : - ntohs(((struct sockaddr_in *) &sin)->sin_port); -#else - { - struct sockaddr_in sain; - memcpy(&sain, &sin, sizeof(sain)); - port = ntohs(sain.sin_port); - } -#endif - - return port; -} - -LWS_VISIBLE LWS_EXTERN int -lws_get_vhost_listen_port(struct lws_vhost *vhost) -{ - return vhost->listen_port; -} - -#if defined(LWS_WITH_IPV6) -LWS_EXTERN unsigned long -lws_get_addr_scope(const char *ipaddr) -{ - unsigned long scope = 0; - -#ifndef WIN32 - struct ifaddrs *addrs, *addr; - char ip[NI_MAXHOST]; - unsigned int i; - - getifaddrs(&addrs); - for (addr = addrs; addr; addr = addr->ifa_next) { - if (!addr->ifa_addr || - addr->ifa_addr->sa_family != AF_INET6) - continue; - - getnameinfo(addr->ifa_addr, - sizeof(struct sockaddr_in6), - ip, sizeof(ip), - NULL, 0, NI_NUMERICHOST); - - i = 0; - while (ip[i]) - if (ip[i++] == '%') { - ip[i - 1] = '\0'; - break; - } - - if (!strcmp(ip, ipaddr)) { - scope = if_nametoindex(addr->ifa_name); - break; - } - } - freeifaddrs(addrs); -#else - PIP_ADAPTER_ADDRESSES adapter, addrs = NULL; - PIP_ADAPTER_UNICAST_ADDRESS addr; - ULONG size = 0; - DWORD ret; - struct sockaddr_in6 *sockaddr; - char ip[NI_MAXHOST]; - unsigned int i; - int found = 0; - - for (i = 0; i < 5; i++) - { - ret = GetAdaptersAddresses(AF_INET6, GAA_FLAG_INCLUDE_PREFIX, - NULL, addrs, &size); - if ((ret == NO_ERROR) || (ret == ERROR_NO_DATA)) { - break; - } else if (ret == ERROR_BUFFER_OVERFLOW) - { - if (addrs) - free(addrs); - addrs = (IP_ADAPTER_ADDRESSES *)malloc(size); - } else - { - if (addrs) - { - free(addrs); - addrs = NULL; - } - lwsl_err("Failed to get IPv6 address table (%d)", ret); - break; - } - } - - if ((ret == NO_ERROR) && (addrs)) { - adapter = addrs; - while (adapter && !found) { - addr = adapter->FirstUnicastAddress; - while (addr && !found) { - if (addr->Address.lpSockaddr->sa_family == - AF_INET6) { - sockaddr = (struct sockaddr_in6 *) - (addr->Address.lpSockaddr); - - lws_plat_inet_ntop(sockaddr->sin6_family, - &sockaddr->sin6_addr, - ip, sizeof(ip)); - - if (!strcmp(ip, ipaddr)) { - scope = sockaddr->sin6_scope_id; - found = 1; - break; - } - } - addr = addr->Next; - } - adapter = adapter->Next; - } - } - if (addrs) - free(addrs); -#endif - - return scope; -} -#endif - -#if !defined(LWS_NO_SERVER) - -LWS_EXTERN struct lws * -lws_create_adopt_udp(struct lws_vhost *vhost, int port, int flags, - const char *protocol_name, struct lws *parent_wsi) -{ - lws_sock_file_fd_type sock; - struct addrinfo h, *r, *rp; - struct lws *wsi = NULL; - char buf[16]; - int n; - - memset(&h, 0, sizeof(h)); - h.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ - h.ai_socktype = SOCK_DGRAM; - h.ai_protocol = IPPROTO_UDP; - h.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; - - lws_snprintf(buf, sizeof(buf), "%u", port); - n = getaddrinfo(NULL, buf, &h, &r); - if (n) { - lwsl_info("%s: getaddrinfo error: %s\n", __func__, - gai_strerror(n)); - goto bail; - } - - for (rp = r; rp; rp = rp->ai_next) { - sock.sockfd = socket(rp->ai_family, rp->ai_socktype, - rp->ai_protocol); - if (sock.sockfd >= 0) - break; - } - if (!rp) { - lwsl_err("%s: unable to create INET socket\n", __func__); - goto bail1; - } - - if ((flags & LWS_CAUDP_BIND) && bind(sock.sockfd, rp->ai_addr, -#if defined(_WIN32) - (int)rp->ai_addrlen -#else - rp->ai_addrlen -#endif - ) == -1) { - lwsl_err("%s: bind failed\n", __func__); - goto bail2; - } - - wsi = lws_adopt_descriptor_vhost(vhost, LWS_ADOPT_RAW_SOCKET_UDP, sock, - protocol_name, parent_wsi); - if (!wsi) - lwsl_err("%s: udp adoption failed\n", __func__); - -bail2: - if (!wsi) - close((int)sock.sockfd); -bail1: - freeaddrinfo(r); - -bail: - return wsi; -} - -#endif - - - -static const char *hex = "0123456789ABCDEF"; - -LWS_VISIBLE LWS_EXTERN const char * -lws_sql_purify(char *escaped, const char *string, int len) -{ - const char *p = string; - char *q = escaped; - - while (*p && len-- > 2) { - if (*p == '\'') { - *q++ = '\''; - *q++ = '\''; - len --; - p++; - } else - *q++ = *p++; - } - *q = '\0'; - - return escaped; -} - -LWS_VISIBLE LWS_EXTERN const char * -lws_json_purify(char *escaped, const char *string, int len) -{ - const char *p = string; - char *q = escaped; - - if (!p) { - escaped[0] = '\0'; - return escaped; - } - - while (*p && len-- > 6) { - if (*p == '\"' || *p == '\\' || *p < 0x20) { - *q++ = '\\'; - *q++ = 'u'; - *q++ = '0'; - *q++ = '0'; - *q++ = hex[((*p) >> 4) & 15]; - *q++ = hex[(*p) & 15]; - len -= 5; - p++; - } else - *q++ = *p++; - } - *q = '\0'; - - return escaped; -} - -LWS_VISIBLE LWS_EXTERN void -lws_filename_purify_inplace(char *filename) -{ - while (*filename) { - - if (*filename == '.' && filename[1] == '.') { - *filename = '_'; - filename[1] = '_'; - } - - if (*filename == ':' || - *filename == '/' || - *filename == '\\' || - *filename == '$' || - *filename == '%') - *filename = '_'; - - filename++; - } -} - -LWS_VISIBLE LWS_EXTERN const char * -lws_urlencode(char *escaped, const char *string, int len) -{ - const char *p = string; - char *q = escaped; - - while (*p && len-- > 3) { - if (*p == ' ') { - *q++ = '+'; - p++; - continue; - } - if ((*p >= '0' && *p <= '9') || - (*p >= 'A' && *p <= 'Z') || - (*p >= 'a' && *p <= 'z')) { - *q++ = *p++; - continue; - } - *q++ = '%'; - *q++ = hex[(*p >> 4) & 0xf]; - *q++ = hex[*p & 0xf]; - - len -= 2; - p++; - } - *q = '\0'; - - return escaped; -} - -LWS_VISIBLE LWS_EXTERN int -lws_urldecode(char *string, const char *escaped, int len) -{ - int state = 0, n; - char sum = 0; - - while (*escaped && len) { - switch (state) { - case 0: - if (*escaped == '%') { - state++; - escaped++; - continue; - } - if (*escaped == '+') { - escaped++; - *string++ = ' '; - len--; - continue; - } - *string++ = *escaped++; - len--; - break; - case 1: - n = char_to_hex(*escaped); - if (n < 0) - return -1; - escaped++; - sum = n << 4; - state++; - break; - - case 2: - n = char_to_hex(*escaped); - if (n < 0) - return -1; - escaped++; - *string++ = sum | n; - len--; - state = 0; - break; - } - - } - *string = '\0'; - - return 0; -} - -LWS_VISIBLE LWS_EXTERN int -lws_finalize_startup(struct lws_context *context) -{ - struct lws_context_creation_info info; - - info.uid = context->uid; - info.gid = context->gid; - -#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) - memcpy(info.caps, context->caps, sizeof(info.caps)); - info.count_caps = context->count_caps; -#endif - - if (lws_check_opt(context->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) - lws_plat_drop_app_privileges(&info); - - return 0; -} - -int -lws_snprintf(char *str, size_t size, const char *format, ...) -{ - va_list ap; - int n; - - if (!size) - return 0; - - va_start(ap, format); - n = vsnprintf(str, size, format, ap); - va_end(ap); - - if (n >= (int)size) - return (int)size; - - return n; -} - -char * -lws_strncpy(char *dest, const char *src, size_t size) -{ - strncpy(dest, src, size - 1); - dest[size - 1] = '\0'; - - return dest; -} - - -LWS_VISIBLE LWS_EXTERN int -lws_is_cgi(struct lws *wsi) { -#ifdef LWS_WITH_CGI - return !!wsi->http.cgi; -#else - return 0; -#endif -} - -const struct lws_protocol_vhost_options * -lws_pvo_search(const struct lws_protocol_vhost_options *pvo, const char *name) -{ - while (pvo) { - if (!strcmp(pvo->name, name)) - break; - - pvo = pvo->next; - } - - return pvo; -} - -void -lws_sum_stats(const struct lws_context *ctx, struct lws_conn_stats *cs) -{ - const struct lws_vhost *vh = ctx->vhost_list; - - while (vh) { - - cs->rx += vh->conn_stats.rx; - cs->tx += vh->conn_stats.tx; - cs->h1_conn += vh->conn_stats.h1_conn; - cs->h1_trans += vh->conn_stats.h1_trans; - cs->h2_trans += vh->conn_stats.h2_trans; - cs->ws_upg += vh->conn_stats.ws_upg; - cs->h2_upg += vh->conn_stats.h2_upg; - cs->h2_alpn += vh->conn_stats.h2_alpn; - cs->h2_subs += vh->conn_stats.h2_subs; - cs->rejected += vh->conn_stats.rejected; - - vh = vh->vhost_next; - } -} - -const char * -lws_cmdline_option(int argc, const char **argv, const char *val) -{ - int n = (int)strlen(val), c = argc; - - while (--c > 0) { - - if (!strncmp(argv[c], val, n)) { - if (!*(argv[c] + n) && c < argc - 1) { - /* coverity treats unchecked argv as "tainted" */ - if (!argv[c + 1] || strlen(argv[c + 1]) > 1024) - return NULL; - return argv[c + 1]; - } - - return argv[c] + n; - } - } - - return NULL; -} - -#ifdef LWS_WITH_SERVER_STATUS - -LWS_EXTERN int -lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len) -{ -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - static const char * const prots[] = { - "http://", - "https://", - "file://", - "cgi://", - ">http://", - ">https://", - "callback://" - }; -#endif - char *orig = buf, *end = buf + len - 1, first = 1; - int n = 0; - - if (len < 100) - return 0; - - buf += lws_snprintf(buf, end - buf, - "{\n \"name\":\"%s\",\n" - " \"port\":\"%d\",\n" - " \"use_ssl\":\"%d\",\n" - " \"sts\":\"%d\",\n" - " \"rx\":\"%llu\",\n" - " \"tx\":\"%llu\",\n" - " \"h1_conn\":\"%lu\",\n" - " \"h1_trans\":\"%lu\",\n" - " \"h2_trans\":\"%lu\",\n" - " \"ws_upg\":\"%lu\",\n" - " \"rejected\":\"%lu\",\n" - " \"h2_upg\":\"%lu\",\n" - " \"h2_alpn\":\"%lu\",\n" - " \"h2_subs\":\"%lu\"" - , - vh->name, vh->listen_port, -#if defined(LWS_WITH_TLS) - vh->tls.use_ssl & LCCSCF_USE_SSL, -#else - 0, -#endif - !!(vh->options & LWS_SERVER_OPTION_STS), - vh->conn_stats.rx, vh->conn_stats.tx, - vh->conn_stats.h1_conn, - vh->conn_stats.h1_trans, - vh->conn_stats.h2_trans, - vh->conn_stats.ws_upg, - vh->conn_stats.rejected, - vh->conn_stats.h2_upg, - vh->conn_stats.h2_alpn, - vh->conn_stats.h2_subs - ); -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - if (vh->http.mount_list) { - const struct lws_http_mount *m = vh->http.mount_list; - - buf += lws_snprintf(buf, end - buf, ",\n \"mounts\":["); - while (m) { - if (!first) - buf += lws_snprintf(buf, end - buf, ","); - buf += lws_snprintf(buf, end - buf, - "\n {\n \"mountpoint\":\"%s\",\n" - " \"origin\":\"%s%s\",\n" - " \"cache_max_age\":\"%d\",\n" - " \"cache_reuse\":\"%d\",\n" - " \"cache_revalidate\":\"%d\",\n" - " \"cache_intermediaries\":\"%d\"\n" - , - m->mountpoint, - prots[m->origin_protocol], - m->origin, - m->cache_max_age, - m->cache_reusable, - m->cache_revalidate, - m->cache_intermediaries); - if (m->def) - buf += lws_snprintf(buf, end - buf, - ",\n \"default\":\"%s\"", - m->def); - buf += lws_snprintf(buf, end - buf, "\n }"); - first = 0; - m = m->mount_next; - } - buf += lws_snprintf(buf, end - buf, "\n ]"); - } -#endif - if (vh->protocols) { - n = 0; - first = 1; - - buf += lws_snprintf(buf, end - buf, ",\n \"ws-protocols\":["); - while (n < vh->count_protocols) { - if (!first) - buf += lws_snprintf(buf, end - buf, ","); - buf += lws_snprintf(buf, end - buf, - "\n {\n \"%s\":{\n" - " \"status\":\"ok\"\n }\n }" - , - vh->protocols[n].name); - first = 0; - n++; - } - buf += lws_snprintf(buf, end - buf, "\n ]"); - } - - buf += lws_snprintf(buf, end - buf, "\n}"); - - return buf - orig; -} - - -LWS_EXTERN LWS_VISIBLE int -lws_json_dump_context(const struct lws_context *context, char *buf, int len, - int hide_vhosts) -{ - char *orig = buf, *end = buf + len - 1, first = 1; - const struct lws_vhost *vh = context->vhost_list; - const struct lws_context_per_thread *pt; - time_t t = time(NULL); - int n, listening = 0, cgi_count = 0; - struct lws_conn_stats cs; - double d = 0; -#ifdef LWS_WITH_CGI - struct lws_cgi * const *pcgi; -#endif - -#ifdef LWS_WITH_LIBUV - uv_uptime(&d); -#endif - - buf += lws_snprintf(buf, end - buf, "{ " - "\"version\":\"%s\",\n" - "\"uptime\":\"%ld\",\n", - lws_get_library_version(), - (long)d); - -#ifdef LWS_HAVE_GETLOADAVG - { - double d[3]; - int m; - - m = getloadavg(d, 3); - for (n = 0; n < m; n++) { - buf += lws_snprintf(buf, end - buf, - "\"l%d\":\"%.2f\",\n", - n + 1, d[n]); - } - } -#endif - - buf += lws_snprintf(buf, end - buf, "\"contexts\":[\n"); - - buf += lws_snprintf(buf, end - buf, "{ " - "\"context_uptime\":\"%ld\",\n" - "\"cgi_spawned\":\"%d\",\n" - "\"pt_fd_max\":\"%d\",\n" - "\"ah_pool_max\":\"%d\",\n" - "\"deprecated\":\"%d\",\n" - "\"wsi_alive\":\"%d\",\n", - (unsigned long)(t - context->time_up), - context->count_cgi_spawned, - context->fd_limit_per_thread, - context->max_http_header_pool, - context->deprecated, - context->count_wsi_allocated); - - buf += lws_snprintf(buf, end - buf, "\"pt\":[\n "); - for (n = 0; n < context->count_threads; n++) { - pt = &context->pt[n]; - if (n) - buf += lws_snprintf(buf, end - buf, ","); - buf += lws_snprintf(buf, end - buf, - "\n {\n" - " \"fds_count\":\"%d\",\n" - " \"ah_pool_inuse\":\"%d\",\n" - " \"ah_wait_list\":\"%d\"\n" - " }", - pt->fds_count, - pt->http.ah_count_in_use, - pt->http.ah_wait_list_length); - } - - buf += lws_snprintf(buf, end - buf, "]"); - - buf += lws_snprintf(buf, end - buf, ", \"vhosts\":[\n "); - - first = 1; - vh = context->vhost_list; - listening = 0; - cs = context->conn_stats; - lws_sum_stats(context, &cs); - while (vh) { - - if (!hide_vhosts) { - if (!first) - if(buf != end) - *buf++ = ','; - buf += lws_json_dump_vhost(vh, buf, end - buf); - first = 0; - } - if (vh->lserv_wsi) - listening++; - vh = vh->vhost_next; - } - - buf += lws_snprintf(buf, end - buf, - "],\n\"listen_wsi\":\"%d\",\n" - " \"rx\":\"%llu\",\n" - " \"tx\":\"%llu\",\n" - " \"h1_conn\":\"%lu\",\n" - " \"h1_trans\":\"%lu\",\n" - " \"h2_trans\":\"%lu\",\n" - " \"ws_upg\":\"%lu\",\n" - " \"rejected\":\"%lu\",\n" - " \"h2_alpn\":\"%lu\",\n" - " \"h2_subs\":\"%lu\",\n" - " \"h2_upg\":\"%lu\"", - listening, cs.rx, cs.tx, - cs.h1_conn, - cs.h1_trans, - cs.h2_trans, - cs.ws_upg, - cs.rejected, - cs.h2_alpn, - cs.h2_subs, - cs.h2_upg); - -#ifdef LWS_WITH_CGI - for (n = 0; n < context->count_threads; n++) { - pt = &context->pt[n]; - pcgi = &pt->http.cgi_list; - - while (*pcgi) { - pcgi = &(*pcgi)->cgi_list; - - cgi_count++; - } - } -#endif - buf += lws_snprintf(buf, end - buf, ",\n \"cgi_alive\":\"%d\"\n ", - cgi_count); - - buf += lws_snprintf(buf, end - buf, "}"); - - - buf += lws_snprintf(buf, end - buf, "]}\n "); - - return buf - orig; -} - -#endif - -#if defined(LWS_WITH_STATS) - -LWS_VISIBLE LWS_EXTERN uint64_t -lws_stats_get(struct lws_context *context, int index) -{ - if (index >= LWSSTATS_SIZE) - return 0; - - return context->lws_stats[index]; -} - -LWS_VISIBLE LWS_EXTERN void -lws_stats_log_dump(struct lws_context *context) -{ - struct lws_vhost *v = context->vhost_list; - int n, m; - - (void)m; - - if (!context->updated) - return; - - context->updated = 0; - - lwsl_notice("\n"); - lwsl_notice("LWS internal statistics dump ----->\n"); - lwsl_notice("LWSSTATS_C_CONNECTIONS: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_CONNECTIONS)); - lwsl_notice("LWSSTATS_C_API_CLOSE: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_API_CLOSE)); - lwsl_notice("LWSSTATS_C_API_READ: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_API_READ)); - lwsl_notice("LWSSTATS_C_API_LWS_WRITE: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_API_LWS_WRITE)); - lwsl_notice("LWSSTATS_C_API_WRITE: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_API_WRITE)); - lwsl_notice("LWSSTATS_C_WRITE_PARTIALS: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_WRITE_PARTIALS)); - lwsl_notice("LWSSTATS_C_WRITEABLE_CB_REQ: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_WRITEABLE_CB_REQ)); - lwsl_notice("LWSSTATS_C_WRITEABLE_CB_EFF_REQ: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_WRITEABLE_CB_EFF_REQ)); - lwsl_notice("LWSSTATS_C_WRITEABLE_CB: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_WRITEABLE_CB)); - lwsl_notice("LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN)); - lwsl_notice("LWSSTATS_C_SSL_CONNECTIONS_FAILED: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_SSL_CONNECTIONS_FAILED)); - lwsl_notice("LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED)); - lwsl_notice("LWSSTATS_C_SSL_CONNS_HAD_RX: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_SSL_CONNS_HAD_RX)); - lwsl_notice("LWSSTATS_C_PEER_LIMIT_AH_DENIED: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_PEER_LIMIT_AH_DENIED)); - lwsl_notice("LWSSTATS_C_PEER_LIMIT_WSI_DENIED: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_PEER_LIMIT_WSI_DENIED)); - - lwsl_notice("LWSSTATS_C_TIMEOUTS: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_TIMEOUTS)); - lwsl_notice("LWSSTATS_C_SERVICE_ENTRY: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_C_SERVICE_ENTRY)); - lwsl_notice("LWSSTATS_B_READ: %8llu\n", - (unsigned long long)lws_stats_get(context, LWSSTATS_B_READ)); - lwsl_notice("LWSSTATS_B_WRITE: %8llu\n", - (unsigned long long)lws_stats_get(context, LWSSTATS_B_WRITE)); - lwsl_notice("LWSSTATS_B_PARTIALS_ACCEPTED_PARTS: %8llu\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_B_PARTIALS_ACCEPTED_PARTS)); - lwsl_notice("LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY: %8llums\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY) / 1000); - if (lws_stats_get(context, LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED)) - lwsl_notice(" Avg accept delay: %8llums\n", - (unsigned long long)(lws_stats_get(context, - LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY) / - lws_stats_get(context, - LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED)) / 1000); - lwsl_notice("LWSSTATS_MS_SSL_RX_DELAY: %8llums\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_MS_SSL_RX_DELAY) / 1000); - if (lws_stats_get(context, LWSSTATS_C_SSL_CONNS_HAD_RX)) - lwsl_notice(" Avg accept-rx delay: %8llums\n", - (unsigned long long)(lws_stats_get(context, - LWSSTATS_MS_SSL_RX_DELAY) / - lws_stats_get(context, - LWSSTATS_C_SSL_CONNS_HAD_RX)) / 1000); - - lwsl_notice("LWSSTATS_MS_WRITABLE_DELAY: %8lluus\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_MS_WRITABLE_DELAY)); - lwsl_notice("LWSSTATS_MS_WORST_WRITABLE_DELAY: %8lluus\n", - (unsigned long long)lws_stats_get(context, - LWSSTATS_MS_WORST_WRITABLE_DELAY)); - if (lws_stats_get(context, LWSSTATS_C_WRITEABLE_CB)) - lwsl_notice(" Avg writable delay: %8lluus\n", - (unsigned long long)(lws_stats_get(context, - LWSSTATS_MS_WRITABLE_DELAY) / - lws_stats_get(context, LWSSTATS_C_WRITEABLE_CB))); - lwsl_notice("Simultaneous SSL restriction: %8d/%d\n", - context->simultaneous_ssl, - context->simultaneous_ssl_restriction); - - lwsl_notice("Live wsi: %8d\n", - context->count_wsi_allocated); - - context->updated = 1; - - while (v) { - if (v->lserv_wsi && - v->lserv_wsi->position_in_fds_table != LWS_NO_FDS_POS) { - - struct lws_context_per_thread *pt = - &context->pt[(int)v->lserv_wsi->tsi]; - struct lws_pollfd *pfd; - - pfd = &pt->fds[v->lserv_wsi->position_in_fds_table]; - - lwsl_notice(" Listen port %d actual POLLIN: %d\n", - v->listen_port, - (int)pfd->events & LWS_POLLIN); - } - - v = v->vhost_next; - } - - for (n = 0; n < context->count_threads; n++) { - struct lws_context_per_thread *pt = &context->pt[n]; - struct lws *wl; - int m = 0; - - lwsl_notice("PT %d\n", n + 1); - - lws_pt_lock(pt, __func__); - - lwsl_notice(" AH in use / max: %d / %d\n", - pt->http.ah_count_in_use, - context->max_http_header_pool); - - wl = pt->http.ah_wait_list; - while (wl) { - m++; - wl = wl->http.ah_wait_list; - } - - lwsl_notice(" AH wait list count / actual: %d / %d\n", - pt->http.ah_wait_list_length, m); - - lws_pt_unlock(pt); - } - -#if defined(LWS_WITH_PEER_LIMITS) - m = 0; - for (n = 0; n < (int)context->pl_hash_elements; n++) { - lws_start_foreach_llp(struct lws_peer **, peer, - context->pl_hash_table[n]) { - m++; - } lws_end_foreach_llp(peer, next); - } - - lwsl_notice(" Peers: total active %d\n", m); - if (m > 10) { - m = 10; - lwsl_notice(" (showing 10 peers only)\n"); - } - - if (m) { - for (n = 0; n < (int)context->pl_hash_elements; n++) { - char buf[72]; - - lws_start_foreach_llp(struct lws_peer **, peer, - context->pl_hash_table[n]) { - struct lws_peer *df = *peer; - - if (!lws_plat_inet_ntop(df->af, df->addr, buf, - sizeof(buf) - 1)) - strcpy(buf, "unknown"); -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - lwsl_notice(" peer %s: count wsi: %d, count ah: %d\n", - buf, df->count_wsi, - df->http.count_ah); -#else - lwsl_notice(" peer %s: count wsi: %d\n", - buf, df->count_wsi); -#endif - - if (!--m) - break; - } lws_end_foreach_llp(peer, next); - } - } -#endif - - lwsl_notice("\n"); -} - -void -lws_stats_atomic_bump(struct lws_context * context, - struct lws_context_per_thread *pt, int index, uint64_t bump) -{ - lws_pt_stats_lock(pt); - context->lws_stats[index] += bump; - if (index != LWSSTATS_C_SERVICE_ENTRY) - context->updated = 1; - lws_pt_stats_unlock(pt); -} - -void -lws_stats_atomic_max(struct lws_context * context, - struct lws_context_per_thread *pt, int index, uint64_t val) -{ - lws_pt_stats_lock(pt); - if (val > context->lws_stats[index]) { - context->lws_stats[index] = val; - context->updated = 1; - } - lws_pt_stats_unlock(pt); -} - -#endif - diff --git a/thirdparty/libwebsockets/core/output.c b/thirdparty/libwebsockets/core/output.c deleted file mode 100644 index 11965a06b9..0000000000 --- a/thirdparty/libwebsockets/core/output.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -/* - * notice this returns number of bytes consumed, or -1 - */ -int lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len) -{ - struct lws_context *context = lws_get_context(wsi); - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - size_t real_len = len; - unsigned int n; - - // lwsl_hexdump_err(buf, len); - - /* - * Detect if we got called twice without going through the - * event loop to handle pending. This would be caused by either - * back-to-back writes in one WRITABLE (illegal) or calling lws_write() - * from outside the WRITABLE callback (illegal). - */ - if (wsi->could_have_pending) { - lwsl_hexdump_level(LLL_ERR, buf, len); - lwsl_err("** %p: vh: %s, prot: %s, role %s: " - "Illegal back-to-back write of %lu detected...\n", - wsi, wsi->vhost->name, wsi->protocol->name, - wsi->role_ops->name, - (unsigned long)len); - // assert(0); - - return -1; - } - - lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_API_WRITE, 1); - - if (!len) - return 0; - /* just ignore sends after we cleared the truncation buffer */ - if (lwsi_state(wsi) == LRS_FLUSHING_BEFORE_CLOSE && !wsi->trunc_len) - return (int)len; - - if (wsi->trunc_len && (buf < wsi->trunc_alloc || - buf > (wsi->trunc_alloc + wsi->trunc_len + wsi->trunc_offset))) { - lwsl_hexdump_level(LLL_ERR, buf, len); - lwsl_err("** %p: vh: %s, prot: %s, Sending new %lu, pending truncated ...\n" - " It's illegal to do an lws_write outside of\n" - " the writable callback: fix your code\n", - wsi, wsi->vhost->name, wsi->protocol->name, - (unsigned long)len); - assert(0); - - return -1; - } - - if (!wsi->http2_substream && !lws_socket_is_valid(wsi->desc.sockfd)) - lwsl_warn("** error invalid sock but expected to send\n"); - - /* limit sending */ - if (wsi->protocol->tx_packet_size) - n = (int)wsi->protocol->tx_packet_size; - else { - n = (int)wsi->protocol->rx_buffer_size; - if (!n) - n = context->pt_serv_buf_size; - } - n += LWS_PRE + 4; - if (n > len) - n = (int)len; - - /* nope, send it on the socket directly */ - lws_latency_pre(context, wsi); - n = lws_ssl_capable_write(wsi, buf, n); - lws_latency(context, wsi, "send lws_issue_raw", n, n == len); - - /* something got written, it can have been truncated now */ - wsi->could_have_pending = 1; - - switch (n) { - case LWS_SSL_CAPABLE_ERROR: - /* we're going to close, let close know sends aren't possible */ - wsi->socket_is_permanently_unusable = 1; - return -1; - case LWS_SSL_CAPABLE_MORE_SERVICE: - /* - * nothing got sent, not fatal. Retry the whole thing later, - * ie, implying treat it was a truncated send so it gets - * retried - */ - n = 0; - break; - } - - /* - * we were already handling a truncated send? - */ - if (wsi->trunc_len) { - lwsl_info("%p partial adv %d (vs %ld)\n", wsi, n, (long)real_len); - wsi->trunc_offset += n; - wsi->trunc_len -= n; - - if (!wsi->trunc_len) { - lwsl_info("** %p partial send completed\n", wsi); - /* done with it, but don't free it */ - n = (int)real_len; - if (lwsi_state(wsi) == LRS_FLUSHING_BEFORE_CLOSE) { - lwsl_info("** %p signalling to close now\n", wsi); - return -1; /* retry closing now */ - } - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) -#if !defined(LWS_WITHOUT_SERVER) - if (wsi->http.deferred_transaction_completed) { - lwsl_notice("%s: partial completed, doing " - "deferred transaction completed\n", - __func__); - wsi->http.deferred_transaction_completed = 0; - return lws_http_transaction_completed(wsi); - } -#endif -#endif - } - /* always callback on writeable */ - lws_callback_on_writable(wsi); - - return n; - } - - if ((unsigned int)n == real_len) - /* what we just sent went out cleanly */ - return n; - - /* - * Newly truncated send. Buffer the remainder (it will get - * first priority next time the socket is writable). - */ - lwsl_debug("%p new partial sent %d from %lu total\n", wsi, n, - (unsigned long)real_len); - - lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_WRITE_PARTIALS, 1); - lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_B_PARTIALS_ACCEPTED_PARTS, n); - - /* - * - if we still have a suitable malloc lying around, use it - * - or, if too small, reallocate it - * - or, if no buffer, create it - */ - if (!wsi->trunc_alloc || real_len - n > wsi->trunc_alloc_len) { - lws_free(wsi->trunc_alloc); - - wsi->trunc_alloc_len = (unsigned int)(real_len - n); - wsi->trunc_alloc = lws_malloc(real_len - n, - "truncated send alloc"); - if (!wsi->trunc_alloc) { - lwsl_err("truncated send: unable to malloc %lu\n", - (unsigned long)(real_len - n)); - return -1; - } - } - wsi->trunc_offset = 0; - wsi->trunc_len = (unsigned int)(real_len - n); - memcpy(wsi->trunc_alloc, buf + n, real_len - n); - -#if !defined(LWS_WITH_ESP32) - if (lws_wsi_is_udp(wsi)) { - /* stash original destination for fulfilling UDP partials */ - wsi->udp->sa_pending = wsi->udp->sa; - wsi->udp->salen_pending = wsi->udp->salen; - } -#endif - - /* since something buffered, force it to get another chance to send */ - lws_callback_on_writable(wsi); - - return (int)real_len; -} - -LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len, - enum lws_write_protocol wp) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - - if (wsi->parent_carries_io) { - struct lws_write_passthru pas; - - pas.buf = buf; - pas.len = len; - pas.wp = wp; - pas.wsi = wsi; - - if (wsi->parent->protocol->callback(wsi->parent, - LWS_CALLBACK_CHILD_WRITE_VIA_PARENT, - wsi->parent->user_space, - (void *)&pas, 0)) - return 1; - - return (int)len; - } - - lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_API_LWS_WRITE, 1); - - if ((int)len < 0) { - lwsl_err("%s: suspicious len int %d, ulong %lu\n", __func__, - (int)len, (unsigned long)len); - return -1; - } - - lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_B_WRITE, len); - -#ifdef LWS_WITH_ACCESS_LOG - wsi->http.access_log.sent += len; -#endif - if (wsi->vhost) - wsi->vhost->conn_stats.tx += len; - - assert(wsi->role_ops); - if (!wsi->role_ops->write_role_protocol) - return lws_issue_raw(wsi, buf, len); - - return wsi->role_ops->write_role_protocol(wsi, buf, len, &wp); -} - -LWS_VISIBLE int -lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len) -{ - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - int n = 0; - - lws_stats_atomic_bump(context, pt, LWSSTATS_C_API_READ, 1); - - if (lws_wsi_is_udp(wsi)) { -#if !defined(LWS_WITH_ESP32) - wsi->udp->salen = sizeof(wsi->udp->sa); - n = recvfrom(wsi->desc.sockfd, (char *)buf, len, 0, - &wsi->udp->sa, &wsi->udp->salen); -#endif - } else - n = recv(wsi->desc.sockfd, (char *)buf, len, 0); - - if (n >= 0) { - if (wsi->vhost) - wsi->vhost->conn_stats.rx += n; - lws_stats_atomic_bump(context, pt, LWSSTATS_B_READ, n); - - return n; - } - - if (LWS_ERRNO == LWS_EAGAIN || - LWS_ERRNO == LWS_EWOULDBLOCK || - LWS_ERRNO == LWS_EINTR) - return LWS_SSL_CAPABLE_MORE_SERVICE; - - lwsl_notice("error on reading from skt : %d\n", LWS_ERRNO); - return LWS_SSL_CAPABLE_ERROR; -} - -LWS_VISIBLE int -lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len) -{ - int n = 0; - - if (lws_wsi_is_udp(wsi)) { -#if !defined(LWS_WITH_ESP32) - if (wsi->trunc_len) - n = sendto(wsi->desc.sockfd, buf, len, 0, &wsi->udp->sa_pending, wsi->udp->salen_pending); - else - n = sendto(wsi->desc.sockfd, buf, len, 0, &wsi->udp->sa, wsi->udp->salen); -#endif - } else - n = send(wsi->desc.sockfd, (char *)buf, len, MSG_NOSIGNAL); -// lwsl_info("%s: sent len %d result %d", __func__, len, n); - if (n >= 0) - return n; - - if (LWS_ERRNO == LWS_EAGAIN || - LWS_ERRNO == LWS_EWOULDBLOCK || - LWS_ERRNO == LWS_EINTR) { - if (LWS_ERRNO == LWS_EWOULDBLOCK) { - lws_set_blocking_send(wsi); - } - - return LWS_SSL_CAPABLE_MORE_SERVICE; - } - - lwsl_debug("ERROR writing len %d to skt fd %d err %d / errno %d\n", - len, wsi->desc.sockfd, n, LWS_ERRNO); - - return LWS_SSL_CAPABLE_ERROR; -} - -LWS_VISIBLE int -lws_ssl_pending_no_ssl(struct lws *wsi) -{ - (void)wsi; -#if defined(LWS_WITH_ESP32) - return 100; -#else - return 0; -#endif -} diff --git a/thirdparty/libwebsockets/core/pollfd.c b/thirdparty/libwebsockets/core/pollfd.c deleted file mode 100644 index 2a632ce8ec..0000000000 --- a/thirdparty/libwebsockets/core/pollfd.c +++ /dev/null @@ -1,616 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -int -_lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa) -{ -#if !defined(LWS_WITH_LIBUV) && !defined(LWS_WITH_LIBEV) && !defined(LWS_WITH_LIBEVENT) - volatile struct lws_context_per_thread *vpt; -#endif - struct lws_context_per_thread *pt; - struct lws_context *context; - int ret = 0, pa_events = 1; - struct lws_pollfd *pfd; - int sampled_tid, tid; - - if (!wsi) - return 0; - - assert(wsi->position_in_fds_table == LWS_NO_FDS_POS || - wsi->position_in_fds_table >= 0); - - if (wsi->position_in_fds_table == LWS_NO_FDS_POS) - return 0; - - if (((volatile struct lws *)wsi)->handling_pollout && - !_and && _or == LWS_POLLOUT) { - /* - * Happening alongside service thread handling POLLOUT. - * The danger is when he is finished, he will disable POLLOUT, - * countermanding what we changed here. - * - * Instead of changing the fds, inform the service thread - * what happened, and ask it to leave POLLOUT active on exit - */ - ((volatile struct lws *)wsi)->leave_pollout_active = 1; - /* - * by definition service thread is not in poll wait, so no need - * to cancel service - */ - - lwsl_debug("%s: using leave_pollout_active\n", __func__); - - return 0; - } - - context = wsi->context; - pt = &context->pt[(int)wsi->tsi]; - - assert(wsi->position_in_fds_table < (int)pt->fds_count); - -#if !defined(LWS_WITH_LIBUV) && \ - !defined(LWS_WITH_LIBEV) && \ - !defined(LWS_WITH_LIBEVENT) - /* - * This only applies when we use the default poll() event loop. - * - * BSD can revert pa->events at any time, when the kernel decides to - * exit from poll(). We can't protect against it using locking. - * - * Therefore we must check first if the service thread is in poll() - * wait; if so, we know we must be being called from a foreign thread, - * and we must keep a strictly ordered list of changes we made instead - * of trying to apply them, since when poll() exits, which may happen - * at any time it would revert our changes. - * - * The plat code will apply them when it leaves the poll() wait - * before doing anything else. - */ - - vpt = (volatile struct lws_context_per_thread *)pt; - - vpt->foreign_spinlock = 1; - lws_memory_barrier(); - - if (vpt->inside_poll) { - struct lws_foreign_thread_pollfd *ftp, **ftp1; - /* - * We are certainly a foreign thread trying to change events - * while the service thread is in the poll() wait. - * - * Create a list of changes to be applied after poll() exit, - * instead of trying to apply them now. - */ - ftp = lws_malloc(sizeof(*ftp), "ftp"); - if (!ftp) { - vpt->foreign_spinlock = 0; - lws_memory_barrier(); - ret = -1; - goto bail; - } - - ftp->_and = _and; - ftp->_or = _or; - ftp->fd_index = wsi->position_in_fds_table; - ftp->next = NULL; - - /* place at END of list to maintain order */ - ftp1 = (struct lws_foreign_thread_pollfd **) - &vpt->foreign_pfd_list; - while (*ftp1) - ftp1 = &((*ftp1)->next); - - *ftp1 = ftp; - vpt->foreign_spinlock = 0; - lws_memory_barrier(); - lws_cancel_service_pt(wsi); - - return 0; - } - - vpt->foreign_spinlock = 0; - lws_memory_barrier(); -#endif - - pfd = &pt->fds[wsi->position_in_fds_table]; - pa->fd = wsi->desc.sockfd; - lwsl_debug("%s: wsi %p: fd %d events %d -> %d\n", __func__, wsi, pa->fd, pfd->events, (pfd->events & ~_and) | _or); - pa->prev_events = pfd->events; - pa->events = pfd->events = (pfd->events & ~_and) | _or; - - if (wsi->http2_substream) - return 0; - - if (wsi->vhost && - wsi->vhost->protocols[0].callback(wsi, - LWS_CALLBACK_CHANGE_MODE_POLL_FD, - wsi->user_space, (void *)pa, 0)) { - ret = -1; - goto bail; - } - - if (context->event_loop_ops->io) { - if (_and & LWS_POLLIN) - context->event_loop_ops->io(wsi, - LWS_EV_STOP | LWS_EV_READ); - - if (_or & LWS_POLLIN) - context->event_loop_ops->io(wsi, - LWS_EV_START | LWS_EV_READ); - - if (_and & LWS_POLLOUT) - context->event_loop_ops->io(wsi, - LWS_EV_STOP | LWS_EV_WRITE); - - if (_or & LWS_POLLOUT) - context->event_loop_ops->io(wsi, - LWS_EV_START | LWS_EV_WRITE); - } - - /* - * if we changed something in this pollfd... - * ... and we're running in a different thread context - * than the service thread... - * ... and the service thread is waiting ... - * then cancel it to force a restart with our changed events - */ - pa_events = pa->prev_events != pa->events; - - if (pa_events) { - if (lws_plat_change_pollfd(context, wsi, pfd)) { - lwsl_info("%s failed\n", __func__); - ret = -1; - goto bail; - } - sampled_tid = context->service_tid; - if (sampled_tid && wsi->vhost) { - tid = wsi->vhost->protocols[0].callback(wsi, - LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); - if (tid == -1) { - ret = -1; - goto bail; - } - if (tid != sampled_tid) - lws_cancel_service_pt(wsi); - } - } - -bail: - return ret; -} - -#ifndef LWS_NO_SERVER -/* - * Enable or disable listen sockets on this pt globally... - * it's modulated according to the pt having space for a new accept. - */ -static void -lws_accept_modulation(struct lws_context *context, - struct lws_context_per_thread *pt, int allow) -{ - struct lws_vhost *vh = context->vhost_list; - struct lws_pollargs pa1; - - while (vh) { - if (vh->lserv_wsi) { - if (allow) - _lws_change_pollfd(vh->lserv_wsi, - 0, LWS_POLLIN, &pa1); - else - _lws_change_pollfd(vh->lserv_wsi, - LWS_POLLIN, 0, &pa1); - } - vh = vh->vhost_next; - } -} -#endif - -int -__insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi) -{ - struct lws_pollargs pa = { wsi->desc.sockfd, LWS_POLLIN, 0 }; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - int ret = 0; - - - lwsl_debug("%s: %p: tsi=%d, sock=%d, pos-in-fds=%d\n", - __func__, wsi, wsi->tsi, wsi->desc.sockfd, pt->fds_count); - - if ((unsigned int)pt->fds_count >= context->fd_limit_per_thread) { - lwsl_err("Too many fds (%d vs %d)\n", context->max_fds, - context->fd_limit_per_thread ); - return 1; - } - -#if !defined(_WIN32) - if (wsi->desc.sockfd - lws_plat_socket_offset() >= context->max_fds) { - lwsl_err("Socket fd %d is too high (%d) offset %d\n", - wsi->desc.sockfd, context->max_fds, lws_plat_socket_offset()); - return 1; - } -#endif - - assert(wsi); - assert(wsi->event_pipe || wsi->vhost); - assert(lws_socket_is_valid(wsi->desc.sockfd)); - - if (wsi->vhost && - wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *) &pa, 1)) - return -1; - - pt->count_conns++; - insert_wsi(context, wsi); - wsi->position_in_fds_table = pt->fds_count; - - pt->fds[wsi->position_in_fds_table].fd = wsi->desc.sockfd; - pt->fds[wsi->position_in_fds_table].events = LWS_POLLIN; - pa.events = pt->fds[pt->fds_count].events; - - lws_plat_insert_socket_into_fds(context, wsi); - - /* external POLL support via protocol 0 */ - if (wsi->vhost && - wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_ADD_POLL_FD, - wsi->user_space, (void *) &pa, 0)) - ret = -1; -#ifndef LWS_NO_SERVER - /* if no more room, defeat accepts on this thread */ - if ((unsigned int)pt->fds_count == context->fd_limit_per_thread - 1) - lws_accept_modulation(context, pt, 0); -#endif - - if (wsi->vhost && - wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL, - wsi->user_space, (void *)&pa, 1)) - ret = -1; - - return ret; -} - -int -__remove_wsi_socket_from_fds(struct lws *wsi) -{ - struct lws_context *context = wsi->context; - struct lws_pollargs pa = { wsi->desc.sockfd, 0, 0 }; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - struct lws *end_wsi; - int v; - int m, ret = 0; - - if (wsi->parent_carries_io) { - lws_same_vh_protocol_remove(wsi); - return 0; - } - -#if !defined(_WIN32) - if (wsi->desc.sockfd - lws_plat_socket_offset() > context->max_fds) { - lwsl_err("fd %d too high (%d)\n", wsi->desc.sockfd, - context->max_fds); - return 1; - } -#endif - - if (wsi->vhost && - wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *)&pa, 1)) - return -1; - - lws_same_vh_protocol_remove(wsi); - - /* the guy who is to be deleted's slot index in pt->fds */ - m = wsi->position_in_fds_table; - - /* these are the only valid possibilities for position_in_fds_table */ - assert(m == LWS_NO_FDS_POS || (m >= 0 && - (unsigned int)m < pt->fds_count)); - - if (context->event_loop_ops->io) - context->event_loop_ops->io(wsi, - LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE | - LWS_EV_PREPARE_DELETION); - - lwsl_debug("%s: wsi=%p, sock=%d, fds pos=%d, end guy pos=%d, endfd=%d\n", - __func__, wsi, wsi->desc.sockfd, wsi->position_in_fds_table, - pt->fds_count, pt->fds[pt->fds_count].fd); - - if (m != LWS_NO_FDS_POS) { - - /* have the last guy take up the now vacant slot */ - pt->fds[m] = pt->fds[pt->fds_count - 1]; - /* this decrements pt->fds_count */ - lws_plat_delete_socket_from_fds(context, wsi, m); - v = (int) pt->fds[m].fd; - /* end guy's "position in fds table" is now the deletion guy's old one */ - end_wsi = wsi_from_fd(context, v); - if (!end_wsi) { - lwsl_err("no wsi for fd %d at pos %d, pt->fds_count=%d\n", - (int)pt->fds[m].fd, m, pt->fds_count); - assert(0); - } else - end_wsi->position_in_fds_table = m; - - /* deletion guy's lws_lookup entry needs nuking */ - delete_from_fd(context, wsi->desc.sockfd); - - /* removed wsi has no position any more */ - wsi->position_in_fds_table = LWS_NO_FDS_POS; - } - - /* remove also from external POLL support via protocol 0 */ - if (lws_socket_is_valid(wsi->desc.sockfd) && wsi->vhost && - wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_DEL_POLL_FD, - wsi->user_space, (void *) &pa, 0)) - ret = -1; - -#ifndef LWS_NO_SERVER - if (!context->being_destroyed && - /* if this made some room, accept connects on this thread */ - (unsigned int)pt->fds_count < context->fd_limit_per_thread - 1) - lws_accept_modulation(context, pt, 1); -#endif - - if (wsi->vhost && - wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL, - wsi->user_space, (void *) &pa, 1)) - ret = -1; - - return ret; -} - -int -__lws_change_pollfd(struct lws *wsi, int _and, int _or) -{ - struct lws_context *context; - struct lws_pollargs pa; - int ret = 0; - - if (!wsi || (!wsi->protocol && !wsi->event_pipe) || - wsi->position_in_fds_table == LWS_NO_FDS_POS) - return 0; - - context = lws_get_context(wsi); - if (!context) - return 1; - - if (wsi->vhost && - wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_LOCK_POLL, - wsi->user_space, (void *) &pa, 0)) - return -1; - - ret = _lws_change_pollfd(wsi, _and, _or, &pa); - if (wsi->vhost && - wsi->vhost->protocols[0].callback(wsi, LWS_CALLBACK_UNLOCK_POLL, - wsi->user_space, (void *) &pa, 0)) - ret = -1; - - return ret; -} - -int -lws_change_pollfd(struct lws *wsi, int _and, int _or) -{ - struct lws_context_per_thread *pt; - int ret = 0; - - pt = &wsi->context->pt[(int)wsi->tsi]; - - lws_pt_lock(pt, __func__); - ret = __lws_change_pollfd(wsi, _and, _or); - lws_pt_unlock(pt); - - return ret; -} - -LWS_VISIBLE int -lws_callback_on_writable(struct lws *wsi) -{ - struct lws_context_per_thread *pt; - int n; - - if (lwsi_state(wsi) == LRS_SHUTDOWN) - return 0; - - if (wsi->socket_is_permanently_unusable) - return 0; - - pt = &wsi->context->pt[(int)wsi->tsi]; - - if (wsi->parent_carries_io) { -#if defined(LWS_WITH_STATS) - if (!wsi->active_writable_req_us) { - wsi->active_writable_req_us = time_in_microseconds(); - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_C_WRITEABLE_CB_EFF_REQ, 1); - } -#endif - n = lws_callback_on_writable(wsi->parent); - if (n < 0) - return n; - - wsi->parent_pending_cb_on_writable = 1; - return 1; - } - - lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_WRITEABLE_CB_REQ, 1); -#if defined(LWS_WITH_STATS) - if (!wsi->active_writable_req_us) { - wsi->active_writable_req_us = time_in_microseconds(); - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_C_WRITEABLE_CB_EFF_REQ, 1); - } -#endif - - - if (wsi->role_ops->callback_on_writable) { - if (wsi->role_ops->callback_on_writable(wsi)) - return 1; - wsi = lws_get_network_wsi(wsi); - } - - if (wsi->position_in_fds_table == LWS_NO_FDS_POS) { - lwsl_debug("%s: failed to find socket %d\n", __func__, - wsi->desc.sockfd); - return -1; - } - - if (__lws_change_pollfd(wsi, 0, LWS_POLLOUT)) - return -1; - - return 1; -} - - -/* - * stitch protocol choice into the vh protocol linked list - * We always insert ourselves at the start of the list - * - * X <-> B - * X <-> pAn <-> pB - * - * Illegal to attach more than once without detach inbetween - */ -void -lws_same_vh_protocol_insert(struct lws *wsi, int n) -{ - if (wsi->same_vh_protocol_prev || wsi->same_vh_protocol_next) { - lws_same_vh_protocol_remove(wsi); - lwsl_notice("Attempted to attach wsi twice to same vh prot\n"); - } - - lws_vhost_lock(wsi->vhost); - - wsi->same_vh_protocol_prev = &wsi->vhost->same_vh_protocol_list[n]; - /* old first guy is our next */ - wsi->same_vh_protocol_next = wsi->vhost->same_vh_protocol_list[n]; - /* we become the new first guy */ - wsi->vhost->same_vh_protocol_list[n] = wsi; - - if (wsi->same_vh_protocol_next) - /* old first guy points back to us now */ - wsi->same_vh_protocol_next->same_vh_protocol_prev = - &wsi->same_vh_protocol_next; - - wsi->on_same_vh_list = 1; - - lws_vhost_unlock(wsi->vhost); -} - -void -lws_same_vh_protocol_remove(struct lws *wsi) -{ - /* - * detach ourselves from vh protocol list if we're on one - * A -> B -> C - * A -> C , or, B -> C, or A -> B - * - * OK to call on already-detached wsi - */ - lwsl_info("%s: removing same prot wsi %p\n", __func__, wsi); - - if (!wsi->vhost || !wsi->on_same_vh_list) - return; - - lws_vhost_lock(wsi->vhost); - - if (wsi->same_vh_protocol_prev) { - assert (*(wsi->same_vh_protocol_prev) == wsi); - lwsl_info("have prev %p, setting him to our next %p\n", - wsi->same_vh_protocol_prev, - wsi->same_vh_protocol_next); - - /* guy who pointed to us should point to our next */ - *(wsi->same_vh_protocol_prev) = wsi->same_vh_protocol_next; - } - - /* our next should point back to our prev */ - if (wsi->same_vh_protocol_next) - wsi->same_vh_protocol_next->same_vh_protocol_prev = - wsi->same_vh_protocol_prev; - - wsi->same_vh_protocol_prev = NULL; - wsi->same_vh_protocol_next = NULL; - wsi->on_same_vh_list = 0; - - lws_vhost_unlock(wsi->vhost); -} - - -LWS_VISIBLE int -lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost, - const struct lws_protocols *protocol) -{ - struct lws *wsi; - - if (protocol < vhost->protocols || - protocol >= (vhost->protocols + vhost->count_protocols)) { - lwsl_err("%s: protocol %p is not from vhost %p (%p - %p)\n", - __func__, protocol, vhost->protocols, vhost, - (vhost->protocols + vhost->count_protocols)); - - return -1; - } - - wsi = vhost->same_vh_protocol_list[protocol - vhost->protocols]; - while (wsi) { - assert(wsi->protocol == protocol); - assert(*wsi->same_vh_protocol_prev == wsi); - if (wsi->same_vh_protocol_next) - assert(wsi->same_vh_protocol_next-> - same_vh_protocol_prev == - &wsi->same_vh_protocol_next); - - lws_callback_on_writable(wsi); - wsi = wsi->same_vh_protocol_next; - } - - return 0; -} - -LWS_VISIBLE int -lws_callback_on_writable_all_protocol(const struct lws_context *context, - const struct lws_protocols *protocol) -{ - struct lws_vhost *vhost; - int n; - - if (!context) - return 0; - - vhost = context->vhost_list; - - while (vhost) { - for (n = 0; n < vhost->count_protocols; n++) - if (protocol->callback == - vhost->protocols[n].callback && - !strcmp(protocol->name, vhost->protocols[n].name)) - break; - if (n != vhost->count_protocols) - lws_callback_on_writable_all_protocol_vhost( - vhost, &vhost->protocols[n]); - - vhost = vhost->vhost_next; - } - - return 0; -} diff --git a/thirdparty/libwebsockets/core/private.h b/thirdparty/libwebsockets/core/private.h deleted file mode 100644 index 73748b0498..0000000000 --- a/thirdparty/libwebsockets/core/private.h +++ /dev/null @@ -1,1770 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "lws_config.h" -#include "lws_config_private.h" - -#if defined(LWS_WITH_CGI) && defined(LWS_HAVE_VFORK) - #define _GNU_SOURCE -#endif - -#if defined(__COVERITY__) && !defined(LWS_COVERITY_WORKAROUND) - #define LWS_COVERITY_WORKAROUND - typedef float _Float32; - typedef float _Float64; - typedef float _Float128; - typedef float _Float32x; - typedef float _Float64x; - typedef float _Float128x; -#endif - -#ifdef LWS_HAVE_SYS_TYPES_H - #include <sys/types.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <ctype.h> -#include <limits.h> -#include <stdarg.h> -#include <inttypes.h> - -#if defined(LWS_WITH_ESP32) - #define MSG_NOSIGNAL 0 - #define SOMAXCONN 3 -#endif - -#define STORE_IN_ROM -#include <assert.h> -#if LWS_MAX_SMP > 1 - #include <pthread.h> -#endif - -#ifdef LWS_HAVE_SYS_STAT_H - #include <sys/stat.h> -#endif - -#if defined(WIN32) || defined(_WIN32) - - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif - - #if (WINVER < 0x0501) - #undef WINVER - #undef _WIN32_WINNT - #define WINVER 0x0501 - #define _WIN32_WINNT WINVER - #endif - - #define LWS_NO_DAEMONIZE - #define LWS_ERRNO WSAGetLastError() - #define LWS_EAGAIN WSAEWOULDBLOCK - #define LWS_EALREADY WSAEALREADY - #define LWS_EINPROGRESS WSAEINPROGRESS - #define LWS_EINTR WSAEINTR - #define LWS_EISCONN WSAEISCONN - #define LWS_EWOULDBLOCK WSAEWOULDBLOCK - #define MSG_NOSIGNAL 0 - #define SHUT_RDWR SD_BOTH - #define SOL_TCP IPPROTO_TCP - #define SHUT_WR SD_SEND - - #define compatible_close(fd) closesocket(fd) - #define lws_set_blocking_send(wsi) wsi->sock_send_blocking = 1 - #define LWS_SOCK_INVALID (INVALID_SOCKET) - - #include <winsock2.h> - #include <ws2tcpip.h> - #include <windows.h> - #include <tchar.h> - #ifdef LWS_HAVE_IN6ADDR_H - #include <in6addr.h> - #endif - #include <mstcpip.h> - #include <io.h> - - #if !defined(LWS_HAVE_ATOLL) - #if defined(LWS_HAVE__ATOI64) - #define atoll _atoi64 - #else - #warning No atoll or _atoi64 available, using atoi - #define atoll atoi - #endif - #endif - - #ifndef __func__ - #define __func__ __FUNCTION__ - #endif - - #ifdef LWS_HAVE__VSNPRINTF - #define vsnprintf _vsnprintf - #endif - - /* we don't have an implementation for this on windows... */ - int kill(int pid, int sig); - int fork(void); - #ifndef SIGINT - #define SIGINT 2 - #endif - -#else /* not windows --> */ - - #include <fcntl.h> - #include <strings.h> - #include <unistd.h> - #include <sys/types.h> - - #ifndef __cplusplus - #include <errno.h> - #endif - #include <netdb.h> - #include <signal.h> - #include <sys/socket.h> - - #if defined(LWS_BUILTIN_GETIFADDRS) - #include "./misc/getifaddrs.h" - #else - #if !defined(LWS_WITH_ESP32) - #if defined(__HAIKU__) - #define _BSD_SOURCE - #endif - #include <ifaddrs.h> - #endif - #endif - #if defined (__ANDROID__) - #include <syslog.h> - #include <sys/resource.h> - #elif defined (__sun) || defined(__HAIKU__) || defined(__QNX__) - #include <syslog.h> - #else - #if !defined(LWS_WITH_ESP32) - #include <sys/syslog.h> - #endif - #endif - #include <netdb.h> - #if !defined(LWS_WITH_ESP32) - #include <sys/mman.h> - #include <sys/un.h> - #include <netinet/in.h> - #include <netinet/tcp.h> - #include <arpa/inet.h> - #include <poll.h> - #endif - #ifndef LWS_NO_FORK - #ifdef LWS_HAVE_SYS_PRCTL_H - #include <sys/prctl.h> - #endif - #endif - - #include <sys/time.h> - - #define LWS_ERRNO errno - #define LWS_EAGAIN EAGAIN - #define LWS_EALREADY EALREADY - #define LWS_EINPROGRESS EINPROGRESS - #define LWS_EINTR EINTR - #define LWS_EISCONN EISCONN - #define LWS_EWOULDBLOCK EWOULDBLOCK - - #define lws_set_blocking_send(wsi) - - #define LWS_SOCK_INVALID (-1) -#endif /* not windows */ - -#ifndef LWS_HAVE_BZERO - #ifndef bzero - #define bzero(b, len) (memset((b), '\0', (len)), (void) 0) - #endif -#endif - -#ifndef LWS_HAVE_STRERROR - #define strerror(x) "" -#endif - - -#define lws_socket_is_valid(x) (x != LWS_SOCK_INVALID) - -#include "libwebsockets.h" - -#include "tls/private.h" - -#if defined(WIN32) || defined(_WIN32) - #include <gettimeofday.h> - - #ifndef BIG_ENDIAN - #define BIG_ENDIAN 4321 /* to show byte order (taken from gcc) */ - #endif - #ifndef LITTLE_ENDIAN - #define LITTLE_ENDIAN 1234 - #endif - #ifndef BYTE_ORDER - #define BYTE_ORDER LITTLE_ENDIAN - #endif - - #undef __P - #ifndef __P - #if __STDC__ - #define __P(protos) protos - #else - #define __P(protos) () - #endif - #endif - -#else /* not windows */ - static LWS_INLINE int compatible_close(int fd) { return close(fd); } - - #include <sys/stat.h> - #include <sys/time.h> - - #if defined(__APPLE__) - #include <machine/endian.h> - #elif defined(__FreeBSD__) - #include <sys/endian.h> - #elif defined(__linux__) - #include <endian.h> - #endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(__QNX__) - #include <gulliver.h> - #if defined(__LITTLEENDIAN__) - #define BYTE_ORDER __LITTLEENDIAN__ - #define LITTLE_ENDIAN __LITTLEENDIAN__ - #define BIG_ENDIAN 4321 /* to show byte order (taken from gcc); for suppres warning that BIG_ENDIAN is not defined. */ - #endif - #if defined(__BIGENDIAN__) - #define BYTE_ORDER __BIGENDIAN__ - #define LITTLE_ENDIAN 1234 /* to show byte order (taken from gcc); for suppres warning that LITTLE_ENDIAN is not defined. */ - #define BIG_ENDIAN __BIGENDIAN__ - #endif -#endif - -#if defined(__sun) && defined(__GNUC__) - - #include <arpa/nameser_compat.h> - - #if !defined (BYTE_ORDER) - #define BYTE_ORDER __BYTE_ORDER__ - #endif - - #if !defined(LITTLE_ENDIAN) - #define LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ - #endif - - #if !defined(BIG_ENDIAN) - #define BIG_ENDIAN __ORDER_BIG_ENDIAN__ - #endif - -#endif /* sun + GNUC */ - -#if !defined(BYTE_ORDER) - #define BYTE_ORDER __BYTE_ORDER -#endif -#if !defined(LITTLE_ENDIAN) - #define LITTLE_ENDIAN __LITTLE_ENDIAN -#endif -#if !defined(BIG_ENDIAN) - #define BIG_ENDIAN __BIG_ENDIAN -#endif - - -/* - * Mac OSX as well as iOS do not define the MSG_NOSIGNAL flag, - * but happily have something equivalent in the SO_NOSIGPIPE flag. - */ -#ifdef __APPLE__ -#define MSG_NOSIGNAL SO_NOSIGPIPE -#endif - -/* - * Solaris 11.X only supports POSIX 2001, MSG_NOSIGNAL appears in - * POSIX 2008. - */ -#ifdef __sun - #define MSG_NOSIGNAL 0 -#endif - -#ifdef _WIN32 - #ifndef FD_HASHTABLE_MODULUS - #define FD_HASHTABLE_MODULUS 32 - #endif -#endif - -#ifndef LWS_DEF_HEADER_LEN -#define LWS_DEF_HEADER_LEN 4096 -#endif -#ifndef LWS_DEF_HEADER_POOL -#define LWS_DEF_HEADER_POOL 4 -#endif -#ifndef LWS_MAX_PROTOCOLS -#define LWS_MAX_PROTOCOLS 5 -#endif -#ifndef LWS_MAX_EXTENSIONS_ACTIVE -#define LWS_MAX_EXTENSIONS_ACTIVE 1 -#endif -#ifndef LWS_MAX_EXT_OFFERS -#define LWS_MAX_EXT_OFFERS 8 -#endif -#ifndef SPEC_LATEST_SUPPORTED -#define SPEC_LATEST_SUPPORTED 13 -#endif -#ifndef AWAITING_TIMEOUT -#define AWAITING_TIMEOUT 20 -#endif -#ifndef CIPHERS_LIST_STRING -#define CIPHERS_LIST_STRING "DEFAULT" -#endif -#ifndef LWS_SOMAXCONN -#define LWS_SOMAXCONN SOMAXCONN -#endif - -#define MAX_WEBSOCKET_04_KEY_LEN 128 - -#ifndef SYSTEM_RANDOM_FILEPATH -#define SYSTEM_RANDOM_FILEPATH "/dev/urandom" -#endif - -#define LWS_H2_RX_SCRATCH_SIZE 512 - -#if defined(WIN32) || defined(_WIN32) - // Visual studio older than 2015 and WIN_CE has only _stricmp - #if (defined(_MSC_VER) && _MSC_VER < 1900) || defined(_WIN32_WCE) - #define strcasecmp _stricmp - #elif !defined(__MINGW32__) - #define strcasecmp stricmp - #endif - #define getdtablesize() 30000 -#endif - -/* - * All lws_tls...() functions must return this type, converting the - * native backend result and doing the extra work to determine which one - * as needed. - * - * Native TLS backend return codes are NOT ALLOWED outside the backend. - * - * Non-SSL mode also uses these types. - */ -enum lws_ssl_capable_status { - LWS_SSL_CAPABLE_ERROR = -1, /* it failed */ - LWS_SSL_CAPABLE_DONE = 0, /* it succeeded */ - LWS_SSL_CAPABLE_MORE_SERVICE_READ = -2, /* retry WANT_READ */ - LWS_SSL_CAPABLE_MORE_SERVICE_WRITE = -3, /* retry WANT_WRITE */ - LWS_SSL_CAPABLE_MORE_SERVICE = -4, /* general retry */ -}; - -#if defined(__clang__) -#define lws_memory_barrier() __sync_synchronize() -#elif defined(__GNUC__) -#define lws_memory_barrier() __sync_synchronize() -#else -#define lws_memory_barrier() -#endif - -/* - * - * ------ roles ------ - * - */ - -#include "roles/private.h" - -/* null-terminated array of pointers to roles lws built with */ -extern const struct lws_role_ops *available_roles[]; - -#define LWS_FOR_EVERY_AVAILABLE_ROLE_START(xx) { \ - const struct lws_role_ops **ppxx = available_roles; \ - while (*ppxx) { \ - const struct lws_role_ops *xx = *ppxx++; - -#define LWS_FOR_EVERY_AVAILABLE_ROLE_END }} - -/* - * - * ------ event_loop ops ------ - * - */ - -#include "event-libs/private.h" - -/* enums of socks version */ -enum socks_version { - SOCKS_VERSION_4 = 4, - SOCKS_VERSION_5 = 5 -}; - -/* enums of subnegotiation version */ -enum socks_subnegotiation_version { - SOCKS_SUBNEGOTIATION_VERSION_1 = 1, -}; - -/* enums of socks commands */ -enum socks_command { - SOCKS_COMMAND_CONNECT = 1, - SOCKS_COMMAND_BIND = 2, - SOCKS_COMMAND_UDP_ASSOCIATE = 3 -}; - -/* enums of socks address type */ -enum socks_atyp { - SOCKS_ATYP_IPV4 = 1, - SOCKS_ATYP_DOMAINNAME = 3, - SOCKS_ATYP_IPV6 = 4 -}; - -/* enums of socks authentication methods */ -enum socks_auth_method { - SOCKS_AUTH_NO_AUTH = 0, - SOCKS_AUTH_GSSAPI = 1, - SOCKS_AUTH_USERNAME_PASSWORD = 2 -}; - -/* enums of subnegotiation status */ -enum socks_subnegotiation_status { - SOCKS_SUBNEGOTIATION_STATUS_SUCCESS = 0, -}; - -/* enums of socks request reply */ -enum socks_request_reply { - SOCKS_REQUEST_REPLY_SUCCESS = 0, - SOCKS_REQUEST_REPLY_FAILURE_GENERAL = 1, - SOCKS_REQUEST_REPLY_CONNECTION_NOT_ALLOWED = 2, - SOCKS_REQUEST_REPLY_NETWORK_UNREACHABLE = 3, - SOCKS_REQUEST_REPLY_HOST_UNREACHABLE = 4, - SOCKS_REQUEST_REPLY_CONNECTION_REFUSED = 5, - SOCKS_REQUEST_REPLY_TTL_EXPIRED = 6, - SOCKS_REQUEST_REPLY_COMMAND_NOT_SUPPORTED = 7, - SOCKS_REQUEST_REPLY_ATYP_NOT_SUPPORTED = 8 -}; - -/* enums used to generate socks messages */ -enum socks_msg_type { - /* greeting */ - SOCKS_MSG_GREETING, - /* credential, user name and password */ - SOCKS_MSG_USERNAME_PASSWORD, - /* connect command */ - SOCKS_MSG_CONNECT -}; - -enum { - LWS_RXFLOW_ALLOW = (1 << 0), - LWS_RXFLOW_PENDING_CHANGE = (1 << 1), -}; - -struct lws_ring { - void *buf; - void (*destroy_element)(void *element); - uint32_t buflen; - uint32_t element_len; - uint32_t head; - uint32_t oldest_tail; -}; - -struct lws_protocols; -struct lws; - -struct lws_io_watcher { -#ifdef LWS_WITH_LIBEV - struct lws_io_watcher_libev ev; -#endif -#ifdef LWS_WITH_LIBUV - struct lws_io_watcher_libuv uv; -#endif -#ifdef LWS_WITH_LIBEVENT - struct lws_io_watcher_libevent event; -#endif - struct lws_context *context; - - uint8_t actual_events; -}; - -struct lws_signal_watcher { -#ifdef LWS_WITH_LIBEV - struct lws_signal_watcher_libev ev; -#endif -#ifdef LWS_WITH_LIBUV - struct lws_signal_watcher_libuv uv; -#endif -#ifdef LWS_WITH_LIBEVENT - struct lws_signal_watcher_libevent event; -#endif - struct lws_context *context; -}; - -#ifdef _WIN32 -#define LWS_FD_HASH(fd) ((fd ^ (fd >> 8) ^ (fd >> 16)) % FD_HASHTABLE_MODULUS) -struct lws_fd_hashtable { - struct lws **wsi; - int length; -}; -#endif - -struct lws_foreign_thread_pollfd { - struct lws_foreign_thread_pollfd *next; - int fd_index; - int _and; - int _or; -}; - - -#define LWS_HRTIMER_NOWAIT (0x7fffffffffffffffll) - -/* - * so we can have n connections being serviced simultaneously, - * these things need to be isolated per-thread. - */ - -struct lws_context_per_thread { -#if LWS_MAX_SMP > 1 - pthread_mutex_t lock; - pthread_mutex_t lock_stats; - pthread_t lock_owner; - const char *last_lock_reason; -#endif - - struct lws_context *context; - - /* - * usable by anything in the service code, but only if the scope - * does not last longer than the service action (since next service - * of any socket can likewise use it and overwrite) - */ - unsigned char *serv_buf; - - struct lws_dll_lws dll_head_timeout; - struct lws_dll_lws dll_head_hrtimer; - struct lws_dll_lws dll_head_buflist; /* guys with pending rxflow */ - -#if defined(LWS_WITH_TLS) - struct lws_pt_tls tls; -#endif - - struct lws_pollfd *fds; - volatile struct lws_foreign_thread_pollfd * volatile foreign_pfd_list; -#ifdef _WIN32 - WSAEVENT *events; -#endif - lws_sockfd_type dummy_pipe_fds[2]; - struct lws *pipe_wsi; - - /* --- role based members --- */ - -#if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS) - struct lws_pt_role_ws ws; -#endif -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - struct lws_pt_role_http http; -#endif - - /* --- event library based members --- */ - -#if defined(LWS_WITH_LIBEV) - struct lws_pt_eventlibs_libev ev; -#endif -#if defined(LWS_WITH_LIBUV) - struct lws_pt_eventlibs_libuv uv; -#endif -#if defined(LWS_WITH_LIBEVENT) - struct lws_pt_eventlibs_libevent event; -#endif - -#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBUV) || defined(LWS_WITH_LIBEVENT) - struct lws_signal_watcher w_sigint; -#endif - - /* --- */ - - unsigned long count_conns; - unsigned int fds_count; - - volatile unsigned char inside_poll; - volatile unsigned char foreign_spinlock; - - unsigned char tid; - - unsigned char lock_depth; - unsigned char inside_service:1; - unsigned char event_loop_foreign:1; - unsigned char event_loop_destroy_processing_done:1; -}; - -struct lws_conn_stats { - unsigned long long rx, tx; - unsigned long h1_conn, h1_trans, h2_trans, ws_upg, h2_alpn, h2_subs, - h2_upg, rejected; -}; - -void -lws_sum_stats(const struct lws_context *ctx, struct lws_conn_stats *cs); - -struct lws_timed_vh_protocol { - struct lws_timed_vh_protocol *next; - const struct lws_protocols *protocol; - time_t time; - int reason; -}; - -/* - * virtual host -related context information - * vhostwide SSL context - * vhostwide proxy - * - * hierarchy: - * - * context -> vhost -> wsi - * - * incoming connection non-SSL vhost binding: - * - * listen socket -> wsi -> select vhost after first headers - * - * incoming connection SSL vhost binding: - * - * SSL SNI -> wsi -> bind after SSL negotiation - */ - - -struct lws_vhost { -#if !defined(LWS_WITHOUT_CLIENT) - char proxy_basic_auth_token[128]; -#endif -#if LWS_MAX_SMP > 1 - pthread_mutex_t lock; -#endif - -#if defined(LWS_ROLE_H2) - struct lws_vhost_role_h2 h2; -#endif -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - struct lws_vhost_role_http http; -#endif -#if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS) - struct lws_vhost_role_ws ws; -#endif - -#if defined(LWS_WITH_SOCKS5) - char socks_proxy_address[128]; - char socks_user[96]; - char socks_password[96]; -#endif -#if defined(LWS_WITH_LIBEV) - struct lws_io_watcher w_accept; -#endif - struct lws_conn_stats conn_stats; - struct lws_context *context; - struct lws_vhost *vhost_next; - - struct lws *lserv_wsi; - const char *name; - const char *iface; - -#if !defined(LWS_WITH_ESP32) && !defined(OPTEE_TA) && !defined(WIN32) - int bind_iface; -#endif - const struct lws_protocols *protocols; - void **protocol_vh_privs; - const struct lws_protocol_vhost_options *pvo; - const struct lws_protocol_vhost_options *headers; - struct lws **same_vh_protocol_list; - struct lws_vhost *no_listener_vhost_list; -#if !defined(LWS_NO_CLIENT) - struct lws_dll_lws dll_active_client_conns; -#endif - -#if defined(LWS_WITH_TLS) - struct lws_vhost_tls tls; -#endif - - struct lws_timed_vh_protocol *timed_vh_protocol_list; - void *user; - - int listen_port; - -#if defined(LWS_WITH_SOCKS5) - unsigned int socks_proxy_port; -#endif - unsigned int options; - int count_protocols; - int ka_time; - int ka_probes; - int ka_interval; - int keepalive_timeout; - int timeout_secs_ah_idle; - -#ifdef LWS_WITH_ACCESS_LOG - int log_fd; -#endif - - unsigned int created_vhost_protocols:1; - unsigned int being_destroyed:1; - - unsigned char default_protocol_index; - unsigned char raw_protocol_index; -}; - -struct lws_deferred_free -{ - struct lws_deferred_free *next; - time_t deadline; - void *payload; -}; - -typedef union { -#ifdef LWS_WITH_IPV6 - struct sockaddr_in6 sa6; -#endif - struct sockaddr_in sa4; -} sockaddr46; - - -#if defined(LWS_WITH_PEER_LIMITS) -struct lws_peer { - struct lws_peer *next; - struct lws_peer *peer_wait_list; - - time_t time_created; - time_t time_closed_all; - - uint8_t addr[32]; - uint32_t hash; - uint32_t count_wsi; - uint32_t total_wsi; - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - struct lws_peer_role_http http; -#endif - - uint8_t af; -}; -#endif - -/* - * the rest is managed per-context, that includes - * - * - processwide single fd -> wsi lookup - * - contextwide headers pool - */ - -struct lws_context { - time_t last_timeout_check_s; - time_t last_ws_ping_pong_check_s; - time_t time_up; - time_t time_discontiguity; - time_t time_fixup; - const struct lws_plat_file_ops *fops; - struct lws_plat_file_ops fops_platform; - struct lws_context **pcontext_finalize; - - const struct lws_tls_ops *tls_ops; - -#if defined(LWS_WITH_HTTP2) - struct http2_settings set; -#endif -#if defined(LWS_WITH_ZIP_FOPS) - struct lws_plat_file_ops fops_zip; -#endif - struct lws_context_per_thread pt[LWS_MAX_SMP]; - struct lws_conn_stats conn_stats; -#if LWS_MAX_SMP > 1 - pthread_mutex_t lock; - int lock_depth; -#endif -#ifdef _WIN32 -/* different implementation between unix and windows */ - struct lws_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS]; -#else - struct lws **lws_lookup; /* fd to wsi */ -#endif - struct lws_vhost *vhost_list; - struct lws_vhost *no_listener_vhost_list; - struct lws_vhost *vhost_pending_destruction_list; - struct lws_plugin *plugin_list; - struct lws_deferred_free *deferred_free_list; -#if defined(LWS_WITH_PEER_LIMITS) - struct lws_peer **pl_hash_table; - struct lws_peer *peer_wait_list; - time_t next_cull; -#endif - - void *external_baggage_free_on_destroy; - const struct lws_token_limits *token_limits; - void *user_space; - const struct lws_protocol_vhost_options *reject_service_keywords; - lws_reload_func deprecation_cb; - void (*eventlib_signal_cb)(void *event_lib_handle, int signum); - -#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) - cap_value_t caps[4]; - char count_caps; -#endif - -#if defined(LWS_WITH_LIBEV) - struct lws_context_eventlibs_libev ev; -#endif -#if defined(LWS_WITH_LIBUV) - struct lws_context_eventlibs_libuv uv; -#endif -#if defined(LWS_WITH_LIBEVENT) - struct lws_context_eventlibs_libevent event; -#endif - struct lws_event_loop_ops *event_loop_ops; - - -#if defined(LWS_WITH_TLS) - struct lws_context_tls tls; -#endif - - char canonical_hostname[128]; - const char *server_string; - -#ifdef LWS_LATENCY - unsigned long worst_latency; - char worst_latency_info[256]; -#endif - -#if defined(LWS_WITH_STATS) - uint64_t lws_stats[LWSSTATS_SIZE]; - uint64_t last_dump; - int updated; -#endif -#if defined(LWS_WITH_ESP32) - unsigned long time_last_state_dump; - uint32_t last_free_heap; -#endif - - int max_fds; - int count_event_loop_static_asset_handles; - int started_with_parent; - int uid, gid; - - int fd_random; - - int count_wsi_allocated; - int count_cgi_spawned; - unsigned int options; - unsigned int fd_limit_per_thread; - unsigned int timeout_secs; - unsigned int pt_serv_buf_size; - int max_http_header_data; - int max_http_header_pool; - int simultaneous_ssl_restriction; - int simultaneous_ssl; -#if defined(LWS_WITH_PEER_LIMITS) - uint32_t pl_hash_elements; /* protected by context->lock */ - uint32_t count_peers; /* protected by context->lock */ - unsigned short ip_limit_ah; - unsigned short ip_limit_wsi; -#endif - unsigned int deprecated:1; - unsigned int being_destroyed:1; - unsigned int being_destroyed1:1; - unsigned int being_destroyed2:1; - unsigned int requested_kill:1; - unsigned int protocol_init_done:1; - unsigned int doing_protocol_init:1; - unsigned int done_protocol_destroy_cb:1; - unsigned int finalize_destroy_after_internal_loops_stopped:1; - /* - * set to the Thread ID that's doing the service loop just before entry - * to poll indicates service thread likely idling in poll() - * volatile because other threads may check it as part of processing - * for pollfd event change. - */ - volatile int service_tid; - int service_tid_detected; - - short count_threads; - short plugin_protocol_count; - short plugin_extension_count; - short server_string_len; - unsigned short ws_ping_pong_interval; - unsigned short deprecation_pending_listen_close_count; - - uint8_t max_fi; -}; - -int -lws_check_deferred_free(struct lws_context *context, int force); - -#define lws_get_context_protocol(ctx, x) ctx->vhost_list->protocols[x] -#define lws_get_vh_protocol(vh, x) vh->protocols[x] - -LWS_EXTERN void -__lws_close_free_wsi_final(struct lws *wsi); -LWS_EXTERN void -lws_libuv_closehandle(struct lws *wsi); -LWS_EXTERN int -lws_libuv_check_watcher_active(struct lws *wsi); - -LWS_VISIBLE LWS_EXTERN int -lws_plat_plugins_init(struct lws_context * context, const char * const *d); - -LWS_VISIBLE LWS_EXTERN int -lws_plat_plugins_destroy(struct lws_context * context); - -LWS_EXTERN void -lws_restart_ws_ping_pong_timer(struct lws *wsi); - -struct lws * -lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd); - -int -lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max); - -void -lws_vhost_destroy1(struct lws_vhost *vh); - -enum { - LWS_EV_READ = (1 << 0), - LWS_EV_WRITE = (1 << 1), - LWS_EV_START = (1 << 2), - LWS_EV_STOP = (1 << 3), - - LWS_EV_PREPARE_DELETION = (1 << 31), -}; - - -#if defined(LWS_WITH_ESP32) -LWS_EXTERN int -lws_find_string_in_file(const char *filename, const char *string, int stringlen); -#endif - -#ifdef LWS_WITH_IPV6 -#define LWS_IPV6_ENABLED(vh) \ - (!lws_check_opt(vh->context->options, LWS_SERVER_OPTION_DISABLE_IPV6) && \ - !lws_check_opt(vh->options, LWS_SERVER_OPTION_DISABLE_IPV6)) -#else -#define LWS_IPV6_ENABLED(context) (0) -#endif - -#ifdef LWS_WITH_UNIX_SOCK -#define LWS_UNIX_SOCK_ENABLED(vhost) \ - (vhost->options & LWS_SERVER_OPTION_UNIX_SOCK) -#else -#define LWS_UNIX_SOCK_ENABLED(vhost) (0) -#endif - -enum uri_path_states { - URIPS_IDLE, - URIPS_SEEN_SLASH, - URIPS_SEEN_SLASH_DOT, - URIPS_SEEN_SLASH_DOT_DOT, -}; - -enum uri_esc_states { - URIES_IDLE, - URIES_SEEN_PERCENT, - URIES_SEEN_PERCENT_H1, -}; - - -#ifndef LWS_NO_CLIENT -struct client_info_stash { - char *address; - char *path; - char *host; - char *origin; - char *protocol; - char *method; - char *iface; - char *alpn; -}; -#endif - - -signed char char_to_hex(const char c); - - -struct lws_buflist { - struct lws_buflist *next; - - size_t len; - size_t pos; - - uint8_t buf[1]; /* true length of this is set by the oversize malloc */ -}; - -#define lws_wsi_is_udp(___wsi) (!!___wsi->udp) - -#define LWS_H2_FRAME_HEADER_LENGTH 9 - - -struct lws { - /* structs */ - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - struct _lws_http_mode_related http; -#endif -#if defined(LWS_ROLE_H2) - struct _lws_h2_related h2; -#endif -#if defined(LWS_ROLE_WS) - struct _lws_websocket_related *ws; /* allocated if we upgrade to ws */ -#endif - - const struct lws_role_ops *role_ops; - lws_wsi_state_t wsistate; - lws_wsi_state_t wsistate_pre_close; - - /* lifetime members */ - -#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBUV) || defined(LWS_WITH_LIBEVENT) - struct lws_io_watcher w_read; -#endif -#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBEVENT) - struct lws_io_watcher w_write; -#endif - - /* pointers */ - - struct lws_context *context; - struct lws_vhost *vhost; - struct lws *parent; /* points to parent, if any */ - struct lws *child_list; /* points to first child */ - struct lws *sibling_list; /* subsequent children at same level */ - - const struct lws_protocols *protocol; - struct lws **same_vh_protocol_prev, *same_vh_protocol_next; - - struct lws_dll_lws dll_timeout; - struct lws_dll_lws dll_hrtimer; - struct lws_dll_lws dll_buflist; /* guys with pending rxflow */ - -#if defined(LWS_WITH_PEER_LIMITS) - struct lws_peer *peer; -#endif - - struct lws_udp *udp; -#ifndef LWS_NO_CLIENT - struct client_info_stash *stash; - char *client_hostname_copy; - struct lws_dll_lws dll_active_client_conns; - struct lws_dll_lws dll_client_transaction_queue_head; - struct lws_dll_lws dll_client_transaction_queue; -#endif - void *user_space; - void *opaque_parent_data; - - struct lws_buflist *buflist; - - /* truncated send handling */ - unsigned char *trunc_alloc; /* non-NULL means buffering in progress */ - -#if defined(LWS_WITH_TLS) - struct lws_lws_tls tls; -#endif - - lws_sock_file_fd_type desc; /* .filefd / .sockfd */ -#if defined(LWS_WITH_STATS) - uint64_t active_writable_req_us; -#if defined(LWS_WITH_TLS) - uint64_t accept_start_us; -#endif -#endif - - lws_usec_t pending_timer; /* hrtimer fires */ - time_t pending_timeout_set; /* second-resolution timeout start */ - -#ifdef LWS_LATENCY - unsigned long action_start; - unsigned long latency_start; -#endif - - /* ints */ -#define LWS_NO_FDS_POS (-1) - int position_in_fds_table; - unsigned int trunc_alloc_len; /* size of malloc */ - unsigned int trunc_offset; /* where we are in terms of spilling */ - unsigned int trunc_len; /* how much is buffered */ -#ifndef LWS_NO_CLIENT - int chunk_remaining; -#endif - unsigned int cache_secs; - - unsigned int hdr_parsing_completed:1; - unsigned int http2_substream:1; - unsigned int upgraded_to_http2:1; - unsigned int h2_stream_carries_ws:1; - unsigned int seen_nonpseudoheader:1; - unsigned int listener:1; - unsigned int user_space_externally_allocated:1; - unsigned int socket_is_permanently_unusable:1; - unsigned int rxflow_change_to:2; - unsigned int conn_stat_done:1; - unsigned int cache_reuse:1; - unsigned int cache_revalidate:1; - unsigned int cache_intermediaries:1; - unsigned int favoured_pollin:1; - unsigned int sending_chunked:1; - unsigned int interpreting:1; - unsigned int already_did_cce:1; - unsigned int told_user_closed:1; - unsigned int told_event_loop_closed:1; - unsigned int waiting_to_send_close_frame:1; - unsigned int close_needs_ack:1; - unsigned int ipv6:1; - unsigned int parent_carries_io:1; - unsigned int parent_pending_cb_on_writable:1; - unsigned int cgi_stdout_zero_length:1; - unsigned int seen_zero_length_recv:1; - unsigned int rxflow_will_be_applied:1; - unsigned int event_pipe:1; - unsigned int on_same_vh_list:1; - unsigned int handling_404:1; - unsigned int protocol_bind_balance:1; - - unsigned int could_have_pending:1; /* detect back-to-back writes */ - unsigned int outer_will_close:1; - -#ifdef LWS_WITH_ACCESS_LOG - unsigned int access_log_pending:1; -#endif -#ifndef LWS_NO_CLIENT - unsigned int do_ws:1; /* whether we are doing http or ws flow */ - unsigned int chunked:1; /* if the clientside connection is chunked */ - unsigned int client_rx_avail:1; - unsigned int client_http_body_pending:1; - unsigned int transaction_from_pipeline_queue:1; - unsigned int keepalive_active:1; - unsigned int keepalive_rejected:1; - unsigned int client_pipeline:1; - unsigned int client_h2_alpn:1; - unsigned int client_h2_substream:1; -#endif - -#ifdef _WIN32 - unsigned int sock_send_blocking:1; -#endif - -#ifndef LWS_NO_CLIENT - unsigned short c_port; -#endif - unsigned short pending_timeout_limit; - - /* chars */ - - char lws_rx_parse_state; /* enum lws_rx_parse_state */ - char rx_frame_type; /* enum lws_write_protocol */ - char pending_timeout; /* enum pending_timeout */ - char tsi; /* thread service index we belong to */ - char protocol_interpret_idx; - char redirects; - uint8_t rxflow_bitmap; -#ifdef LWS_WITH_CGI - char cgi_channel; /* which of stdin/out/err */ - char hdr_state; -#endif -#ifndef LWS_NO_CLIENT - char chunk_parser; /* enum lws_chunk_parser */ -#endif -#if defined(LWS_WITH_CGI) || !defined(LWS_NO_CLIENT) - char reason_bf; /* internal writeable callback reason bitfield */ -#endif -#if defined(LWS_WITH_STATS) && defined(LWS_WITH_TLS) - char seen_rx; -#endif - uint8_t ws_over_h2_count; - /* volatile to make sure code is aware other thread can change */ - volatile char handling_pollout; - volatile char leave_pollout_active; -}; - -#define lws_is_flowcontrolled(w) (!!(wsi->rxflow_bitmap)) - -void -lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt); - -LWS_EXTERN int log_level; - -LWS_EXTERN int -lws_socket_bind(struct lws_vhost *vhost, lws_sockfd_type sockfd, int port, - const char *iface); - -#if defined(LWS_WITH_IPV6) -LWS_EXTERN unsigned long -lws_get_addr_scope(const char *ipaddr); -#endif - -LWS_EXTERN void -lws_close_free_wsi(struct lws *wsi, enum lws_close_status, const char *caller); -LWS_EXTERN void -__lws_close_free_wsi(struct lws *wsi, enum lws_close_status, const char *caller); - -LWS_EXTERN void -__lws_free_wsi(struct lws *wsi); - -LWS_EXTERN int -__remove_wsi_socket_from_fds(struct lws *wsi); -LWS_EXTERN int -lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len); - -#ifndef LWS_LATENCY -static LWS_INLINE void -lws_latency(struct lws_context *context, struct lws *wsi, const char *action, - int ret, int completion) { - do { - (void)context; (void)wsi; (void)action; (void)ret; - (void)completion; - } while (0); -} -static LWS_INLINE void -lws_latency_pre(struct lws_context *context, struct lws *wsi) { - do { (void)context; (void)wsi; } while (0); -} -#else -#define lws_latency_pre(_context, _wsi) lws_latency(_context, _wsi, NULL, 0, 0) -extern void -lws_latency(struct lws_context *context, struct lws *wsi, const char *action, - int ret, int completion); -#endif - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_ws_client_rx_sm(struct lws *wsi, unsigned char c); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_parse(struct lws *wsi, unsigned char *buf, int *len); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_parse_urldecode(struct lws *wsi, uint8_t *_c); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_http_action(struct lws *wsi); - -LWS_EXTERN int -lws_b64_selftest(void); - -LWS_EXTERN int -lws_service_flag_pending(struct lws_context *context, int tsi); - -LWS_EXTERN int -lws_timed_callback_remove(struct lws_vhost *vh, struct lws_timed_vh_protocol *p); - -#if defined(_WIN32) -LWS_EXTERN struct lws * -wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd); - -LWS_EXTERN int -insert_wsi(struct lws_context *context, struct lws *wsi); - -LWS_EXTERN int -delete_from_fd(struct lws_context *context, lws_sockfd_type fd); -#else -#define wsi_from_fd(A,B) A->lws_lookup[B - lws_plat_socket_offset()] -#define insert_wsi(A,B) assert(A->lws_lookup[B->desc.sockfd - lws_plat_socket_offset()] == 0); A->lws_lookup[B->desc.sockfd - lws_plat_socket_offset()]=B -#define delete_from_fd(A,B) A->lws_lookup[B - lws_plat_socket_offset()]=0 -#endif - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -__insert_wsi_socket_into_fds(struct lws_context *context, struct lws *wsi); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len); - -LWS_EXTERN void -lws_remove_from_timeout_list(struct lws *wsi); - -LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT -lws_client_connect_2(struct lws *wsi); - -LWS_VISIBLE struct lws * LWS_WARN_UNUSED_RESULT -lws_client_reset(struct lws **wsi, int ssl, const char *address, int port, - const char *path, const char *host); - -LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT -lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi); - -LWS_EXTERN char * LWS_WARN_UNUSED_RESULT -lws_generate_client_handshake(struct lws *wsi, char *pkt); - -LWS_EXTERN int -lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd); - -LWS_EXTERN struct lws * -lws_client_connect_via_info2(struct lws *wsi); - - - -LWS_EXTERN void -lws_client_stash_destroy(struct lws *wsi); - -/* - * EXTENSIONS - */ - -#if defined(LWS_WITHOUT_EXTENSIONS) -#define lws_any_extension_handled(_a, _b, _c, _d) (0) -#define lws_ext_cb_active(_a, _b, _c, _d) (0) -#define lws_ext_cb_all_exts(_a, _b, _c, _d, _e) (0) -#define lws_issue_raw_ext_access lws_issue_raw -#define lws_context_init_extensions(_a, _b) -#endif - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_client_interpret_server_handshake(struct lws *wsi); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_ws_rx_sm(struct lws *wsi, char already_processed, unsigned char c); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len); - -LWS_EXTERN void -lws_role_transition(struct lws *wsi, enum lwsi_role role, enum lwsi_state state, - struct lws_role_ops *ops); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -user_callback_handle_rxflow(lws_callback_function, struct lws *wsi, - enum lws_callback_reasons reason, void *user, - void *in, size_t len); - -LWS_EXTERN int -lws_plat_socket_offset(void); - -LWS_EXTERN int -lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd); - -LWS_EXTERN int -lws_plat_check_connection_error(struct lws *wsi); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_header_table_attach(struct lws *wsi, int autoservice); - -LWS_EXTERN int -lws_header_table_detach(struct lws *wsi, int autoservice); -LWS_EXTERN int -__lws_header_table_detach(struct lws *wsi, int autoservice); - -LWS_EXTERN void -lws_header_table_reset(struct lws *wsi, int autoservice); - -void -__lws_header_table_reset(struct lws *wsi, int autoservice); - -LWS_EXTERN char * LWS_WARN_UNUSED_RESULT -lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_ensure_user_space(struct lws *wsi); - -LWS_EXTERN int -lws_change_pollfd(struct lws *wsi, int _and, int _or); - -#ifndef LWS_NO_SERVER - int _lws_vhost_init_server(const struct lws_context_creation_info *info, - struct lws_vhost *vhost); - LWS_EXTERN struct lws_vhost * - lws_select_vhost(struct lws_context *context, int port, const char *servername); - LWS_EXTERN int LWS_WARN_UNUSED_RESULT - lws_parse_ws(struct lws *wsi, unsigned char **buf, size_t len); - LWS_EXTERN void - lws_server_get_canonical_hostname(struct lws_context *context, - const struct lws_context_creation_info *info); -#else - #define _lws_vhost_init_server(_a, _b) (0) - #define lws_parse_ws(_a, _b, _c) (0) - #define lws_server_get_canonical_hostname(_a, _b) -#endif - -#ifndef LWS_NO_DAEMONIZE - LWS_EXTERN int get_daemonize_pid(); -#else - #define get_daemonize_pid() (0) -#endif - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -interface_to_sa(struct lws_vhost *vh, const char *ifname, - struct sockaddr_in *addr, size_t addrlen); -LWS_EXTERN void lwsl_emit_stderr(int level, const char *line); - -#if !defined(LWS_WITH_TLS) - #define LWS_SSL_ENABLED(context) (0) - #define lws_context_init_server_ssl(_a, _b) (0) - #define lws_ssl_destroy(_a) - #define lws_context_init_alpn(_a) - #define lws_ssl_capable_read lws_ssl_capable_read_no_ssl - #define lws_ssl_capable_write lws_ssl_capable_write_no_ssl - #define lws_ssl_pending lws_ssl_pending_no_ssl - #define lws_server_socket_service_ssl(_b, _c) (0) - #define lws_ssl_close(_a) (0) - #define lws_ssl_context_destroy(_a) - #define lws_ssl_SSL_CTX_destroy(_a) - #define lws_ssl_remove_wsi_from_buffered_list(_a) - #define __lws_ssl_remove_wsi_from_buffered_list(_a) - #define lws_context_init_ssl_library(_a) - #define lws_tls_check_all_cert_lifetimes(_a) - #define lws_tls_acme_sni_cert_destroy(_a) -#endif - - -#if LWS_MAX_SMP > 1 - -static LWS_INLINE void -lws_pt_mutex_init(struct lws_context_per_thread *pt) -{ - pthread_mutex_init(&pt->lock, NULL); - pthread_mutex_init(&pt->lock_stats, NULL); -} - -static LWS_INLINE void -lws_pt_mutex_destroy(struct lws_context_per_thread *pt) -{ - pthread_mutex_destroy(&pt->lock_stats); - pthread_mutex_destroy(&pt->lock); -} - -static LWS_INLINE void -lws_pt_lock(struct lws_context_per_thread *pt, const char *reason) -{ - if (pt->lock_owner == pthread_self()) { - pt->lock_depth++; - return; - } - pthread_mutex_lock(&pt->lock); - pt->last_lock_reason = reason; - pt->lock_owner = pthread_self(); - //lwsl_notice("tid %d: lock %s\n", pt->tid, reason); -} - -static LWS_INLINE void -lws_pt_unlock(struct lws_context_per_thread *pt) -{ - if (pt->lock_depth) { - pt->lock_depth--; - return; - } - pt->last_lock_reason = "free"; - pt->lock_owner = 0; - //lwsl_notice("tid %d: unlock %s\n", pt->tid, pt->last_lock_reason); - pthread_mutex_unlock(&pt->lock); -} - -static LWS_INLINE void -lws_pt_stats_lock(struct lws_context_per_thread *pt) -{ - pthread_mutex_lock(&pt->lock_stats); -} - -static LWS_INLINE void -lws_pt_stats_unlock(struct lws_context_per_thread *pt) -{ - pthread_mutex_unlock(&pt->lock_stats); -} - -static LWS_INLINE void -lws_context_lock(struct lws_context *context) -{ - pthread_mutex_lock(&context->lock); -} - -static LWS_INLINE void -lws_context_unlock(struct lws_context *context) -{ - pthread_mutex_unlock(&context->lock); -} - -static LWS_INLINE void -lws_vhost_lock(struct lws_vhost *vhost) -{ - pthread_mutex_lock(&vhost->lock); -} - -static LWS_INLINE void -lws_vhost_unlock(struct lws_vhost *vhost) -{ - pthread_mutex_unlock(&vhost->lock); -} - - -#else -#define lws_pt_mutex_init(_a) (void)(_a) -#define lws_pt_mutex_destroy(_a) (void)(_a) -#define lws_pt_lock(_a, b) (void)(_a) -#define lws_pt_unlock(_a) (void)(_a) -#define lws_context_lock(_a) (void)(_a) -#define lws_context_unlock(_a) (void)(_a) -#define lws_vhost_lock(_a) (void)(_a) -#define lws_vhost_unlock(_a) (void)(_a) -#define lws_pt_stats_lock(_a) (void)(_a) -#define lws_pt_stats_unlock(_a) (void)(_a) -#endif - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_ssl_capable_read_no_ssl(struct lws *wsi, unsigned char *buf, int len); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_ssl_capable_write_no_ssl(struct lws *wsi, unsigned char *buf, int len); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_ssl_pending_no_ssl(struct lws *wsi); - -int -lws_tls_check_cert_lifetime(struct lws_vhost *vhost); - -int lws_jws_selftest(void); - - -#ifndef LWS_NO_CLIENT -LWS_EXTERN int lws_client_socket_service(struct lws *wsi, - struct lws_pollfd *pollfd, - struct lws *wsi_conn); -LWS_EXTERN struct lws * -lws_client_wsi_effective(struct lws *wsi); -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_http_transaction_completed_client(struct lws *wsi); -#if !defined(LWS_WITH_TLS) - #define lws_context_init_client_ssl(_a, _b) (0) -#endif -LWS_EXTERN void -lws_decode_ssl_error(void); -#else -#define lws_context_init_client_ssl(_a, _b) (0) -#endif - -LWS_EXTERN int -__lws_rx_flow_control(struct lws *wsi); - -LWS_EXTERN int -_lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa); - -#ifndef LWS_NO_SERVER -LWS_EXTERN int -lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len); -#else -#define lws_server_socket_service(_b, _c) (0) -#define lws_handshake_server(_a, _b, _c) (0) -#endif - -#ifdef LWS_WITH_ACCESS_LOG -LWS_EXTERN int -lws_access_log(struct lws *wsi); -LWS_EXTERN void -lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int meth); -#else -#define lws_access_log(_a) -#endif - -LWS_EXTERN int -lws_cgi_kill_terminated(struct lws_context_per_thread *pt); - -LWS_EXTERN void -lws_cgi_remove_and_kill(struct lws *wsi); - -int -lws_protocol_init(struct lws_context *context); - -int -lws_bind_protocol(struct lws *wsi, const struct lws_protocols *p); - -const struct lws_http_mount * -lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len); - -/* - * custom allocator - */ -LWS_EXTERN void * -lws_realloc(void *ptr, size_t size, const char *reason); - -LWS_EXTERN void * LWS_WARN_UNUSED_RESULT -lws_zalloc(size_t size, const char *reason); - -#ifdef LWS_PLAT_OPTEE -void *lws_malloc(size_t size, const char *reason); -void lws_free(void *p); -#define lws_free_set_NULL(P) do { lws_free(P); (P) = NULL; } while(0) -#else -#define lws_malloc(S, R) lws_realloc(NULL, S, R) -#define lws_free(P) lws_realloc(P, 0, "lws_free") -#define lws_free_set_NULL(P) do { lws_realloc(P, 0, "free"); (P) = NULL; } while(0) -#endif - -char * -lws_strdup(const char *s); - -int -lws_plat_pipe_create(struct lws *wsi); -int -lws_plat_pipe_signal(struct lws *wsi); -void -lws_plat_pipe_close(struct lws *wsi); -int -lws_create_event_pipes(struct lws_context *context); - -int lws_open(const char *__file, int __oflag, ...); -void lws_plat_apply_FD_CLOEXEC(int n); - -const struct lws_plat_file_ops * -lws_vfs_select_fops(const struct lws_plat_file_ops *fops, const char *vfs_path, - const char **vpath); - -/* lws_plat_ */ -LWS_EXTERN void -lws_plat_delete_socket_from_fds(struct lws_context *context, - struct lws *wsi, int m); -LWS_EXTERN void -lws_plat_insert_socket_into_fds(struct lws_context *context, - struct lws *wsi); -LWS_EXTERN void -lws_plat_service_periodic(struct lws_context *context); - -LWS_EXTERN int -lws_plat_change_pollfd(struct lws_context *context, struct lws *wsi, - struct lws_pollfd *pfd); -LWS_EXTERN void -lws_add_wsi_to_draining_ext_list(struct lws *wsi); -LWS_EXTERN void -lws_remove_wsi_from_draining_ext_list(struct lws *wsi); -LWS_EXTERN int -lws_plat_context_early_init(void); -LWS_EXTERN void -lws_plat_context_early_destroy(struct lws_context *context); -LWS_EXTERN void -lws_plat_context_late_destroy(struct lws_context *context); -LWS_EXTERN int -lws_poll_listen_fd(struct lws_pollfd *fd); -LWS_EXTERN int -lws_plat_service(struct lws_context *context, int timeout_ms); -LWS_EXTERN LWS_VISIBLE int -_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi); -LWS_EXTERN int -lws_plat_init(struct lws_context *context, - const struct lws_context_creation_info *info); -LWS_EXTERN void -lws_plat_drop_app_privileges(const struct lws_context_creation_info *info); -LWS_EXTERN unsigned long long -time_in_microseconds(void); -LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT -lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt); -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_plat_inet_pton(int af, const char *src, void *dst); - -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_check_utf8(unsigned char *state, unsigned char *buf, size_t len); -LWS_EXTERN int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf, - lws_filepos_t *amount); - - -LWS_EXTERN void -lws_same_vh_protocol_remove(struct lws *wsi); -LWS_EXTERN void -lws_same_vh_protocol_insert(struct lws *wsi, int n); - -LWS_EXTERN int -lws_broadcast(struct lws_context *context, int reason, void *in, size_t len); - -#if defined(LWS_WITH_STATS) - void - lws_stats_atomic_bump(struct lws_context * context, - struct lws_context_per_thread *pt, int index, uint64_t bump); - void - lws_stats_atomic_max(struct lws_context * context, - struct lws_context_per_thread *pt, int index, uint64_t val); -#else - static LWS_INLINE uint64_t lws_stats_atomic_bump(struct lws_context * context, - struct lws_context_per_thread *pt, int index, uint64_t bump) { - (void)context; (void)pt; (void)index; (void)bump; return 0; } - static LWS_INLINE uint64_t lws_stats_atomic_max(struct lws_context * context, - struct lws_context_per_thread *pt, int index, uint64_t val) { - (void)context; (void)pt; (void)index; (void)val; return 0; } -#endif - -/* socks */ -void socks_generate_msg(struct lws *wsi, enum socks_msg_type type, - ssize_t *msg_len); - -#if defined(LWS_WITH_PEER_LIMITS) -void -lws_peer_track_wsi_close(struct lws_context *context, struct lws_peer *peer); -int -lws_peer_confirm_ah_attach_ok(struct lws_context *context, struct lws_peer *peer); -void -lws_peer_track_ah_detach(struct lws_context *context, struct lws_peer *peer); -void -lws_peer_cull_peer_wait_list(struct lws_context *context); -struct lws_peer * -lws_get_or_create_peer(struct lws_vhost *vhost, lws_sockfd_type sockfd); -void -lws_peer_add_wsi(struct lws_context *context, struct lws_peer *peer, - struct lws *wsi); -void -lws_peer_dump_from_wsi(struct lws *wsi); -#endif - -#ifdef LWS_WITH_HTTP_PROXY -hubbub_error -html_parser_cb(const hubbub_token *token, void *pw); -#endif - - -void -__lws_remove_from_timeout_list(struct lws *wsi); - -lws_usec_t -__lws_hrtimer_service(struct lws_context_per_thread *pt); - -void -__lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); -int -__lws_change_pollfd(struct lws *wsi, int _and, int _or); - - -int -lws_callback_as_writeable(struct lws *wsi); -int -lws_buflist_aware_read(struct lws_context_per_thread *pt, struct lws *wsi, - struct lws_tokens *ebuf); -int -lws_buflist_aware_consume(struct lws *wsi, struct lws_tokens *ebuf, int used, - int buffered); - - -char * -lws_generate_client_ws_handshake(struct lws *wsi, char *p); -int -lws_client_ws_upgrade(struct lws *wsi, const char **cce); -int -lws_create_client_ws_object(struct lws_client_connect_info *i, struct lws *wsi); -int -lws_alpn_comma_to_openssl(const char *comma, uint8_t *os, int len); -int -lws_role_call_alpn_negotiated(struct lws *wsi, const char *alpn); -int -lws_tls_server_conn_alpn(struct lws *wsi); - -int -lws_ws_client_rx_sm_block(struct lws *wsi, unsigned char **buf, size_t len); -void -lws_destroy_event_pipe(struct lws *wsi); -void -lws_context_destroy2(struct lws_context *context); - -#ifdef __cplusplus -}; -#endif diff --git a/thirdparty/libwebsockets/core/service.c b/thirdparty/libwebsockets/core/service.c deleted file mode 100644 index 6523058814..0000000000 --- a/thirdparty/libwebsockets/core/service.c +++ /dev/null @@ -1,987 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -int -lws_callback_as_writeable(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - int n, m; - - lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_WRITEABLE_CB, 1); -#if defined(LWS_WITH_STATS) - if (wsi->active_writable_req_us) { - uint64_t ul = time_in_microseconds() - - wsi->active_writable_req_us; - - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_MS_WRITABLE_DELAY, ul); - lws_stats_atomic_max(wsi->context, pt, - LWSSTATS_MS_WORST_WRITABLE_DELAY, ul); - wsi->active_writable_req_us = 0; - } -#endif - - n = wsi->role_ops->writeable_cb[lwsi_role_server(wsi)]; - - m = user_callback_handle_rxflow(wsi->protocol->callback, - wsi, (enum lws_callback_reasons) n, - wsi->user_space, NULL, 0); - - return m; -} - -LWS_VISIBLE int -lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd) -{ - volatile struct lws *vwsi = (volatile struct lws *)wsi; - int n; - - //lwsl_notice("%s: %p\n", __func__, wsi); - - vwsi->leave_pollout_active = 0; - vwsi->handling_pollout = 1; - /* - * if another thread wants POLLOUT on us, from here on while - * handling_pollout is set, he will only set leave_pollout_active. - * If we are going to disable POLLOUT, we will check that first. - */ - wsi->could_have_pending = 0; /* clear back-to-back write detection */ - - /* - * user callback is lowest priority to get these notifications - * actually, since other pending things cannot be disordered - * - * Priority 1: pending truncated sends are incomplete ws fragments - * If anything else sent first the protocol would be - * corrupted. - */ - - if (wsi->trunc_len) { - //lwsl_notice("%s: completing partial\n", __func__); - if (lws_issue_raw(wsi, wsi->trunc_alloc + wsi->trunc_offset, - wsi->trunc_len) < 0) { - lwsl_info("%s signalling to close\n", __func__); - goto bail_die; - } - /* leave POLLOUT active either way */ - goto bail_ok; - } else - if (lwsi_state(wsi) == LRS_FLUSHING_BEFORE_CLOSE) { - wsi->socket_is_permanently_unusable = 1; - goto bail_die; /* retry closing now */ - } - -#ifdef LWS_WITH_CGI - /* - * A cgi master's wire protocol remains h1 or h2. He is just getting - * his data from his child cgis. - */ - if (wsi->http.cgi) { - /* also one shot */ - if (pollfd) - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) { - lwsl_info("failed at set pollfd\n"); - return 1; - } - goto user_service_go_again; - } -#endif - - /* if we got here, we should have wire protocol ops set on the wsi */ - assert(wsi->role_ops); - - if (!wsi->role_ops->handle_POLLOUT) - goto bail_ok; - - switch ((wsi->role_ops->handle_POLLOUT)(wsi)) { - case LWS_HP_RET_BAIL_OK: - goto bail_ok; - case LWS_HP_RET_BAIL_DIE: - goto bail_die; - case LWS_HP_RET_USER_SERVICE: - break; - default: - assert(0); - } - - /* one shot */ - - if (wsi->parent_carries_io) { - vwsi->handling_pollout = 0; - vwsi->leave_pollout_active = 0; - - return lws_callback_as_writeable(wsi); - } - - if (pollfd) { - int eff = vwsi->leave_pollout_active; - - if (!eff) { - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) { - lwsl_info("failed at set pollfd\n"); - goto bail_die; - } - } - - vwsi->handling_pollout = 0; - - /* cannot get leave_pollout_active set after the above */ - if (!eff && wsi->leave_pollout_active) { - /* - * got set inbetween sampling eff and clearing - * handling_pollout, force POLLOUT on - */ - lwsl_debug("leave_pollout_active\n"); - if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) { - lwsl_info("failed at set pollfd\n"); - goto bail_die; - } - } - - vwsi->leave_pollout_active = 0; - } - - if (lwsi_role_client(wsi) && - !wsi->hdr_parsing_completed && - lwsi_state(wsi) != LRS_H2_WAITING_TO_SEND_HEADERS && - lwsi_state(wsi) != LRS_ISSUE_HTTP_BODY - ) - goto bail_ok; - - -#ifdef LWS_WITH_CGI -user_service_go_again: -#endif - - if (wsi->role_ops->perform_user_POLLOUT) { - if (wsi->role_ops->perform_user_POLLOUT(wsi) == -1) - goto bail_die; - else - goto bail_ok; - } - - lwsl_debug("%s: %p: non mux: wsistate 0x%x, ops %s\n", __func__, wsi, - wsi->wsistate, wsi->role_ops->name); - - vwsi = (volatile struct lws *)wsi; - vwsi->leave_pollout_active = 0; - - n = lws_callback_as_writeable(wsi); - vwsi->handling_pollout = 0; - - if (vwsi->leave_pollout_active) - lws_change_pollfd(wsi, 0, LWS_POLLOUT); - - return n; - - /* - * since these don't disable the POLLOUT, they are always doing the - * right thing for leave_pollout_active whether it was set or not. - */ - -bail_ok: - vwsi->handling_pollout = 0; - vwsi->leave_pollout_active = 0; - - return 0; - -bail_die: - vwsi->handling_pollout = 0; - vwsi->leave_pollout_active = 0; - - return -1; -} - -static int -__lws_service_timeout_check(struct lws *wsi, time_t sec) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - int n = 0; - - (void)n; - - /* - * if we went beyond the allowed time, kill the - * connection - */ - if (wsi->dll_timeout.prev && - lws_compare_time_t(wsi->context, sec, wsi->pending_timeout_set) > - wsi->pending_timeout_limit) { - - if (wsi->desc.sockfd != LWS_SOCK_INVALID && - wsi->position_in_fds_table >= 0) - n = pt->fds[wsi->position_in_fds_table].events; - - lws_stats_atomic_bump(wsi->context, pt, LWSSTATS_C_TIMEOUTS, 1); - - /* no need to log normal idle keepalive timeout */ - if (wsi->pending_timeout != PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE) -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - lwsl_info("wsi %p: TIMEDOUT WAITING on %d " - "(did hdr %d, ah %p, wl %d, pfd " - "events %d) %llu vs %llu\n", - (void *)wsi, wsi->pending_timeout, - wsi->hdr_parsing_completed, wsi->http.ah, - pt->http.ah_wait_list_length, n, - (unsigned long long)sec, - (unsigned long long)wsi->pending_timeout_limit); -#if defined(LWS_WITH_CGI) - if (wsi->http.cgi) - lwsl_notice("CGI timeout: %s\n", wsi->http.cgi->summary); -#endif -#else - lwsl_info("wsi %p: TIMEDOUT WAITING on %d ", (void *)wsi, - wsi->pending_timeout); -#endif - - /* - * Since he failed a timeout, he already had a chance to do - * something and was unable to... that includes situations like - * half closed connections. So process this "failed timeout" - * close as a violent death and don't try to do protocol - * cleanup like flush partials. - */ - wsi->socket_is_permanently_unusable = 1; - if (lwsi_state(wsi) == LRS_WAITING_SSL && wsi->protocol) - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, - (void *)"Timed out waiting SSL", 21); - - __lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "timeout"); - - return 1; - } - - return 0; -} - -int lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - uint8_t *buffered; - size_t blen; - int ret = 0, m; - - /* his RX is flowcontrolled, don't send remaining now */ - blen = lws_buflist_next_segment_len(&wsi->buflist, &buffered); - if (blen) { - if (buf >= buffered && buf + len <= buffered + blen) { - /* rxflow while we were spilling prev rxflow */ - lwsl_info("%s: staying in rxflow buf\n", __func__); - - return 1; - } - ret = 1; - } - - /* a new rxflow, buffer it and warn caller */ - - m = lws_buflist_append_segment(&wsi->buflist, buf + n, len - n); - - if (m < 0) - return -1; - if (m) { - lwsl_debug("%s: added %p to rxflow list\n", __func__, wsi); - lws_dll_lws_add_front(&wsi->dll_buflist, &pt->dll_head_buflist); - } - - return ret; -} - -/* this is used by the platform service code to stop us waiting for network - * activity in poll() when we have something that already needs service - */ - -LWS_VISIBLE LWS_EXTERN int -lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int tsi) -{ - struct lws_context_per_thread *pt = &context->pt[tsi]; - - /* Figure out if we really want to wait in poll() - * We only need to wait if really nothing already to do and we have - * to wait for something from network - */ -#if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS) - /* 1) if we know we are draining rx ext, do not wait in poll */ - if (pt->ws.rx_draining_ext_list) - return 0; -#endif - - /* 2) if we know we have non-network pending data, do not wait in poll */ - - if (pt->context->tls_ops && - pt->context->tls_ops->fake_POLLIN_for_buffered) - if (pt->context->tls_ops->fake_POLLIN_for_buffered(pt)) - return 0; - - /* 3) If there is any wsi with rxflow buffered and in a state to process - * it, we should not wait in poll - */ - - lws_start_foreach_dll(struct lws_dll_lws *, d, pt->dll_head_buflist.next) { - struct lws *wsi = lws_container_of(d, struct lws, dll_buflist); - - if (lwsi_state(wsi) != LRS_DEFERRING_ACTION) - return 0; - - } lws_end_foreach_dll(d); - - return timeout_ms; -} - -/* - * POLLIN said there is something... we must read it, and either use it; or - * if other material already in the buflist append it and return the buflist - * head material. - */ -int -lws_buflist_aware_read(struct lws_context_per_thread *pt, struct lws *wsi, - struct lws_tokens *ebuf) -{ - int n, prior = (int)lws_buflist_next_segment_len(&wsi->buflist, NULL); - - ebuf->token = (char *)pt->serv_buf; - ebuf->len = lws_ssl_capable_read(wsi, pt->serv_buf, - wsi->context->pt_serv_buf_size); - - if (ebuf->len == LWS_SSL_CAPABLE_MORE_SERVICE && prior) - goto get_from_buflist; - - if (ebuf->len <= 0) - return 0; - - /* nothing in buflist already? Then just use what we read */ - - if (!prior) - return 0; - - /* stash what we read */ - - n = lws_buflist_append_segment(&wsi->buflist, (uint8_t *)ebuf->token, - ebuf->len); - if (n < 0) - return -1; - if (n) { - lwsl_debug("%s: added %p to rxflow list\n", __func__, wsi); - lws_dll_lws_add_front(&wsi->dll_buflist, &pt->dll_head_buflist); - } - - /* get the first buflist guy in line */ - -get_from_buflist: - - ebuf->len = (int)lws_buflist_next_segment_len(&wsi->buflist, - (uint8_t **)&ebuf->token); - - return 1; /* came from buflist */ -} - -int -lws_buflist_aware_consume(struct lws *wsi, struct lws_tokens *ebuf, int used, - int buffered) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - int m; - - /* it's in the buflist; we didn't use any */ - - if (!used && buffered) - return 0; - - if (used && buffered) { - m = lws_buflist_use_segment(&wsi->buflist, used); - lwsl_info("%s: draining rxflow: used %d, next %d\n", - __func__, used, m); - if (m) - return 0; - - lwsl_info("%s: removed %p from dll_buflist\n", __func__, wsi); - lws_dll_lws_remove(&wsi->dll_buflist); - - return 0; - } - - /* any remainder goes on the buflist */ - - if (used != ebuf->len) { - m = lws_buflist_append_segment(&wsi->buflist, - (uint8_t *)ebuf->token + used, - ebuf->len - used); - if (m < 0) - return 1; /* OOM */ - if (m) { - lwsl_debug("%s: added %p to rxflow list\n", __func__, wsi); - lws_dll_lws_add_front(&wsi->dll_buflist, &pt->dll_head_buflist); - } - } - - return 0; -} - -void -lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt) -{ - struct lws_pollfd pfd; - - if (!pt->dll_head_buflist.next) - return; - - /* - * service all guys with pending rxflow that reached a state they can - * accept the pending data - */ - - lws_pt_lock(pt, __func__); - - lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, - pt->dll_head_buflist.next) { - struct lws *wsi = lws_container_of(d, struct lws, dll_buflist); - - pfd.events = LWS_POLLIN; - pfd.revents = LWS_POLLIN; - pfd.fd = -1; - - lwsl_debug("%s: rxflow processing: %p 0x%x\n", __func__, wsi, - wsi->wsistate); - - if (!lws_is_flowcontrolled(wsi) && - lwsi_state(wsi) != LRS_DEFERRING_ACTION && - (wsi->role_ops->handle_POLLIN)(pt, wsi, &pfd) == - LWS_HPI_RET_PLEASE_CLOSE_ME) - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, - "close_and_handled"); - - } lws_end_foreach_dll_safe(d, d1); - - lws_pt_unlock(pt); -} - -/* - * guys that need POLLIN service again without waiting for network action - * can force POLLIN here if not flowcontrolled, so they will get service. - * - * Return nonzero if anybody got their POLLIN faked - */ -int -lws_service_flag_pending(struct lws_context *context, int tsi) -{ - struct lws_context_per_thread *pt = &context->pt[tsi]; - -#if defined(LWS_WITH_TLS) - struct lws *wsi, *wsi_next; -#endif - int forced = 0; - - lws_pt_lock(pt, __func__); - - /* - * 1) If there is any wsi with a buflist and in a state to process - * it, we should not wait in poll - */ - - lws_start_foreach_dll(struct lws_dll_lws *, d, pt->dll_head_buflist.next) { - struct lws *wsi = lws_container_of(d, struct lws, dll_buflist); - - if (lwsi_state(wsi) != LRS_DEFERRING_ACTION) { - forced = 1; - break; - } - } lws_end_foreach_dll(d); - -#if defined(LWS_ROLE_WS) - forced |= role_ops_ws.service_flag_pending(context, tsi); -#endif - -#if defined(LWS_WITH_TLS) - /* - * 2) For all guys with buffered SSL read data already saved up, if they - * are not flowcontrolled, fake their POLLIN status so they'll get - * service to use up the buffered incoming data, even though their - * network socket may have nothing - */ - wsi = pt->tls.pending_read_list; - while (wsi) { - wsi_next = wsi->tls.pending_read_list_next; - pt->fds[wsi->position_in_fds_table].revents |= - pt->fds[wsi->position_in_fds_table].events & LWS_POLLIN; - if (pt->fds[wsi->position_in_fds_table].revents & LWS_POLLIN) { - forced = 1; - /* - * he's going to get serviced now, take him off the - * list of guys with buffered SSL. If he still has some - * at the end of the service, he'll get put back on the - * list then. - */ - __lws_ssl_remove_wsi_from_buffered_list(wsi); - } - - wsi = wsi_next; - } -#endif - - lws_pt_unlock(pt); - - return forced; -} - -static int -lws_service_periodic_checks(struct lws_context *context, - struct lws_pollfd *pollfd, int tsi) -{ - struct lws_context_per_thread *pt = &context->pt[tsi]; - lws_sockfd_type our_fd = 0, tmp_fd; - struct lws *wsi; - int timed_out = 0; - time_t now; -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - struct allocated_headers *ah; - int m; -#endif - - if (!context->protocol_init_done) - if (lws_protocol_init(context)) - return -1; - - time(&now); - - /* - * handle case that system time was uninitialized when lws started - * at boot, and got initialized a little later - */ - if (context->time_up < 1464083026 && now > 1464083026) - context->time_up = now; - - if (context->last_timeout_check_s && - now - context->last_timeout_check_s > 100) { - /* - * There has been a discontiguity. Any stored time that is - * less than context->time_discontiguity should have context-> - * time_fixup added to it. - * - * Some platforms with no RTC will experience this as a normal - * event when ntp sets their clock, but we can have started - * long before that with a 0-based unix time. - */ - - context->time_discontiguity = now; - context->time_fixup = now - context->last_timeout_check_s; - - lwsl_notice("time discontiguity: at old time %llus, " - "new time %llus: +%llus\n", - (unsigned long long)context->last_timeout_check_s, - (unsigned long long)context->time_discontiguity, - (unsigned long long)context->time_fixup); - - context->last_timeout_check_s = now - 1; - } - - if (!lws_compare_time_t(context, context->last_timeout_check_s, now)) - return 0; - - context->last_timeout_check_s = now; - -#if defined(LWS_WITH_STATS) - if (!tsi && now - context->last_dump > 10) { - lws_stats_log_dump(context); - context->last_dump = now; - } -#endif - - lws_plat_service_periodic(context); - lws_check_deferred_free(context, 0); - -#if defined(LWS_WITH_PEER_LIMITS) - lws_peer_cull_peer_wait_list(context); -#endif - - /* retire unused deprecated context */ -#if !defined(LWS_PLAT_OPTEE) && !defined(LWS_WITH_ESP32) -#if !defined(_WIN32) - if (context->deprecated && !context->count_wsi_allocated) { - lwsl_notice("%s: ending deprecated context\n", __func__); - kill(getpid(), SIGINT); - return 0; - } -#endif -#endif - /* global timeout check once per second */ - - if (pollfd) - our_fd = pollfd->fd; - - /* - * Phase 1: check every wsi on the timeout check list - */ - - lws_pt_lock(pt, __func__); - - lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, - context->pt[tsi].dll_head_timeout.next) { - wsi = lws_container_of(d, struct lws, dll_timeout); - tmp_fd = wsi->desc.sockfd; - if (__lws_service_timeout_check(wsi, now)) { - /* he did time out... */ - if (tmp_fd == our_fd) - /* it was the guy we came to service! */ - timed_out = 1; - /* he's gone, no need to mark as handled */ - } - } lws_end_foreach_dll_safe(d, d1); - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - /* - * Phase 2: double-check active ah timeouts independent of wsi - * timeout status - */ - - ah = pt->http.ah_list; - while (ah) { - int len; - char buf[256]; - const unsigned char *c; - - if (!ah->in_use || !ah->wsi || !ah->assigned || - (ah->wsi->vhost && - lws_compare_time_t(context, now, ah->assigned) < - ah->wsi->vhost->timeout_secs_ah_idle + 360)) { - ah = ah->next; - continue; - } - - /* - * a single ah session somehow got held for - * an unreasonable amount of time. - * - * Dump info on the connection... - */ - wsi = ah->wsi; - buf[0] = '\0'; -#if !defined(LWS_PLAT_OPTEE) - lws_get_peer_simple(wsi, buf, sizeof(buf)); -#else - buf[0] = '\0'; -#endif - lwsl_notice("ah excessive hold: wsi %p\n" - " peer address: %s\n" - " ah pos %u\n", - wsi, buf, ah->pos); - buf[0] = '\0'; - m = 0; - do { - c = lws_token_to_string(m); - if (!c) - break; - if (!(*c)) - break; - - len = lws_hdr_total_length(wsi, m); - if (!len || len > (int)sizeof(buf) - 1) { - m++; - continue; - } - - if (lws_hdr_copy(wsi, buf, - sizeof buf, m) > 0) { - buf[sizeof(buf) - 1] = '\0'; - - lwsl_notice(" %s = %s\n", - (const char *)c, buf); - } - m++; - } while (1); - - /* explicitly detach the ah */ - lws_header_table_detach(wsi, 0); - - /* ... and then drop the connection */ - - m = 0; - if (wsi->desc.sockfd == our_fd) { - m = timed_out; - - /* it was the guy we came to service! */ - timed_out = 1; - } - - if (!m) /* if he didn't already timeout */ - __lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, - "excessive ah"); - - ah = pt->http.ah_list; - } -#endif - lws_pt_unlock(pt); - -#if 0 - { - char s[300], *p = s; - - for (n = 0; n < context->count_threads; n++) - p += sprintf(p, " %7lu (%5d), ", - context->pt[n].count_conns, - context->pt[n].fds_count); - - lwsl_notice("load: %s\n", s); - } -#endif - /* - * Phase 3: vhost / protocol timer callbacks - */ - - wsi = NULL; - lws_start_foreach_ll(struct lws_vhost *, v, context->vhost_list) { - struct lws_timed_vh_protocol *nx; - if (v->timed_vh_protocol_list) { - lws_start_foreach_ll(struct lws_timed_vh_protocol *, - q, v->timed_vh_protocol_list) { - if (now >= q->time) { - if (!wsi) - wsi = lws_zalloc(sizeof(*wsi), "cbwsi"); - wsi->context = context; - wsi->vhost = v; - wsi->protocol = q->protocol; - lwsl_debug("timed cb: vh %s, protocol %s, reason %d\n", v->name, q->protocol->name, q->reason); - q->protocol->callback(wsi, q->reason, NULL, NULL, 0); - nx = q->next; - lws_timed_callback_remove(v, q); - q = nx; - continue; /* we pointed ourselves to the next from the now-deleted guy */ - } - } lws_end_foreach_ll(q, next); - } - } lws_end_foreach_ll(v, vhost_next); - if (wsi) - lws_free(wsi); - - /* - * Phase 4: check for unconfigured vhosts due to required - * interface missing before - */ - - lws_context_lock(context); - lws_start_foreach_llp(struct lws_vhost **, pv, - context->no_listener_vhost_list) { - struct lws_vhost *v = *pv; - lwsl_debug("deferred iface: checking if on vh %s\n", (*pv)->name); - if (_lws_vhost_init_server(NULL, *pv) == 0) { - /* became happy */ - lwsl_notice("vh %s: became connected\n", v->name); - *pv = v->no_listener_vhost_list; - v->no_listener_vhost_list = NULL; - break; - } - } lws_end_foreach_llp(pv, no_listener_vhost_list); - lws_context_unlock(context); - - /* - * Phase 5: role periodic checks - */ -#if defined(LWS_ROLE_WS) - role_ops_ws.periodic_checks(context, tsi, now); -#endif -#if defined(LWS_ROLE_CGI) - role_ops_cgi.periodic_checks(context, tsi, now); -#endif - - /* - * Phase 6: check the remaining cert lifetime daily - */ - - if (context->tls_ops && - context->tls_ops->periodic_housekeeping) - context->tls_ops->periodic_housekeeping(context, now); - - return timed_out; -} - -LWS_VISIBLE int -lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, - int tsi) -{ - struct lws_context_per_thread *pt = &context->pt[tsi]; - struct lws *wsi; - - if (!context || context->being_destroyed1) - return -1; - - /* the socket we came to service timed out, nothing to do */ - if (lws_service_periodic_checks(context, pollfd, tsi) || !pollfd) - return 0; - - /* no, here to service a socket descriptor */ - wsi = wsi_from_fd(context, pollfd->fd); - if (!wsi) - /* not lws connection ... leave revents alone and return */ - return 0; - - /* - * so that caller can tell we handled, past here we need to - * zero down pollfd->revents after handling - */ - - /* handle session socket closed */ - - if ((!(pollfd->revents & pollfd->events & LWS_POLLIN)) && - (pollfd->revents & LWS_POLLHUP)) { - wsi->socket_is_permanently_unusable = 1; - lwsl_debug("Session Socket %p (fd=%d) dead\n", - (void *)wsi, pollfd->fd); - - goto close_and_handled; - } - -#ifdef _WIN32 - if (pollfd->revents & LWS_POLLOUT) - wsi->sock_send_blocking = FALSE; -#endif - - if ((!(pollfd->revents & pollfd->events & LWS_POLLIN)) && - (pollfd->revents & LWS_POLLHUP)) { - lwsl_debug("pollhup\n"); - wsi->socket_is_permanently_unusable = 1; - goto close_and_handled; - } - -#if defined(LWS_WITH_TLS) - if (lwsi_state(wsi) == LRS_SHUTDOWN && - lws_is_ssl(wsi) && wsi->tls.ssl) { - switch (__lws_tls_shutdown(wsi)) { - case LWS_SSL_CAPABLE_DONE: - case LWS_SSL_CAPABLE_ERROR: - goto close_and_handled; - - case LWS_SSL_CAPABLE_MORE_SERVICE_READ: - case LWS_SSL_CAPABLE_MORE_SERVICE_WRITE: - case LWS_SSL_CAPABLE_MORE_SERVICE: - goto handled; - } - } -#endif - wsi->could_have_pending = 0; /* clear back-to-back write detection */ - - /* okay, what we came here to do... */ - - /* if we got here, we should have wire protocol ops set on the wsi */ - assert(wsi->role_ops); - - // lwsl_notice("%s: %s: wsistate 0x%x\n", __func__, wsi->role_ops->name, - // wsi->wsistate); - - switch ((wsi->role_ops->handle_POLLIN)(pt, wsi, pollfd)) { - case LWS_HPI_RET_WSI_ALREADY_DIED: - return 1; - case LWS_HPI_RET_HANDLED: - break; - case LWS_HPI_RET_PLEASE_CLOSE_ME: -close_and_handled: - lwsl_debug("%p: Close and handled\n", wsi); - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, - "close_and_handled"); -#if defined(_DEBUG) && defined(LWS_WITH_LIBUV) - /* - * confirm close has no problem being called again while - * it waits for libuv service to complete the first async - * close - */ - if (context->event_loop_ops == &event_loop_ops_uv) - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, - "close_and_handled uv repeat test"); -#endif - /* - * pollfd may point to something else after the close - * due to pollfd swapping scheme on delete on some platforms - * we can't clear revents now because it'd be the wrong guy's - * revents - */ - return 1; - default: - assert(0); - } -#if defined(LWS_WITH_TLS) -handled: -#endif - pollfd->revents = 0; - - lws_pt_lock(pt, __func__); - __lws_hrtimer_service(pt); - lws_pt_unlock(pt); - - return 0; -} - -LWS_VISIBLE int -lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd) -{ - return lws_service_fd_tsi(context, pollfd, 0); -} - -LWS_VISIBLE int -lws_service(struct lws_context *context, int timeout_ms) -{ - struct lws_context_per_thread *pt = &context->pt[0]; - int n; - - if (!context) - return 1; - - pt->inside_service = 1; - - if (context->event_loop_ops->run_pt) { - /* we are configured for an event loop */ - context->event_loop_ops->run_pt(context, 0); - - pt->inside_service = 0; - - return 1; - } - n = lws_plat_service(context, timeout_ms); - - pt->inside_service = 0; - - return n; -} - -LWS_VISIBLE int -lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi) -{ - struct lws_context_per_thread *pt = &context->pt[tsi]; - int n; - - pt->inside_service = 1; - - if (context->event_loop_ops->run_pt) { - /* we are configured for an event loop */ - context->event_loop_ops->run_pt(context, tsi); - - pt->inside_service = 0; - - return 1; - } - - n = _lws_plat_service_tsi(context, timeout_ms, tsi); - - pt->inside_service = 0; - - return n; -} diff --git a/thirdparty/libwebsockets/event-libs/poll/poll.c b/thirdparty/libwebsockets/event-libs/poll/poll.c deleted file mode 100644 index 09af5b15d8..0000000000 --- a/thirdparty/libwebsockets/event-libs/poll/poll.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * This is included from core/private.h if LWS_ROLE_WS - */ - -#include <core/private.h> - -struct lws_event_loop_ops event_loop_ops_poll = { - /* name */ "poll", - /* init_context */ NULL, - /* destroy_context1 */ NULL, - /* destroy_context2 */ NULL, - /* init_vhost_listen_wsi */ NULL, - /* init_pt */ NULL, - /* wsi_logical_close */ NULL, - /* check_client_connect_ok */ NULL, - /* close_handle_manually */ NULL, - /* accept */ NULL, - /* io */ NULL, - /* run */ NULL, - /* destroy_pt */ NULL, - /* destroy wsi */ NULL, - - /* periodic_events_available */ 1, -};
\ No newline at end of file diff --git a/thirdparty/libwebsockets/event-libs/poll/private.h b/thirdparty/libwebsockets/event-libs/poll/private.h deleted file mode 100644 index ca313ebfb0..0000000000 --- a/thirdparty/libwebsockets/event-libs/poll/private.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - */ - -extern struct lws_event_loop_ops event_loop_ops_poll; diff --git a/thirdparty/libwebsockets/event-libs/private.h b/thirdparty/libwebsockets/event-libs/private.h deleted file mode 100644 index c36d39c8c2..0000000000 --- a/thirdparty/libwebsockets/event-libs/private.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * This is included from core/private.h - */ - -struct lws_event_loop_ops { - const char *name; - /* event loop-specific context init during context creation */ - int (*init_context)(struct lws_context *context, - const struct lws_context_creation_info *info); - /* called during lws_destroy_context */ - int (*destroy_context1)(struct lws_context *context); - /* called during lws_destroy_context2 */ - int (*destroy_context2)(struct lws_context *context); - /* init vhost listening wsi */ - int (*init_vhost_listen_wsi)(struct lws *wsi); - /* init the event loop for a pt */ - int (*init_pt)(struct lws_context *context, void *_loop, int tsi); - /* called at end of first phase of close_free_wsi() */ - int (*wsi_logical_close)(struct lws *wsi); - /* return nonzero if client connect not allowed */ - int (*check_client_connect_ok)(struct lws *wsi); - /* close handle manually */ - void (*close_handle_manually)(struct lws *wsi); - /* event loop accept processing */ - void (*accept)(struct lws *wsi); - /* control wsi active events */ - void (*io)(struct lws *wsi, int flags); - /* run the event loop for a pt */ - void (*run_pt)(struct lws_context *context, int tsi); - /* called before pt is destroyed */ - void (*destroy_pt)(struct lws_context *context, int tsi); - /* called just before wsi is freed */ - void (*destroy_wsi)(struct lws *wsi); - - unsigned int periodic_events_available:1; -}; - -/* bring in event libs private declarations */ - -#if defined(LWS_WITH_POLL) -#include "event-libs/poll/private.h" -#endif - -#if defined(LWS_WITH_LIBUV) -#include "event-libs/libuv/private.h" -#endif - -#if defined(LWS_WITH_LIBEVENT) -#include "event-libs/libevent/private.h" -#endif - -#if defined(LWS_WITH_LIBEV) -#include "event-libs/libev/private.h" -#endif - diff --git a/thirdparty/libwebsockets/ipv6_fixes.diff b/thirdparty/libwebsockets/ipv6_fixes.diff deleted file mode 100644 index fe3e5e4b63..0000000000 --- a/thirdparty/libwebsockets/ipv6_fixes.diff +++ /dev/null @@ -1,32 +0,0 @@ -diff --git a/thirdparty/libwebsockets/plat/lws-plat-unix.c b/thirdparty/libwebsockets/plat/lws-plat-unix.c -index 7dba3bd82..d1bca8b5d 100644 ---- a/thirdparty/libwebsockets/plat/lws-plat-unix.c -+++ b/thirdparty/libwebsockets/plat/lws-plat-unix.c -@@ -328,6 +328,11 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, int fd) - int optval = 1; - socklen_t optlen = sizeof(optval); - -+#ifdef LWS_WITH_IPV6 -+ optval = 0; -+ setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&optval, optlen); -+#endif -+ - #if defined(__APPLE__) || \ - defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \ - defined(__NetBSD__) || \ -diff --git a/thirdparty/libwebsockets/plat/lws-plat-win.c b/thirdparty/libwebsockets/plat/lws-plat-win.c -index 1850b6425..26caab2cd 100644 ---- a/thirdparty/libwebsockets/plat/lws-plat-win.c -+++ b/thirdparty/libwebsockets/plat/lws-plat-win.c -@@ -348,6 +348,11 @@ lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd) - struct protoent *tcp_proto; - #endif - -+#ifdef LWS_WITH_IPV6 -+ optval = 0; -+ setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&optval, optlen); -+#endif -+ - if (vhost->ka_time) { - /* enable keepalive on this socket */ - optval = 1; diff --git a/thirdparty/libwebsockets/libwebsockets.h b/thirdparty/libwebsockets/libwebsockets.h deleted file mode 100644 index 2c01696404..0000000000 --- a/thirdparty/libwebsockets/libwebsockets.h +++ /dev/null @@ -1,7346 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -/** @file */ - -#ifndef LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C -#define LIBWEBSOCKET_H_3060898B846849FF9F88F5DB59B5950C - -#ifdef __cplusplus -#include <cstddef> -#include <cstdarg> - -extern "C" { -#else -#include <stdarg.h> -#endif - -#include <string.h> -#include <stdlib.h> - -#include "lws_config.h" - -/* - * CARE: everything using cmake defines needs to be below here - */ - -#if defined(LWS_HAS_INTPTR_T) -#include <stdint.h> -#define lws_intptr_t intptr_t -#else -typedef unsigned long long lws_intptr_t; -#endif - -#if defined(WIN32) || defined(_WIN32) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif - -#include <winsock2.h> -#include <ws2tcpip.h> -#include <stddef.h> -#include <basetsd.h> -#include <io.h> -#ifndef _WIN32_WCE -#include <fcntl.h> -#else -#define _O_RDONLY 0x0000 -#define O_RDONLY _O_RDONLY -#endif - -#define LWS_INLINE __inline -#define LWS_VISIBLE -#define LWS_WARN_UNUSED_RESULT -#define LWS_WARN_DEPRECATED -#define LWS_FORMAT(string_index) - -#ifdef LWS_DLL -#ifdef LWS_INTERNAL -#define LWS_EXTERN extern __declspec(dllexport) -#else -#define LWS_EXTERN extern __declspec(dllimport) -#endif -#else -#define LWS_EXTERN -#endif - -#define LWS_INVALID_FILE INVALID_HANDLE_VALUE -#define LWS_O_RDONLY _O_RDONLY -#define LWS_O_WRONLY _O_WRONLY -#define LWS_O_CREAT _O_CREAT -#define LWS_O_TRUNC _O_TRUNC - -#ifndef __func__ -#define __func__ __FUNCTION__ -#endif - -#else /* NOT WIN32 */ -#include <unistd.h> -#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) -#include <sys/capability.h> -#endif - -#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__QNX__) || defined(__OpenBSD__) -#include <sys/socket.h> -#include <netinet/in.h> -#endif - -#define LWS_INLINE inline -#define LWS_O_RDONLY O_RDONLY -#define LWS_O_WRONLY O_WRONLY -#define LWS_O_CREAT O_CREAT -#define LWS_O_TRUNC O_TRUNC - -#if !defined(LWS_PLAT_OPTEE) && !defined(OPTEE_TA) && !defined(LWS_WITH_ESP32) -#include <poll.h> -#include <netdb.h> -#define LWS_INVALID_FILE -1 -#else -#define getdtablesize() (30) -#if defined(LWS_WITH_ESP32) -#define LWS_INVALID_FILE NULL -#else -#define LWS_INVALID_FILE NULL -#endif -#endif - -#if defined(__GNUC__) - -/* warn_unused_result attribute only supported by GCC 3.4 or later */ -#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -#define LWS_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) -#else -#define LWS_WARN_UNUSED_RESULT -#endif - -#define LWS_VISIBLE __attribute__((visibility("default"))) -#define LWS_WARN_DEPRECATED __attribute__ ((deprecated)) -#define LWS_FORMAT(string_index) __attribute__ ((format(printf, string_index, string_index+1))) -#else -#define LWS_VISIBLE -#define LWS_WARN_UNUSED_RESULT -#define LWS_WARN_DEPRECATED -#define LWS_FORMAT(string_index) -#endif - -#if defined(__ANDROID__) -#include <netinet/in.h> -#include <unistd.h> -#define getdtablesize() sysconf(_SC_OPEN_MAX) -#endif - -#endif - -#if defined(LWS_WITH_LIBEV) -#include <ev.h> -#endif /* LWS_WITH_LIBEV */ -#ifdef LWS_WITH_LIBUV -#include <uv.h> -#ifdef LWS_HAVE_UV_VERSION_H -#include <uv-version.h> -#endif -#ifdef LWS_HAVE_NEW_UV_VERSION_H -#include <uv/version.h> -#endif -#endif /* LWS_WITH_LIBUV */ -#if defined(LWS_WITH_LIBEVENT) -#include <event2/event.h> -#endif /* LWS_WITH_LIBEVENT */ - -#ifndef LWS_EXTERN -#define LWS_EXTERN extern -#endif - -#ifdef _WIN32 -#define random rand -#else -#if !defined(OPTEE_TA) -#include <sys/time.h> -#include <unistd.h> -#endif -#endif - -#if defined(LWS_WITH_TLS) - -#ifdef USE_WOLFSSL -#ifdef USE_OLD_CYASSL -#ifdef _WIN32 -/* - * Include user-controlled settings for windows from - * <wolfssl-root>/IDE/WIN/user_settings.h - */ -#include <IDE/WIN/user_settings.h> -#include <cyassl/ctaocrypt/settings.h> -#else -#include <cyassl/options.h> -#endif -#include <cyassl/openssl/ssl.h> -#include <cyassl/error-ssl.h> - -#else -#ifdef _WIN32 -/* - * Include user-controlled settings for windows from - * <wolfssl-root>/IDE/WIN/user_settings.h - */ -#include <IDE/WIN/user_settings.h> -#include <wolfssl/wolfcrypt/settings.h> -#else -#include <wolfssl/options.h> -#endif -#include <wolfssl/openssl/ssl.h> -#include <wolfssl/error-ssl.h> -#endif /* not USE_OLD_CYASSL */ -#else -#if defined(LWS_WITH_MBEDTLS) -#if defined(LWS_WITH_ESP32) -/* this filepath is passed to us but without quotes or <> */ -#undef MBEDTLS_CONFIG_FILE -#define MBEDTLS_CONFIG_FILE <mbedtls/esp_config.h> -#endif -#include <mbedtls/ssl.h> -#else -#include <openssl/ssl.h> -#if !defined(LWS_WITH_MBEDTLS) -#include <openssl/err.h> -#endif -#endif -#endif /* not USE_WOLFSSL */ -#endif - -/* - * Helpers for pthread mutex in user code... if lws is built for - * multiple service threads, these resolve to pthread mutex - * operations. In the case LWS_MAX_SMP is 1 (the default), they - * are all NOPs and no pthread type or api is referenced. - */ - -#if LWS_MAX_SMP > 1 - -#include <pthread.h> - -#define lws_pthread_mutex(name) pthread_mutex_t name; - -static LWS_INLINE void -lws_pthread_mutex_init(pthread_mutex_t *lock) -{ - pthread_mutex_init(lock, NULL); -} - -static LWS_INLINE void -lws_pthread_mutex_destroy(pthread_mutex_t *lock) -{ - pthread_mutex_destroy(lock); -} - -static LWS_INLINE void -lws_pthread_mutex_lock(pthread_mutex_t *lock) -{ - pthread_mutex_lock(lock); -} - -static LWS_INLINE void -lws_pthread_mutex_unlock(pthread_mutex_t *lock) -{ - pthread_mutex_unlock(lock); -} - -#else -#define lws_pthread_mutex(name) -#define lws_pthread_mutex_init(_a) -#define lws_pthread_mutex_destroy(_a) -#define lws_pthread_mutex_lock(_a) -#define lws_pthread_mutex_unlock(_a) -#endif - - -#define CONTEXT_PORT_NO_LISTEN -1 -#define CONTEXT_PORT_NO_LISTEN_SERVER -2 - -/** \defgroup log Logging - * - * ##Logging - * - * Lws provides flexible and filterable logging facilities, which can be - * used inside lws and in user code. - * - * Log categories may be individually filtered bitwise, and directed to built-in - * sinks for syslog-compatible logging, or a user-defined function. - */ -///@{ - -enum lws_log_levels { - LLL_ERR = 1 << 0, - LLL_WARN = 1 << 1, - LLL_NOTICE = 1 << 2, - LLL_INFO = 1 << 3, - LLL_DEBUG = 1 << 4, - LLL_PARSER = 1 << 5, - LLL_HEADER = 1 << 6, - LLL_EXT = 1 << 7, - LLL_CLIENT = 1 << 8, - LLL_LATENCY = 1 << 9, - LLL_USER = 1 << 10, - - LLL_COUNT = 11 /* set to count of valid flags */ -}; - -LWS_VISIBLE LWS_EXTERN void _lws_log(int filter, const char *format, ...) LWS_FORMAT(2); -LWS_VISIBLE LWS_EXTERN void _lws_logv(int filter, const char *format, va_list vl); -/** - * lwsl_timestamp: generate logging timestamp string - * - * \param level: logging level - * \param p: char * buffer to take timestamp - * \param len: length of p - * - * returns length written in p - */ -LWS_VISIBLE LWS_EXTERN int -lwsl_timestamp(int level, char *p, int len); - -/* these guys are unconditionally included */ - -#define lwsl_err(...) _lws_log(LLL_ERR, __VA_ARGS__) -#define lwsl_user(...) _lws_log(LLL_USER, __VA_ARGS__) - -#if !defined(LWS_WITH_NO_LOGS) -/* notice and warn are usually included by being compiled in */ -#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) -#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) -#endif -/* - * weaker logging can be deselected by telling CMake to build in RELEASE mode - * that gets rid of the overhead of checking while keeping _warn and _err - * active - */ - -#ifdef _DEBUG -#if defined(LWS_WITH_NO_LOGS) -/* notice, warn and log are always compiled in */ -#define lwsl_warn(...) _lws_log(LLL_WARN, __VA_ARGS__) -#define lwsl_notice(...) _lws_log(LLL_NOTICE, __VA_ARGS__) -#endif -#define lwsl_info(...) _lws_log(LLL_INFO, __VA_ARGS__) -#define lwsl_debug(...) _lws_log(LLL_DEBUG, __VA_ARGS__) -#define lwsl_parser(...) _lws_log(LLL_PARSER, __VA_ARGS__) -#define lwsl_header(...) _lws_log(LLL_HEADER, __VA_ARGS__) -#define lwsl_ext(...) _lws_log(LLL_EXT, __VA_ARGS__) -#define lwsl_client(...) _lws_log(LLL_CLIENT, __VA_ARGS__) -#define lwsl_latency(...) _lws_log(LLL_LATENCY, __VA_ARGS__) - -#else /* no debug */ -#if defined(LWS_WITH_NO_LOGS) -#define lwsl_warn(...) do {} while(0) -#define lwsl_notice(...) do {} while(0) -#endif -#define lwsl_info(...) do {} while(0) -#define lwsl_debug(...) do {} while(0) -#define lwsl_parser(...) do {} while(0) -#define lwsl_header(...) do {} while(0) -#define lwsl_ext(...) do {} while(0) -#define lwsl_client(...) do {} while(0) -#define lwsl_latency(...) do {} while(0) - -#endif - -#define lwsl_hexdump_err(...) lwsl_hexdump_level(LLL_ERR, __VA_ARGS__) -#define lwsl_hexdump_warn(...) lwsl_hexdump_level(LLL_WARN, __VA_ARGS__) -#define lwsl_hexdump_notice(...) lwsl_hexdump_level(LLL_NOTICE, __VA_ARGS__) -#define lwsl_hexdump_info(...) lwsl_hexdump_level(LLL_INFO, __VA_ARGS__) -#define lwsl_hexdump_debug(...) lwsl_hexdump_level(LLL_DEBUG, __VA_ARGS__) - -/** - * lwsl_hexdump_level() - helper to hexdump a buffer at a selected debug level - * - * \param level: one of LLL_ constants - * \param vbuf: buffer start to dump - * \param len: length of buffer to dump - * - * If \p level is visible, does a nice hexdump -C style dump of \p vbuf for - * \p len bytes. This can be extremely convenient while debugging. - */ -LWS_VISIBLE LWS_EXTERN void -lwsl_hexdump_level(int level, const void *vbuf, size_t len); - -/** - * lwsl_hexdump() - helper to hexdump a buffer (DEBUG builds only) - * - * \param buf: buffer start to dump - * \param len: length of buffer to dump - * - * Calls through to lwsl_hexdump_level(LLL_DEBUG, ... for compatability. - * It's better to use lwsl_hexdump_level(level, ... directly so you can control - * the visibility. - */ -LWS_VISIBLE LWS_EXTERN void -lwsl_hexdump(const void *buf, size_t len); - -/** - * lws_is_be() - returns nonzero if the platform is Big Endian - */ -static LWS_INLINE int lws_is_be(void) { - const int probe = ~0xff; - - return *(const char *)&probe; -} - -/** - * lws_set_log_level() - Set the logging bitfield - * \param level: OR together the LLL_ debug contexts you want output from - * \param log_emit_function: NULL to leave it as it is, or a user-supplied - * function to perform log string emission instead of - * the default stderr one. - * - * log level defaults to "err", "warn" and "notice" contexts enabled and - * emission on stderr. If stderr is a tty (according to isatty()) then - * the output is coloured according to the log level using ANSI escapes. - */ -LWS_VISIBLE LWS_EXTERN void -lws_set_log_level(int level, - void (*log_emit_function)(int level, const char *line)); - -/** - * lwsl_emit_syslog() - helper log emit function writes to system log - * - * \param level: one of LLL_ log level indexes - * \param line: log string - * - * You use this by passing the function pointer to lws_set_log_level(), to set - * it as the log emit function, it is not called directly. - */ -LWS_VISIBLE LWS_EXTERN void -lwsl_emit_syslog(int level, const char *line); - -/** - * lwsl_visible() - returns true if the log level should be printed - * - * \param level: one of LLL_ log level indexes - * - * This is useful if you have to do work to generate the log content, you - * can skip the work if the log level used to print it is not actually - * enabled at runtime. - */ -LWS_VISIBLE LWS_EXTERN int -lwsl_visible(int level); - -///@} - - -#include <stddef.h> - -#ifndef lws_container_of -#define lws_container_of(P,T,M) ((T *)((char *)(P) - offsetof(T, M))) -#endif - -struct lws; - -typedef int64_t lws_usec_t; - -/* api change list for user code to test against */ - -#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_ARG - -/* the struct lws_protocols has the id field present */ -#define LWS_FEATURE_PROTOCOLS_HAS_ID_FIELD - -/* you can call lws_get_peer_write_allowance */ -#define LWS_FEATURE_PROTOCOLS_HAS_PEER_WRITE_ALLOWANCE - -/* extra parameter introduced in 917f43ab821 */ -#define LWS_FEATURE_SERVE_HTTP_FILE_HAS_OTHER_HEADERS_LEN - -/* File operations stuff exists */ -#define LWS_FEATURE_FOPS - - -#if defined(_WIN32) -typedef SOCKET lws_sockfd_type; -typedef HANDLE lws_filefd_type; - -struct lws_pollfd { - lws_sockfd_type fd; /**< file descriptor */ - SHORT events; /**< which events to respond to */ - SHORT revents; /**< which events happened */ -}; -#define LWS_POLLHUP (FD_CLOSE) -#define LWS_POLLIN (FD_READ | FD_ACCEPT) -#define LWS_POLLOUT (FD_WRITE) -#else - - -#if defined(LWS_WITH_ESP32) - -typedef int lws_sockfd_type; -typedef int lws_filefd_type; - -struct pollfd { - lws_sockfd_type fd; /**< fd related to */ - short events; /**< which POLL... events to respond to */ - short revents; /**< which POLL... events occurred */ -}; -#define POLLIN 0x0001 -#define POLLPRI 0x0002 -#define POLLOUT 0x0004 -#define POLLERR 0x0008 -#define POLLHUP 0x0010 -#define POLLNVAL 0x0020 - -#include <freertos/FreeRTOS.h> -#include <freertos/event_groups.h> -#include <string.h> -#include "esp_wifi.h" -#include "esp_system.h" -#include "esp_event.h" -#include "esp_event_loop.h" -#include "nvs.h" -#include "driver/gpio.h" -#include "esp_spi_flash.h" -#include "freertos/timers.h" - -#if !defined(CONFIG_FREERTOS_HZ) -#define CONFIG_FREERTOS_HZ 100 -#endif - -typedef TimerHandle_t uv_timer_t; -typedef void uv_cb_t(uv_timer_t *); -typedef void * uv_handle_t; - -struct timer_mapping { - uv_cb_t *cb; - uv_timer_t *t; -}; - -#define UV_VERSION_MAJOR 1 - -#define lws_uv_getloop(a, b) (NULL) - -static LWS_INLINE void uv_timer_init(void *l, uv_timer_t *t) -{ - (void)l; - *t = NULL; -} - -extern void esp32_uvtimer_cb(TimerHandle_t t); - -static LWS_INLINE void uv_timer_start(uv_timer_t *t, uv_cb_t *cb, int first, int rep) -{ - struct timer_mapping *tm = (struct timer_mapping *)malloc(sizeof(*tm)); - - if (!tm) - return; - - tm->t = t; - tm->cb = cb; - - *t = xTimerCreate("x", pdMS_TO_TICKS(first), !!rep, tm, - (TimerCallbackFunction_t)esp32_uvtimer_cb); - xTimerStart(*t, 0); -} - -static LWS_INLINE void uv_timer_stop(uv_timer_t *t) -{ - xTimerStop(*t, 0); -} - -static LWS_INLINE void uv_close(uv_handle_t *h, void *v) -{ - free(pvTimerGetTimerID((uv_timer_t)h)); - xTimerDelete(*(uv_timer_t *)h, 0); -} - -/* ESP32 helper declarations */ - -#include <mdns.h> -#include <esp_partition.h> - -#define LWS_PLUGIN_STATIC -#define LWS_MAGIC_REBOOT_TYPE_ADS 0x50001ffc -#define LWS_MAGIC_REBOOT_TYPE_REQ_FACTORY 0xb00bcafe -#define LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY 0xfaceb00b -#define LWS_MAGIC_REBOOT_TYPE_FORCED_FACTORY_BUTTON 0xf0cedfac - - -/* user code provides these */ - -extern void -lws_esp32_identify_physical_device(void); - -/* lws-plat-esp32 provides these */ - -typedef void (*lws_cb_scan_done)(uint16_t count, wifi_ap_record_t *recs, void *arg); - -enum genled_state { - LWSESP32_GENLED__INIT, - LWSESP32_GENLED__LOST_NETWORK, - LWSESP32_GENLED__NO_NETWORK, - LWSESP32_GENLED__CONN_AP, - LWSESP32_GENLED__GOT_IP, - LWSESP32_GENLED__OK, -}; - -struct lws_group_member { - struct lws_group_member *next; - uint64_t last_seen; - char model[16]; - char role[16]; - char host[32]; - char mac[20]; - int width, height; - struct ip4_addr addr; - struct ip6_addr addrv6; - uint8_t flags; -}; - -#define LWS_SYSTEM_GROUP_MEMBER_ADD 1 -#define LWS_SYSTEM_GROUP_MEMBER_CHANGE 2 -#define LWS_SYSTEM_GROUP_MEMBER_REMOVE 3 - -#define LWS_GROUP_FLAG_SELF 1 - -struct lws_esp32 { - char sta_ip[16]; - char sta_mask[16]; - char sta_gw[16]; - char serial[16]; - char opts[16]; - char model[16]; - char group[16]; - char role[16]; - char ssid[4][64]; - char password[4][64]; - char active_ssid[64]; - char access_pw[16]; - char hostname[32]; - char mac[20]; - char le_dns[64]; - char le_email[64]; - char region; - char inet; - char conn_ap; - - enum genled_state genled; - uint64_t genled_t; - - lws_cb_scan_done scan_consumer; - void *scan_consumer_arg; - struct lws_group_member *first; - int extant_group_members; - - char acme; - char upload; - - volatile char button_is_down; -}; - -struct lws_esp32_image { - uint32_t romfs; - uint32_t romfs_len; - uint32_t json; - uint32_t json_len; -}; - -extern struct lws_esp32 lws_esp32; -struct lws_vhost; - -extern esp_err_t -lws_esp32_event_passthru(void *ctx, system_event_t *event); -extern void -lws_esp32_wlan_config(void); -extern void -lws_esp32_wlan_start_ap(void); -extern void -lws_esp32_wlan_start_station(void); -struct lws_context_creation_info; -extern void -lws_esp32_set_creation_defaults(struct lws_context_creation_info *info); -extern struct lws_context * -lws_esp32_init(struct lws_context_creation_info *, struct lws_vhost **pvh); -extern int -lws_esp32_wlan_nvs_get(int retry); -extern esp_err_t -lws_nvs_set_str(nvs_handle handle, const char* key, const char* value); -extern void -lws_esp32_restart_guided(uint32_t type); -extern const esp_partition_t * -lws_esp_ota_get_boot_partition(void); -extern int -lws_esp32_get_image_info(const esp_partition_t *part, struct lws_esp32_image *i, char *json, int json_len); -extern int -lws_esp32_leds_network_indication(void); - -extern uint32_t lws_esp32_get_reboot_type(void); -extern uint16_t lws_esp32_sine_interp(int n); - -/* required in external code by esp32 plat (may just return if no leds) */ -extern void lws_esp32_leds_timer_cb(TimerHandle_t th); -#else -typedef int lws_sockfd_type; -typedef int lws_filefd_type; -#endif - -#define lws_pollfd pollfd -#define LWS_POLLHUP (POLLHUP|POLLERR) -#define LWS_POLLIN (POLLIN) -#define LWS_POLLOUT (POLLOUT) -#endif - - -#if (defined(WIN32) || defined(_WIN32)) && !defined(__MINGW32__) -/* ... */ -#define ssize_t SSIZE_T -#endif - -#if defined(WIN32) && defined(LWS_HAVE__STAT32I64) -#include <sys/types.h> -#include <sys/stat.h> -#endif - -#if defined(LWS_HAVE_STDINT_H) -#include <stdint.h> -#else -#if defined(WIN32) || defined(_WIN32) -/* !!! >:-[ */ -typedef unsigned __int32 uint32_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int8 uint8_t; -#else -typedef unsigned int uint32_t; -typedef unsigned short uint16_t; -typedef unsigned char uint8_t; -#endif -#endif - -typedef unsigned long long lws_filepos_t; -typedef long long lws_fileofs_t; -typedef uint32_t lws_fop_flags_t; - -/** struct lws_pollargs - argument structure for all external poll related calls - * passed in via 'in' */ -struct lws_pollargs { - lws_sockfd_type fd; /**< applicable socket descriptor */ - int events; /**< the new event mask */ - int prev_events; /**< the previous event mask */ -}; - -struct lws_tokens; -struct lws_token_limits; - -/*! \defgroup wsclose Websocket Close - * - * ##Websocket close frame control - * - * When we close a ws connection, we can send a reason code and a short - * UTF-8 description back with the close packet. - */ -///@{ - -/* - * NOTE: These public enums are part of the abi. If you want to add one, - * add it at where specified so existing users are unaffected. - */ -/** enum lws_close_status - RFC6455 close status codes */ -enum lws_close_status { - LWS_CLOSE_STATUS_NOSTATUS = 0, - LWS_CLOSE_STATUS_NORMAL = 1000, - /**< 1000 indicates a normal closure, meaning that the purpose for - which the connection was established has been fulfilled. */ - LWS_CLOSE_STATUS_GOINGAWAY = 1001, - /**< 1001 indicates that an endpoint is "going away", such as a server - going down or a browser having navigated away from a page. */ - LWS_CLOSE_STATUS_PROTOCOL_ERR = 1002, - /**< 1002 indicates that an endpoint is terminating the connection due - to a protocol error. */ - LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE = 1003, - /**< 1003 indicates that an endpoint is terminating the connection - because it has received a type of data it cannot accept (e.g., an - endpoint that understands only text data MAY send this if it - receives a binary message). */ - LWS_CLOSE_STATUS_RESERVED = 1004, - /**< Reserved. The specific meaning might be defined in the future. */ - LWS_CLOSE_STATUS_NO_STATUS = 1005, - /**< 1005 is a reserved value and MUST NOT be set as a status code in a - Close control frame by an endpoint. It is designated for use in - applications expecting a status code to indicate that no status - code was actually present. */ - LWS_CLOSE_STATUS_ABNORMAL_CLOSE = 1006, - /**< 1006 is a reserved value and MUST NOT be set as a status code in a - Close control frame by an endpoint. It is designated for use in - applications expecting a status code to indicate that the - connection was closed abnormally, e.g., without sending or - receiving a Close control frame. */ - LWS_CLOSE_STATUS_INVALID_PAYLOAD = 1007, - /**< 1007 indicates that an endpoint is terminating the connection - because it has received data within a message that was not - consistent with the type of the message (e.g., non-UTF-8 [RFC3629] - data within a text message). */ - LWS_CLOSE_STATUS_POLICY_VIOLATION = 1008, - /**< 1008 indicates that an endpoint is terminating the connection - because it has received a message that violates its policy. This - is a generic status code that can be returned when there is no - other more suitable status code (e.g., 1003 or 1009) or if there - is a need to hide specific details about the policy. */ - LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE = 1009, - /**< 1009 indicates that an endpoint is terminating the connection - because it has received a message that is too big for it to - process. */ - LWS_CLOSE_STATUS_EXTENSION_REQUIRED = 1010, - /**< 1010 indicates that an endpoint (client) is terminating the - connection because it has expected the server to negotiate one or - more extension, but the server didn't return them in the response - message of the WebSocket handshake. The list of extensions that - are needed SHOULD appear in the /reason/ part of the Close frame. - Note that this status code is not used by the server, because it - can fail the WebSocket handshake instead */ - LWS_CLOSE_STATUS_UNEXPECTED_CONDITION = 1011, - /**< 1011 indicates that a server is terminating the connection because - it encountered an unexpected condition that prevented it from - fulfilling the request. */ - LWS_CLOSE_STATUS_TLS_FAILURE = 1015, - /**< 1015 is a reserved value and MUST NOT be set as a status code in a - Close control frame by an endpoint. It is designated for use in - applications expecting a status code to indicate that the - connection was closed due to a failure to perform a TLS handshake - (e.g., the server certificate can't be verified). */ - - LWS_CLOSE_STATUS_CLIENT_TRANSACTION_DONE = 2000, - - /****** add new things just above ---^ ******/ - - LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY = 9999, -}; - -/** - * lws_close_reason - Set reason and aux data to send with Close packet - * If you are going to return nonzero from the callback - * requesting the connection to close, you can optionally - * call this to set the reason the peer will be told if - * possible. - * - * \param wsi: The websocket connection to set the close reason on - * \param status: A valid close status from websocket standard - * \param buf: NULL or buffer containing up to 124 bytes of auxiliary data - * \param len: Length of data in \param buf to send - */ -LWS_VISIBLE LWS_EXTERN void -lws_close_reason(struct lws *wsi, enum lws_close_status status, - unsigned char *buf, size_t len); - -///@} - -struct lws; -struct lws_context; -/* needed even with extensions disabled for create context */ -struct lws_extension; - - -/*! \defgroup usercb User Callback - * - * ##User protocol callback - * - * The protocol callback is the primary way lws interacts with - * user code. For one of a list of a few dozen reasons the callback gets - * called at some event to be handled. - * - * All of the events can be ignored, returning 0 is taken as "OK" and returning - * nonzero in most cases indicates that the connection should be closed. - */ -///@{ - -struct lws_ssl_info { - int where; - int ret; -}; - -enum lws_cert_update_state { - LWS_CUS_IDLE, - LWS_CUS_STARTING, - LWS_CUS_SUCCESS, - LWS_CUS_FAILED, - - LWS_CUS_CREATE_KEYS, - LWS_CUS_REG, - LWS_CUS_AUTH, - LWS_CUS_CHALLENGE, - LWS_CUS_CREATE_REQ, - LWS_CUS_REQ, - LWS_CUS_CONFIRM, - LWS_CUS_ISSUE, -}; - -enum { - LWS_TLS_REQ_ELEMENT_COUNTRY, - LWS_TLS_REQ_ELEMENT_STATE, - LWS_TLS_REQ_ELEMENT_LOCALITY, - LWS_TLS_REQ_ELEMENT_ORGANIZATION, - LWS_TLS_REQ_ELEMENT_COMMON_NAME, - LWS_TLS_REQ_ELEMENT_EMAIL, - - LWS_TLS_REQ_ELEMENT_COUNT, - - LWS_TLS_SET_DIR_URL = LWS_TLS_REQ_ELEMENT_COUNT, - LWS_TLS_SET_AUTH_PATH, - LWS_TLS_SET_CERT_PATH, - LWS_TLS_SET_KEY_PATH, - - LWS_TLS_TOTAL_COUNT -}; - -struct lws_acme_cert_aging_args { - struct lws_vhost *vh; - const char *element_overrides[LWS_TLS_TOTAL_COUNT]; /* NULL = use pvo */ -}; - -/* - * NOTE: These public enums are part of the abi. If you want to add one, - * add it at where specified so existing users are unaffected. - */ -/** enum lws_callback_reasons - reason you're getting a protocol callback */ -enum lws_callback_reasons { - - /* --------------------------------------------------------------------- - * ----- Callbacks related to wsi and protocol binding lifecycle ----- - */ - - LWS_CALLBACK_PROTOCOL_INIT = 27, - /**< One-time call per protocol, per-vhost using it, so it can - * do initial setup / allocations etc */ - - LWS_CALLBACK_PROTOCOL_DESTROY = 28, - /**< One-time call per protocol, per-vhost using it, indicating - * this protocol won't get used at all after this callback, the - * vhost is getting destroyed. Take the opportunity to - * deallocate everything that was allocated by the protocol. */ - - LWS_CALLBACK_WSI_CREATE = 29, - /**< outermost (earliest) wsi create notification to protocols[0] */ - - LWS_CALLBACK_WSI_DESTROY = 30, - /**< outermost (latest) wsi destroy notification to protocols[0] */ - - LWS_CALLBACK_HTTP_BIND_PROTOCOL = 49, - /**< By default, all HTTP handling is done in protocols[0]. - * However you can bind different protocols (by name) to - * different parts of the URL space using callback mounts. This - * callback occurs in the new protocol when a wsi is bound - * to that protocol. Any protocol allocation related to the - * http transaction processing should be created then. - * These specific callbacks are necessary because with HTTP/1.1, - * a single connection may perform at series of different - * transactions at different URLs, thus the lifetime of the - * protocol bind is just for one transaction, not connection. */ - - LWS_CALLBACK_HTTP_DROP_PROTOCOL = 50, - /**< This is called when a transaction is unbound from a protocol. - * It indicates the connection completed its transaction and may - * do something different now. Any protocol allocation related - * to the http transaction processing should be destroyed. */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to Server TLS ----- - */ - - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS = 21, - /**< if configured for - * including OpenSSL support, this callback allows your user code - * to perform extra SSL_CTX_load_verify_locations() or similar - * calls to direct OpenSSL where to find certificates the client - * can use to confirm the remote server identity. user is the - * OpenSSL SSL_CTX* */ - - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS = 22, - /**< if configured for - * including OpenSSL support, this callback allows your user code - * to load extra certificates into the server which allow it to - * verify the validity of certificates returned by clients. user - * is the server's OpenSSL SSL_CTX* and in is the lws_vhost */ - - LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION = 23, - /**< if the libwebsockets vhost was created with the option - * LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT, then this - * callback is generated during OpenSSL verification of the cert - * sent from the client. It is sent to protocol[0] callback as - * no protocol has been negotiated on the connection yet. - * Notice that the libwebsockets context and wsi are both NULL - * during this callback. See - * http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html - * to understand more detail about the OpenSSL callback that - * generates this libwebsockets callback and the meanings of the - * arguments passed. In this callback, user is the x509_ctx, - * in is the ssl pointer and len is preverify_ok - * Notice that this callback maintains libwebsocket return - * conventions, return 0 to mean the cert is OK or 1 to fail it. - * This also means that if you don't handle this callback then - * the default callback action of returning 0 allows the client - * certificates. */ - - LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY = 37, - /**< if configured for including OpenSSL support but no private key - * file has been specified (ssl_private_key_filepath is NULL), this is - * called to allow the user to set the private key directly via - * libopenssl and perform further operations if required; this might be - * useful in situations where the private key is not directly accessible - * by the OS, for example if it is stored on a smartcard. - * user is the server's OpenSSL SSL_CTX* */ - - LWS_CALLBACK_SSL_INFO = 67, - /**< SSL connections only. An event you registered an - * interest in at the vhost has occurred on a connection - * using the vhost. in is a pointer to a - * struct lws_ssl_info containing information about the - * event*/ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to Client TLS ----- - */ - - LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION = 58, - /**< Similar to LWS_CALLBACK_OPENSSL_PERFORM_CLIENT_CERT_VERIFICATION - * this callback is called during OpenSSL verification of the cert - * sent from the server to the client. It is sent to protocol[0] - * callback as no protocol has been negotiated on the connection yet. - * Notice that the wsi is set because lws_client_connect_via_info was - * successful. - * - * See http://www.openssl.org/docs/ssl/SSL_CTX_set_verify.html - * to understand more detail about the OpenSSL callback that - * generates this libwebsockets callback and the meanings of the - * arguments passed. In this callback, user is the x509_ctx, - * in is the ssl pointer and len is preverify_ok. - * - * THIS IS NOT RECOMMENDED BUT if a cert validation error shall be - * overruled and cert shall be accepted as ok, - * X509_STORE_CTX_set_error((X509_STORE_CTX*)user, X509_V_OK); must be - * called and return value must be 0 to mean the cert is OK; - * returning 1 will fail the cert in any case. - * - * This also means that if you don't handle this callback then - * the default callback action of returning 0 will not accept the - * certificate in case of a validation error decided by the SSL lib. - * - * This is expected and secure behaviour when validating certificates. - * - * Note: LCCSCF_ALLOW_SELFSIGNED and - * LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK still work without this - * callback being implemented. - */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to HTTP Server ----- - */ - - LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED = 19, - /**< A new client has been accepted by the ws server. This - * callback allows setting any relevant property to it. Because this - * happens immediately after the instantiation of a new client, - * there's no websocket protocol selected yet so this callback is - * issued only to protocol 0. Only wsi is defined, pointing to the - * new client, and the return value is ignored. */ - - LWS_CALLBACK_HTTP = 12, - /**< an http request has come from a client that is not - * asking to upgrade the connection to a websocket - * one. This is a chance to serve http content, - * for example, to send a script to the client - * which will then open the websockets connection. - * in points to the URI path requested and - * lws_serve_http_file() makes it very - * simple to send back a file to the client. - * Normally after sending the file you are done - * with the http connection, since the rest of the - * activity will come by websockets from the script - * that was delivered by http, so you will want to - * return 1; to close and free up the connection. */ - - LWS_CALLBACK_HTTP_BODY = 13, - /**< the next len bytes data from the http - * request body HTTP connection is now available in in. */ - - LWS_CALLBACK_HTTP_BODY_COMPLETION = 14, - /**< the expected amount of http request body has been delivered */ - - LWS_CALLBACK_HTTP_FILE_COMPLETION = 15, - /**< a file requested to be sent down http link has completed. */ - - LWS_CALLBACK_HTTP_WRITEABLE = 16, - /**< you can write more down the http protocol link now. */ - - LWS_CALLBACK_CLOSED_HTTP = 5, - /**< when a HTTP (non-websocket) session ends */ - - LWS_CALLBACK_FILTER_HTTP_CONNECTION = 18, - /**< called when the request has - * been received and parsed from the client, but the response is - * not sent yet. Return non-zero to disallow the connection. - * user is a pointer to the connection user space allocation, - * in is the URI, eg, "/" - * In your handler you can use the public APIs - * lws_hdr_total_length() / lws_hdr_copy() to access all of the - * headers using the header enums lws_token_indexes from - * libwebsockets.h to check for and read the supported header - * presence and content before deciding to allow the http - * connection to proceed or to kill the connection. */ - - LWS_CALLBACK_ADD_HEADERS = 53, - /**< This gives your user code a chance to add headers to a server - * transaction bound to your protocol. `in` points to a - * `struct lws_process_html_args` describing a buffer and length - * you can add headers into using the normal lws apis. - * - * (see LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to add headers to - * a client transaction) - * - * Only `args->p` and `args->len` are valid, and `args->p` should - * be moved on by the amount of bytes written, if any. Eg - * - * case LWS_CALLBACK_ADD_HEADERS: - * - * struct lws_process_html_args *args = - * (struct lws_process_html_args *)in; - * - * if (lws_add_http_header_by_name(wsi, - * (unsigned char *)"set-cookie:", - * (unsigned char *)cookie, cookie_len, - * (unsigned char **)&args->p, - * (unsigned char *)args->p + args->max_len)) - * return 1; - * - * break; - */ - - LWS_CALLBACK_CHECK_ACCESS_RIGHTS = 51, - /**< This gives the user code a chance to forbid an http access. - * `in` points to a `struct lws_process_html_args`, which - * describes the URL, and a bit mask describing the type of - * authentication required. If the callback returns nonzero, - * the transaction ends with HTTP_STATUS_UNAUTHORIZED. */ - - LWS_CALLBACK_PROCESS_HTML = 52, - /**< This gives your user code a chance to mangle outgoing - * HTML. `in` points to a `struct lws_process_html_args` - * which describes the buffer containing outgoing HTML. - * The buffer may grow up to `.max_len` (currently +128 - * bytes per buffer). - */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to HTTP Client ----- - */ - - LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP = 44, - /**< The HTTP client connection has succeeded, and is now - * connected to the server */ - - LWS_CALLBACK_CLOSED_CLIENT_HTTP = 45, - /**< The HTTP client connection is closing */ - - LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ = 48, - /**< This is generated by lws_http_client_read() used to drain - * incoming data. In the case the incoming data was chunked, it will - * be split into multiple smaller callbacks for each chunk block, - * removing the chunk headers. If not chunked, it will appear all in - * one callback. */ - - LWS_CALLBACK_RECEIVE_CLIENT_HTTP = 46, - /**< This simply indicates data was received on the HTTP client - * connection. It does NOT drain or provide the data. - * This exists to neatly allow a proxying type situation, - * where this incoming data will go out on another connection. - * If the outgoing connection stalls, we should stall processing - * the incoming data. So a handler for this in that case should - * simply set a flag to indicate there is incoming data ready - * and ask for a writeable callback on the outgoing connection. - * In the writable callback he can check the flag and then get - * and drain the waiting incoming data using lws_http_client_read(). - * This will use callbacks to LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ - * to get and drain the incoming data, where it should be sent - * back out on the outgoing connection. */ - LWS_CALLBACK_COMPLETED_CLIENT_HTTP = 47, - /**< The client transaction completed... at the moment this - * is the same as closing since transaction pipelining on - * client side is not yet supported. */ - - LWS_CALLBACK_CLIENT_HTTP_WRITEABLE = 57, - /**< when doing an HTTP type client connection, you can call - * lws_client_http_body_pending(wsi, 1) from - * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER to get these callbacks - * sending the HTTP headers. - * - * From this callback, when you have sent everything, you should let - * lws know by calling lws_client_http_body_pending(wsi, 0) - */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to Websocket Server ----- - */ - - LWS_CALLBACK_ESTABLISHED = 0, - /**< (VH) after the server completes a handshake with an incoming - * client. If you built the library with ssl support, in is a - * pointer to the ssl struct associated with the connection or NULL. - * - * b0 of len is set if the connection was made using ws-over-h2 - */ - - LWS_CALLBACK_CLOSED = 4, - /**< when the websocket session ends */ - - LWS_CALLBACK_SERVER_WRITEABLE = 11, - /**< See LWS_CALLBACK_CLIENT_WRITEABLE */ - - LWS_CALLBACK_RECEIVE = 6, - /**< data has appeared for this server endpoint from a - * remote client, it can be found at *in and is - * len bytes long */ - - LWS_CALLBACK_RECEIVE_PONG = 7, - /**< servers receive PONG packets with this callback reason */ - - LWS_CALLBACK_WS_PEER_INITIATED_CLOSE = 38, - /**< The peer has sent an unsolicited Close WS packet. in and - * len are the optional close code (first 2 bytes, network - * order) and the optional additional information which is not - * defined in the standard, and may be a string or non human-readable - * data. - * If you return 0 lws will echo the close and then close the - * connection. If you return nonzero lws will just close the - * connection. */ - - LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION = 20, - /**< called when the handshake has - * been received and parsed from the client, but the response is - * not sent yet. Return non-zero to disallow the connection. - * user is a pointer to the connection user space allocation, - * in is the requested protocol name - * In your handler you can use the public APIs - * lws_hdr_total_length() / lws_hdr_copy() to access all of the - * headers using the header enums lws_token_indexes from - * libwebsockets.h to check for and read the supported header - * presence and content before deciding to allow the handshake - * to proceed or to kill the connection. */ - - LWS_CALLBACK_CONFIRM_EXTENSION_OKAY = 25, - /**< When the server handshake code - * sees that it does support a requested extension, before - * accepting the extension by additing to the list sent back to - * the client it gives this callback just to check that it's okay - * to use that extension. It calls back to the requested protocol - * and with in being the extension name, len is 0 and user is - * valid. Note though at this time the ESTABLISHED callback hasn't - * happened yet so if you initialize user content there, user - * content during this callback might not be useful for anything. */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to Websocket Client ----- - */ - - LWS_CALLBACK_CLIENT_CONNECTION_ERROR = 1, - /**< the request client connection has been unable to complete a - * handshake with the remote server. If in is non-NULL, you can - * find an error string of length len where it points to - * - * Diagnostic strings that may be returned include - * - * "getaddrinfo (ipv6) failed" - * "unknown address family" - * "getaddrinfo (ipv4) failed" - * "set socket opts failed" - * "insert wsi failed" - * "lws_ssl_client_connect1 failed" - * "lws_ssl_client_connect2 failed" - * "Peer hung up" - * "read failed" - * "HS: URI missing" - * "HS: Redirect code but no Location" - * "HS: URI did not parse" - * "HS: Redirect failed" - * "HS: Server did not return 200" - * "HS: OOM" - * "HS: disallowed by client filter" - * "HS: disallowed at ESTABLISHED" - * "HS: ACCEPT missing" - * "HS: ws upgrade response not 101" - * "HS: UPGRADE missing" - * "HS: Upgrade to something other than websocket" - * "HS: CONNECTION missing" - * "HS: UPGRADE malformed" - * "HS: PROTOCOL malformed" - * "HS: Cannot match protocol" - * "HS: EXT: list too big" - * "HS: EXT: failed setting defaults" - * "HS: EXT: failed parsing defaults" - * "HS: EXT: failed parsing options" - * "HS: EXT: Rejects server options" - * "HS: EXT: unknown ext" - * "HS: Accept hash wrong" - * "HS: Rejected by filter cb" - * "HS: OOM" - * "HS: SO_SNDBUF failed" - * "HS: Rejected at CLIENT_ESTABLISHED" - */ - - LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH = 2, - /**< this is the last chance for the client user code to examine the - * http headers and decide to reject the connection. If the - * content in the headers is interesting to the - * client (url, etc) it needs to copy it out at - * this point since it will be destroyed before - * the CLIENT_ESTABLISHED call */ - - LWS_CALLBACK_CLIENT_ESTABLISHED = 3, - /**< after your client connection completed the websocket upgrade - * handshake with the remote server */ - - LWS_CALLBACK_CLIENT_CLOSED = 75, - /**< when a client websocket session ends */ - - LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER = 24, - /**< this callback happens - * when a client handshake is being compiled. user is NULL, - * in is a char **, it's pointing to a char * which holds the - * next location in the header buffer where you can add - * headers, and len is the remaining space in the header buffer, - * which is typically some hundreds of bytes. So, to add a canned - * cookie, your handler code might look similar to: - * - * char **p = (char **)in; - * - * if (len < 100) - * return 1; - * - * *p += sprintf(*p, "Cookie: a=b\x0d\x0a"); - * - * return 0; - * - * Notice if you add anything, you just have to take care about - * the CRLF on the line you added. Obviously this callback is - * optional, if you don't handle it everything is fine. - * - * Notice the callback is coming to protocols[0] all the time, - * because there is no specific protocol negotiated yet. - * - * See LWS_CALLBACK_ADD_HEADERS for adding headers to server - * transactions. - */ - - LWS_CALLBACK_CLIENT_RECEIVE = 8, - /**< data has appeared from the server for the client connection, it - * can be found at *in and is len bytes long */ - - LWS_CALLBACK_CLIENT_RECEIVE_PONG = 9, - /**< clients receive PONG packets with this callback reason */ - - LWS_CALLBACK_CLIENT_WRITEABLE = 10, - /**< If you call lws_callback_on_writable() on a connection, you will - * get one of these callbacks coming when the connection socket - * is able to accept another write packet without blocking. - * If it already was able to take another packet without blocking, - * you'll get this callback at the next call to the service loop - * function. Notice that CLIENTs get LWS_CALLBACK_CLIENT_WRITEABLE - * and servers get LWS_CALLBACK_SERVER_WRITEABLE. */ - - LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED = 26, - /**< When a ws client - * connection is being prepared to start a handshake to a server, - * each supported extension is checked with protocols[0] callback - * with this reason, giving the user code a chance to suppress the - * claim to support that extension by returning non-zero. If - * unhandled, by default 0 will be returned and the extension - * support included in the header to the server. Notice this - * callback comes to protocols[0]. */ - - LWS_CALLBACK_WS_EXT_DEFAULTS = 39, - /**< Gives client connections an opportunity to adjust negotiated - * extension defaults. `user` is the extension name that was - * negotiated (eg, "permessage-deflate"). `in` points to a - * buffer and `len` is the buffer size. The user callback can - * set the buffer to a string describing options the extension - * should parse. Or just ignore for defaults. */ - - - LWS_CALLBACK_FILTER_NETWORK_CONNECTION = 17, - /**< called when a client connects to - * the server at network level; the connection is accepted but then - * passed to this callback to decide whether to hang up immediately - * or not, based on the client IP. in contains the connection - * socket's descriptor. Since the client connection information is - * not available yet, wsi still pointing to the main server socket. - * Return non-zero to terminate the connection before sending or - * receiving anything. Because this happens immediately after the - * network connection from the client, there's no websocket protocol - * selected yet so this callback is issued only to protocol 0. */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to external poll loop integration ----- - */ - - LWS_CALLBACK_GET_THREAD_ID = 31, - /**< lws can accept callback when writable requests from other - * threads, if you implement this callback and return an opaque - * current thread ID integer. */ - - /* external poll() management support */ - LWS_CALLBACK_ADD_POLL_FD = 32, - /**< lws normally deals with its poll() or other event loop - * internally, but in the case you are integrating with another - * server you will need to have lws sockets share a - * polling array with the other server. This and the other - * POLL_FD related callbacks let you put your specialized - * poll array interface code in the callback for protocol 0, the - * first protocol you support, usually the HTTP protocol in the - * serving case. - * This callback happens when a socket needs to be - * added to the polling loop: in points to a struct - * lws_pollargs; the fd member of the struct is the file - * descriptor, and events contains the active events - * - * If you are using the internal lws polling / event loop - * you can just ignore these callbacks. */ - - LWS_CALLBACK_DEL_POLL_FD = 33, - /**< This callback happens when a socket descriptor - * needs to be removed from an external polling array. in is - * again the struct lws_pollargs containing the fd member - * to be removed. If you are using the internal polling - * loop, you can just ignore it. */ - - LWS_CALLBACK_CHANGE_MODE_POLL_FD = 34, - /**< This callback happens when lws wants to modify the events for - * a connection. - * in is the struct lws_pollargs with the fd to change. - * The new event mask is in events member and the old mask is in - * the prev_events member. - * If you are using the internal polling loop, you can just ignore - * it. */ - - LWS_CALLBACK_LOCK_POLL = 35, - /**< These allow the external poll changes driven - * by lws to participate in an external thread locking - * scheme around the changes, so the whole thing is threadsafe. - * These are called around three activities in the library, - * - inserting a new wsi in the wsi / fd table (len=1) - * - deleting a wsi from the wsi / fd table (len=1) - * - changing a wsi's POLLIN/OUT state (len=0) - * Locking and unlocking external synchronization objects when - * len == 1 allows external threads to be synchronized against - * wsi lifecycle changes if it acquires the same lock for the - * duration of wsi dereference from the other thread context. */ - - LWS_CALLBACK_UNLOCK_POLL = 36, - /**< See LWS_CALLBACK_LOCK_POLL, ignore if using lws internal poll */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to CGI serving ----- - */ - - LWS_CALLBACK_CGI = 40, - /**< CGI: CGI IO events on stdin / out / err are sent here on - * protocols[0]. The provided `lws_callback_http_dummy()` - * handles this and the callback should be directed there if - * you use CGI. */ - - LWS_CALLBACK_CGI_TERMINATED = 41, - /**< CGI: The related CGI process ended, this is called before - * the wsi is closed. Used to, eg, terminate chunking. - * The provided `lws_callback_http_dummy()` - * handles this and the callback should be directed there if - * you use CGI. The child PID that terminated is in len. */ - - LWS_CALLBACK_CGI_STDIN_DATA = 42, - /**< CGI: Data is, to be sent to the CGI process stdin, eg from - * a POST body. The provided `lws_callback_http_dummy()` - * handles this and the callback should be directed there if - * you use CGI. */ - - LWS_CALLBACK_CGI_STDIN_COMPLETED = 43, - /**< CGI: no more stdin is coming. The provided - * `lws_callback_http_dummy()` handles this and the callback - * should be directed there if you use CGI. */ - - LWS_CALLBACK_CGI_PROCESS_ATTACH = 70, - /**< CGI: Sent when the CGI process is spawned for the wsi. The - * len parameter is the PID of the child process */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to Generic Sessions ----- - */ - - LWS_CALLBACK_SESSION_INFO = 54, - /**< This is only generated by user code using generic sessions. - * It's used to get a `struct lws_session_info` filled in by - * generic sessions with information about the logged-in user. - * See the messageboard sample for an example of how to use. */ - - LWS_CALLBACK_GS_EVENT = 55, - /**< Indicates an event happened to the Generic Sessions session. - * `in` contains a `struct lws_gs_event_args` describing the event. */ - - LWS_CALLBACK_HTTP_PMO = 56, - /**< per-mount options for this connection, called before - * the normal LWS_CALLBACK_HTTP when the mount has per-mount - * options. - */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to RAW sockets ----- - */ - - LWS_CALLBACK_RAW_RX = 59, - /**< RAW mode connection RX */ - - LWS_CALLBACK_RAW_CLOSE = 60, - /**< RAW mode connection is closing */ - - LWS_CALLBACK_RAW_WRITEABLE = 61, - /**< RAW mode connection may be written */ - - LWS_CALLBACK_RAW_ADOPT = 62, - /**< RAW mode connection was adopted (equivalent to 'wsi created') */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to RAW file handles ----- - */ - - LWS_CALLBACK_RAW_ADOPT_FILE = 63, - /**< RAW mode file was adopted (equivalent to 'wsi created') */ - - LWS_CALLBACK_RAW_RX_FILE = 64, - /**< This is the indication the RAW mode file has something to read. - * This doesn't actually do the read of the file and len is always - * 0... your code should do the read having been informed there is - * something to read now. */ - - LWS_CALLBACK_RAW_WRITEABLE_FILE = 65, - /**< RAW mode file is writeable */ - - LWS_CALLBACK_RAW_CLOSE_FILE = 66, - /**< RAW mode wsi that adopted a file is closing */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to generic wsi events ----- - */ - - LWS_CALLBACK_TIMER = 73, - /**< When the time elapsed after a call to - * lws_set_timer_usecs(wsi, usecs) is up, the wsi will get one of - * these callbacks. The deadline can be continuously extended into the - * future by later calls to lws_set_timer_usecs() before the deadline - * expires, or cancelled by lws_set_timer_usecs(wsi, -1); - * See the note on lws_set_timer_usecs() about which event loops are - * supported. */ - - LWS_CALLBACK_EVENT_WAIT_CANCELLED = 71, - /**< This is sent to every protocol of every vhost in response - * to lws_cancel_service() or lws_cancel_service_pt(). This - * callback is serialized in the lws event loop normally, even - * if the lws_cancel_service[_pt]() call was from a different - * thread. */ - - LWS_CALLBACK_CHILD_CLOSING = 69, - /**< Sent to parent to notify them a child is closing / being - * destroyed. in is the child wsi. - */ - - LWS_CALLBACK_CHILD_WRITE_VIA_PARENT = 68, - /**< Child has been marked with parent_carries_io attribute, so - * lws_write directs the to this callback at the parent, - * in is a struct lws_write_passthru containing the args - * the lws_write() was called with. - */ - - /* --------------------------------------------------------------------- - * ----- Callbacks related to TLS certificate management ----- - */ - - LWS_CALLBACK_VHOST_CERT_AGING = 72, - /**< When a vhost TLS cert has its expiry checked, this callback - * is broadcast to every protocol of every vhost in case the - * protocol wants to take some action with this information. - * \p in is a pointer to a struct lws_acme_cert_aging_args, - * and \p len is the number of days left before it expires, as - * a (ssize_t). In the struct lws_acme_cert_aging_args, vh - * points to the vhost the cert aging information applies to, - * and element_overrides[] is an optional way to update information - * from the pvos... NULL in an index means use the information from - * from the pvo for the cert renewal, non-NULL in the array index - * means use that pointer instead for the index. */ - - LWS_CALLBACK_VHOST_CERT_UPDATE = 74, - /**< When a vhost TLS cert is being updated, progress is - * reported to the vhost in question here, including completion - * and failure. in points to optional JSON, and len represents the - * connection state using enum lws_cert_update_state */ - - - /****** add new things just above ---^ ******/ - - LWS_CALLBACK_USER = 1000, - /**< user code can use any including above without fear of clashes */ -}; - - - -/** - * typedef lws_callback_function() - User server actions - * \param wsi: Opaque websocket instance pointer - * \param reason: The reason for the call - * \param user: Pointer to per-session user data allocated by library - * \param in: Pointer used for some callback reasons - * \param len: Length set for some callback reasons - * - * This callback is the way the user controls what is served. All the - * protocol detail is hidden and handled by the library. - * - * For each connection / session there is user data allocated that is - * pointed to by "user". You set the size of this user data area when - * the library is initialized with lws_create_server. - */ -typedef int -lws_callback_function(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len); - -#define LWS_CB_REASON_AUX_BF__CGI 1 -#define LWS_CB_REASON_AUX_BF__PROXY 2 -#define LWS_CB_REASON_AUX_BF__CGI_CHUNK_END 4 -#define LWS_CB_REASON_AUX_BF__CGI_HEADERS 8 -///@} - -struct lws_vhost; - -/*! \defgroup generic hash - * ## Generic Hash related functions - * - * Lws provides generic hash / digest accessors that abstract the ones - * provided by whatever OpenSSL library you are linking against. - * - * It lets you use the same code if you build against mbedtls or OpenSSL - * for example. - */ -///@{ - -#if defined(LWS_WITH_TLS) - -#if defined(LWS_WITH_MBEDTLS) -#include <mbedtls/sha1.h> -#include <mbedtls/sha256.h> -#include <mbedtls/sha512.h> -#endif - -enum lws_genhash_types { - LWS_GENHASH_TYPE_SHA1, - LWS_GENHASH_TYPE_SHA256, - LWS_GENHASH_TYPE_SHA384, - LWS_GENHASH_TYPE_SHA512, -}; - -enum lws_genhmac_types { - LWS_GENHMAC_TYPE_SHA256, - LWS_GENHMAC_TYPE_SHA384, - LWS_GENHMAC_TYPE_SHA512, -}; - -#define LWS_GENHASH_LARGEST 64 - -struct lws_genhash_ctx { - uint8_t type; -#if defined(LWS_WITH_MBEDTLS) - union { - mbedtls_sha1_context sha1; - mbedtls_sha256_context sha256; - mbedtls_sha512_context sha512; /* 384 also uses this */ - const mbedtls_md_info_t *hmac; - } u; -#else - const EVP_MD *evp_type; - EVP_MD_CTX *mdctx; -#endif -}; - -struct lws_genhmac_ctx { - uint8_t type; -#if defined(LWS_WITH_MBEDTLS) - const mbedtls_md_info_t *hmac; - mbedtls_md_context_t ctx; -#else - const EVP_MD *evp_type; - EVP_MD_CTX *ctx; -#endif -}; - -/** lws_genhash_size() - get hash size in bytes - * - * \param type: one of LWS_GENHASH_TYPE_... - * - * Returns number of bytes in this type of hash - */ -LWS_VISIBLE LWS_EXTERN size_t LWS_WARN_UNUSED_RESULT -lws_genhash_size(enum lws_genhash_types type); - -/** lws_genhmac_size() - get hash size in bytes - * - * \param type: one of LWS_GENHASH_TYPE_... - * - * Returns number of bytes in this type of hmac - */ -LWS_VISIBLE LWS_EXTERN size_t LWS_WARN_UNUSED_RESULT -lws_genhmac_size(enum lws_genhmac_types type); - -/** lws_genhash_init() - prepare your struct lws_genhash_ctx for use - * - * \param ctx: your struct lws_genhash_ctx - * \param type: one of LWS_GENHASH_TYPE_... - * - * Initializes the hash context for the type you requested - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type); - -/** lws_genhash_update() - digest len bytes of the buffer starting at in - * - * \param ctx: your struct lws_genhash_ctx - * \param in: start of the bytes to digest - * \param len: count of bytes to digest - * - * Updates the state of your hash context to reflect digesting len bytes from in - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len); - -/** lws_genhash_destroy() - copy out the result digest and destroy the ctx - * - * \param ctx: your struct lws_genhash_ctx - * \param result: NULL, or where to copy the result hash - * - * Finalizes the hash and copies out the digest. Destroys any allocations such - * that ctx can safely go out of scope after calling this. - * - * NULL result is supported so that you can destroy the ctx cleanly on error - * conditions, where there is no valid result. - */ -LWS_VISIBLE LWS_EXTERN int -lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result); - -/** lws_genhmac_init() - prepare your struct lws_genhmac_ctx for use - * - * \param ctx: your struct lws_genhmac_ctx - * \param type: one of LWS_GENHMAC_TYPE_... - * \param key: pointer to the start of the HMAC key - * \param key_len: length of the HMAC key - * - * Initializes the hash context for the type you requested - * - * If the return is nonzero, it failed and there is nothing needing to be - * destroyed. - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type, - const uint8_t *key, size_t key_len); - -/** lws_genhmac_update() - digest len bytes of the buffer starting at in - * - * \param ctx: your struct lws_genhmac_ctx - * \param in: start of the bytes to digest - * \param len: count of bytes to digest - * - * Updates the state of your hash context to reflect digesting len bytes from in - * - * If the return is nonzero, it failed and needs destroying. - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len); - -/** lws_genhmac_destroy() - copy out the result digest and destroy the ctx - * - * \param ctx: your struct lws_genhmac_ctx - * \param result: NULL, or where to copy the result hash - * - * Finalizes the hash and copies out the digest. Destroys any allocations such - * that ctx can safely go out of scope after calling this. - * - * NULL result is supported so that you can destroy the ctx cleanly on error - * conditions, where there is no valid result. - */ -LWS_VISIBLE LWS_EXTERN int -lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result); -///@} - -/*! \defgroup generic RSA - * ## Generic RSA related functions - * - * Lws provides generic RSA functions that abstract the ones - * provided by whatever OpenSSL library you are linking against. - * - * It lets you use the same code if you build against mbedtls or OpenSSL - * for example. - */ -///@{ - -enum enum_jwk_tok { - JWK_KEY_E, - JWK_KEY_N, - JWK_KEY_D, - JWK_KEY_P, - JWK_KEY_Q, - JWK_KEY_DP, - JWK_KEY_DQ, - JWK_KEY_QI, - JWK_KTY, /* also serves as count of real elements */ - JWK_KEY, -}; - -#define LWS_COUNT_RSA_ELEMENTS JWK_KTY - -struct lws_genrsa_ctx { -#if defined(LWS_WITH_MBEDTLS) - mbedtls_rsa_context *ctx; -#else - BIGNUM *bn[LWS_COUNT_RSA_ELEMENTS]; - RSA *rsa; -#endif -}; - -struct lws_genrsa_element { - uint8_t *buf; - uint16_t len; -}; - -struct lws_genrsa_elements { - struct lws_genrsa_element e[LWS_COUNT_RSA_ELEMENTS]; -}; - -/** lws_jwk_destroy_genrsa_elements() - Free allocations in genrsa_elements - * - * \param el: your struct lws_genrsa_elements - * - * This is a helper for user code making use of struct lws_genrsa_elements - * where the elements are allocated on the heap, it frees any non-NULL - * buf element and sets the buf to NULL. - * - * NB: lws_genrsa_public_... apis do not need this as they take care of the key - * creation and destruction themselves. - */ -LWS_VISIBLE LWS_EXTERN void -lws_jwk_destroy_genrsa_elements(struct lws_genrsa_elements *el); - -/** lws_genrsa_public_decrypt_create() - Create RSA public decrypt context - * - * \param ctx: your struct lws_genrsa_ctx - * \param el: struct prepared with key element data - * - * Creates an RSA context with a public key associated with it, formed from - * the key elements in \p el. - * - * Returns 0 for OK or nonzero for error. - * - * This and related APIs operate identically with OpenSSL or mbedTLS backends. - */ -LWS_VISIBLE LWS_EXTERN int -lws_genrsa_create(struct lws_genrsa_ctx *ctx, struct lws_genrsa_elements *el); - -/** lws_genrsa_new_keypair() - Create new RSA keypair - * - * \param context: your struct lws_context (may be used for RNG) - * \param ctx: your struct lws_genrsa_ctx - * \param el: struct to get the new key element data allocated into it - * \param bits: key size, eg, 4096 - * - * Creates a new RSA context and generates a new keypair into it, with \p bits - * bits. - * - * Returns 0 for OK or nonzero for error. - * - * This and related APIs operate identically with OpenSSL or mbedTLS backends. - */ -LWS_VISIBLE LWS_EXTERN int -lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx *ctx, - struct lws_genrsa_elements *el, int bits); - -/** lws_genrsa_public_decrypt() - Perform RSA public decryption - * - * \param ctx: your struct lws_genrsa_ctx - * \param in: encrypted input - * \param in_len: length of encrypted input - * \param out: decrypted output - * \param out_max: size of output buffer - * - * Performs the decryption. - * - * Returns <0 for error, or length of decrypted data. - * - * This and related APIs operate identically with OpenSSL or mbedTLS backends. - */ -LWS_VISIBLE LWS_EXTERN int -lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in, - size_t in_len, uint8_t *out, size_t out_max); - -/** lws_genrsa_public_verify() - Perform RSA public verification - * - * \param ctx: your struct lws_genrsa_ctx - * \param in: unencrypted payload (usually a recomputed hash) - * \param hash_type: one of LWS_GENHASH_TYPE_ - * \param sig: pointer to the signature we received with the payload - * \param sig_len: length of the signature we are checking in bytes - * - * Returns <0 for error, or 0 if signature matches the payload + key. - * - * This and related APIs operate identically with OpenSSL or mbedTLS backends. - */ -LWS_VISIBLE LWS_EXTERN int -lws_genrsa_public_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in, - enum lws_genhash_types hash_type, - const uint8_t *sig, size_t sig_len); - -/** lws_genrsa_public_sign() - Create RSA signature - * - * \param ctx: your struct lws_genrsa_ctx - * \param in: precomputed hash - * \param hash_type: one of LWS_GENHASH_TYPE_ - * \param sig: pointer to buffer to take signature - * \param sig_len: length of the buffer (must be >= length of key N) - * - * Returns <0 for error, or 0 for success. - * - * This and related APIs operate identically with OpenSSL or mbedTLS backends. - */ -LWS_VISIBLE LWS_EXTERN int -lws_genrsa_public_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in, - enum lws_genhash_types hash_type, uint8_t *sig, - size_t sig_len); - -/** lws_genrsa_public_decrypt_destroy() - Destroy RSA public decrypt context - * - * \param ctx: your struct lws_genrsa_ctx - * - * Destroys any allocations related to \p ctx. - * - * This and related APIs operate identically with OpenSSL or mbedTLS backends. - */ -LWS_VISIBLE LWS_EXTERN void -lws_genrsa_destroy(struct lws_genrsa_ctx *ctx); - -/** lws_genrsa_render_pkey_asn1() - Exports public or private key to ASN1/DER - * - * \param ctx: your struct lws_genrsa_ctx - * \param _private: 0 = public part only, 1 = all parts of the key - * \param pkey_asn1: pointer to buffer to take the ASN1 - * \param pkey_asn1_len: max size of the pkey_asn1_len - * - * Returns length of pkey_asn1 written, or -1 for error. - */ -LWS_VISIBLE LWS_EXTERN int -lws_genrsa_render_pkey_asn1(struct lws_genrsa_ctx *ctx, int _private, - uint8_t *pkey_asn1, size_t pkey_asn1_len); -///@} - -/*! \defgroup jwk JSON Web Keys - * ## JSON Web Keys API - * - * Lws provides an API to parse JSON Web Keys into a struct lws_genrsa_elements. - * - * "oct" and "RSA" type keys are supported. For "oct" keys, they are held in - * the "e" member of the struct lws_genrsa_elements. - * - * Keys elements are allocated on the heap. You must destroy the allocations - * in the struct lws_genrsa_elements by calling - * lws_jwk_destroy_genrsa_elements() when you are finished with it. - */ -///@{ - -struct lws_jwk { - char keytype[5]; /**< "oct" or "RSA" */ - struct lws_genrsa_elements el; /**< OCTet key is in el.e */ -}; - -/** lws_jwk_import() - Create a JSON Web key from the textual representation - * - * \param s: the JWK object to create - * \param in: a single JWK JSON stanza in utf-8 - * \param len: the length of the JWK JSON stanza in bytes - * - * Creates an lws_jwk struct filled with data from the JSON representation. - * "oct" and "rsa" key types are supported. - * - * For "oct" type keys, it is loaded into el.e. - */ -LWS_VISIBLE LWS_EXTERN int -lws_jwk_import(struct lws_jwk *s, const char *in, size_t len); - -/** lws_jwk_destroy() - Destroy a JSON Web key - * - * \param s: the JWK object to destroy - * - * All allocations in the lws_jwk are destroyed - */ -LWS_VISIBLE LWS_EXTERN void -lws_jwk_destroy(struct lws_jwk *s); - -/** lws_jwk_export() - Export a JSON Web key to a textual representation - * - * \param s: the JWK object to export - * \param _private: 0 = just export public parts, 1 = export everything - * \param p: the buffer to write the exported JWK to - * \param len: the length of the buffer \p p in bytes - * - * Returns length of the used part of the buffer if OK, or -1 for error. - * - * Serializes the content of the JWK into a char buffer. - */ -LWS_VISIBLE LWS_EXTERN int -lws_jwk_export(struct lws_jwk *s, int _private, char *p, size_t len); - -/** lws_jwk_load() - Import a JSON Web key from a file - * - * \param s: the JWK object to load into - * \param filename: filename to load from - * - * Returns 0 for OK or -1 for failure - */ -LWS_VISIBLE int -lws_jwk_load(struct lws_jwk *s, const char *filename); - -/** lws_jwk_save() - Export a JSON Web key to a file - * - * \param s: the JWK object to save from - * \param filename: filename to save to - * - * Returns 0 for OK or -1 for failure - */ -LWS_VISIBLE int -lws_jwk_save(struct lws_jwk *s, const char *filename); - -/** lws_jwk_rfc7638_fingerprint() - jwk to RFC7638 compliant fingerprint - * - * \param s: the JWK object to fingerprint - * \param digest32: buffer to take 32-byte digest - * - * Returns 0 for OK or -1 for failure - */ -LWS_VISIBLE int -lws_jwk_rfc7638_fingerprint(struct lws_jwk *s, char *digest32); -///@} - - -/*! \defgroup jws JSON Web Signature - * ## JSON Web Signature API - * - * Lws provides an API to check and create RFC7515 JSON Web Signatures - * - * SHA256/384/512 HMAC, and RSA 256/384/512 are supported. - * - * The API uses your TLS library crypto, but works exactly the same no matter - * what you TLS backend is. - */ -///@{ - -LWS_VISIBLE LWS_EXTERN int -lws_jws_confirm_sig(const char *in, size_t len, struct lws_jwk *jwk); - -/** - * lws_jws_sign_from_b64() - add b64 sig to b64 hdr + payload - * - * \param b64_hdr: protected header encoded in b64, may be NULL - * \param hdr_len: bytes in b64 coding of protected header - * \param b64_pay: payload encoded in b64 - * \param pay_len: bytes in b64 coding of payload - * \param b64_sig: buffer to write the b64 encoded signature into - * \param sig_len: max bytes we can write at b64_sig - * \param hash_type: one of LWS_GENHASH_TYPE_SHA[256|384|512] - * \param jwk: the struct lws_jwk containing the signing key - * - * This adds a b64-coded JWS signature of the b64-encoded protected header - * and b64-encoded payload, at \p b64_sig. The signature will be as large - * as the N element of the RSA key when the RSA key is used, eg, 512 bytes for - * a 4096-bit key, and then b64-encoding on top. - * - * In some special cases, there is only payload to sign and no header, in that - * case \p b64_hdr may be NULL, and only the payload will be hashed before - * signing. - * - * Returns the length of the encoded signature written to \p b64_sig, or -1. - */ -LWS_VISIBLE LWS_EXTERN int -lws_jws_sign_from_b64(const char *b64_hdr, size_t hdr_len, const char *b64_pay, - size_t pay_len, char *b64_sig, size_t sig_len, - enum lws_genhash_types hash_type, struct lws_jwk *jwk); - -/** - * lws_jws_create_packet() - add b64 sig to b64 hdr + payload - * - * \param jwk: the struct lws_jwk containing the signing key - * \param payload: unencoded payload JSON - * \param len: length of unencoded payload JSON - * \param nonce: Nonse string to include in protected header - * \param out: buffer to take signed packet - * \param out_len: size of \p out buffer - * - * This creates a "flattened" JWS packet from the jwk and the plaintext - * payload, and signs it. The packet is written into \p out. - * - * This does the whole packet assembly and signing, calling through to - * lws_jws_sign_from_b64() as part of the process. - * - * Returns the length written to \p out, or -1. - */ -LWS_VISIBLE LWS_EXTERN int -lws_jws_create_packet(struct lws_jwk *jwk, const char *payload, size_t len, - const char *nonce, char *out, size_t out_len); - -/** - * lws_jws_base64_enc() - encode input data into b64url data - * - * \param in: the incoming plaintext - * \param in_len: the length of the incoming plaintext in bytes - * \param out: the buffer to store the b64url encoded data to - * \param out_max: the length of \p out in bytes - * - * Returns either -1 if problems, or the number of bytes written to \p out. - */ -LWS_VISIBLE LWS_EXTERN int -lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max); -///@} -#endif - -/*! \defgroup extensions Extension related functions - * ##Extension releated functions - * - * Ws defines optional extensions, lws provides the ability to implement these - * in user code if so desired. - * - * We provide one extensions permessage-deflate. - */ -///@{ - -/* - * NOTE: These public enums are part of the abi. If you want to add one, - * add it at where specified so existing users are unaffected. - */ -enum lws_extension_callback_reasons { - LWS_EXT_CB_CONSTRUCT = 4, - LWS_EXT_CB_CLIENT_CONSTRUCT = 5, - LWS_EXT_CB_DESTROY = 8, - LWS_EXT_CB_PACKET_TX_PRESEND = 12, - LWS_EXT_CB_PAYLOAD_TX = 21, - LWS_EXT_CB_PAYLOAD_RX = 22, - LWS_EXT_CB_OPTION_DEFAULT = 23, - LWS_EXT_CB_OPTION_SET = 24, - LWS_EXT_CB_OPTION_CONFIRM = 25, - LWS_EXT_CB_NAMED_OPTION_SET = 26, - - /****** add new things just above ---^ ******/ -}; - -/** enum lws_ext_options_types */ -enum lws_ext_options_types { - EXTARG_NONE, /**< does not take an argument */ - EXTARG_DEC, /**< requires a decimal argument */ - EXTARG_OPT_DEC /**< may have an optional decimal argument */ - - /* Add new things just above here ---^ - * This is part of the ABI, don't needlessly break compatibility */ -}; - -/** struct lws_ext_options - Option arguments to the extension. These are - * used in the negotiation at ws upgrade time. - * The helper function lws_ext_parse_options() - * uses these to generate callbacks */ -struct lws_ext_options { - const char *name; /**< Option name, eg, "server_no_context_takeover" */ - enum lws_ext_options_types type; /**< What kind of args the option can take */ - - /* Add new things just above here ---^ - * This is part of the ABI, don't needlessly break compatibility */ -}; - -/** struct lws_ext_option_arg */ -struct lws_ext_option_arg { - const char *option_name; /**< may be NULL, option_index used then */ - int option_index; /**< argument ordinal to use if option_name missing */ - const char *start; /**< value */ - int len; /**< length of value */ -}; - -/** - * typedef lws_extension_callback_function() - Hooks to allow extensions to operate - * \param context: Websockets context - * \param ext: This extension - * \param wsi: Opaque websocket instance pointer - * \param reason: The reason for the call - * \param user: Pointer to ptr to per-session user data allocated by library - * \param in: Pointer used for some callback reasons - * \param len: Length set for some callback reasons - * - * Each extension that is active on a particular connection receives - * callbacks during the connection lifetime to allow the extension to - * operate on websocket data and manage itself. - * - * Libwebsockets takes care of allocating and freeing "user" memory for - * each active extension on each connection. That is what is pointed to - * by the user parameter. - * - * LWS_EXT_CB_CONSTRUCT: called when the server has decided to - * select this extension from the list provided by the client, - * just before the server will send back the handshake accepting - * the connection with this extension active. This gives the - * extension a chance to initialize its connection context found - * in user. - * - * LWS_EXT_CB_CLIENT_CONSTRUCT: same as LWS_EXT_CB_CONSTRUCT - * but called when client is instantiating this extension. Some - * extensions will work the same on client and server side and then - * you can just merge handlers for both CONSTRUCTS. - * - * LWS_EXT_CB_DESTROY: called when the connection the extension was - * being used on is about to be closed and deallocated. It's the - * last chance for the extension to deallocate anything it has - * allocated in the user data (pointed to by user) before the - * user data is deleted. This same callback is used whether you - * are in client or server instantiation context. - * - * LWS_EXT_CB_PACKET_TX_PRESEND: this works the same way as - * LWS_EXT_CB_PACKET_RX_PREPARSE above, except it gives the - * extension a chance to change websocket data just before it will - * be sent out. Using the same lws_token pointer scheme in in, - * the extension can change the buffer and the length to be - * transmitted how it likes. Again if it wants to grow the - * buffer safely, it should copy the data into its own buffer and - * set the lws_tokens token pointer to it. - * - * LWS_EXT_CB_ARGS_VALIDATE: - */ -typedef int -lws_extension_callback_function(struct lws_context *context, - const struct lws_extension *ext, struct lws *wsi, - enum lws_extension_callback_reasons reason, - void *user, void *in, size_t len); - -/** struct lws_extension - An extension we support */ -struct lws_extension { - const char *name; /**< Formal extension name, eg, "permessage-deflate" */ - lws_extension_callback_function *callback; /**< Service callback */ - const char *client_offer; /**< String containing exts and options client offers */ - - /* Add new things just above here ---^ - * This is part of the ABI, don't needlessly break compatibility */ -}; - -/** - * lws_set_extension_option(): set extension option if possible - * - * \param wsi: websocket connection - * \param ext_name: name of ext, like "permessage-deflate" - * \param opt_name: name of option, like "rx_buf_size" - * \param opt_val: value to set option to - */ -LWS_VISIBLE LWS_EXTERN int -lws_set_extension_option(struct lws *wsi, const char *ext_name, - const char *opt_name, const char *opt_val); - -/** - * lws_ext_parse_options() - deal with parsing negotiated extension options - * - * \param ext: related extension struct - * \param wsi: websocket connection - * \param ext_user: per-connection extension private data - * \param opts: list of supported options - * \param o: option string to parse - * \param len: length - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_ext_parse_options(const struct lws_extension *ext, struct lws *wsi, - void *ext_user, const struct lws_ext_options *opts, - const char *o, int len); - -/** lws_extension_callback_pm_deflate() - extension for RFC7692 - * - * \param context: lws context - * \param ext: related lws_extension struct - * \param wsi: websocket connection - * \param reason: incoming callback reason - * \param user: per-connection extension private data - * \param in: pointer parameter - * \param len: length parameter - * - * Built-in callback implementing RFC7692 permessage-deflate - */ -LWS_EXTERN -int lws_extension_callback_pm_deflate( - struct lws_context *context, const struct lws_extension *ext, - struct lws *wsi, enum lws_extension_callback_reasons reason, - void *user, void *in, size_t len); - -/* - * The internal exts are part of the public abi - * If we add more extensions, publish the callback here ------v - */ -///@} - -/*! \defgroup Protocols-and-Plugins Protocols and Plugins - * \ingroup lwsapi - * - * ##Protocol and protocol plugin -related apis - * - * Protocols bind ws protocol names to a custom callback specific to that - * protocol implementaion. - * - * A list of protocols can be passed in at context creation time, but it is - * also legal to leave that NULL and add the protocols and their callback code - * using plugins. - * - * Plugins are much preferable compared to cut and pasting code into an - * application each time, since they can be used standalone. - */ -///@{ -/** struct lws_protocols - List of protocols and handlers client or server - * supports. */ - -struct lws_protocols { - const char *name; - /**< Protocol name that must match the one given in the client - * Javascript new WebSocket(url, 'protocol') name. */ - lws_callback_function *callback; - /**< The service callback used for this protocol. It allows the - * service action for an entire protocol to be encapsulated in - * the protocol-specific callback */ - size_t per_session_data_size; - /**< Each new connection using this protocol gets - * this much memory allocated on connection establishment and - * freed on connection takedown. A pointer to this per-connection - * allocation is passed into the callback in the 'user' parameter */ - size_t rx_buffer_size; - /**< lws allocates this much space for rx data and informs callback - * when something came. Due to rx flow control, the callback may not - * be able to consume it all without having to return to the event - * loop. That is supported in lws. - * - * If .tx_packet_size is 0, this also controls how much may be sent at - * once for backwards compatibility. - */ - unsigned int id; - /**< ignored by lws, but useful to contain user information bound - * to the selected protocol. For example if this protocol was - * called "myprotocol-v2", you might set id to 2, and the user - * code that acts differently according to the version can do so by - * switch (wsi->protocol->id), user code might use some bits as - * capability flags based on selected protocol version, etc. */ - void *user; /**< ignored by lws, but user code can pass a pointer - here it can later access from the protocol callback */ - size_t tx_packet_size; - /**< 0 indicates restrict send() size to .rx_buffer_size for backwards- - * compatibility. - * If greater than zero, a single send() is restricted to this amount - * and any remainder is buffered by lws and sent afterwards also in - * these size chunks. Since that is expensive, it's preferable - * to restrict one fragment you are trying to send to match this - * size. - */ - - /* Add new things just above here ---^ - * This is part of the ABI, don't needlessly break compatibility */ -}; - -/** - * lws_vhost_name_to_protocol() - get vhost's protocol object from its name - * - * \param vh: vhost to search - * \param name: protocol name - * - * Returns NULL or a pointer to the vhost's protocol of the requested name - */ -LWS_VISIBLE LWS_EXTERN const struct lws_protocols * -lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name); - -/** - * lws_get_protocol() - Returns a protocol pointer from a websocket - * connection. - * \param wsi: pointer to struct websocket you want to know the protocol of - * - * - * Some apis can act on all live connections of a given protocol, - * this is how you can get a pointer to the active protocol if needed. - */ -LWS_VISIBLE LWS_EXTERN const struct lws_protocols * -lws_get_protocol(struct lws *wsi); - -/** lws_protocol_get() - deprecated: use lws_get_protocol */ -LWS_VISIBLE LWS_EXTERN const struct lws_protocols * -lws_protocol_get(struct lws *wsi) LWS_WARN_DEPRECATED; - -/** - * lws_protocol_vh_priv_zalloc() - Allocate and zero down a protocol's per-vhost - * storage - * \param vhost: vhost the instance is related to - * \param prot: protocol the instance is related to - * \param size: bytes to allocate - * - * Protocols often find it useful to allocate a per-vhost struct, this is a - * helper to be called in the per-vhost init LWS_CALLBACK_PROTOCOL_INIT - */ -LWS_VISIBLE LWS_EXTERN void * -lws_protocol_vh_priv_zalloc(struct lws_vhost *vhost, const struct lws_protocols *prot, - int size); - -/** - * lws_protocol_vh_priv_get() - retreive a protocol's per-vhost storage - * - * \param vhost: vhost the instance is related to - * \param prot: protocol the instance is related to - * - * Recover a pointer to the allocated per-vhost storage for the protocol created - * by lws_protocol_vh_priv_zalloc() earlier - */ -LWS_VISIBLE LWS_EXTERN void * -lws_protocol_vh_priv_get(struct lws_vhost *vhost, const struct lws_protocols *prot); - -/** - * lws_adjust_protocol_psds - change a vhost protocol's per session data size - * - * \param wsi: a connection with the protocol to change - * \param new_size: the new size of the per session data size for the protocol - * - * Returns user_space for the wsi, after allocating - * - * This should not be used except to initalize a vhost protocol's per session - * data size one time, before any connections are accepted. - * - * Sometimes the protocol wraps another protocol and needs to discover and set - * its per session data size at runtime. - */ -LWS_VISIBLE LWS_EXTERN void * -lws_adjust_protocol_psds(struct lws *wsi, size_t new_size); - -/** - * lws_finalize_startup() - drop initial process privileges - * - * \param context: lws context - * - * This is called after the end of the vhost protocol initializations, but - * you may choose to call it earlier - */ -LWS_VISIBLE LWS_EXTERN int -lws_finalize_startup(struct lws_context *context); - -/** - * lws_pvo_search() - helper to find a named pvo in a linked-list - * - * \param pvo: the first pvo in the linked-list - * \param name: the name of the pvo to return if found - * - * Returns NULL, or a pointer to the name pvo in the linked-list - */ -LWS_VISIBLE LWS_EXTERN const struct lws_protocol_vhost_options * -lws_pvo_search(const struct lws_protocol_vhost_options *pvo, const char *name); - -LWS_VISIBLE LWS_EXTERN int -lws_protocol_init(struct lws_context *context); - -#ifdef LWS_WITH_PLUGINS - -/* PLUGINS implies LIBUV */ - -#define LWS_PLUGIN_API_MAGIC 180 - -/** struct lws_plugin_capability - how a plugin introduces itself to lws */ -struct lws_plugin_capability { - unsigned int api_magic; /**< caller fills this in, plugin fills rest */ - const struct lws_protocols *protocols; /**< array of supported protocols provided by plugin */ - int count_protocols; /**< how many protocols */ - const struct lws_extension *extensions; /**< array of extensions provided by plugin */ - int count_extensions; /**< how many extensions */ -}; - -typedef int (*lws_plugin_init_func)(struct lws_context *, - struct lws_plugin_capability *); -typedef int (*lws_plugin_destroy_func)(struct lws_context *); - -/** struct lws_plugin */ -struct lws_plugin { - struct lws_plugin *list; /**< linked list */ -#if (UV_VERSION_MAJOR > 0) - uv_lib_t lib; /**< shared library pointer */ -#else - void *l; /**< so we can compile on ancient libuv */ -#endif - char name[64]; /**< name of the plugin */ - struct lws_plugin_capability caps; /**< plugin capabilities */ -}; - -#endif - -///@} - - -/*! \defgroup generic-sessions plugin: generic-sessions - * \ingroup Protocols-and-Plugins - * - * ##Plugin Generic-sessions related - * - * generic-sessions plugin provides a reusable, generic session and login / - * register / forgot password framework including email verification. - */ -///@{ - -#define LWSGS_EMAIL_CONTENT_SIZE 16384 -/**< Maximum size of email we might send */ - -/* SHA-1 binary and hexified versions */ -/** typedef struct lwsgw_hash_bin */ -typedef struct { unsigned char bin[20]; /**< binary representation of hash */} lwsgw_hash_bin; -/** typedef struct lwsgw_hash */ -typedef struct { char id[41]; /**< ascii hex representation of hash */ } lwsgw_hash; - -/** enum lwsgs_auth_bits */ -enum lwsgs_auth_bits { - LWSGS_AUTH_LOGGED_IN = 1, /**< user is logged in as somebody */ - LWSGS_AUTH_ADMIN = 2, /**< logged in as the admin user */ - LWSGS_AUTH_VERIFIED = 4, /**< user has verified his email */ - LWSGS_AUTH_FORGOT_FLOW = 8, /**< he just completed "forgot password" flow */ -}; - -/** struct lws_session_info - information about user session status */ -struct lws_session_info { - char username[32]; /**< username logged in as, or empty string */ - char email[100]; /**< email address associated with login, or empty string */ - char ip[72]; /**< ip address session was started from */ - unsigned int mask; /**< access rights mask associated with session - * see enum lwsgs_auth_bits */ - char session[42]; /**< session id string, usable as opaque uid when not logged in */ -}; - -/** enum lws_gs_event */ -enum lws_gs_event { - LWSGSE_CREATED, /**< a new user was created */ - LWSGSE_DELETED /**< an existing user was deleted */ -}; - -/** struct lws_gs_event_args */ -struct lws_gs_event_args { - enum lws_gs_event event; /**< which event happened */ - const char *username; /**< which username the event happened to */ - const char *email; /**< the email address of that user */ -}; - -///@} - - -/*! \defgroup context-and-vhost context and vhost related functions - * ##Context and Vhost releated functions - * \ingroup lwsapi - * - * - * LWS requires that there is one context, in which you may define multiple - * vhosts. Each vhost is a virtual host, with either its own listen port - * or sharing an existing one. Each vhost has its own SSL context that can - * be set up individually or left disabled. - * - * If you don't care about multiple "site" support, you can ignore it and - * lws will create a single default vhost at context creation time. - */ -///@{ - -/* - * NOTE: These public enums are part of the abi. If you want to add one, - * add it at where specified so existing users are unaffected. - */ - -/** enum lws_context_options - context and vhost options */ -enum lws_context_options { - LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT = (1 << 1) | - (1 << 12), - /**< (VH) Don't allow the connection unless the client has a - * client cert that we recognize; provides - * LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT */ - LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME = (1 << 2), - /**< (CTX) Don't try to get the server's hostname */ - LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT = (1 << 3) | - (1 << 12), - /**< (VH) Allow non-SSL (plaintext) connections on the same - * port as SSL is listening... undermines the security of SSL; - * provides LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT */ - LWS_SERVER_OPTION_LIBEV = (1 << 4), - /**< (CTX) Use libev event loop */ - LWS_SERVER_OPTION_DISABLE_IPV6 = (1 << 5), - /**< (VH) Disable IPV6 support */ - LWS_SERVER_OPTION_DISABLE_OS_CA_CERTS = (1 << 6), - /**< (VH) Don't load OS CA certs, you will need to load your - * own CA cert(s) */ - LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED = (1 << 7), - /**< (VH) Accept connections with no valid Cert (eg, selfsigned) */ - LWS_SERVER_OPTION_VALIDATE_UTF8 = (1 << 8), - /**< (VH) Check UT-8 correctness */ - LWS_SERVER_OPTION_SSL_ECDH = (1 << 9) | - (1 << 12), - /**< (VH) initialize ECDH ciphers */ - LWS_SERVER_OPTION_LIBUV = (1 << 10), - /**< (CTX) Use libuv event loop */ - LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS = (1 << 11) | - (1 << 12), - /**< (VH) Use http redirect to force http to https - * (deprecated: use mount redirection) */ - LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT = (1 << 12), - /**< (CTX) Initialize the SSL library at all */ - LWS_SERVER_OPTION_EXPLICIT_VHOSTS = (1 << 13), - /**< (CTX) Only create the context when calling context - * create api, implies user code will create its own vhosts */ - LWS_SERVER_OPTION_UNIX_SOCK = (1 << 14), - /**< (VH) Use Unix socket */ - LWS_SERVER_OPTION_STS = (1 << 15), - /**< (VH) Send Strict Transport Security header, making - * clients subsequently go to https even if user asked for http */ - LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY = (1 << 16), - /**< (VH) Enable LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE to take effect */ - LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE = (1 << 17), - /**< (VH) if set, only ipv6 allowed on the vhost */ - LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN = (1 << 18), - /**< (CTX) Libuv only: Do not spin on SIGSEGV / SIGFPE. A segfault - * normally makes the lib spin so you can attach a debugger to it - * even if it happened without a debugger in place. You can disable - * that by giving this option. - */ - LWS_SERVER_OPTION_JUST_USE_RAW_ORIGIN = (1 << 19), - /**< For backwards-compatibility reasons, by default - * lws prepends "http://" to the origin you give in the client - * connection info struct. If you give this flag when you create - * the context, only the string you give in the client connect - * info for .origin (if any) will be used directly. - */ - LWS_SERVER_OPTION_FALLBACK_TO_RAW = (1 << 20), - /**< (VH) if invalid http is coming in the first line, */ - LWS_SERVER_OPTION_LIBEVENT = (1 << 21), - /**< (CTX) Use libevent event loop */ - LWS_SERVER_OPTION_ONLY_RAW = (1 << 22), - /**< (VH) All connections to this vhost / port are RAW as soon as - * the connection is accepted, no HTTP is going to be coming. - */ - LWS_SERVER_OPTION_ALLOW_LISTEN_SHARE = (1 << 23), - /**< (VH) Set to allow multiple listen sockets on one interface + - * address + port. The default is to strictly allow only one - * listen socket at a time. This is automatically selected if you - * have multiple service threads. - */ - LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX = (1 << 24), - /**< (VH) Force setting up the vhost SSL_CTX, even though the user - * code doesn't explicitly provide a cert in the info struct. It - * implies the user code is going to provide a cert at the - * LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS callback, which - * provides the vhost SSL_CTX * in the user parameter. - */ - LWS_SERVER_OPTION_SKIP_PROTOCOL_INIT = (1 << 25), - /**< (VH) You probably don't want this. It forces this vhost to not - * call LWS_CALLBACK_PROTOCOL_INIT on its protocols. It's used in the - * special case of a temporary vhost bound to a single protocol. - */ - LWS_SERVER_OPTION_IGNORE_MISSING_CERT = (1 << 26), - /**< (VH) Don't fail if the vhost TLS cert or key are missing, just - * continue. The vhost won't be able to serve anything, but if for - * example the ACME plugin was configured to fetch a cert, this lets - * you bootstrap your vhost from having no cert to start with. - */ - - /****** add new things just above ---^ ******/ -}; - -#define lws_check_opt(c, f) (((c) & (f)) == (f)) - -struct lws_plat_file_ops; - -/** struct lws_context_creation_info - parameters to create context and /or vhost with - * - * This is also used to create vhosts.... if LWS_SERVER_OPTION_EXPLICIT_VHOSTS - * is not given, then for backwards compatibility one vhost is created at - * context-creation time using the info from this struct. - * - * If LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, then no vhosts are created - * at the same time as the context, they are expected to be created afterwards. - */ -struct lws_context_creation_info { - int port; - /**< VHOST: Port to listen on. Use CONTEXT_PORT_NO_LISTEN to suppress - * listening for a client. Use CONTEXT_PORT_NO_LISTEN_SERVER if you are - * writing a server but you are using \ref sock-adopt instead of the - * built-in listener. - * - * You can also set port to 0, in which case the kernel will pick - * a random port that is not already in use. You can find out what - * port the vhost is listening on using lws_get_vhost_listen_port() */ - const char *iface; - /**< VHOST: NULL to bind the listen socket to all interfaces, or the - * interface name, eg, "eth2" - * If options specifies LWS_SERVER_OPTION_UNIX_SOCK, this member is - * the pathname of a UNIX domain socket. you can use the UNIX domain - * sockets in abstract namespace, by prepending an at symbol to the - * socket name. */ - const struct lws_protocols *protocols; - /**< VHOST: Array of structures listing supported protocols and a protocol- - * specific callback for each one. The list is ended with an - * entry that has a NULL callback pointer. */ - const struct lws_extension *extensions; - /**< VHOST: NULL or array of lws_extension structs listing the - * extensions this context supports. */ - const struct lws_token_limits *token_limits; - /**< CONTEXT: NULL or struct lws_token_limits pointer which is initialized - * with a token length limit for each possible WSI_TOKEN_ */ - const char *ssl_private_key_password; - /**< VHOST: NULL or the passphrase needed for the private key. (For - * backwards compatibility, this can also be used to pass the client - * cert passphrase when setting up a vhost client SSL context, but it is - * preferred to use .client_ssl_private_key_password for that.) */ - const char *ssl_cert_filepath; - /**< VHOST: If libwebsockets was compiled to use ssl, and you want - * to listen using SSL, set to the filepath to fetch the - * server cert from, otherwise NULL for unencrypted. (For backwards - * compatibility, this can also be used to pass the client certificate - * when setting up a vhost client SSL context, but it is preferred to - * use .client_ssl_cert_filepath for that.) */ - const char *ssl_private_key_filepath; - /**< VHOST: filepath to private key if wanting SSL mode; - * if this is set to NULL but ssl_cert_filepath is set, the - * OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY callback is called - * to allow setting of the private key directly via openSSL - * library calls. (For backwards compatibility, this can also be used - * to pass the client cert private key filepath when setting up a - * vhost client SSL context, but it is preferred to use - * .client_ssl_private_key_filepath for that.) */ - const char *ssl_ca_filepath; - /**< VHOST: CA certificate filepath or NULL. (For backwards - * compatibility, this can also be used to pass the client CA - * filepath when setting up a vhost client SSL context, - * but it is preferred to use .client_ssl_ca_filepath for that.) */ - const char *ssl_cipher_list; - /**< VHOST: List of valid ciphers to use (eg, - * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" - * or you can leave it as NULL to get "DEFAULT" (For backwards - * compatibility, this can also be used to pass the client cipher - * list when setting up a vhost client SSL context, - * but it is preferred to use .client_ssl_cipher_list for that.)*/ - const char *http_proxy_address; - /**< VHOST: If non-NULL, attempts to proxy via the given address. - * If proxy auth is required, use format "username:password\@server:port" */ - unsigned int http_proxy_port; - /**< VHOST: If http_proxy_address was non-NULL, uses this port */ - int gid; - /**< CONTEXT: group id to change to after setting listen socket, or -1. */ - int uid; - /**< CONTEXT: user id to change to after setting listen socket, or -1. */ - unsigned int options; - /**< VHOST + CONTEXT: 0, or LWS_SERVER_OPTION_... bitfields */ - void *user; - /**< VHOST + CONTEXT: optional user pointer that will be associated - * with the context when creating the context (and can be retrieved by - * lws_context_user(context), or with the vhost when creating the vhost - * (and can be retrieved by lws_vhost_user(vhost)). You will need to - * use LWS_SERVER_OPTION_EXPLICIT_VHOSTS and create the vhost separately - * if you care about giving the context and vhost different user pointer - * values. - */ - int ka_time; - /**< CONTEXT: 0 for no TCP keepalive, otherwise apply this keepalive - * timeout to all libwebsocket sockets, client or server */ - int ka_probes; - /**< CONTEXT: if ka_time was nonzero, after the timeout expires how many - * times to try to get a response from the peer before giving up - * and killing the connection */ - int ka_interval; - /**< CONTEXT: if ka_time was nonzero, how long to wait before each ka_probes - * attempt */ -#if defined(LWS_WITH_TLS) && !defined(LWS_WITH_MBEDTLS) - SSL_CTX *provided_client_ssl_ctx; - /**< CONTEXT: If non-null, swap out libwebsockets ssl - * implementation for the one provided by provided_ssl_ctx. - * Libwebsockets no longer is responsible for freeing the context - * if this option is selected. */ -#else /* maintain structure layout either way */ - void *provided_client_ssl_ctx; /**< dummy if ssl disabled */ -#endif - - short max_http_header_data; - /**< CONTEXT: The max amount of header payload that can be handled - * in an http request (unrecognized header payload is dropped) */ - short max_http_header_pool; - /**< CONTEXT: The max number of connections with http headers that - * can be processed simultaneously (the corresponding memory is - * allocated and deallocated dynamically as needed). If the pool is - * fully busy new incoming connections must wait for accept until one - * becomes free. 0 = allow as many ah as number of availble fds for - * the process */ - - unsigned int count_threads; - /**< CONTEXT: how many contexts to create in an array, 0 = 1 */ - unsigned int fd_limit_per_thread; - /**< CONTEXT: nonzero means restrict each service thread to this - * many fds, 0 means the default which is divide the process fd - * limit by the number of threads. */ - unsigned int timeout_secs; - /**< VHOST: various processes involving network roundtrips in the - * library are protected from hanging forever by timeouts. If - * nonzero, this member lets you set the timeout used in seconds. - * Otherwise a default timeout is used. */ - const char *ecdh_curve; - /**< VHOST: if NULL, defaults to initializing server with "prime256v1" */ - const char *vhost_name; - /**< VHOST: name of vhost, must match external DNS name used to - * access the site, like "warmcat.com" as it's used to match - * Host: header and / or SNI name for SSL. */ - const char * const *plugin_dirs; - /**< CONTEXT: NULL, or NULL-terminated array of directories to - * scan for lws protocol plugins at context creation time */ - const struct lws_protocol_vhost_options *pvo; - /**< VHOST: pointer to optional linked list of per-vhost - * options made accessible to protocols */ - int keepalive_timeout; - /**< VHOST: (default = 0 = 5s) seconds to allow remote - * client to hold on to an idle HTTP/1.1 connection */ - const char *log_filepath; - /**< VHOST: filepath to append logs to... this is opened before - * any dropping of initial privileges */ - const struct lws_http_mount *mounts; - /**< VHOST: optional linked list of mounts for this vhost */ - const char *server_string; - /**< CONTEXT: string used in HTTP headers to identify server - * software, if NULL, "libwebsockets". */ - unsigned int pt_serv_buf_size; - /**< CONTEXT: 0 = default of 4096. This buffer is used by - * various service related features including file serving, it - * defines the max chunk of file that can be sent at once. - * At the risk of lws having to buffer failed large sends, it - * can be increased to, eg, 128KiB to improve throughput. */ - unsigned int max_http_header_data2; - /**< CONTEXT: if max_http_header_data is 0 and this - * is nonzero, this will be used in place of the default. It's - * like this for compatibility with the original short version, - * this is unsigned int length. */ - long ssl_options_set; - /**< VHOST: Any bits set here will be set as SSL options */ - long ssl_options_clear; - /**< VHOST: Any bits set here will be cleared as SSL options */ - unsigned short ws_ping_pong_interval; - /**< CONTEXT: 0 for none, else interval in seconds between sending - * PINGs on idle websocket connections. When the PING is sent, - * the PONG must come within the normal timeout_secs timeout period - * or the connection will be dropped. - * Any RX or TX traffic on the connection restarts the interval timer, - * so a connection which always sends or receives something at intervals - * less than the interval given here will never send PINGs / expect - * PONGs. Conversely as soon as the ws connection is established, an - * idle connection will do the PING / PONG roundtrip as soon as - * ws_ping_pong_interval seconds has passed without traffic - */ - const struct lws_protocol_vhost_options *headers; - /**< VHOST: pointer to optional linked list of per-vhost - * canned headers that are added to server responses */ - - const struct lws_protocol_vhost_options *reject_service_keywords; - /**< CONTEXT: Optional list of keywords and rejection codes + text. - * - * The keywords are checked for existing in the user agent string. - * - * Eg, "badrobot" "404 Not Found" - */ - void *external_baggage_free_on_destroy; - /**< CONTEXT: NULL, or pointer to something externally malloc'd, that - * should be freed when the context is destroyed. This allows you to - * automatically sync the freeing action to the context destruction - * action, so there is no need for an external free() if the context - * succeeded to create. - */ - - const char *client_ssl_private_key_password; - /**< VHOST: Client SSL context init: NULL or the passphrase needed - * for the private key */ - const char *client_ssl_cert_filepath; - /**< VHOST: Client SSL context init:T he certificate the client - * should present to the peer on connection */ - const char *client_ssl_private_key_filepath; - /**< VHOST: Client SSL context init: filepath to client private key - * if this is set to NULL but client_ssl_cert_filepath is set, you - * can handle the LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS - * callback of protocols[0] to allow setting of the private key directly - * via openSSL library calls */ - const char *client_ssl_ca_filepath; - /**< VHOST: Client SSL context init: CA certificate filepath or NULL */ - const char *client_ssl_cipher_list; - /**< VHOST: Client SSL context init: List of valid ciphers to use (eg, - * "RC4-MD5:RC4-SHA:AES128-SHA:AES256-SHA:HIGH:!DSS:!aNULL" - * or you can leave it as NULL to get "DEFAULT" */ - - const struct lws_plat_file_ops *fops; - /**< CONTEXT: NULL, or pointer to an array of fops structs, terminated - * by a sentinel with NULL .open. - * - * If NULL, lws provides just the platform file operations struct for - * backwards compatibility. - */ - int simultaneous_ssl_restriction; - /**< CONTEXT: 0 (no limit) or limit of simultaneous SSL sessions possible.*/ - const char *socks_proxy_address; - /**< VHOST: If non-NULL, attempts to proxy via the given address. - * If proxy auth is required, use format "username:password\@server:port" */ - unsigned int socks_proxy_port; - /**< VHOST: If socks_proxy_address was non-NULL, uses this port */ -#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) - cap_value_t caps[4]; - /**< CONTEXT: array holding Linux capabilities you want to - * continue to be available to the server after it transitions - * to a noprivileged user. Usually none are needed but for, eg, - * .bind_iface, CAP_NET_RAW is required. This gives you a way - * to still have the capability but drop root. - */ - char count_caps; - /**< CONTEXT: count of Linux capabilities in .caps[]. 0 means - * no capabilities will be inherited from root (the default) */ -#endif - int bind_iface; - /**< VHOST: nonzero to strictly bind sockets to the interface name in - * .iface (eg, "eth2"), using SO_BIND_TO_DEVICE. - * - * Requires SO_BINDTODEVICE support from your OS and CAP_NET_RAW - * capability. - * - * Notice that common things like access network interface IP from - * your local machine use your lo / loopback interface and will be - * disallowed by this. - */ - int ssl_info_event_mask; - /**< VHOST: mask of ssl events to be reported on LWS_CALLBACK_SSL_INFO - * callback for connections on this vhost. The mask values are of - * the form SSL_CB_ALERT, defined in openssl/ssl.h. The default of - * 0 means no info events will be reported. - */ - unsigned int timeout_secs_ah_idle; - /**< VHOST: seconds to allow a client to hold an ah without using it. - * 0 defaults to 10s. */ - unsigned short ip_limit_ah; - /**< CONTEXT: max number of ah a single IP may use simultaneously - * 0 is no limit. This is a soft limit: if the limit is - * reached, connections from that IP will wait in the ah - * waiting list and not be able to acquire an ah until - * a connection belonging to the IP relinquishes one it - * already has. - */ - unsigned short ip_limit_wsi; - /**< CONTEXT: max number of wsi a single IP may use simultaneously. - * 0 is no limit. This is a hard limit, connections from - * the same IP will simply be dropped once it acquires the - * amount of simultaneous wsi / accepted connections - * given here. - */ - uint32_t http2_settings[7]; - /**< VHOST: if http2_settings[0] is nonzero, the values given in - * http2_settings[1]..[6] are used instead of the lws - * platform default values. - * Just leave all at 0 if you don't care. - */ - const char *error_document_404; - /**< VHOST: If non-NULL, when asked to serve a non-existent file, - * lws attempts to server this url path instead. Eg, - * "/404.html" */ - const char *alpn; - /**< CONTEXT: If non-NULL, default list of advertised alpn, comma- - * separated - * - * VHOST: If non-NULL, per-vhost list of advertised alpn, comma- - * separated - */ - void **foreign_loops; - /**< CONTEXT: This is ignored if the context is not being started with - * an event loop, ie, .options has a flag like - * LWS_SERVER_OPTION_LIBUV. - * - * NULL indicates lws should start its own even loop for - * each service thread, and deal with closing the loops - * when the context is destroyed. - * - * Non-NULL means it points to an array of external - * ("foreign") event loops that are to be used in turn for - * each service thread. In the default case of 1 service - * thread, it can just point to one foreign event loop. - */ - void (*signal_cb)(void *event_lib_handle, int signum); - /**< CONTEXT: NULL: default signal handling. Otherwise this receives - * the signal handler callback. event_lib_handle is the - * native event library signal handle, eg uv_signal_t * - * for libuv. - */ - - /* Add new things just above here ---^ - * This is part of the ABI, don't needlessly break compatibility - * - * The below is to ensure later library versions with new - * members added above will see 0 (default) even if the app - * was not built against the newer headers. - */ - struct lws_context **pcontext; - /**< CONTEXT: if non-NULL, at the end of context destroy processing, - * the pointer pointed to by pcontext is written with NULL. You can - * use this to let foreign event loops know that lws context destruction - * is fully completed. - */ - - void *_unused[4]; /**< dummy */ -}; - -/** - * lws_create_context() - Create the websocket handler - * \param info: pointer to struct with parameters - * - * This function creates the listening socket (if serving) and takes care - * of all initialization in one step. - * - * If option LWS_SERVER_OPTION_EXPLICIT_VHOSTS is given, no vhost is - * created; you're expected to create your own vhosts afterwards using - * lws_create_vhost(). Otherwise a vhost named "default" is also created - * using the information in the vhost-related members, for compatibility. - * - * After initialization, it returns a struct lws_context * that - * represents this server. After calling, user code needs to take care - * of calling lws_service() with the context pointer to get the - * server's sockets serviced. This must be done in the same process - * context as the initialization call. - * - * The protocol callback functions are called for a handful of events - * including http requests coming in, websocket connections becoming - * established, and data arriving; it's also called periodically to allow - * async transmission. - * - * HTTP requests are sent always to the FIRST protocol in protocol, since - * at that time websocket protocol has not been negotiated. Other - * protocols after the first one never see any HTTP callback activity. - * - * The server created is a simple http server by default; part of the - * websocket standard is upgrading this http connection to a websocket one. - * - * This allows the same server to provide files like scripts and favicon / - * images or whatever over http and dynamic data over websockets all in - * one place; they're all handled in the user callback. - */ -LWS_VISIBLE LWS_EXTERN struct lws_context * -lws_create_context(const struct lws_context_creation_info *info); - - -/** - * lws_context_destroy() - Destroy the websocket context - * \param context: Websocket context - * - * This function closes any active connections and then frees the - * context. After calling this, any further use of the context is - * undefined. - */ -LWS_VISIBLE LWS_EXTERN void -lws_context_destroy(struct lws_context *context); - -typedef int (*lws_reload_func)(void); - -/** - * lws_context_deprecate() - Deprecate the websocket context - * - * \param context: Websocket context - * \param cb: Callback notified when old context listen sockets are closed - * - * This function is used on an existing context before superceding it - * with a new context. - * - * It closes any listen sockets in the context, so new connections are - * not possible. - * - * And it marks the context to be deleted when the number of active - * connections into it falls to zero. - * - * Otherwise if you attach the deprecated context to the replacement - * context when it has been created using lws_context_attach_deprecated() - * both any deprecated and the new context will service their connections. - * - * This is aimed at allowing seamless configuration reloads. - * - * The callback cb will be called after the listen sockets are actually - * closed and may be reopened. In the callback the new context should be - * configured and created. (With libuv, socket close happens async after - * more loop events). - */ -LWS_VISIBLE LWS_EXTERN void -lws_context_deprecate(struct lws_context *context, lws_reload_func cb); - -LWS_VISIBLE LWS_EXTERN int -lws_context_is_deprecated(struct lws_context *context); - -/** - * lws_set_proxy() - Setups proxy to lws_context. - * \param vhost: pointer to struct lws_vhost you want set proxy for - * \param proxy: pointer to c string containing proxy in format address:port - * - * Returns 0 if proxy string was parsed and proxy was setup. - * Returns -1 if proxy is NULL or has incorrect format. - * - * This is only required if your OS does not provide the http_proxy - * environment variable (eg, OSX) - * - * IMPORTANT! You should call this function right after creation of the - * lws_context and before call to connect. If you call this - * function after connect behavior is undefined. - * This function will override proxy settings made on lws_context - * creation with genenv() call. - */ -LWS_VISIBLE LWS_EXTERN int -lws_set_proxy(struct lws_vhost *vhost, const char *proxy); - -/** - * lws_set_socks() - Setup socks to lws_context. - * \param vhost: pointer to struct lws_vhost you want set socks for - * \param socks: pointer to c string containing socks in format address:port - * - * Returns 0 if socks string was parsed and socks was setup. - * Returns -1 if socks is NULL or has incorrect format. - * - * This is only required if your OS does not provide the socks_proxy - * environment variable (eg, OSX) - * - * IMPORTANT! You should call this function right after creation of the - * lws_context and before call to connect. If you call this - * function after connect behavior is undefined. - * This function will override proxy settings made on lws_context - * creation with genenv() call. - */ -LWS_VISIBLE LWS_EXTERN int -lws_set_socks(struct lws_vhost *vhost, const char *socks); - -struct lws_vhost; - -/** - * lws_create_vhost() - Create a vhost (virtual server context) - * \param context: pointer to result of lws_create_context() - * \param info: pointer to struct with parameters - * - * This function creates a virtual server (vhost) using the vhost-related - * members of the info struct. You can create many vhosts inside one context - * if you created the context with the option LWS_SERVER_OPTION_EXPLICIT_VHOSTS - */ -LWS_VISIBLE LWS_EXTERN struct lws_vhost * -lws_create_vhost(struct lws_context *context, - const struct lws_context_creation_info *info); - -/** - * lws_vhost_destroy() - Destroy a vhost (virtual server context) - * - * \param vh: pointer to result of lws_create_vhost() - * - * This function destroys a vhost. Normally, if you just want to exit, - * then lws_destroy_context() will take care of everything. If you want - * to destroy an individual vhost and all connections and allocations, you - * can do it with this. - * - * If the vhost has a listen sockets shared by other vhosts, it will be given - * to one of the vhosts sharing it rather than closed. - */ -LWS_VISIBLE LWS_EXTERN void -lws_vhost_destroy(struct lws_vhost *vh); - -/** - * lwsws_get_config_globals() - Parse a JSON server config file - * \param info: pointer to struct with parameters - * \param d: filepath of the config file - * \param config_strings: storage for the config strings extracted from JSON, - * the pointer is incremented as strings are stored - * \param len: pointer to the remaining length left in config_strings - * the value is decremented as strings are stored - * - * This function prepares a n lws_context_creation_info struct with global - * settings from a file d. - * - * Requires CMake option LWS_WITH_LEJP_CONF to have been enabled - */ -LWS_VISIBLE LWS_EXTERN int -lwsws_get_config_globals(struct lws_context_creation_info *info, const char *d, - char **config_strings, int *len); - -/** - * lwsws_get_config_vhosts() - Create vhosts from a JSON server config file - * \param context: pointer to result of lws_create_context() - * \param info: pointer to struct with parameters - * \param d: filepath of the config file - * \param config_strings: storage for the config strings extracted from JSON, - * the pointer is incremented as strings are stored - * \param len: pointer to the remaining length left in config_strings - * the value is decremented as strings are stored - * - * This function creates vhosts into a context according to the settings in - *JSON files found in directory d. - * - * Requires CMake option LWS_WITH_LEJP_CONF to have been enabled - */ -LWS_VISIBLE LWS_EXTERN int -lwsws_get_config_vhosts(struct lws_context *context, - struct lws_context_creation_info *info, const char *d, - char **config_strings, int *len); - -/** lws_vhost_get() - \deprecated deprecated: use lws_get_vhost() */ -LWS_VISIBLE LWS_EXTERN struct lws_vhost * -lws_vhost_get(struct lws *wsi) LWS_WARN_DEPRECATED; - -/** - * lws_get_vhost() - return the vhost a wsi belongs to - * - * \param wsi: which connection - */ -LWS_VISIBLE LWS_EXTERN struct lws_vhost * -lws_get_vhost(struct lws *wsi); - -/** - * lws_get_vhost_name() - returns the name of a vhost - * - * \param vhost: which vhost - */ -LWS_VISIBLE LWS_EXTERN const char * -lws_get_vhost_name(struct lws_vhost *vhost); - -/** - * lws_get_vhost_port() - returns the port a vhost listens on, or -1 - * - * \param vhost: which vhost - */ -LWS_VISIBLE LWS_EXTERN int -lws_get_vhost_port(struct lws_vhost *vhost); - -/** - * lws_get_vhost_user() - returns the user pointer for the vhost - * - * \param vhost: which vhost - */ -LWS_VISIBLE LWS_EXTERN void * -lws_get_vhost_user(struct lws_vhost *vhost); - -/** - * lws_get_vhost_iface() - returns the binding for the vhost listen socket - * - * \param vhost: which vhost - */ -LWS_VISIBLE LWS_EXTERN const char * -lws_get_vhost_iface(struct lws_vhost *vhost); - -/** - * lws_json_dump_vhost() - describe vhost state and stats in JSON - * - * \param vh: the vhost - * \param buf: buffer to fill with JSON - * \param len: max length of buf - */ -LWS_VISIBLE LWS_EXTERN int -lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len); - -/** - * lws_json_dump_context() - describe context state and stats in JSON - * - * \param context: the context - * \param buf: buffer to fill with JSON - * \param len: max length of buf - * \param hide_vhosts: nonzero to not provide per-vhost mount etc information - * - * Generates a JSON description of vhost state into buf - */ -LWS_VISIBLE LWS_EXTERN int -lws_json_dump_context(const struct lws_context *context, char *buf, int len, - int hide_vhosts); - -/** - * lws_vhost_user() - get the user data associated with the vhost - * \param vhost: Websocket vhost - * - * This returns the optional user pointer that can be attached to - * a vhost when it was created. Lws never dereferences this pointer, it only - * sets it when the vhost is created, and returns it using this api. - */ -LWS_VISIBLE LWS_EXTERN void * -lws_vhost_user(struct lws_vhost *vhost); - -/** - * lws_context_user() - get the user data associated with the context - * \param context: Websocket context - * - * This returns the optional user allocation that can be attached to - * the context the sockets live in at context_create time. It's a way - * to let all sockets serviced in the same context share data without - * using globals statics in the user code. - */ -LWS_VISIBLE LWS_EXTERN void * -lws_context_user(struct lws_context *context); - -/*! \defgroup vhost-mounts Vhost mounts and options - * \ingroup context-and-vhost-creation - * - * ##Vhost mounts and options - */ -///@{ -/** struct lws_protocol_vhost_options - linked list of per-vhost protocol - * name=value options - * - * This provides a general way to attach a linked-list of name=value pairs, - * which can also have an optional child link-list using the options member. - */ -struct lws_protocol_vhost_options { - const struct lws_protocol_vhost_options *next; /**< linked list */ - const struct lws_protocol_vhost_options *options; /**< child linked-list of more options for this node */ - const char *name; /**< name of name=value pair */ - const char *value; /**< value of name=value pair */ -}; - -/** enum lws_mount_protocols - * This specifies the mount protocol for a mountpoint, whether it is to be - * served from a filesystem, or it is a cgi etc. - */ -enum lws_mount_protocols { - LWSMPRO_HTTP = 0, /**< http reverse proxy */ - LWSMPRO_HTTPS = 1, /**< https reverse proxy */ - LWSMPRO_FILE = 2, /**< serve from filesystem directory */ - LWSMPRO_CGI = 3, /**< pass to CGI to handle */ - LWSMPRO_REDIR_HTTP = 4, /**< redirect to http:// url */ - LWSMPRO_REDIR_HTTPS = 5, /**< redirect to https:// url */ - LWSMPRO_CALLBACK = 6, /**< hand by named protocol's callback */ -}; - -/** struct lws_http_mount - * - * arguments for mounting something in a vhost's url namespace - */ -struct lws_http_mount { - const struct lws_http_mount *mount_next; - /**< pointer to next struct lws_http_mount */ - const char *mountpoint; - /**< mountpoint in http pathspace, eg, "/" */ - const char *origin; - /**< path to be mounted, eg, "/var/www/warmcat.com" */ - const char *def; - /**< default target, eg, "index.html" */ - const char *protocol; - /**<"protocol-name" to handle mount */ - - const struct lws_protocol_vhost_options *cgienv; - /**< optional linked-list of cgi options. These are created - * as environment variables for the cgi process - */ - const struct lws_protocol_vhost_options *extra_mimetypes; - /**< optional linked-list of mimetype mappings */ - const struct lws_protocol_vhost_options *interpret; - /**< optional linked-list of files to be interpreted */ - - int cgi_timeout; - /**< seconds cgi is allowed to live, if cgi://mount type */ - int cache_max_age; - /**< max-age for reuse of client cache of files, seconds */ - unsigned int auth_mask; - /**< bits set here must be set for authorized client session */ - - unsigned int cache_reusable:1; /**< set if client cache may reuse this */ - unsigned int cache_revalidate:1; /**< set if client cache should revalidate on use */ - unsigned int cache_intermediaries:1; /**< set if intermediaries are allowed to cache */ - - unsigned char origin_protocol; /**< one of enum lws_mount_protocols */ - unsigned char mountpoint_len; /**< length of mountpoint string */ - - const char *basic_auth_login_file; - /**<NULL, or filepath to use to check basic auth logins against */ - - /* Add new things just above here ---^ - * This is part of the ABI, don't needlessly break compatibility - * - * The below is to ensure later library versions with new - * members added above will see 0 (default) even if the app - * was not built against the newer headers. - */ - - void *_unused[2]; /**< dummy */ -}; -///@} -///@} - -/*! \defgroup client Client related functions - * ##Client releated functions - * \ingroup lwsapi - * - * */ -///@{ - -/** enum lws_client_connect_ssl_connection_flags - flags that may be used - * with struct lws_client_connect_info ssl_connection member to control if - * and how SSL checks apply to the client connection being created - */ - -enum lws_client_connect_ssl_connection_flags { - LCCSCF_USE_SSL = (1 << 0), - LCCSCF_ALLOW_SELFSIGNED = (1 << 1), - LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK = (1 << 2), - LCCSCF_ALLOW_EXPIRED = (1 << 3), - - LCCSCF_PIPELINE = (1 << 16), - /**< Serialize / pipeline multiple client connections - * on a single connection where possible. - * - * HTTP/1.0: possible if Keep-Alive: yes sent by server - * HTTP/1.1: always possible... uses pipelining - * HTTP/2: always possible... uses parallel streams - * */ -}; - -/** struct lws_client_connect_info - parameters to connect with when using - * lws_client_connect_via_info() */ - -struct lws_client_connect_info { - struct lws_context *context; - /**< lws context to create connection in */ - const char *address; - /**< remote address to connect to */ - int port; - /**< remote port to connect to */ - int ssl_connection; - /**< 0, or a combination of LCCSCF_ flags */ - const char *path; - /**< uri path */ - const char *host; - /**< content of host header */ - const char *origin; - /**< content of origin header */ - const char *protocol; - /**< list of ws protocols we could accept */ - int ietf_version_or_minus_one; - /**< deprecated: currently leave at 0 or -1 */ - void *userdata; - /**< if non-NULL, use this as wsi user_data instead of malloc it */ - const void *client_exts; - /**< UNUSED... provide in info.extensions at context creation time */ - const char *method; - /**< if non-NULL, do this http method instead of ws[s] upgrade. - * use "GET" to be a simple http client connection. "RAW" gets - * you a connected socket that lws itself will leave alone once - * connected. */ - struct lws *parent_wsi; - /**< if another wsi is responsible for this connection, give it here. - * this is used to make sure if the parent closes so do any - * child connections first. */ - const char *uri_replace_from; - /**< if non-NULL, when this string is found in URIs in - * text/html content-encoding, it's replaced with uri_replace_to */ - const char *uri_replace_to; - /**< see uri_replace_from */ - struct lws_vhost *vhost; - /**< vhost to bind to (used to determine related SSL_CTX) */ - struct lws **pwsi; - /**< if not NULL, store the new wsi here early in the connection - * process. Although we return the new wsi, the call to create the - * client connection does progress the connection somewhat and may - * meet an error that will result in the connection being scrubbed and - * NULL returned. While the wsi exists though, he may process a - * callback like CLIENT_CONNECTION_ERROR with his wsi: this gives the - * user callback a way to identify which wsi it is that faced the error - * even before the new wsi is returned and even if ultimately no wsi - * is returned. - */ - const char *iface; - /**< NULL to allow routing on any interface, or interface name or IP - * to bind the socket to */ - const char *local_protocol_name; - /**< NULL: .protocol is used both to select the local protocol handler - * to bind to and as the list of remote ws protocols we could - * accept. - * non-NULL: this protocol name is used to bind the connection to - * the local protocol handler. .protocol is used for the - * list of remote ws protocols we could accept */ - - /* Add new things just above here ---^ - * This is part of the ABI, don't needlessly break compatibility - * - * The below is to ensure later library versions with new - * members added above will see 0 (default) even if the app - * was not built against the newer headers. - */ - const char *alpn; - /* NULL: allow lws default ALPN list, from vhost if present or from - * list of roles built into lws - * non-NULL: require one from provided comma-separated list of alpn - * tokens - */ - - void *_unused[4]; /**< dummy */ -}; - -/** - * lws_client_connect_via_info() - Connect to another websocket server - * \param ccinfo: pointer to lws_client_connect_info struct - * - * This function creates a connection to a remote server using the - * information provided in ccinfo. - */ -LWS_VISIBLE LWS_EXTERN struct lws * -lws_client_connect_via_info(struct lws_client_connect_info * ccinfo); - -/** - * lws_client_connect() - Connect to another websocket server - * \deprecated DEPRECATED use lws_client_connect_via_info - * \param clients: Websocket context - * \param address: Remote server address, eg, "myserver.com" - * \param port: Port to connect to on the remote server, eg, 80 - * \param ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self - * signed certs - * \param path: Websocket path on server - * \param host: Hostname on server - * \param origin: Socket origin name - * \param protocol: Comma-separated list of protocols being asked for from - * the server, or just one. The server will pick the one it - * likes best. If you don't want to specify a protocol, which is - * legal, use NULL here. - * \param ietf_version_or_minus_one: -1 to ask to connect using the default, latest - * protocol supported, or the specific protocol ordinal - * - * This function creates a connection to a remote server - */ -/* deprecated, use lws_client_connect_via_info() */ -LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT -lws_client_connect(struct lws_context *clients, const char *address, - int port, int ssl_connection, const char *path, - const char *host, const char *origin, const char *protocol, - int ietf_version_or_minus_one) LWS_WARN_DEPRECATED; -/* deprecated, use lws_client_connect_via_info() */ -/** - * lws_client_connect_extended() - Connect to another websocket server - * \deprecated DEPRECATED use lws_client_connect_via_info - * \param clients: Websocket context - * \param address: Remote server address, eg, "myserver.com" - * \param port: Port to connect to on the remote server, eg, 80 - * \param ssl_connection: 0 = ws://, 1 = wss:// encrypted, 2 = wss:// allow self - * signed certs - * \param path: Websocket path on server - * \param host: Hostname on server - * \param origin: Socket origin name - * \param protocol: Comma-separated list of protocols being asked for from - * the server, or just one. The server will pick the one it - * likes best. - * \param ietf_version_or_minus_one: -1 to ask to connect using the default, latest - * protocol supported, or the specific protocol ordinal - * \param userdata: Pre-allocated user data - * - * This function creates a connection to a remote server - */ -LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT -lws_client_connect_extended(struct lws_context *clients, const char *address, - int port, int ssl_connection, const char *path, - const char *host, const char *origin, - const char *protocol, int ietf_version_or_minus_one, - void *userdata) LWS_WARN_DEPRECATED; - -/** - * lws_init_vhost_client_ssl() - also enable client SSL on an existing vhost - * - * \param info: client ssl related info - * \param vhost: which vhost to initialize client ssl operations on - * - * You only need to call this if you plan on using SSL client connections on - * the vhost. For non-SSL client connections, it's not necessary to call this. - * - * The following members of info are used during the call - * - * - options must have LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT set, - * otherwise the call does nothing - * - provided_client_ssl_ctx must be NULL to get a generated client - * ssl context, otherwise you can pass a prepared one in by setting it - * - ssl_cipher_list may be NULL or set to the client valid cipher list - * - ssl_ca_filepath may be NULL or client cert filepath - * - ssl_cert_filepath may be NULL or client cert filepath - * - ssl_private_key_filepath may be NULL or client cert private key - * - * You must create your vhost explicitly if you want to use this, so you have - * a pointer to the vhost. Create the context first with the option flag - * LWS_SERVER_OPTION_EXPLICIT_VHOSTS and then call lws_create_vhost() with - * the same info struct. - */ -LWS_VISIBLE LWS_EXTERN int -lws_init_vhost_client_ssl(const struct lws_context_creation_info *info, - struct lws_vhost *vhost); -/** - * lws_http_client_read() - consume waiting received http client data - * - * \param wsi: client connection - * \param buf: pointer to buffer pointer - fill with pointer to your buffer - * \param len: pointer to chunk length - fill with max length of buffer - * - * This is called when the user code is notified client http data has arrived. - * The user code may choose to delay calling it to consume the data, for example - * waiting until an onward connection is writeable. - * - * For non-chunked connections, up to len bytes of buf are filled with the - * received content. len is set to the actual amount filled before return. - * - * For chunked connections, the linear buffer content contains the chunking - * headers and it cannot be passed in one lump. Instead, this function will - * call back LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ with in pointing to the - * chunk start and len set to the chunk length. There will be as many calls - * as there are chunks or partial chunks in the buffer. - */ -LWS_VISIBLE LWS_EXTERN int -lws_http_client_read(struct lws *wsi, char **buf, int *len); - -/** - * lws_http_client_http_response() - get last HTTP response code - * - * \param wsi: client connection - * - * Returns the last server response code, eg, 200 for client http connections. - * - * You should capture this during the LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP - * callback, because after that the memory reserved for storing the related - * headers is freed and this value is lost. - */ -LWS_VISIBLE LWS_EXTERN unsigned int -lws_http_client_http_response(struct lws *wsi); - -LWS_VISIBLE LWS_EXTERN void -lws_client_http_body_pending(struct lws *wsi, int something_left_to_send); - -/** - * lws_client_http_body_pending() - control if client connection neeeds to send body - * - * \param wsi: client connection - * \param something_left_to_send: nonzero if need to send more body, 0 (default) - * if nothing more to send - * - * If you will send payload data with your HTTP client connection, eg, for POST, - * when you set the related http headers in - * LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER callback you should also call - * this API with something_left_to_send nonzero, and call - * lws_callback_on_writable(wsi); - * - * After sending the headers, lws will call your callback with - * LWS_CALLBACK_CLIENT_HTTP_WRITEABLE reason when writable. You can send the - * next part of the http body payload, calling lws_callback_on_writable(wsi); - * if there is more to come, or lws_client_http_body_pending(wsi, 0); to - * let lws know the last part is sent and the connection can move on. - */ - -///@} - -/** \defgroup service Built-in service loop entry - * - * ##Built-in service loop entry - * - * If you're not using libev / libuv, these apis are needed to enter the poll() - * wait in lws and service any connections with pending events. - */ -///@{ - -/** - * lws_service() - Service any pending websocket activity - * \param context: Websocket context - * \param timeout_ms: Timeout for poll; 0 means return immediately if nothing needed - * service otherwise block and service immediately, returning - * after the timeout if nothing needed service. - * - * This function deals with any pending websocket traffic, for three - * kinds of event. It handles these events on both server and client - * types of connection the same. - * - * 1) Accept new connections to our context's server - * - * 2) Call the receive callback for incoming frame data received by - * server or client connections. - * - * You need to call this service function periodically to all the above - * functions to happen; if your application is single-threaded you can - * just call it in your main event loop. - * - * Alternatively you can fork a new process that asynchronously handles - * calling this service in a loop. In that case you are happy if this - * call blocks your thread until it needs to take care of something and - * would call it with a large nonzero timeout. Your loop then takes no - * CPU while there is nothing happening. - * - * If you are calling it in a single-threaded app, you don't want it to - * wait around blocking other things in your loop from happening, so you - * would call it with a timeout_ms of 0, so it returns immediately if - * nothing is pending, or as soon as it services whatever was pending. - */ -LWS_VISIBLE LWS_EXTERN int -lws_service(struct lws_context *context, int timeout_ms); - -/** - * lws_service_tsi() - Service any pending websocket activity - * - * \param context: Websocket context - * \param timeout_ms: Timeout for poll; 0 means return immediately if nothing needed - * service otherwise block and service immediately, returning - * after the timeout if nothing needed service. - * \param tsi: Thread service index, starting at 0 - * - * Same as lws_service(), but for a specific thread service index. Only needed - * if you are spawning multiple service threads. - */ -LWS_VISIBLE LWS_EXTERN int -lws_service_tsi(struct lws_context *context, int timeout_ms, int tsi); - -/** - * lws_cancel_service_pt() - Cancel servicing of pending socket activity - * on one thread - * \param wsi: Cancel service on the thread this wsi is serviced by - * - * Same as lws_cancel_service(), but targets a single service thread, the one - * the wsi belongs to. You probably want to use lws_cancel_service() instead. - */ -LWS_VISIBLE LWS_EXTERN void -lws_cancel_service_pt(struct lws *wsi); - -/** - * lws_cancel_service() - Cancel wait for new pending socket activity - * \param context: Websocket context - * - * This function creates an immediate "synchronous interrupt" to the lws poll() - * wait or event loop. As soon as possible in the serialzed service sequencing, - * a LWS_CALLBACK_EVENT_WAIT_CANCELLED callback is sent to every protocol on - * every vhost. - * - * lws_cancel_service() may be called from another thread while the context - * exists, and its effect will be immediately serialized. - */ -LWS_VISIBLE LWS_EXTERN void -lws_cancel_service(struct lws_context *context); - -/** - * lws_service_fd() - Service polled socket with something waiting - * \param context: Websocket context - * \param pollfd: The pollfd entry describing the socket fd and which events - * happened, or NULL to tell lws to do only timeout servicing. - * - * This function takes a pollfd that has POLLIN or POLLOUT activity and - * services it according to the state of the associated - * struct lws. - * - * The one call deals with all "service" that might happen on a socket - * including listen accepts, http files as well as websocket protocol. - * - * If a pollfd says it has something, you can just pass it to - * lws_service_fd() whether it is a socket handled by lws or not. - * If it sees it is a lws socket, the traffic will be handled and - * pollfd->revents will be zeroed now. - * - * If the socket is foreign to lws, it leaves revents alone. So you can - * see if you should service yourself by checking the pollfd revents - * after letting lws try to service it. - * - * You should also call this with pollfd = NULL to just allow the - * once-per-second global timeout checks; if less than a second since the last - * check it returns immediately then. - */ -LWS_VISIBLE LWS_EXTERN int -lws_service_fd(struct lws_context *context, struct lws_pollfd *pollfd); - -/** - * lws_service_fd_tsi() - Service polled socket in specific service thread - * \param context: Websocket context - * \param pollfd: The pollfd entry describing the socket fd and which events - * happened. - * \param tsi: thread service index - * - * Same as lws_service_fd() but used with multiple service threads - */ -LWS_VISIBLE LWS_EXTERN int -lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, - int tsi); - -/** - * lws_service_adjust_timeout() - Check for any connection needing forced service - * \param context: Websocket context - * \param timeout_ms: The original poll timeout value. You can just set this - * to 1 if you don't really have a poll timeout. - * \param tsi: thread service index - * - * Under some conditions connections may need service even though there is no - * pending network action on them, this is "forced service". For default - * poll() and libuv / libev, the library takes care of calling this and - * dealing with it for you. But for external poll() integration, you need - * access to the apis. - * - * If anybody needs "forced service", returned timeout is zero. In that case, - * you can call lws_service_tsi() with a timeout of -1 to only service - * guys who need forced service. - */ -LWS_VISIBLE LWS_EXTERN int -lws_service_adjust_timeout(struct lws_context *context, int timeout_ms, int tsi); - -/* Backwards compatibility */ -#define lws_plat_service_tsi lws_service_tsi - -LWS_VISIBLE LWS_EXTERN int -lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd); - -///@} - -/*! \defgroup http HTTP - - Modules related to handling HTTP -*/ -//@{ - -/*! \defgroup httpft HTTP File transfer - * \ingroup http - - APIs for sending local files in response to HTTP requests -*/ -//@{ - -/** - * lws_get_mimetype() - Determine mimetype to use from filename - * - * \param file: filename - * \param m: NULL, or mount context - * - * This uses a canned list of known filetypes first, if no match and m is - * non-NULL, then tries a list of per-mount file suffix to mimtype mappings. - * - * Returns either NULL or a pointer to the mimetype matching the file. - */ -LWS_VISIBLE LWS_EXTERN const char * -lws_get_mimetype(const char *file, const struct lws_http_mount *m); - -/** - * lws_serve_http_file() - Send a file back to the client using http - * \param wsi: Websocket instance (available from user callback) - * \param file: The file to issue over http - * \param content_type: The http content type, eg, text/html - * \param other_headers: NULL or pointer to header string - * \param other_headers_len: length of the other headers if non-NULL - * - * This function is intended to be called from the callback in response - * to http requests from the client. It allows the callback to issue - * local files down the http link in a single step. - * - * Returning <0 indicates error and the wsi should be closed. Returning - * >0 indicates the file was completely sent and - * lws_http_transaction_completed() called on the wsi (and close if != 0) - * ==0 indicates the file transfer is started and needs more service later, - * the wsi should be left alone. - */ -LWS_VISIBLE LWS_EXTERN int -lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, - const char *other_headers, int other_headers_len); - -LWS_VISIBLE LWS_EXTERN int -lws_serve_http_file_fragment(struct lws *wsi); -//@} - - -enum http_status { - HTTP_STATUS_CONTINUE = 100, - - HTTP_STATUS_OK = 200, - HTTP_STATUS_NO_CONTENT = 204, - HTTP_STATUS_PARTIAL_CONTENT = 206, - - HTTP_STATUS_MOVED_PERMANENTLY = 301, - HTTP_STATUS_FOUND = 302, - HTTP_STATUS_SEE_OTHER = 303, - HTTP_STATUS_NOT_MODIFIED = 304, - - HTTP_STATUS_BAD_REQUEST = 400, - HTTP_STATUS_UNAUTHORIZED, - HTTP_STATUS_PAYMENT_REQUIRED, - HTTP_STATUS_FORBIDDEN, - HTTP_STATUS_NOT_FOUND, - HTTP_STATUS_METHOD_NOT_ALLOWED, - HTTP_STATUS_NOT_ACCEPTABLE, - HTTP_STATUS_PROXY_AUTH_REQUIRED, - HTTP_STATUS_REQUEST_TIMEOUT, - HTTP_STATUS_CONFLICT, - HTTP_STATUS_GONE, - HTTP_STATUS_LENGTH_REQUIRED, - HTTP_STATUS_PRECONDITION_FAILED, - HTTP_STATUS_REQ_ENTITY_TOO_LARGE, - HTTP_STATUS_REQ_URI_TOO_LONG, - HTTP_STATUS_UNSUPPORTED_MEDIA_TYPE, - HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE, - HTTP_STATUS_EXPECTATION_FAILED, - - HTTP_STATUS_INTERNAL_SERVER_ERROR = 500, - HTTP_STATUS_NOT_IMPLEMENTED, - HTTP_STATUS_BAD_GATEWAY, - HTTP_STATUS_SERVICE_UNAVAILABLE, - HTTP_STATUS_GATEWAY_TIMEOUT, - HTTP_STATUS_HTTP_VERSION_NOT_SUPPORTED, -}; -/*! \defgroup html-chunked-substitution HTML Chunked Substitution - * \ingroup http - * - * ##HTML chunked Substitution - * - * APIs for receiving chunks of text, replacing a set of variable names via - * a callback, and then prepending and appending HTML chunked encoding - * headers. - */ -//@{ - -struct lws_process_html_args { - char *p; /**< pointer to the buffer containing the data */ - int len; /**< length of the original data at p */ - int max_len; /**< maximum length we can grow the data to */ - int final; /**< set if this is the last chunk of the file */ - int chunked; /**< 0 == unchunked, 1 == produce chunk headers (incompatible with HTTP/2) */ -}; - -typedef const char *(*lws_process_html_state_cb)(void *data, int index); - -struct lws_process_html_state { - char *start; /**< pointer to start of match */ - char swallow[16]; /**< matched character buffer */ - int pos; /**< position in match */ - void *data; /**< opaque pointer */ - const char * const *vars; /**< list of variable names */ - int count_vars; /**< count of variable names */ - - lws_process_html_state_cb replace; /**< called on match to perform substitution */ -}; - -/*! lws_chunked_html_process() - generic chunked substitution - * \param args: buffer to process using chunked encoding - * \param s: current processing state - */ -LWS_VISIBLE LWS_EXTERN int -lws_chunked_html_process(struct lws_process_html_args *args, - struct lws_process_html_state *s); -//@} - -/** \defgroup HTTP-headers-read HTTP headers: read - * \ingroup http - * - * ##HTTP header releated functions - * - * In lws the client http headers are temporarily stored in a pool, only for the - * duration of the http part of the handshake. It's because in most cases, - * the header content is ignored for the whole rest of the connection lifetime - * and would then just be taking up space needlessly. - * - * During LWS_CALLBACK_HTTP when the URI path is delivered is the last time - * the http headers are still allocated, you can use these apis then to - * look at and copy out interesting header content (cookies, etc) - * - * Notice that the header total length reported does not include a terminating - * '\0', however you must allocate for it when using the _copy apis. So the - * length reported for a header containing "123" is 3, but you must provide - * a buffer of length 4 so that "123\0" may be copied into it, or the copy - * will fail with a nonzero return code. - * - * In the special case of URL arguments, like ?x=1&y=2, the arguments are - * stored in a token named for the method, eg, WSI_TOKEN_GET_URI if it - * was a GET or WSI_TOKEN_POST_URI if POST. You can check the total - * length to confirm the method. - * - * For URL arguments, each argument is stored urldecoded in a "fragment", so - * you can use the fragment-aware api lws_hdr_copy_fragment() to access each - * argument in turn: the fragments contain urldecoded strings like x=1 or y=2. - * - * As a convenience, lws has an api that will find the fragment with a - * given name= part, lws_get_urlarg_by_name(). - */ -///@{ - -/** struct lws_tokens - * you need these to look at headers that have been parsed if using the - * LWS_CALLBACK_FILTER_CONNECTION callback. If a header from the enum - * list below is absent, .token = NULL and len = 0. Otherwise .token - * points to .len chars containing that header content. - */ -struct lws_tokens { - char *token; /**< pointer to start of the token */ - int len; /**< length of the token's value */ -}; - -/* enum lws_token_indexes - * these have to be kept in sync with lextable.h / minilex.c - * - * NOTE: These public enums are part of the abi. If you want to add one, - * add it at where specified so existing users are unaffected. - */ -enum lws_token_indexes { - WSI_TOKEN_GET_URI = 0, - WSI_TOKEN_POST_URI = 1, - WSI_TOKEN_OPTIONS_URI = 2, - WSI_TOKEN_HOST = 3, - WSI_TOKEN_CONNECTION = 4, - WSI_TOKEN_UPGRADE = 5, - WSI_TOKEN_ORIGIN = 6, - WSI_TOKEN_DRAFT = 7, - WSI_TOKEN_CHALLENGE = 8, - WSI_TOKEN_EXTENSIONS = 9, - WSI_TOKEN_KEY1 = 10, - WSI_TOKEN_KEY2 = 11, - WSI_TOKEN_PROTOCOL = 12, - WSI_TOKEN_ACCEPT = 13, - WSI_TOKEN_NONCE = 14, - WSI_TOKEN_HTTP = 15, - WSI_TOKEN_HTTP2_SETTINGS = 16, - WSI_TOKEN_HTTP_ACCEPT = 17, - WSI_TOKEN_HTTP_AC_REQUEST_HEADERS = 18, - WSI_TOKEN_HTTP_IF_MODIFIED_SINCE = 19, - WSI_TOKEN_HTTP_IF_NONE_MATCH = 20, - WSI_TOKEN_HTTP_ACCEPT_ENCODING = 21, - WSI_TOKEN_HTTP_ACCEPT_LANGUAGE = 22, - WSI_TOKEN_HTTP_PRAGMA = 23, - WSI_TOKEN_HTTP_CACHE_CONTROL = 24, - WSI_TOKEN_HTTP_AUTHORIZATION = 25, - WSI_TOKEN_HTTP_COOKIE = 26, - WSI_TOKEN_HTTP_CONTENT_LENGTH = 27, - WSI_TOKEN_HTTP_CONTENT_TYPE = 28, - WSI_TOKEN_HTTP_DATE = 29, - WSI_TOKEN_HTTP_RANGE = 30, - WSI_TOKEN_HTTP_REFERER = 31, - WSI_TOKEN_KEY = 32, - WSI_TOKEN_VERSION = 33, - WSI_TOKEN_SWORIGIN = 34, - - WSI_TOKEN_HTTP_COLON_AUTHORITY = 35, - WSI_TOKEN_HTTP_COLON_METHOD = 36, - WSI_TOKEN_HTTP_COLON_PATH = 37, - WSI_TOKEN_HTTP_COLON_SCHEME = 38, - WSI_TOKEN_HTTP_COLON_STATUS = 39, - - WSI_TOKEN_HTTP_ACCEPT_CHARSET = 40, - WSI_TOKEN_HTTP_ACCEPT_RANGES = 41, - WSI_TOKEN_HTTP_ACCESS_CONTROL_ALLOW_ORIGIN = 42, - WSI_TOKEN_HTTP_AGE = 43, - WSI_TOKEN_HTTP_ALLOW = 44, - WSI_TOKEN_HTTP_CONTENT_DISPOSITION = 45, - WSI_TOKEN_HTTP_CONTENT_ENCODING = 46, - WSI_TOKEN_HTTP_CONTENT_LANGUAGE = 47, - WSI_TOKEN_HTTP_CONTENT_LOCATION = 48, - WSI_TOKEN_HTTP_CONTENT_RANGE = 49, - WSI_TOKEN_HTTP_ETAG = 50, - WSI_TOKEN_HTTP_EXPECT = 51, - WSI_TOKEN_HTTP_EXPIRES = 52, - WSI_TOKEN_HTTP_FROM = 53, - WSI_TOKEN_HTTP_IF_MATCH = 54, - WSI_TOKEN_HTTP_IF_RANGE = 55, - WSI_TOKEN_HTTP_IF_UNMODIFIED_SINCE = 56, - WSI_TOKEN_HTTP_LAST_MODIFIED = 57, - WSI_TOKEN_HTTP_LINK = 58, - WSI_TOKEN_HTTP_LOCATION = 59, - WSI_TOKEN_HTTP_MAX_FORWARDS = 60, - WSI_TOKEN_HTTP_PROXY_AUTHENTICATE = 61, - WSI_TOKEN_HTTP_PROXY_AUTHORIZATION = 62, - WSI_TOKEN_HTTP_REFRESH = 63, - WSI_TOKEN_HTTP_RETRY_AFTER = 64, - WSI_TOKEN_HTTP_SERVER = 65, - WSI_TOKEN_HTTP_SET_COOKIE = 66, - WSI_TOKEN_HTTP_STRICT_TRANSPORT_SECURITY = 67, - WSI_TOKEN_HTTP_TRANSFER_ENCODING = 68, - WSI_TOKEN_HTTP_USER_AGENT = 69, - WSI_TOKEN_HTTP_VARY = 70, - WSI_TOKEN_HTTP_VIA = 71, - WSI_TOKEN_HTTP_WWW_AUTHENTICATE = 72, - - WSI_TOKEN_PATCH_URI = 73, - WSI_TOKEN_PUT_URI = 74, - WSI_TOKEN_DELETE_URI = 75, - - WSI_TOKEN_HTTP_URI_ARGS = 76, - WSI_TOKEN_PROXY = 77, - WSI_TOKEN_HTTP_X_REAL_IP = 78, - WSI_TOKEN_HTTP1_0 = 79, - WSI_TOKEN_X_FORWARDED_FOR = 80, - WSI_TOKEN_CONNECT = 81, - WSI_TOKEN_HEAD_URI = 82, - WSI_TOKEN_TE = 83, - WSI_TOKEN_REPLAY_NONCE = 84, - WSI_TOKEN_COLON_PROTOCOL = 85, - WSI_TOKEN_X_AUTH_TOKEN = 86, - - /****** add new things just above ---^ ******/ - - /* use token storage to stash these internally, not for - * user use */ - - _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, - _WSI_TOKEN_CLIENT_PEER_ADDRESS, - _WSI_TOKEN_CLIENT_URI, - _WSI_TOKEN_CLIENT_HOST, - _WSI_TOKEN_CLIENT_ORIGIN, - _WSI_TOKEN_CLIENT_METHOD, - _WSI_TOKEN_CLIENT_IFACE, - _WSI_TOKEN_CLIENT_ALPN, - - /* always last real token index*/ - WSI_TOKEN_COUNT, - - /* parser state additions, no storage associated */ - WSI_TOKEN_NAME_PART, - WSI_TOKEN_SKIPPING, - WSI_TOKEN_SKIPPING_SAW_CR, - WSI_PARSING_COMPLETE, - WSI_INIT_TOKEN_MUXURL, -}; - -struct lws_token_limits { - unsigned short token_limit[WSI_TOKEN_COUNT]; /**< max chars for this token */ -}; - -/** - * lws_token_to_string() - returns a textual representation of a hdr token index - * - * \param token: token index - */ -LWS_VISIBLE LWS_EXTERN const unsigned char * -lws_token_to_string(enum lws_token_indexes token); - -/** - * lws_hdr_total_length: report length of all fragments of a header totalled up - * The returned length does not include the space for a - * terminating '\0' - * - * \param wsi: websocket connection - * \param h: which header index we are interested in - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h); - -/** - * lws_hdr_fragment_length: report length of a single fragment of a header - * The returned length does not include the space for a - * terminating '\0' - * - * \param wsi: websocket connection - * \param h: which header index we are interested in - * \param frag_idx: which fragment of h we want to get the length of - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx); - -/** - * lws_hdr_copy() - copy a single fragment of the given header to a buffer - * The buffer length len must include space for an additional - * terminating '\0', or it will fail returning -1. - * - * \param wsi: websocket connection - * \param dest: destination buffer - * \param len: length of destination buffer - * \param h: which header index we are interested in - * - * copies the whole, aggregated header, even if it was delivered in - * several actual headers piece by piece - */ -LWS_VISIBLE LWS_EXTERN int -lws_hdr_copy(struct lws *wsi, char *dest, int len, enum lws_token_indexes h); - -/** - * lws_hdr_copy_fragment() - copy a single fragment of the given header to a buffer - * The buffer length len must include space for an additional - * terminating '\0', or it will fail returning -1. - * If the requested fragment index is not present, it fails - * returning -1. - * - * \param wsi: websocket connection - * \param dest: destination buffer - * \param len: length of destination buffer - * \param h: which header index we are interested in - * \param frag_idx: which fragment of h we want to copy - * - * Normally this is only useful - * to parse URI arguments like ?x=1&y=2, token index WSI_TOKEN_HTTP_URI_ARGS - * fragment 0 will contain "x=1" and fragment 1 "y=2" - */ -LWS_VISIBLE LWS_EXTERN int -lws_hdr_copy_fragment(struct lws *wsi, char *dest, int len, - enum lws_token_indexes h, int frag_idx); - -/** - * lws_get_urlarg_by_name() - return pointer to arg value if present - * \param wsi: the connection to check - * \param name: the arg name, like "token=" - * \param buf: the buffer to receive the urlarg (including the name= part) - * \param len: the length of the buffer to receive the urlarg - * - * Returns NULL if not found or a pointer inside buf to just after the - * name= part. - */ -LWS_VISIBLE LWS_EXTERN const char * -lws_get_urlarg_by_name(struct lws *wsi, const char *name, char *buf, int len); -///@} - -/*! \defgroup HTTP-headers-create HTTP headers: create - * - * ## HTTP headers: Create - * - * These apis allow you to create HTTP response headers in a way compatible with - * both HTTP/1.x and HTTP/2. - * - * They each append to a buffer taking care about the buffer end, which is - * passed in as a pointer. When data is written to the buffer, the current - * position p is updated accordingly. - * - * All of these apis are LWS_WARN_UNUSED_RESULT as they can run out of space - * and fail with nonzero return. - */ -///@{ - -#define LWSAHH_CODE_MASK ((1 << 16) - 1) -#define LWSAHH_FLAG_NO_SERVER_NAME (1 << 30) - -/** - * lws_add_http_header_status() - add the HTTP response status code - * - * \param wsi: the connection to check - * \param code: an HTTP code like 200, 404 etc (see enum http_status) - * \param p: pointer to current position in buffer pointer - * \param end: pointer to end of buffer - * - * Adds the initial response code, so should be called first. - * - * Code may additionally take OR'd flags: - * - * LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_add_http_header_status(struct lws *wsi, - unsigned int code, unsigned char **p, - unsigned char *end); -/** - * lws_add_http_header_by_name() - append named header and value - * - * \param wsi: the connection to check - * \param name: the hdr name, like "my-header" - * \param value: the value after the = for this header - * \param length: the length of the value - * \param p: pointer to current position in buffer pointer - * \param end: pointer to end of buffer - * - * Appends name: value to the headers - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name, - const unsigned char *value, int length, - unsigned char **p, unsigned char *end); -/** - * lws_add_http_header_by_token() - append given header and value - * - * \param wsi: the connection to check - * \param token: the token index for the hdr - * \param value: the value after the = for this header - * \param length: the length of the value - * \param p: pointer to current position in buffer pointer - * \param end: pointer to end of buffer - * - * Appends name=value to the headers, but is able to take advantage of better - * HTTP/2 coding mechanisms where possible. - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token, - const unsigned char *value, int length, - unsigned char **p, unsigned char *end); -/** - * lws_add_http_header_content_length() - append content-length helper - * - * \param wsi: the connection to check - * \param content_length: the content length to use - * \param p: pointer to current position in buffer pointer - * \param end: pointer to end of buffer - * - * Appends content-length: content_length to the headers - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_add_http_header_content_length(struct lws *wsi, - lws_filepos_t content_length, - unsigned char **p, unsigned char *end); -/** - * lws_finalize_http_header() - terminate header block - * - * \param wsi: the connection to check - * \param p: pointer to current position in buffer pointer - * \param end: pointer to end of buffer - * - * Indicates no more headers will be added - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_finalize_http_header(struct lws *wsi, unsigned char **p, - unsigned char *end); - -/** - * lws_finalize_write_http_header() - Helper finializing and writing http headers - * - * \param wsi: the connection to check - * \param start: pointer to the start of headers in the buffer, eg &buf[LWS_PRE] - * \param p: pointer to current position in buffer pointer - * \param end: pointer to end of buffer - * - * Terminates the headers correctly accoring to the protocol in use (h1 / h2) - * and writes the headers. Returns nonzero for error. - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_finalize_write_http_header(struct lws *wsi, unsigned char *start, - unsigned char **p, unsigned char *end); - -#define LWS_ILLEGAL_HTTP_CONTENT_LEN ((lws_filepos_t)-1ll) - -/** - * lws_add_http_common_headers() - Helper preparing common http headers - * - * \param wsi: the connection to check - * \param code: an HTTP code like 200, 404 etc (see enum http_status) - * \param content_type: the content type, like "text/html" - * \param content_len: the content length, in bytes - * \param p: pointer to current position in buffer pointer - * \param end: pointer to end of buffer - * - * Adds the initial response code, so should be called first. - * - * Code may additionally take OR'd flags: - * - * LWSAHH_FLAG_NO_SERVER_NAME: don't apply server name header this time - * - * This helper just calls public apis to simplify adding headers that are - * commonly needed. If it doesn't fit your case, or you want to add additional - * headers just call the public apis directly yourself for what you want. - * - * You can miss out the content length header by providing the constant - * LWS_ILLEGAL_HTTP_CONTENT_LEN for the content_len. - * - * It does not call lws_finalize_http_header(), to allow you to add further - * headers after calling this. You will need to call that yourself at the end. - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_add_http_common_headers(struct lws *wsi, unsigned int code, - const char *content_type, lws_filepos_t content_len, - unsigned char **p, unsigned char *end); -///@} - -/** \defgroup form-parsing Form Parsing - * \ingroup http - * ##POSTed form parsing functions - * - * These lws_spa (stateful post arguments) apis let you parse and urldecode - * POSTed form arguments, both using simple urlencoded and multipart transfer - * encoding. - * - * It's capable of handling file uploads as well a named input parsing, - * and the apis are the same for both form upload styles. - * - * You feed it a list of parameter names and it creates pointers to the - * urldecoded arguments: file upload parameters pass the file data in chunks to - * a user-supplied callback as they come. - * - * Since it's stateful, it handles the incoming data needing more than one - * POST_BODY callback and has no limit on uploaded file size. - */ -///@{ - -/** enum lws_spa_fileupload_states */ -enum lws_spa_fileupload_states { - LWS_UFS_CONTENT, - /**< a chunk of file content has arrived */ - LWS_UFS_FINAL_CONTENT, - /**< the last chunk (possibly zero length) of file content has arrived */ - LWS_UFS_OPEN - /**< a new file is starting to arrive */ -}; - -/** - * lws_spa_fileupload_cb() - callback to receive file upload data - * - * \param data: opt_data pointer set in lws_spa_create - * \param name: name of the form field being uploaded - * \param filename: original filename from client - * \param buf: start of data to receive - * \param len: length of data to receive - * \param state: information about how this call relates to file - * - * Notice name and filename shouldn't be trusted, as they are passed from - * HTTP provided by the client. - */ -typedef int (*lws_spa_fileupload_cb)(void *data, const char *name, - const char *filename, char *buf, int len, - enum lws_spa_fileupload_states state); - -/** struct lws_spa - opaque urldecode parser capable of handling multipart - * and file uploads */ -struct lws_spa; - -/** - * lws_spa_create() - create urldecode parser - * - * \param wsi: lws connection (used to find Content Type) - * \param param_names: array of form parameter names, like "username" - * \param count_params: count of param_names - * \param max_storage: total amount of form parameter values we can store - * \param opt_cb: NULL, or callback to receive file upload data. - * \param opt_data: NULL, or user pointer provided to opt_cb. - * - * Creates a urldecode parser and initializes it. - * - * opt_cb can be NULL if you just want normal name=value parsing, however - * if one or more entries in your form are bulk data (file transfer), you - * can provide this callback and filter on the name callback parameter to - * treat that urldecoded data separately. The callback should return -1 - * in case of fatal error, and 0 if OK. - */ -LWS_VISIBLE LWS_EXTERN struct lws_spa * -lws_spa_create(struct lws *wsi, const char * const *param_names, - int count_params, int max_storage, lws_spa_fileupload_cb opt_cb, - void *opt_data); - -/** - * lws_spa_process() - parses a chunk of input data - * - * \param spa: the parser object previously created - * \param in: incoming, urlencoded data - * \param len: count of bytes valid at \param in - */ -LWS_VISIBLE LWS_EXTERN int -lws_spa_process(struct lws_spa *spa, const char *in, int len); - -/** - * lws_spa_finalize() - indicate incoming data completed - * - * \param spa: the parser object previously created - */ -LWS_VISIBLE LWS_EXTERN int -lws_spa_finalize(struct lws_spa *spa); - -/** - * lws_spa_get_length() - return length of parameter value - * - * \param spa: the parser object previously created - * \param n: parameter ordinal to return length of value for - */ -LWS_VISIBLE LWS_EXTERN int -lws_spa_get_length(struct lws_spa *spa, int n); - -/** - * lws_spa_get_string() - return pointer to parameter value - * \param spa: the parser object previously created - * \param n: parameter ordinal to return pointer to value for - */ -LWS_VISIBLE LWS_EXTERN const char * -lws_spa_get_string(struct lws_spa *spa, int n); - -/** - * lws_spa_destroy() - destroy parser object - * - * \param spa: the parser object previously created - */ -LWS_VISIBLE LWS_EXTERN int -lws_spa_destroy(struct lws_spa *spa); -///@} - -/*! \defgroup urlendec Urlencode and Urldecode - * \ingroup http - * - * ##HTML chunked Substitution - * - * APIs for receiving chunks of text, replacing a set of variable names via - * a callback, and then prepending and appending HTML chunked encoding - * headers. - */ -//@{ - -/** - * lws_urlencode() - like strncpy but with urlencoding - * - * \param escaped: output buffer - * \param string: input buffer ('/0' terminated) - * \param len: output buffer max length - * - * Because urlencoding expands the output string, it's not - * possible to do it in-place, ie, with escaped == string - */ -LWS_VISIBLE LWS_EXTERN const char * -lws_urlencode(char *escaped, const char *string, int len); - -/* - * URLDECODE 1 / 2 - * - * This simple urldecode only operates until the first '\0' and requires the - * data to exist all at once - */ -/** - * lws_urldecode() - like strncpy but with urldecoding - * - * \param string: output buffer - * \param escaped: input buffer ('\0' terminated) - * \param len: output buffer max length - * - * This is only useful for '\0' terminated strings - * - * Since urldecoding only shrinks the output string, it is possible to - * do it in-place, ie, string == escaped - * - * Returns 0 if completed OK or nonzero for urldecode violation (non-hex chars - * where hex required, etc) - */ -LWS_VISIBLE LWS_EXTERN int -lws_urldecode(char *string, const char *escaped, int len); -///@} -/** - * lws_return_http_status() - Return simple http status - * \param wsi: Websocket instance (available from user callback) - * \param code: Status index, eg, 404 - * \param html_body: User-readable HTML description < 1KB, or NULL - * - * Helper to report HTTP errors back to the client cleanly and - * consistently - */ -LWS_VISIBLE LWS_EXTERN int -lws_return_http_status(struct lws *wsi, unsigned int code, - const char *html_body); - -/** - * lws_http_redirect() - write http redirect out on wsi - * - * \param wsi: websocket connection - * \param code: HTTP response code (eg, 301) - * \param loc: where to redirect to - * \param len: length of loc - * \param p: pointer current position in buffer (updated as we write) - * \param end: pointer to end of buffer - * - * Returns amount written, or < 0 indicating fatal write failure. - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len, - unsigned char **p, unsigned char *end); - -/** - * lws_http_transaction_completed() - wait for new http transaction or close - * \param wsi: websocket connection - * - * Returns 1 if the HTTP connection must close now - * Returns 0 and resets connection to wait for new HTTP header / - * transaction if possible - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_http_transaction_completed(struct lws *wsi); -///@} - -/*! \defgroup pur Sanitize / purify SQL and JSON helpers - * - * ##Sanitize / purify SQL and JSON helpers - * - * APIs for escaping untrusted JSON and SQL safely before use - */ -//@{ - -/** - * lws_sql_purify() - like strncpy but with escaping for sql quotes - * - * \param escaped: output buffer - * \param string: input buffer ('/0' terminated) - * \param len: output buffer max length - * - * Because escaping expands the output string, it's not - * possible to do it in-place, ie, with escaped == string - */ -LWS_VISIBLE LWS_EXTERN const char * -lws_sql_purify(char *escaped, const char *string, int len); - -/** - * lws_json_purify() - like strncpy but with escaping for json chars - * - * \param escaped: output buffer - * \param string: input buffer ('/0' terminated) - * \param len: output buffer max length - * - * Because escaping expands the output string, it's not - * possible to do it in-place, ie, with escaped == string - */ -LWS_VISIBLE LWS_EXTERN const char * -lws_json_purify(char *escaped, const char *string, int len); - -/** - * lws_filename_purify_inplace() - replace scary filename chars with underscore - * - * \param filename: filename to be purified - * - * Replace scary characters in the filename (it should not be a path) - * with underscore, so it's safe to use. - */ -LWS_VISIBLE LWS_EXTERN void -lws_filename_purify_inplace(char *filename); - -LWS_VISIBLE LWS_EXTERN int -lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf, - int len); -LWS_VISIBLE LWS_EXTERN int -lws_plat_write_file(const char *filename, void *buf, int len); - -LWS_VISIBLE LWS_EXTERN int -lws_plat_read_file(const char *filename, void *buf, int len); - -LWS_VISIBLE LWS_EXTERN int -lws_plat_recommended_rsa_bits(void); -///@} - -/*! \defgroup uv libuv helpers - * - * ##libuv helpers - * - * APIs specific to libuv event loop itegration - */ -///@{ -#ifdef LWS_WITH_LIBUV -/* - * Any direct libuv allocations in lws protocol handlers must participate in the - * lws reference counting scheme. Two apis are provided: - * - * - lws_libuv_static_refcount_add(handle, context) to mark the handle with - * a pointer to the context and increment the global uv object counter - * - * - lws_libuv_static_refcount_del() which should be used as the close callback - * for your own libuv objects declared in the protocol scope. - * - * Using the apis allows lws to detach itself from a libuv loop completely - * cleanly and at the moment all of its libuv objects have completed close. - */ - -LWS_VISIBLE LWS_EXTERN uv_loop_t * -lws_uv_getloop(struct lws_context *context, int tsi); - -LWS_VISIBLE LWS_EXTERN void -lws_libuv_static_refcount_add(uv_handle_t *, struct lws_context *context); - -LWS_VISIBLE LWS_EXTERN void -lws_libuv_static_refcount_del(uv_handle_t *); - -#endif /* LWS_WITH_LIBUV */ - -#if defined(LWS_WITH_ESP32) -#define lws_libuv_static_refcount_add(_a, _b) -#define lws_libuv_static_refcount_del NULL -#endif -///@} - - -/*! \defgroup timeout Connection timeouts - - APIs related to setting connection timeouts -*/ -//@{ - -/* - * NOTE: These public enums are part of the abi. If you want to add one, - * add it at where specified so existing users are unaffected. - */ -enum pending_timeout { - NO_PENDING_TIMEOUT = 0, - PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE = 1, - PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE = 2, - PENDING_TIMEOUT_ESTABLISH_WITH_SERVER = 3, - PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE = 4, - PENDING_TIMEOUT_AWAITING_PING = 5, - PENDING_TIMEOUT_CLOSE_ACK = 6, - PENDING_TIMEOUT_UNUSED1 = 7, - PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE = 8, - PENDING_TIMEOUT_SSL_ACCEPT = 9, - PENDING_TIMEOUT_HTTP_CONTENT = 10, - PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND = 11, - PENDING_FLUSH_STORED_SEND_BEFORE_CLOSE = 12, - PENDING_TIMEOUT_SHUTDOWN_FLUSH = 13, - PENDING_TIMEOUT_CGI = 14, - PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE = 15, - PENDING_TIMEOUT_WS_PONG_CHECK_SEND_PING = 16, - PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG = 17, - PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD = 18, - PENDING_TIMEOUT_AWAITING_SOCKS_GREETING_REPLY = 19, - PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY = 20, - PENDING_TIMEOUT_AWAITING_SOCKS_AUTH_REPLY = 21, - PENDING_TIMEOUT_KILLED_BY_SSL_INFO = 22, - PENDING_TIMEOUT_KILLED_BY_PARENT = 23, - PENDING_TIMEOUT_CLOSE_SEND = 24, - PENDING_TIMEOUT_HOLDING_AH = 25, - PENDING_TIMEOUT_UDP_IDLE = 26, - PENDING_TIMEOUT_CLIENT_CONN_IDLE = 27, - PENDING_TIMEOUT_LAGGING = 28, - - /****** add new things just above ---^ ******/ - - PENDING_TIMEOUT_USER_REASON_BASE = 1000 -}; - -#define LWS_TO_KILL_ASYNC -1 -/**< If LWS_TO_KILL_ASYNC is given as the timeout sec in a lws_set_timeout() - * call, then the connection is marked to be killed at the next timeout - * check. This is how you should force-close the wsi being serviced if - * you are doing it outside the callback (where you should close by nonzero - * return). - */ -#define LWS_TO_KILL_SYNC -2 -/**< If LWS_TO_KILL_SYNC is given as the timeout sec in a lws_set_timeout() - * call, then the connection is closed before returning (which may delete - * the wsi). This should only be used where the wsi being closed is not the - * wsi currently being serviced. - */ -/** - * lws_set_timeout() - marks the wsi as subject to a timeout - * - * You will not need this unless you are doing something special - * - * \param wsi: Websocket connection instance - * \param reason: timeout reason - * \param secs: how many seconds. You may set to LWS_TO_KILL_ASYNC to - * force the connection to timeout at the next opportunity, or - * LWS_TO_KILL_SYNC to close it synchronously if you know the - * wsi is not the one currently being serviced. - */ -LWS_VISIBLE LWS_EXTERN void -lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs); - -#define LWS_SET_TIMER_USEC_CANCEL ((lws_usec_t)-1ll) -#define LWS_USEC_PER_SEC (1000000ll) - -/** - * lws_set_timer_usecs() - schedules a callback on the wsi in the future - * - * \param wsi: Websocket connection instance - * \param usecs: LWS_SET_TIMER_USEC_CANCEL removes any existing scheduled - * callback, otherwise number of microseconds in the future - * the callback will occur at. - * - * NOTE: event loop support for this: - * - * default poll() loop: yes - * libuv event loop: yes - * libev: not implemented (patch welcome) - * libevent: not implemented (patch welcome) - * - * After the deadline expires, the wsi will get a callback of type - * LWS_CALLBACK_TIMER and the timer is exhausted. The deadline may be - * continuously deferred by further calls to lws_set_timer_usecs() with a later - * deadline, or cancelled by lws_set_timer_usecs(wsi, -1). - * - * If the timer should repeat, lws_set_timer_usecs() must be called again from - * LWS_CALLBACK_TIMER. - * - * Accuracy depends on the platform and the load on the event loop or system... - * all that's guaranteed is the callback will come after the requested wait - * period. - */ -LWS_VISIBLE LWS_EXTERN void -lws_set_timer_usecs(struct lws *wsi, lws_usec_t usecs); - -/* - * lws_timed_callback_vh_protocol() - calls back a protocol on a vhost after - * the specified delay - * - * \param vh: the vhost to call back - * \param protocol: the protocol to call back - * \param reason: callback reason - * \param secs: how many seconds in the future to do the callback. Set to - * -1 to cancel the timer callback. - * - * Callback the specified protocol with a fake wsi pointing to the specified - * vhost and protocol, with the specified reason, at the specified time in the - * future. - * - * Returns 0 if OK. - */ -LWS_VISIBLE LWS_EXTERN int -lws_timed_callback_vh_protocol(struct lws_vhost *vh, - const struct lws_protocols *prot, - int reason, int secs); -///@} - -/*! \defgroup sending-data Sending data - - APIs related to writing data on a connection -*/ -//@{ -#if !defined(LWS_SIZEOFPTR) -#define LWS_SIZEOFPTR ((int)sizeof (void *)) -#endif - -#if defined(__x86_64__) -#define _LWS_PAD_SIZE 16 /* Intel recommended for best performance */ -#else -#define _LWS_PAD_SIZE LWS_SIZEOFPTR /* Size of a pointer on the target arch */ -#endif -#define _LWS_PAD(n) (((n) % _LWS_PAD_SIZE) ? \ - ((n) + (_LWS_PAD_SIZE - ((n) % _LWS_PAD_SIZE))) : (n)) -/* last 2 is for lws-meta */ -#define LWS_PRE _LWS_PAD(4 + 10 + 2) -/* used prior to 1.7 and retained for backward compatibility */ -#define LWS_SEND_BUFFER_PRE_PADDING LWS_PRE -#define LWS_SEND_BUFFER_POST_PADDING 0 - -#define LWS_WRITE_RAW LWS_WRITE_HTTP - -/* - * NOTE: These public enums are part of the abi. If you want to add one, - * add it at where specified so existing users are unaffected. - */ -enum lws_write_protocol { - LWS_WRITE_TEXT = 0, - /**< Send a ws TEXT message,the pointer must have LWS_PRE valid - * memory behind it. The receiver expects only valid utf-8 in the - * payload */ - LWS_WRITE_BINARY = 1, - /**< Send a ws BINARY message, the pointer must have LWS_PRE valid - * memory behind it. Any sequence of bytes is valid */ - LWS_WRITE_CONTINUATION = 2, - /**< Continue a previous ws message, the pointer must have LWS_PRE valid - * memory behind it */ - LWS_WRITE_HTTP = 3, - /**< Send HTTP content */ - - /* LWS_WRITE_CLOSE is handled by lws_close_reason() */ - LWS_WRITE_PING = 5, - LWS_WRITE_PONG = 6, - - /* Same as write_http but we know this write ends the transaction */ - LWS_WRITE_HTTP_FINAL = 7, - - /* HTTP2 */ - - LWS_WRITE_HTTP_HEADERS = 8, - /**< Send http headers (http2 encodes this payload and LWS_WRITE_HTTP - * payload differently, http 1.x links also handle this correctly. so - * to be compatible with both in the future,header response part should - * be sent using this regardless of http version expected) - */ - LWS_WRITE_HTTP_HEADERS_CONTINUATION = 9, - /**< Continuation of http/2 headers - */ - - /****** add new things just above ---^ ******/ - - /* flags */ - - LWS_WRITE_NO_FIN = 0x40, - /**< This part of the message is not the end of the message */ - - LWS_WRITE_H2_STREAM_END = 0x80, - /**< Flag indicates this packet should go out with STREAM_END if h2 - * STREAM_END is allowed on DATA or HEADERS. - */ - - LWS_WRITE_CLIENT_IGNORE_XOR_MASK = 0x80 - /**< client packet payload goes out on wire unmunged - * only useful for security tests since normal servers cannot - * decode the content if used */ -}; - -/* used with LWS_CALLBACK_CHILD_WRITE_VIA_PARENT */ - -struct lws_write_passthru { - struct lws *wsi; - unsigned char *buf; - size_t len; - enum lws_write_protocol wp; -}; - - -/** - * lws_write() - Apply protocol then write data to client - * \param wsi: Websocket instance (available from user callback) - * \param buf: The data to send. For data being sent on a websocket - * connection (ie, not default http), this buffer MUST have - * LWS_PRE bytes valid BEFORE the pointer. - * This is so the protocol header data can be added in-situ. - * \param len: Count of the data bytes in the payload starting from buf - * \param protocol: Use LWS_WRITE_HTTP to reply to an http connection, and one - * of LWS_WRITE_BINARY or LWS_WRITE_TEXT to send appropriate - * data on a websockets connection. Remember to allow the extra - * bytes before and after buf if LWS_WRITE_BINARY or LWS_WRITE_TEXT - * are used. - * - * This function provides the way to issue data back to the client - * for both http and websocket protocols. - * - * IMPORTANT NOTICE! - * - * When sending with websocket protocol - * - * LWS_WRITE_TEXT, - * LWS_WRITE_BINARY, - * LWS_WRITE_CONTINUATION, - * LWS_WRITE_PING, - * LWS_WRITE_PONG - * - * the send buffer has to have LWS_PRE bytes valid BEFORE - * the buffer pointer you pass to lws_write(). - * - * This allows us to add protocol info before and after the data, and send as - * one packet on the network without payload copying, for maximum efficiency. - * - * So for example you need this kind of code to use lws_write with a - * 128-byte payload - * - * char buf[LWS_PRE + 128]; - * - * // fill your part of the buffer... for example here it's all zeros - * memset(&buf[LWS_PRE], 0, 128); - * - * lws_write(wsi, &buf[LWS_PRE], 128, LWS_WRITE_TEXT); - * - * When sending HTTP, with - * - * LWS_WRITE_HTTP, - * LWS_WRITE_HTTP_HEADERS - * LWS_WRITE_HTTP_FINAL - * - * there is no protocol data prepended, and don't need to take care about the - * LWS_PRE bytes valid before the buffer pointer. - * - * LWS_PRE is at least the frame nonce + 2 header + 8 length - * LWS_SEND_BUFFER_POST_PADDING is deprecated, it's now 0 and can be left off. - * The example apps no longer use it. - * - * Pad LWS_PRE to the CPU word size, so that word references - * to the address immediately after the padding won't cause an unaligned access - * error. Sometimes for performance reasons the recommended padding is even - * larger than sizeof(void *). - * - * In the case of sending using websocket protocol, be sure to allocate - * valid storage before and after buf as explained above. This scheme - * allows maximum efficiency of sending data and protocol in a single - * packet while not burdening the user code with any protocol knowledge. - * - * Return may be -1 for a fatal error needing connection close, or the - * number of bytes sent. - * - * Truncated Writes - * ================ - * - * The OS may not accept everything you asked to write on the connection. - * - * Posix defines POLLOUT indication from poll() to show that the connection - * will accept more write data, but it doesn't specifiy how much. It may just - * accept one byte of whatever you wanted to send. - * - * LWS will buffer the remainder automatically, and send it out autonomously. - * - * During that time, WRITABLE callbacks will be suppressed. - * - * This is to handle corner cases where unexpectedly the OS refuses what we - * usually expect it to accept. You should try to send in chunks that are - * almost always accepted in order to avoid the inefficiency of the buffering. - */ -LWS_VISIBLE LWS_EXTERN int -lws_write(struct lws *wsi, unsigned char *buf, size_t len, - enum lws_write_protocol protocol); - -/* helper for case where buffer may be const */ -#define lws_write_http(wsi, buf, len) \ - lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) - -/* helper for multi-frame ws message flags */ -static LWS_INLINE int -lws_write_ws_flags(int initial, int is_start, int is_end) -{ - int r; - - if (is_start) - r = initial; - else - r = LWS_WRITE_CONTINUATION; - - if (!is_end) - r |= LWS_WRITE_NO_FIN; - - return r; -} -///@} - -/** \defgroup callback-when-writeable Callback when writeable - * - * ##Callback When Writeable - * - * lws can only write data on a connection when it is able to accept more - * data without blocking. - * - * So a basic requirement is we should only use the lws_write() apis when the - * connection we want to write on says that he can accept more data. - * - * When lws cannot complete your send at the time, it will buffer the data - * and send it in the background, suppressing any further WRITEABLE callbacks - * on that connection until it completes. So it is important to write new - * things in a new writeable callback. - * - * These apis reflect the various ways we can indicate we would like to be - * called back when one or more connections is writeable. - */ -///@{ - -/** - * lws_callback_on_writable() - Request a callback when this socket - * becomes able to be written to without - * blocking - * - * \param wsi: Websocket connection instance to get callback for - * - * - Which: only this wsi - * - When: when the individual connection becomes writeable - * - What: LWS_CALLBACK_*_WRITEABLE - */ -LWS_VISIBLE LWS_EXTERN int -lws_callback_on_writable(struct lws *wsi); - -/** - * lws_callback_on_writable_all_protocol() - Request a callback for all - * connections using the given protocol when it - * becomes possible to write to each socket without - * blocking in turn. - * - * \param context: lws_context - * \param protocol: Protocol whose connections will get callbacks - * - * - Which: connections using this protocol on ANY VHOST - * - When: when the individual connection becomes writeable - * - What: LWS_CALLBACK_*_WRITEABLE - */ -LWS_VISIBLE LWS_EXTERN int -lws_callback_on_writable_all_protocol(const struct lws_context *context, - const struct lws_protocols *protocol); - -/** - * lws_callback_on_writable_all_protocol_vhost() - Request a callback for - * all connections on same vhost using the given protocol - * when it becomes possible to write to each socket without - * blocking in turn. - * - * \param vhost: Only consider connections on this lws_vhost - * \param protocol: Protocol whose connections will get callbacks - * - * - Which: connections using this protocol on GIVEN VHOST ONLY - * - When: when the individual connection becomes writeable - * - What: LWS_CALLBACK_*_WRITEABLE - */ -LWS_VISIBLE LWS_EXTERN int -lws_callback_on_writable_all_protocol_vhost(const struct lws_vhost *vhost, - const struct lws_protocols *protocol); - -/** - * lws_callback_all_protocol() - Callback all connections using - * the given protocol with the given reason - * - * \param context: lws_context - * \param protocol: Protocol whose connections will get callbacks - * \param reason: Callback reason index - * - * - Which: connections using this protocol on ALL VHOSTS - * - When: before returning - * - What: reason - * - * This isn't normally what you want... normally any update of connection- - * specific information can wait until a network-related callback like rx, - * writable, or close. - */ -LWS_VISIBLE LWS_EXTERN int -lws_callback_all_protocol(struct lws_context *context, - const struct lws_protocols *protocol, int reason); - -/** - * lws_callback_all_protocol_vhost() - Callback all connections using - * the given protocol with the given reason. This is - * deprecated since v2.4: use lws_callback_all_protocol_vhost_args - * - * \param vh: Vhost whose connections will get callbacks - * \param protocol: Which protocol to match. NULL means all. - * \param reason: Callback reason index - * - * - Which: connections using this protocol on GIVEN VHOST ONLY - * - When: now - * - What: reason - */ -LWS_VISIBLE LWS_EXTERN int -lws_callback_all_protocol_vhost(struct lws_vhost *vh, - const struct lws_protocols *protocol, int reason) -LWS_WARN_DEPRECATED; - -/** - * lws_callback_all_protocol_vhost_args() - Callback all connections using - * the given protocol with the given reason and args - * - * \param vh: Vhost whose connections will get callbacks - * \param protocol: Which protocol to match. NULL means all. - * \param reason: Callback reason index - * \param argp: Callback "in" parameter - * \param len: Callback "len" parameter - * - * - Which: connections using this protocol on GIVEN VHOST ONLY - * - When: now - * - What: reason - */ -LWS_VISIBLE int -lws_callback_all_protocol_vhost_args(struct lws_vhost *vh, - const struct lws_protocols *protocol, int reason, - void *argp, size_t len); - -/** - * lws_callback_vhost_protocols() - Callback all protocols enabled on a vhost - * with the given reason - * - * \param wsi: wsi whose vhost will get callbacks - * \param reason: Callback reason index - * \param in: in argument to callback - * \param len: len argument to callback - * - * - Which: connections using this protocol on same VHOST as wsi ONLY - * - When: now - * - What: reason - * - * This is deprecated since v2.5, use lws_callback_vhost_protocols_vhost() - * which takes the pointer to the vhost directly without using or needing the - * wsi. - */ -LWS_VISIBLE LWS_EXTERN int -lws_callback_vhost_protocols(struct lws *wsi, int reason, void *in, int len) -LWS_WARN_DEPRECATED; - -/** - * lws_callback_vhost_protocols_vhost() - Callback all protocols enabled on a vhost - * with the given reason - * - * \param vh: vhost that will get callbacks - * \param reason: Callback reason index - * \param in: in argument to callback - * \param len: len argument to callback - * - * - Which: connections using this protocol on same VHOST as wsi ONLY - * - When: now - * - What: reason - */ -LWS_VISIBLE LWS_EXTERN int -lws_callback_vhost_protocols_vhost(struct lws_vhost *vh, int reason, void *in, - size_t len); - -LWS_VISIBLE LWS_EXTERN int -lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason, - void *user, void *in, size_t len); - -/** - * lws_get_socket_fd() - returns the socket file descriptor - * - * This is needed to use sendto() on UDP raw sockets - * - * \param wsi: Websocket connection instance - */ -LWS_VISIBLE LWS_EXTERN lws_sockfd_type -lws_get_socket_fd(struct lws *wsi); - -/** - * lws_get_peer_write_allowance() - get the amount of data writeable to peer - * if known - * - * \param wsi: Websocket connection instance - * - * if the protocol does not have any guidance, returns -1. Currently only - * http2 connections get send window information from this API. But your code - * should use it so it can work properly with any protocol. - * - * If nonzero return is the amount of payload data the peer or intermediary has - * reported it has buffer space for. That has NO relationship with the amount - * of buffer space your OS can accept on this connection for a write action. - * - * This number represents the maximum you could send to the peer or intermediary - * on this connection right now without the protocol complaining. - * - * lws manages accounting for send window updates and payload writes - * automatically, so this number reflects the situation at the peer or - * intermediary dynamically. - */ -LWS_VISIBLE LWS_EXTERN lws_fileofs_t -lws_get_peer_write_allowance(struct lws *wsi); -///@} - -enum { - /* - * Flags for enable and disable rxflow with reason bitmap and with - * backwards-compatible single bool - */ - LWS_RXFLOW_REASON_USER_BOOL = (1 << 0), - LWS_RXFLOW_REASON_HTTP_RXBUFFER = (1 << 6), - LWS_RXFLOW_REASON_H2_PPS_PENDING = (1 << 7), - - LWS_RXFLOW_REASON_APPLIES = (1 << 14), - LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT = (1 << 13), - LWS_RXFLOW_REASON_APPLIES_ENABLE = LWS_RXFLOW_REASON_APPLIES | - LWS_RXFLOW_REASON_APPLIES_ENABLE_BIT, - LWS_RXFLOW_REASON_APPLIES_DISABLE = LWS_RXFLOW_REASON_APPLIES, - LWS_RXFLOW_REASON_FLAG_PROCESS_NOW = (1 << 12), - -}; - -/** - * lws_rx_flow_control() - Enable and disable socket servicing for - * received packets. - * - * If the output side of a server process becomes choked, this allows flow - * control for the input side. - * - * \param wsi: Websocket connection instance to get callback for - * \param enable: 0 = disable read servicing for this connection, 1 = enable - * - * If you need more than one additive reason for rxflow control, you can give - * iLWS_RXFLOW_REASON_APPLIES_ENABLE or _DISABLE together with one or more of - * b5..b0 set to idicate which bits to enable or disable. If any bits are - * enabled, rx on the connection is suppressed. - * - * LWS_RXFLOW_REASON_FLAG_PROCESS_NOW flag may also be given to force any change - * in rxflowbstatus to benapplied immediately, this should be used when you are - * changing a wsi flow control state from outside a callback on that wsi. - */ -LWS_VISIBLE LWS_EXTERN int -lws_rx_flow_control(struct lws *wsi, int enable); - -/** - * lws_rx_flow_allow_all_protocol() - Allow all connections with this protocol to receive - * - * When the user server code realizes it can accept more input, it can - * call this to have the RX flow restriction removed from all connections using - * the given protocol. - * \param context: lws_context - * \param protocol: all connections using this protocol will be allowed to receive - */ -LWS_VISIBLE LWS_EXTERN void -lws_rx_flow_allow_all_protocol(const struct lws_context *context, - const struct lws_protocols *protocol); - -/** - * lws_remaining_packet_payload() - Bytes to come before "overall" - * rx fragment is complete - * \param wsi: Websocket instance (available from user callback) - * - * This tracks how many bytes are left in the current ws fragment, according - * to the ws length given in the fragment header. - * - * If the message was in a single fragment, and there is no compression, this - * is the same as "how much data is left to read for this message". - * - * However, if the message is being sent in multiple fragments, this will - * reflect the unread amount of the current **fragment**, not the message. With - * ws, it is legal to not know the length of the message before it completes. - * - * Additionally if the message is sent via the negotiated permessage-deflate - * extension, this number only tells the amount of **compressed** data left to - * be read, since that is the only information available at the ws layer. - */ -LWS_VISIBLE LWS_EXTERN size_t -lws_remaining_packet_payload(struct lws *wsi); - - -/** \defgroup sock-adopt Socket adoption helpers - * ##Socket adoption helpers - * - * When integrating with an external app with its own event loop, these can - * be used to accept connections from someone else's listening socket. - * - * When using lws own event loop, these are not needed. - */ -///@{ - -/** - * lws_adopt_socket() - adopt foreign socket as if listen socket accepted it - * for the default vhost of context. - * - * \param context: lws context - * \param accept_fd: fd of already-accepted socket to adopt - * - * Either returns new wsi bound to accept_fd, or closes accept_fd and - * returns NULL, having cleaned up any new wsi pieces. - * - * LWS adopts the socket in http serving mode, it's ready to accept an upgrade - * to ws or just serve http. - */ -LWS_VISIBLE LWS_EXTERN struct lws * -lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd); -/** - * lws_adopt_socket_vhost() - adopt foreign socket as if listen socket accepted it - * for vhost - * - * \param vh: lws vhost - * \param accept_fd: fd of already-accepted socket to adopt - * - * Either returns new wsi bound to accept_fd, or closes accept_fd and - * returns NULL, having cleaned up any new wsi pieces. - * - * LWS adopts the socket in http serving mode, it's ready to accept an upgrade - * to ws or just serve http. - */ -LWS_VISIBLE LWS_EXTERN struct lws * -lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd); - -typedef enum { - LWS_ADOPT_RAW_FILE_DESC = 0, /* convenience constant */ - LWS_ADOPT_HTTP = 1, /* flag: absent implies RAW */ - LWS_ADOPT_SOCKET = 2, /* flag: absent implies file descr */ - LWS_ADOPT_ALLOW_SSL = 4, /* flag: if set requires LWS_ADOPT_SOCKET */ - LWS_ADOPT_WS_PARENTIO = 8, /* flag: ws mode parent handles IO - * if given must be only flag - * wsi put directly into ws mode */ - LWS_ADOPT_FLAG_UDP = 16, /* flag: socket is UDP */ - - LWS_ADOPT_RAW_SOCKET_UDP = LWS_ADOPT_SOCKET | LWS_ADOPT_FLAG_UDP, -} lws_adoption_type; - -typedef union { - lws_sockfd_type sockfd; - lws_filefd_type filefd; -} lws_sock_file_fd_type; - -#if !defined(LWS_WITH_ESP32) -struct lws_udp { - struct sockaddr sa; - socklen_t salen; - - struct sockaddr sa_pending; - socklen_t salen_pending; -}; -#endif - -/* -* lws_adopt_descriptor_vhost() - adopt foreign socket or file descriptor -* if socket descriptor, should already have been accepted from listen socket -* -* \param vhost: lws vhost -* \param type: OR-ed combinations of lws_adoption_type flags -* \param fd: union with either .sockfd or .filefd set -* \param vh_prot_name: NULL or vh protocol name to bind raw connection to -* \param parent: NULL or struct lws to attach new_wsi to as a child -* -* Either returns new wsi bound to accept_fd, or closes accept_fd and -* returns NULL, having cleaned up any new wsi pieces. -* -* If LWS_ADOPT_SOCKET is set, LWS adopts the socket in http serving mode, it's -* ready to accept an upgrade to ws or just serve http. -* -* parent may be NULL, if given it should be an existing wsi that will become the -* parent of the new wsi created by this call. -*/ -LWS_VISIBLE LWS_EXTERN struct lws * -lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type, - lws_sock_file_fd_type fd, const char *vh_prot_name, - struct lws *parent); - -/** - * lws_adopt_socket_readbuf() - adopt foreign socket and first rx as if listen socket accepted it - * for the default vhost of context. - * \param context: lws context - * \param accept_fd: fd of already-accepted socket to adopt - * \param readbuf: NULL or pointer to data that must be drained before reading from - * accept_fd - * \param len: The length of the data held at \param readbuf - * - * Either returns new wsi bound to accept_fd, or closes accept_fd and - * returns NULL, having cleaned up any new wsi pieces. - * - * LWS adopts the socket in http serving mode, it's ready to accept an upgrade - * to ws or just serve http. - * - * If your external code did not already read from the socket, you can use - * lws_adopt_socket() instead. - * - * This api is guaranteed to use the data at \param readbuf first, before reading from - * the socket. - * - * readbuf is limited to the size of the ah rx buf, currently 2048 bytes. - */ -LWS_VISIBLE LWS_EXTERN struct lws * -lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd, - const char *readbuf, size_t len); -/** - * lws_adopt_socket_vhost_readbuf() - adopt foreign socket and first rx as if listen socket - * accepted it for vhost. - * \param vhost: lws vhost - * \param accept_fd: fd of already-accepted socket to adopt - * \param readbuf: NULL or pointer to data that must be drained before reading from - * accept_fd - * \param len: The length of the data held at \param readbuf - * - * Either returns new wsi bound to accept_fd, or closes accept_fd and - * returns NULL, having cleaned up any new wsi pieces. - * - * LWS adopts the socket in http serving mode, it's ready to accept an upgrade - * to ws or just serve http. - * - * If your external code did not already read from the socket, you can use - * lws_adopt_socket() instead. - * - * This api is guaranteed to use the data at \param readbuf first, before reading from - * the socket. - * - * readbuf is limited to the size of the ah rx buf, currently 2048 bytes. - */ -LWS_VISIBLE LWS_EXTERN struct lws * -lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost, lws_sockfd_type accept_fd, - const char *readbuf, size_t len); - -#define LWS_CAUDP_BIND 1 - -/** - * lws_create_adopt_udp() - create, bind and adopt a UDP socket - * - * \param vhost: lws vhost - * \param port: UDP port to bind to, -1 means unbound - * \param flags: 0 or LWS_CAUDP_NO_BIND - * \param protocol_name: Name of protocol on vhost to bind wsi to - * \param parent_wsi: NULL or parent wsi new wsi will be a child of - * - * Either returns new wsi bound to accept_fd, or closes accept_fd and - * returns NULL, having cleaned up any new wsi pieces. - * */ -LWS_VISIBLE LWS_EXTERN struct lws * -lws_create_adopt_udp(struct lws_vhost *vhost, int port, int flags, - const char *protocol_name, struct lws *parent_wsi); -///@} - -/** \defgroup net Network related helper APIs - * ##Network related helper APIs - * - * These wrap miscellaneous useful network-related functions - */ -///@{ - -/** - * lws_canonical_hostname() - returns this host's hostname - * - * This is typically used by client code to fill in the host parameter - * when making a client connection. You can only call it after the context - * has been created. - * - * \param context: Websocket context - */ -LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT -lws_canonical_hostname(struct lws_context *context); - -/** - * lws_get_peer_addresses() - Get client address information - * \param wsi: Local struct lws associated with - * \param fd: Connection socket descriptor - * \param name: Buffer to take client address name - * \param name_len: Length of client address name buffer - * \param rip: Buffer to take client address IP dotted quad - * \param rip_len: Length of client address IP buffer - * - * This function fills in name and rip with the name and IP of - * the client connected with socket descriptor fd. Names may be - * truncated if there is not enough room. If either cannot be - * determined, they will be returned as valid zero-length strings. - */ -LWS_VISIBLE LWS_EXTERN void -lws_get_peer_addresses(struct lws *wsi, lws_sockfd_type fd, char *name, - int name_len, char *rip, int rip_len); - -/** - * lws_get_peer_simple() - Get client address information without RDNS - * - * \param wsi: Local struct lws associated with - * \param name: Buffer to take client address name - * \param namelen: Length of client address name buffer - * - * This provides a 123.123.123.123 type IP address in name from the - * peer that has connected to wsi - */ -LWS_VISIBLE LWS_EXTERN const char * -lws_get_peer_simple(struct lws *wsi, char *name, int namelen); - - -#define LWS_ITOSA_NOT_EXIST -1 -#define LWS_ITOSA_NOT_USABLE -2 -#define LWS_ITOSA_USABLE 0 -#if !defined(LWS_WITH_ESP32) -/** - * lws_interface_to_sa() - Convert interface name or IP to sockaddr struct - * - * \param ipv6: Allow IPV6 addresses - * \param ifname: Interface name or IP - * \param addr: struct sockaddr_in * to be written - * \param addrlen: Length of addr - * - * This converts a textual network interface name to a sockaddr usable by - * other network functions. - * - * If the network interface doesn't exist, it will return LWS_ITOSA_NOT_EXIST. - * - * If the network interface is not usable, eg ethernet cable is removed, it - * may logically exist but not have any IP address. As such it will return - * LWS_ITOSA_NOT_USABLE. - * - * If the network interface exists and is usable, it will return - * LWS_ITOSA_USABLE. - */ -LWS_VISIBLE LWS_EXTERN int -lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr, - size_t addrlen); -///@} -#endif - -/** \defgroup misc Miscellaneous APIs -* ##Miscellaneous APIs -* -* Various APIs outside of other categories -*/ -///@{ - -/** - * lws_start_foreach_ll(): linkedlist iterator helper start - * - * \param type: type of iteration, eg, struct xyz * - * \param it: iterator var name to create - * \param start: start of list - * - * This helper creates an iterator and starts a while (it) { - * loop. The iterator runs through the linked list starting at start and - * ends when it gets a NULL. - * The while loop should be terminated using lws_start_foreach_ll(). - */ -#define lws_start_foreach_ll(type, it, start)\ -{ \ - type it = start; \ - while (it) { - -/** - * lws_end_foreach_ll(): linkedlist iterator helper end - * - * \param it: same iterator var name given when starting - * \param nxt: member name in the iterator pointing to next list element - * - * This helper is the partner for lws_start_foreach_ll() that ends the - * while loop. - */ - -#define lws_end_foreach_ll(it, nxt) \ - it = it->nxt; \ - } \ -} - -/** - * lws_start_foreach_llp(): linkedlist pointer iterator helper start - * - * \param type: type of iteration, eg, struct xyz ** - * \param it: iterator var name to create - * \param start: start of list - * - * This helper creates an iterator and starts a while (it) { - * loop. The iterator runs through the linked list starting at the - * address of start and ends when it gets a NULL. - * The while loop should be terminated using lws_start_foreach_llp(). - * - * This helper variant iterates using a pointer to the previous linked-list - * element. That allows you to easily delete list members by rewriting the - * previous pointer to the element's next pointer. - */ -#define lws_start_foreach_llp(type, it, start)\ -{ \ - type it = &(start); \ - while (*(it)) { - -#define lws_start_foreach_llp_safe(type, it, start, nxt)\ -{ \ - type it = &(start); \ - type next; \ - while (*(it)) { \ - next = &((*(it))->nxt); \ - -/** - * lws_end_foreach_llp(): linkedlist pointer iterator helper end - * - * \param it: same iterator var name given when starting - * \param nxt: member name in the iterator pointing to next list element - * - * This helper is the partner for lws_start_foreach_llp() that ends the - * while loop. - */ - -#define lws_end_foreach_llp(it, nxt) \ - it = &(*(it))->nxt; \ - } \ -} - -#define lws_end_foreach_llp_safe(it) \ - it = next; \ - } \ -} - -#define lws_ll_fwd_insert(\ - ___new_object, /* pointer to new object */ \ - ___m_list, /* member for next list object ptr */ \ - ___list_head /* list head */ \ - ) {\ - ___new_object->___m_list = ___list_head; \ - ___list_head = ___new_object; \ - } - -#define lws_ll_fwd_remove(\ - ___type, /* type of listed object */ \ - ___m_list, /* member for next list object ptr */ \ - ___target, /* object to remove from list */ \ - ___list_head /* list head */ \ - ) { \ - lws_start_foreach_llp(___type **, ___ppss, ___list_head) { \ - if (*___ppss == ___target) { \ - *___ppss = ___target->___m_list; \ - break; \ - } \ - } lws_end_foreach_llp(___ppss, ___m_list); \ - } - -/* - * doubly linked-list - */ - -struct lws_dll { /* abstract */ - struct lws_dll *prev; - struct lws_dll *next; -}; - -/* - * these all point to the composed list objects... you have to use the - * lws_container_of() helper to recover the start of the containing struct - */ - -LWS_VISIBLE LWS_EXTERN void -lws_dll_add_front(struct lws_dll *d, struct lws_dll *phead); - -LWS_VISIBLE LWS_EXTERN void -lws_dll_remove(struct lws_dll *d); - -struct lws_dll_lws { /* typed as struct lws * */ - struct lws_dll_lws *prev; - struct lws_dll_lws *next; -}; - -#define lws_dll_is_null(___dll) (!(___dll)->prev && !(___dll)->next) - -static LWS_INLINE void -lws_dll_lws_add_front(struct lws_dll_lws *_a, struct lws_dll_lws *_head) -{ - lws_dll_add_front((struct lws_dll *)_a, (struct lws_dll *)_head); -} - -static LWS_INLINE void -lws_dll_lws_remove(struct lws_dll_lws *_a) -{ - lws_dll_remove((struct lws_dll *)_a); -} - -/* - * these are safe against the current container object getting deleted, - * since the hold his next in a temp and go to that next. ___tmp is - * the temp. - */ - -#define lws_start_foreach_dll_safe(___type, ___it, ___tmp, ___start) \ -{ \ - ___type ___it = ___start; \ - while (___it) { \ - ___type ___tmp = (___it)->next; - -#define lws_end_foreach_dll_safe(___it, ___tmp) \ - ___it = ___tmp; \ - } \ -} - -#define lws_start_foreach_dll(___type, ___it, ___start) \ -{ \ - ___type ___it = ___start; \ - while (___it) { - -#define lws_end_foreach_dll(___it) \ - ___it = (___it)->next; \ - } \ -} - -struct lws_buflist; - -/** - * lws_buflist_append_segment(): add buffer to buflist at head - * - * \param head: list head - * \param buf: buffer to stash - * \param len: length of buffer to stash - * - * Returns -1 on OOM, 1 if this was the first segment on the list, and 0 if - * it was a subsequent segment. - */ -LWS_VISIBLE LWS_EXTERN int -lws_buflist_append_segment(struct lws_buflist **head, const uint8_t *buf, - size_t len); -/** - * lws_buflist_next_segment_len(): number of bytes left in current segment - * - * \param head: list head - * \param buf: if non-NULL, *buf is written with the address of the start of - * the remaining data in the segment - * - * Returns the number of bytes left in the current segment. 0 indicates - * that the buflist is empty (there are no segments on the buflist). - */ -LWS_VISIBLE LWS_EXTERN size_t -lws_buflist_next_segment_len(struct lws_buflist **head, uint8_t **buf); -/** - * lws_buflist_use_segment(): remove len bytes from the current segment - * - * \param head: list head - * \param len: number of bytes to mark as used - * - * If len is less than the remaining length of the current segment, the position - * in the current segment is simply advanced and it returns. - * - * If len uses up the remaining length of the current segment, then the segment - * is deleted and the list head moves to the next segment if any. - * - * Returns the number of bytes left in the current segment. 0 indicates - * that the buflist is empty (there are no segments on the buflist). - */ -LWS_VISIBLE LWS_EXTERN int -lws_buflist_use_segment(struct lws_buflist **head, size_t len); -/** - * lws_buflist_destroy_all_segments(): free all segments on the list - * - * \param head: list head - * - * This frees everything on the list unconditionally. *head is always - * NULL after this. - */ -LWS_VISIBLE LWS_EXTERN void -lws_buflist_destroy_all_segments(struct lws_buflist **head); - -void -lws_buflist_describe(struct lws_buflist **head, void *id); - -/** - * lws_ptr_diff(): helper to report distance between pointers as an int - * - * \param head: the pointer with the larger address - * \param tail: the pointer with the smaller address - * - * This helper gives you an int representing the number of bytes further - * forward the first pointer is compared to the second pointer. - */ -#define lws_ptr_diff(head, tail) \ - ((int)((char *)(head) - (char *)(tail))) - -/** - * lws_snprintf(): snprintf that truncates the returned length too - * - * \param str: destination buffer - * \param size: bytes left in destination buffer - * \param format: format string - * \param ...: args for format - * - * This lets you correctly truncate buffers by concatenating lengths, if you - * reach the limit the reported length doesn't exceed the limit. - */ -LWS_VISIBLE LWS_EXTERN int -lws_snprintf(char *str, size_t size, const char *format, ...) LWS_FORMAT(3); - -/** - * lws_strncpy(): strncpy that guarantees NUL on truncated copy - * - * \param dest: destination buffer - * \param src: source buffer - * \param size: bytes left in destination buffer - * - * This lets you correctly truncate buffers by concatenating lengths, if you - * reach the limit the reported length doesn't exceed the limit. - */ -LWS_VISIBLE LWS_EXTERN char * -lws_strncpy(char *dest, const char *src, size_t size); - -/** - * lws_get_random(): fill a buffer with platform random data - * - * \param context: the lws context - * \param buf: buffer to fill - * \param len: how much to fill - * - * This is intended to be called from the LWS_CALLBACK_RECEIVE callback if - * it's interested to see if the frame it's dealing with was sent in binary - * mode. - */ -LWS_VISIBLE LWS_EXTERN int -lws_get_random(struct lws_context *context, void *buf, int len); -/** - * lws_daemonize(): make current process run in the background - * - * \param _lock_path: the filepath to write the lock file - * - * Spawn lws as a background process, taking care of various things - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_daemonize(const char *_lock_path); -/** - * lws_get_library_version(): return string describing the version of lws - * - * On unix, also includes the git describe - */ -LWS_VISIBLE LWS_EXTERN const char * LWS_WARN_UNUSED_RESULT -lws_get_library_version(void); - -/** - * lws_wsi_user() - get the user data associated with the connection - * \param wsi: lws connection - * - * Not normally needed since it's passed into the callback - */ -LWS_VISIBLE LWS_EXTERN void * -lws_wsi_user(struct lws *wsi); - -/** - * lws_wsi_set_user() - set the user data associated with the client connection - * \param wsi: lws connection - * \param user: user data - * - * By default lws allocates this and it's not legal to externally set it - * yourself. However client connections may have it set externally when the - * connection is created... if so, this api can be used to modify it at - * runtime additionally. - */ -LWS_VISIBLE LWS_EXTERN void -lws_set_wsi_user(struct lws *wsi, void *user); - -/** - * lws_parse_uri: cut up prot:/ads:port/path into pieces - * Notice it does so by dropping '\0' into input string - * and the leading / on the path is consequently lost - * - * \param p: incoming uri string.. will get written to - * \param prot: result pointer for protocol part (https://) - * \param ads: result pointer for address part - * \param port: result pointer for port part - * \param path: result pointer for path part - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_parse_uri(char *p, const char **prot, const char **ads, int *port, - const char **path); -/** - * lws_cmdline_option(): simple commandline parser - * - * \param argc: count of argument strings - * \param argv: argument strings - * \param val: string to find - * - * Returns NULL if the string \p val is not found in the arguments. - * - * If it is found, then it returns a pointer to the next character after \p val. - * So if \p val is "-d", then for the commandlines "myapp -d15" and - * "myapp -d 15", in both cases the return will point to the "15". - * - * In the case there is no argument, like "myapp -d", the return will - * either point to the '\\0' at the end of -d, or to the start of the - * next argument, ie, will be non-NULL. - */ -LWS_VISIBLE LWS_EXTERN const char * -lws_cmdline_option(int argc, const char **argv, const char *val); - -/** - * lws_now_secs(): return seconds since 1970-1-1 - */ -LWS_VISIBLE LWS_EXTERN unsigned long -lws_now_secs(void); - -/** - * lws_compare_time_t(): return relationship between two time_t - * - * \param context: struct lws_context - * \param t1: time_t 1 - * \param t2: time_t 2 - * - * returns <0 if t2 > t1; >0 if t1 > t2; or == 0 if t1 == t2. - * - * This is aware of clock discontiguities that may have affected either t1 or - * t2 and adapts the comparison for them. - * - * For the discontiguity detection to work, you must avoid any arithmetic on - * the times being compared. For example to have a timeout that triggers - * 15s from when it was set, store the time it was set and compare like - * `if (lws_compare_time_t(context, now, set_time) > 15)` - */ -LWS_VISIBLE LWS_EXTERN int -lws_compare_time_t(struct lws_context *context, time_t t1, time_t t2); - -/** - * lws_get_context - Allow getting lws_context from a Websocket connection - * instance - * - * With this function, users can access context in the callback function. - * Otherwise users may have to declare context as a global variable. - * - * \param wsi: Websocket connection instance - */ -LWS_VISIBLE LWS_EXTERN struct lws_context * LWS_WARN_UNUSED_RESULT -lws_get_context(const struct lws *wsi); - -/** - * lws_get_vhost_listen_port - Find out the port number a vhost is listening on - * - * In the case you passed 0 for the port number at context creation time, you - * can discover the port number that was actually chosen for the vhost using - * this api. - * - * \param vhost: Vhost to get listen port from - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_get_vhost_listen_port(struct lws_vhost *vhost); - -/** - * lws_get_count_threads(): how many service threads the context uses - * - * \param context: the lws context - * - * By default this is always 1, if you asked for more than lws can handle it - * will clip the number of threads. So you can use this to find out how many - * threads are actually in use. - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_get_count_threads(struct lws_context *context); - -/** - * lws_get_parent() - get parent wsi or NULL - * \param wsi: lws connection - * - * Specialized wsi like cgi stdin/out/err are associated to a parent wsi, - * this allows you to get their parent. - */ -LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT -lws_get_parent(const struct lws *wsi); - -/** - * lws_get_child() - get child wsi or NULL - * \param wsi: lws connection - * - * Allows you to find a related wsi from the parent wsi. - */ -LWS_VISIBLE LWS_EXTERN struct lws * LWS_WARN_UNUSED_RESULT -lws_get_child(const struct lws *wsi); - -/** - * lws_get_udp() - get wsi's udp struct - * - * \param wsi: lws connection - * - * Returns NULL or pointer to the wsi's UDP-specific information - */ -LWS_VISIBLE LWS_EXTERN const struct lws_udp * LWS_WARN_UNUSED_RESULT -lws_get_udp(const struct lws *wsi); - -/** - * lws_parent_carries_io() - mark wsi as needing to send messages via parent - * - * \param wsi: child lws connection - */ - -LWS_VISIBLE LWS_EXTERN void -lws_set_parent_carries_io(struct lws *wsi); - -LWS_VISIBLE LWS_EXTERN void * -lws_get_opaque_parent_data(const struct lws *wsi); - -LWS_VISIBLE LWS_EXTERN void -lws_set_opaque_parent_data(struct lws *wsi, void *data); - -LWS_VISIBLE LWS_EXTERN int -lws_get_child_pending_on_writable(const struct lws *wsi); - -LWS_VISIBLE LWS_EXTERN void -lws_clear_child_pending_on_writable(struct lws *wsi); - -LWS_VISIBLE LWS_EXTERN int -lws_get_close_length(struct lws *wsi); - -LWS_VISIBLE LWS_EXTERN unsigned char * -lws_get_close_payload(struct lws *wsi); - -/** - * lws_get_network_wsi() - Returns wsi that has the tcp connection for this wsi - * - * \param wsi: wsi you have - * - * Returns wsi that has the tcp connection (which may be the incoming wsi) - * - * HTTP/1 connections will always return the incoming wsi - * HTTP/2 connections may return a different wsi that has the tcp connection - */ -LWS_VISIBLE LWS_EXTERN -struct lws *lws_get_network_wsi(struct lws *wsi); - -/** - * lws_set_allocator() - custom allocator support - * - * \param realloc - * - * Allows you to replace the allocator (and deallocator) used by lws - */ -LWS_VISIBLE LWS_EXTERN void -lws_set_allocator(void *(*realloc)(void *ptr, size_t size, const char *reason)); -///@} - -/** \defgroup wsstatus Websocket status APIs - * ##Websocket connection status APIs - * - * These provide information about ws connection or message status - */ -///@{ -/** - * lws_send_pipe_choked() - tests if socket is writable or not - * \param wsi: lws connection - * - * Allows you to check if you can write more on the socket - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_send_pipe_choked(struct lws *wsi); - -/** - * lws_is_final_fragment() - tests if last part of ws message - * - * \param wsi: lws connection - */ -LWS_VISIBLE LWS_EXTERN int -lws_is_final_fragment(struct lws *wsi); - -/** - * lws_is_first_fragment() - tests if first part of ws message - * - * \param wsi: lws connection - */ -LWS_VISIBLE LWS_EXTERN int -lws_is_first_fragment(struct lws *wsi); - -/** - * lws_get_reserved_bits() - access reserved bits of ws frame - * \param wsi: lws connection - */ -LWS_VISIBLE LWS_EXTERN unsigned char -lws_get_reserved_bits(struct lws *wsi); - -/** - * lws_partial_buffered() - find out if lws buffered the last write - * \param wsi: websocket connection to check - * - * Returns 1 if you cannot use lws_write because the last - * write on this connection is still buffered, and can't be cleared without - * returning to the service loop and waiting for the connection to be - * writeable again. - * - * If you will try to do >1 lws_write call inside a single - * WRITEABLE callback, you must check this after every write and bail if - * set, ask for a new writeable callback and continue writing from there. - * - * This is never set at the start of a writeable callback, but any write - * may set it. - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_partial_buffered(struct lws *wsi); - -/** - * lws_frame_is_binary(): true if the current frame was sent in binary mode - * - * \param wsi: the connection we are inquiring about - * - * This is intended to be called from the LWS_CALLBACK_RECEIVE callback if - * it's interested to see if the frame it's dealing with was sent in binary - * mode. - */ -LWS_VISIBLE LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_frame_is_binary(struct lws *wsi); - -/** - * lws_is_ssl() - Find out if connection is using SSL - * \param wsi: websocket connection to check - * - * Returns 0 if the connection is not using SSL, 1 if using SSL and - * using verified cert, and 2 if using SSL but the cert was not - * checked (appears for client wsi told to skip check on connection) - */ -LWS_VISIBLE LWS_EXTERN int -lws_is_ssl(struct lws *wsi); -/** - * lws_is_cgi() - find out if this wsi is running a cgi process - * \param wsi: lws connection - */ -LWS_VISIBLE LWS_EXTERN int -lws_is_cgi(struct lws *wsi); - - -struct lws_wifi_scan { /* generic wlan scan item */ - struct lws_wifi_scan *next; - char ssid[32]; - int32_t rssi; /* divide by .count to get db */ - uint8_t bssid[6]; - uint8_t count; - uint8_t channel; - uint8_t authmode; -}; - -#if defined(LWS_WITH_TLS) && !defined(LWS_WITH_MBEDTLS) -/** - * lws_get_ssl() - Return wsi's SSL context structure - * \param wsi: websocket connection - * - * Returns pointer to the SSL library's context structure - */ -LWS_VISIBLE LWS_EXTERN SSL* -lws_get_ssl(struct lws *wsi); -#endif - -enum lws_tls_cert_info { - LWS_TLS_CERT_INFO_VALIDITY_FROM, - /**< fills .time with the time_t the cert validity started from */ - LWS_TLS_CERT_INFO_VALIDITY_TO, - /**< fills .time with the time_t the cert validity ends at */ - LWS_TLS_CERT_INFO_COMMON_NAME, - /**< fills up to len bytes of .ns.name with the cert common name */ - LWS_TLS_CERT_INFO_ISSUER_NAME, - /**< fills up to len bytes of .ns.name with the cert issuer name */ - LWS_TLS_CERT_INFO_USAGE, - /**< fills verified with a bitfield asserting the valid uses */ - LWS_TLS_CERT_INFO_VERIFIED, - /**< fills .verified with a bool representing peer cert validity, - * call returns -1 if no cert */ - LWS_TLS_CERT_INFO_OPAQUE_PUBLIC_KEY, - /**< the certificate's public key, as an opaque bytestream. These - * opaque bytestreams can only be compared with each other using the - * same tls backend, ie, OpenSSL or mbedTLS. The different backends - * produce different, incompatible representations for the same cert. - */ -}; - -union lws_tls_cert_info_results { - unsigned int verified; - time_t time; - unsigned int usage; - struct { - int len; - /* KEEP LAST... notice the [64] is only there because - * name[] is not allowed in a union. The actual length of - * name[] is arbitrary and is passed into the api using the - * len parameter. Eg - * - * char big[1024]; - * union lws_tls_cert_info_results *buf = - * (union lws_tls_cert_info_results *)big; - * - * lws_tls_peer_cert_info(wsi, type, buf, sizeof(big) - - * sizeof(*buf) + sizeof(buf->ns.name)); - */ - char name[64]; - } ns; -}; - -/** - * lws_tls_peer_cert_info() - get information from the peer's TLS cert - * - * \param wsi: the connection to query - * \param type: one of LWS_TLS_CERT_INFO_ - * \param buf: pointer to union to take result - * \param len: when result is a string, the true length of buf->ns.name[] - * - * lws_tls_peer_cert_info() lets you get hold of information from the peer - * certificate. - * - * Return 0 if there is a result in \p buf, or -1 indicating there was no cert - * or another problem. - * - * This function works the same no matter if the TLS backend is OpenSSL or - * mbedTLS. - */ -LWS_VISIBLE LWS_EXTERN int -lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type, - union lws_tls_cert_info_results *buf, size_t len); - -/** - * lws_tls_vhost_cert_info() - get information from the vhost's own TLS cert - * - * \param vhost: the vhost to query - * \param type: one of LWS_TLS_CERT_INFO_ - * \param buf: pointer to union to take result - * \param len: when result is a string, the true length of buf->ns.name[] - * - * lws_tls_vhost_cert_info() lets you get hold of information from the vhost - * certificate. - * - * Return 0 if there is a result in \p buf, or -1 indicating there was no cert - * or another problem. - * - * This function works the same no matter if the TLS backend is OpenSSL or - * mbedTLS. - */ -LWS_VISIBLE LWS_EXTERN int -lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type, - union lws_tls_cert_info_results *buf, size_t len); - -/** - * lws_tls_acme_sni_cert_create() - creates a temp selfsigned cert - * and attaches to a vhost - * - * \param vhost: the vhost to acquire the selfsigned cert - * \param san_a: SAN written into the certificate - * \param san_b: second SAN written into the certificate - * - * - * Returns 0 if created and attached to the vhost. Returns -1 if problems and - * frees all allocations before returning. - * - * On success, any allocations are destroyed at vhost destruction automatically. - */ -LWS_VISIBLE LWS_EXTERN int -lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a, - const char *san_b); - -/** - * lws_tls_acme_sni_csr_create() - creates a CSR and related private key PEM - * - * \param context: lws_context used for random - * \param elements: array of LWS_TLS_REQ_ELEMENT_COUNT const char * - * \param csr: buffer that will get the b64URL(ASN-1 CSR) - * \param csr_len: max length of the csr buffer - * \param privkey_pem: pointer to pointer allocated to hold the privkey_pem - * \param privkey_len: pointer to size_t set to the length of the privkey_pem - * - * Creates a CSR according to the information in \p elements, and a private - * RSA key used to sign the CSR. - * - * The outputs are the b64URL(ASN-1 CSR) into csr, and the PEM private key into - * privkey_pem. - * - * Notice that \p elements points to an array of const char *s pointing to the - * information listed in the enum above. If an entry is NULL or an empty - * string, the element is set to "none" in the CSR. - * - * Returns 0 on success or nonzero for failure. - */ -LWS_VISIBLE LWS_EXTERN int -lws_tls_acme_sni_csr_create(struct lws_context *context, const char *elements[], - uint8_t *csr, size_t csr_len, char **privkey_pem, - size_t *privkey_len); - -/** - * lws_tls_cert_updated() - update every vhost using the given cert path - * - * \param context: our lws_context - * \param certpath: the filepath to the certificate - * \param keypath: the filepath to the private key of the certificate - * \param mem_cert: copy of the cert in memory - * \param len_mem_cert: length of the copy of the cert in memory - * \param mem_privkey: copy of the private key in memory - * \param len_mem_privkey: length of the copy of the private key in memory - * - * Checks every vhost to see if it is the using certificate described by the - * the given filepaths. If so, it attempts to update the vhost ssl_ctx to use - * the new certificate. - * - * Returns 0 on success or nonzero for failure. - */ -LWS_VISIBLE LWS_EXTERN int -lws_tls_cert_updated(struct lws_context *context, const char *certpath, - const char *keypath, - const char *mem_cert, size_t len_mem_cert, - const char *mem_privkey, size_t len_mem_privkey); -///@} - -/** \defgroup lws_ring LWS Ringbuffer APIs - * ##lws_ring: generic ringbuffer struct - * - * Provides an abstract ringbuffer api supporting one head and one or an - * unlimited number of tails. - * - * All of the members are opaque and manipulated by lws_ring_...() apis. - * - * The lws_ring and its buffer is allocated at runtime on the heap, using - * - * - lws_ring_create() - * - lws_ring_destroy() - * - * It may contain any type, the size of the "element" stored in the ring - * buffer and the number of elements is given at creation time. - * - * When you create the ringbuffer, you can optionally provide an element - * destroy callback that frees any allocations inside the element. This is then - * automatically called for elements with no tail behind them, ie, elements - * which don't have any pending consumer are auto-freed. - * - * Whole elements may be inserted into the ringbuffer and removed from it, using - * - * - lws_ring_insert() - * - lws_ring_consume() - * - * You can find out how many whole elements are free or waiting using - * - * - lws_ring_get_count_free_elements() - * - lws_ring_get_count_waiting_elements() - * - * In addition there are special purpose optional byte-centric apis - * - * - lws_ring_next_linear_insert_range() - * - lws_ring_bump_head() - * - * which let you, eg, read() directly into the ringbuffer without needing - * an intermediate bounce buffer. - * - * The accessors understand that the ring wraps, and optimizes insertion and - * consumption into one or two memcpy()s depending on if the head or tail - * wraps. - * - * lws_ring only supports a single head, but optionally multiple tails with - * an API to inform it when the "oldest" tail has moved on. You can give - * NULL where-ever an api asks for a tail pointer, and it will use an internal - * single tail pointer for convenience. - * - * The "oldest tail", which is the only tail if you give it NULL instead of - * some other tail, is used to track which elements in the ringbuffer are - * still unread by anyone. - * - * - lws_ring_update_oldest_tail() - */ -///@{ -struct lws_ring; - -/** - * lws_ring_create(): create a new ringbuffer - * - * \param element_len: the size in bytes of one element in the ringbuffer - * \param count: the number of elements the ringbuffer can contain - * \param destroy_element: NULL, or callback to be called for each element - * that is removed from the ringbuffer due to the - * oldest tail moving beyond it - * - * Creates the ringbuffer and allocates the storage. Returns the new - * lws_ring *, or NULL if the allocation failed. - * - * If non-NULL, destroy_element will get called back for every element that is - * retired from the ringbuffer after the oldest tail has gone past it, and for - * any element still left in the ringbuffer when it is destroyed. It replaces - * all other element destruction code in your user code. - */ -LWS_VISIBLE LWS_EXTERN struct lws_ring * -lws_ring_create(size_t element_len, size_t count, - void (*destroy_element)(void *element)); - -/** - * lws_ring_destroy(): destroy a previously created ringbuffer - * - * \param ring: the struct lws_ring to destroy - * - * Destroys the ringbuffer allocation and the struct lws_ring itself. - */ -LWS_VISIBLE LWS_EXTERN void -lws_ring_destroy(struct lws_ring *ring); - -/** - * lws_ring_get_count_free_elements(): return how many elements can fit - * in the free space - * - * \param ring: the struct lws_ring to report on - * - * Returns how much room is left in the ringbuffer for whole element insertion. - */ -LWS_VISIBLE LWS_EXTERN size_t -lws_ring_get_count_free_elements(struct lws_ring *ring); - -/** - * lws_ring_get_count_waiting_elements(): return how many elements can be consumed - * - * \param ring: the struct lws_ring to report on - * \param tail: a pointer to the tail struct to use, or NULL for single tail - * - * Returns how many elements are waiting to be consumed from the perspective - * of the tail pointer given. - */ -LWS_VISIBLE LWS_EXTERN size_t -lws_ring_get_count_waiting_elements(struct lws_ring *ring, uint32_t *tail); - -/** - * lws_ring_insert(): attempt to insert up to max_count elements from src - * - * \param ring: the struct lws_ring to report on - * \param src: the array of elements to be inserted - * \param max_count: the number of available elements at src - * - * Attempts to insert as many of the elements at src as possible, up to the - * maximum max_count. Returns the number of elements actually inserted. - */ -LWS_VISIBLE LWS_EXTERN size_t -lws_ring_insert(struct lws_ring *ring, const void *src, size_t max_count); - -/** - * lws_ring_consume(): attempt to copy out and remove up to max_count elements - * to src - * - * \param ring: the struct lws_ring to report on - * \param tail: a pointer to the tail struct to use, or NULL for single tail - * \param dest: the array of elements to be inserted. or NULL for no copy - * \param max_count: the number of available elements at src - * - * Attempts to copy out as many waiting elements as possible into dest, from - * the perspective of the given tail, up to max_count. If dest is NULL, the - * copying out is not done but the elements are logically consumed as usual. - * NULL dest is useful in combination with lws_ring_get_element(), where you - * can use the element direct from the ringbuffer and then call this with NULL - * dest to logically consume it. - * - * Increments the tail position according to how many elements could be - * consumed. - * - * Returns the number of elements consumed. - */ -LWS_VISIBLE LWS_EXTERN size_t -lws_ring_consume(struct lws_ring *ring, uint32_t *tail, void *dest, - size_t max_count); - -/** - * lws_ring_get_element(): get a pointer to the next waiting element for tail - * - * \param ring: the struct lws_ring to report on - * \param tail: a pointer to the tail struct to use, or NULL for single tail - * - * Points to the next element that tail would consume, directly in the - * ringbuffer. This lets you write() or otherwise use the element without - * having to copy it out somewhere first. - * - * After calling this, you must call lws_ring_consume(ring, &tail, NULL, 1) - * which will logically consume the element you used up and increment your - * tail (tail may also be NULL there if you use a single tail). - * - * Returns NULL if no waiting element, or a const void * pointing to it. - */ -LWS_VISIBLE LWS_EXTERN const void * -lws_ring_get_element(struct lws_ring *ring, uint32_t *tail); - -/** - * lws_ring_update_oldest_tail(): free up elements older than tail for reuse - * - * \param ring: the struct lws_ring to report on - * \param tail: a pointer to the tail struct to use, or NULL for single tail - * - * If you are using multiple tails, you must use this API to inform the - * lws_ring when none of the tails still need elements in the fifo any more, - * by updating it when the "oldest" tail has moved on. - */ -LWS_VISIBLE LWS_EXTERN void -lws_ring_update_oldest_tail(struct lws_ring *ring, uint32_t tail); - -/** - * lws_ring_get_oldest_tail(): get current oldest available data index - * - * \param ring: the struct lws_ring to report on - * - * If you are initializing a new ringbuffer consumer, you can set its tail to - * this to start it from the oldest ringbuffer entry still available. - */ -LWS_VISIBLE LWS_EXTERN uint32_t -lws_ring_get_oldest_tail(struct lws_ring *ring); - -/** - * lws_ring_next_linear_insert_range(): used to write directly into the ring - * - * \param ring: the struct lws_ring to report on - * \param start: pointer to a void * set to the start of the next ringbuffer area - * \param bytes: pointer to a size_t set to the max length you may use from *start - * - * This provides a low-level, bytewise access directly into the ringbuffer - * allowing direct insertion of data without having to use a bounce buffer. - * - * The api reports the position and length of the next linear range that can - * be written in the ringbuffer, ie, up to the point it would wrap, and sets - * *start and *bytes accordingly. You can then, eg, directly read() into - * *start for up to *bytes, and use lws_ring_bump_head() to update the lws_ring - * with what you have done. - * - * Returns nonzero if no insertion is currently possible. - */ -LWS_VISIBLE LWS_EXTERN int -lws_ring_next_linear_insert_range(struct lws_ring *ring, void **start, - size_t *bytes); - -/** - * lws_ring_bump_head(): used to write directly into the ring - * - * \param ring: the struct lws_ring to operate on - * \param bytes: the number of bytes you inserted at the current head - */ -LWS_VISIBLE LWS_EXTERN void -lws_ring_bump_head(struct lws_ring *ring, size_t bytes); - -LWS_VISIBLE LWS_EXTERN void -lws_ring_dump(struct lws_ring *ring, uint32_t *tail); - -/* - * This is a helper that combines the common pattern of needing to consume - * some ringbuffer elements, move the consumer tail on, and check if that - * has moved any ringbuffer elements out of scope, because it was the last - * consumer that had not already consumed them. - * - * Elements that go out of scope because the oldest tail is now after them - * get garbage-collected by calling the destroy_element callback on them - * defined when the ringbuffer was created. - */ - -#define lws_ring_consume_and_update_oldest_tail(\ - ___ring, /* the lws_ring object */ \ - ___type, /* type of objects with tails */ \ - ___ptail, /* ptr to tail of obj with tail doing consuming */ \ - ___count, /* count of payload objects being consumed */ \ - ___list_head, /* head of list of objects with tails */ \ - ___mtail, /* member name of tail in ___type */ \ - ___mlist /* member name of next list member ptr in ___type */ \ - ) { \ - int ___n, ___m; \ - \ - ___n = lws_ring_get_oldest_tail(___ring) == *(___ptail); \ - lws_ring_consume(___ring, ___ptail, NULL, ___count); \ - if (___n) { \ - uint32_t ___oldest; \ - ___n = 0; \ - ___oldest = *(___ptail); \ - lws_start_foreach_llp(___type **, ___ppss, ___list_head) { \ - ___m = lws_ring_get_count_waiting_elements( \ - ___ring, &(*___ppss)->tail); \ - if (___m >= ___n) { \ - ___n = ___m; \ - ___oldest = (*___ppss)->tail; \ - } \ - } lws_end_foreach_llp(___ppss, ___mlist); \ - \ - lws_ring_update_oldest_tail(___ring, ___oldest); \ - } \ -} - -/* - * This does the same as the lws_ring_consume_and_update_oldest_tail() - * helper, but for the simpler case there is only one consumer, so one - * tail, and that tail is always the oldest tail. - */ - -#define lws_ring_consume_single_tail(\ - ___ring, /* the lws_ring object */ \ - ___ptail, /* ptr to tail of obj with tail doing consuming */ \ - ___count /* count of payload objects being consumed */ \ - ) { \ - lws_ring_consume(___ring, ___ptail, NULL, ___count); \ - lws_ring_update_oldest_tail(___ring, *(___ptail)); \ -} -///@} - -/** \defgroup sha SHA and B64 helpers - * ##SHA and B64 helpers - * - * These provide SHA-1 and B64 helper apis - */ -///@{ -#ifdef LWS_SHA1_USE_OPENSSL_NAME -#define lws_SHA1 SHA1 -#else -/** - * lws_SHA1(): make a SHA-1 digest of a buffer - * - * \param d: incoming buffer - * \param n: length of incoming buffer - * \param md: buffer for message digest (must be >= 20 bytes) - * - * Reduces any size buffer into a 20-byte SHA-1 hash. - */ -LWS_VISIBLE LWS_EXTERN unsigned char * -lws_SHA1(const unsigned char *d, size_t n, unsigned char *md); -#endif -/** - * lws_b64_encode_string(): encode a string into base 64 - * - * \param in: incoming buffer - * \param in_len: length of incoming buffer - * \param out: result buffer - * \param out_size: length of result buffer - * - * Encodes a string using b64 - */ -LWS_VISIBLE LWS_EXTERN int -lws_b64_encode_string(const char *in, int in_len, char *out, int out_size); -/** - * lws_b64_encode_string_url(): encode a string into base 64 - * - * \param in: incoming buffer - * \param in_len: length of incoming buffer - * \param out: result buffer - * \param out_size: length of result buffer - * - * Encodes a string using b64 with the "URL" variant (+ -> -, and / -> _) - */ -LWS_VISIBLE LWS_EXTERN int -lws_b64_encode_string_url(const char *in, int in_len, char *out, int out_size); -/** - * lws_b64_decode_string(): decode a string from base 64 - * - * \param in: incoming buffer - * \param out: result buffer - * \param out_size: length of result buffer - * - * Decodes a NUL-terminated string using b64 - */ -LWS_VISIBLE LWS_EXTERN int -lws_b64_decode_string(const char *in, char *out, int out_size); -/** - * lws_b64_decode_string_len(): decode a string from base 64 - * - * \param in: incoming buffer - * \param in_len: length of incoming buffer - * \param out: result buffer - * \param out_size: length of result buffer - * - * Decodes a range of chars using b64 - */ -LWS_VISIBLE LWS_EXTERN int -lws_b64_decode_string_len(const char *in, int in_len, char *out, int out_size); -///@} - - -/*! \defgroup cgi cgi handling - * - * ##CGI handling - * - * These functions allow low-level control over stdin/out/err of the cgi. - * - * However for most cases, binding the cgi to http in and out, the default - * lws implementation already does the right thing. - */ - -enum lws_enum_stdinouterr { - LWS_STDIN = 0, - LWS_STDOUT = 1, - LWS_STDERR = 2, -}; - -enum lws_cgi_hdr_state { - LCHS_HEADER, - LCHS_CR1, - LCHS_LF1, - LCHS_CR2, - LCHS_LF2, - LHCS_RESPONSE, - LHCS_DUMP_HEADERS, - LHCS_PAYLOAD, - LCHS_SINGLE_0A, -}; - -struct lws_cgi_args { - struct lws **stdwsi; /**< get fd with lws_get_socket_fd() */ - enum lws_enum_stdinouterr ch; /**< channel index */ - unsigned char *data; /**< for messages with payload */ - enum lws_cgi_hdr_state hdr_state; /**< track where we are in cgi headers */ - int len; /**< length */ -}; - -#ifdef LWS_WITH_CGI -/** - * lws_cgi: spawn network-connected cgi process - * - * \param wsi: connection to own the process - * \param exec_array: array of "exec-name" "arg1" ... "argn" NULL - * \param script_uri_path_len: how many chars on the left of the uri are the - * path to the cgi, or -1 to spawn without URL-related env vars - * \param timeout_secs: seconds script should be allowed to run - * \param mp_cgienv: pvo list with per-vhost cgi options to put in env - */ -LWS_VISIBLE LWS_EXTERN int -lws_cgi(struct lws *wsi, const char * const *exec_array, - int script_uri_path_len, int timeout_secs, - const struct lws_protocol_vhost_options *mp_cgienv); - -/** - * lws_cgi_write_split_stdout_headers: write cgi output accounting for header part - * - * \param wsi: connection to own the process - */ -LWS_VISIBLE LWS_EXTERN int -lws_cgi_write_split_stdout_headers(struct lws *wsi); - -/** - * lws_cgi_kill: terminate cgi process associated with wsi - * - * \param wsi: connection to own the process - */ -LWS_VISIBLE LWS_EXTERN int -lws_cgi_kill(struct lws *wsi); - -/** - * lws_cgi_get_stdwsi: get wsi for stdin, stdout, or stderr - * - * \param wsi: parent wsi that has cgi - * \param ch: which of LWS_STDIN, LWS_STDOUT or LWS_STDERR - */ -LWS_VISIBLE LWS_EXTERN struct lws * -lws_cgi_get_stdwsi(struct lws *wsi, enum lws_enum_stdinouterr ch); - -#endif -///@} - - -/*! \defgroup fops file operation wrapping - * - * ##File operation wrapping - * - * Use these helper functions if you want to access a file from the perspective - * of a specific wsi, which is usually the case. If you just want contextless - * file access, use the fops callbacks directly with NULL wsi instead of these - * helpers. - * - * If so, then it calls the platform handler or user overrides where present - * (as defined in info->fops) - * - * The advantage from all this is user code can be portable for file operations - * without having to deal with differences between platforms. - */ -//@{ - -/** struct lws_plat_file_ops - Platform-specific file operations - * - * These provide platform-agnostic ways to deal with filesystem access in the - * library and in the user code. - */ - -#if defined(LWS_WITH_ESP32) -/* sdk preprocessor defs? compiler issue? gets confused with member names */ -#define LWS_FOP_OPEN _open -#define LWS_FOP_CLOSE _close -#define LWS_FOP_SEEK_CUR _seek_cur -#define LWS_FOP_READ _read -#define LWS_FOP_WRITE _write -#else -#define LWS_FOP_OPEN open -#define LWS_FOP_CLOSE close -#define LWS_FOP_SEEK_CUR seek_cur -#define LWS_FOP_READ read -#define LWS_FOP_WRITE write -#endif - -#define LWS_FOP_FLAGS_MASK ((1 << 23) - 1) -#define LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP (1 << 24) -#define LWS_FOP_FLAG_COMPR_IS_GZIP (1 << 25) -#define LWS_FOP_FLAG_MOD_TIME_VALID (1 << 26) -#define LWS_FOP_FLAG_VIRTUAL (1 << 27) - -struct lws_plat_file_ops; - -struct lws_fop_fd { - lws_filefd_type fd; - /**< real file descriptor related to the file... */ - const struct lws_plat_file_ops *fops; - /**< fops that apply to this fop_fd */ - void *filesystem_priv; - /**< ignored by lws; owned by the fops handlers */ - lws_filepos_t pos; - /**< generic "position in file" */ - lws_filepos_t len; - /**< generic "length of file" */ - lws_fop_flags_t flags; - /**< copy of the returned flags */ - uint32_t mod_time; - /**< optional "modification time of file", only valid if .open() - * set the LWS_FOP_FLAG_MOD_TIME_VALID flag */ -}; -typedef struct lws_fop_fd *lws_fop_fd_t; - -struct lws_fops_index { - const char *sig; /* NULL or vfs signature, eg, ".zip/" */ - uint8_t len; /* length of above string */ -}; - -struct lws_plat_file_ops { - lws_fop_fd_t (*LWS_FOP_OPEN)(const struct lws_plat_file_ops *fops, - const char *filename, const char *vpath, - lws_fop_flags_t *flags); - /**< Open file (always binary access if plat supports it) - * vpath may be NULL, or if the fops understands it, the point at which - * the filename's virtual part starts. - * *flags & LWS_FOP_FLAGS_MASK should be set to O_RDONLY or O_RDWR. - * If the file may be gzip-compressed, - * LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP is set. If it actually is - * gzip-compressed, then the open handler should OR - * LWS_FOP_FLAG_COMPR_IS_GZIP on to *flags before returning. - */ - int (*LWS_FOP_CLOSE)(lws_fop_fd_t *fop_fd); - /**< close file AND set the pointer to NULL */ - lws_fileofs_t (*LWS_FOP_SEEK_CUR)(lws_fop_fd_t fop_fd, - lws_fileofs_t offset_from_cur_pos); - /**< seek from current position */ - int (*LWS_FOP_READ)(lws_fop_fd_t fop_fd, lws_filepos_t *amount, - uint8_t *buf, lws_filepos_t len); - /**< Read from file, on exit *amount is set to amount actually read */ - int (*LWS_FOP_WRITE)(lws_fop_fd_t fop_fd, lws_filepos_t *amount, - uint8_t *buf, lws_filepos_t len); - /**< Write to file, on exit *amount is set to amount actually written */ - - struct lws_fops_index fi[3]; - /**< vfs path signatures implying use of this fops */ - - const struct lws_plat_file_ops *next; - /**< NULL or next fops in list */ - - /* Add new things just above here ---^ - * This is part of the ABI, don't needlessly break compatibility */ -}; - -/** - * lws_get_fops() - get current file ops - * - * \param context: context - */ -LWS_VISIBLE LWS_EXTERN struct lws_plat_file_ops * LWS_WARN_UNUSED_RESULT -lws_get_fops(struct lws_context *context); -LWS_VISIBLE LWS_EXTERN void -lws_set_fops(struct lws_context *context, const struct lws_plat_file_ops *fops); -/** - * lws_vfs_tell() - get current file position - * - * \param fop_fd: fop_fd we are asking about - */ -LWS_VISIBLE LWS_EXTERN lws_filepos_t LWS_WARN_UNUSED_RESULT -lws_vfs_tell(lws_fop_fd_t fop_fd); -/** - * lws_vfs_get_length() - get current file total length in bytes - * - * \param fop_fd: fop_fd we are asking about - */ -LWS_VISIBLE LWS_EXTERN lws_filepos_t LWS_WARN_UNUSED_RESULT -lws_vfs_get_length(lws_fop_fd_t fop_fd); -/** - * lws_vfs_get_mod_time() - get time file last modified - * - * \param fop_fd: fop_fd we are asking about - */ -LWS_VISIBLE LWS_EXTERN uint32_t LWS_WARN_UNUSED_RESULT -lws_vfs_get_mod_time(lws_fop_fd_t fop_fd); -/** - * lws_vfs_file_seek_set() - seek relative to start of file - * - * \param fop_fd: fop_fd we are seeking in - * \param offset: offset from start of file - */ -LWS_VISIBLE LWS_EXTERN lws_fileofs_t -lws_vfs_file_seek_set(lws_fop_fd_t fop_fd, lws_fileofs_t offset); -/** - * lws_vfs_file_seek_end() - seek relative to end of file - * - * \param fop_fd: fop_fd we are seeking in - * \param offset: offset from start of file - */ -LWS_VISIBLE LWS_EXTERN lws_fileofs_t -lws_vfs_file_seek_end(lws_fop_fd_t fop_fd, lws_fileofs_t offset); - -extern struct lws_plat_file_ops fops_zip; - -/** - * lws_plat_file_open() - open vfs filepath - * - * \param fops: file ops struct that applies to this descriptor - * \param vfs_path: filename to open - * \param flags: pointer to open flags - * - * The vfs_path is scanned for known fops signatures, and the open directed - * to any matching fops open. - * - * User code should use this api to perform vfs opens. - * - * returns semi-opaque handle - */ -LWS_VISIBLE LWS_EXTERN lws_fop_fd_t LWS_WARN_UNUSED_RESULT -lws_vfs_file_open(const struct lws_plat_file_ops *fops, const char *vfs_path, - lws_fop_flags_t *flags); - -/** - * lws_plat_file_close() - close file - * - * \param fop_fd: file handle to close - */ -static LWS_INLINE int -lws_vfs_file_close(lws_fop_fd_t *fop_fd) -{ - return (*fop_fd)->fops->LWS_FOP_CLOSE(fop_fd); -} - -/** - * lws_plat_file_seek_cur() - close file - * - * - * \param fop_fd: file handle - * \param offset: position to seek to - */ -static LWS_INLINE lws_fileofs_t -lws_vfs_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset) -{ - return fop_fd->fops->LWS_FOP_SEEK_CUR(fop_fd, offset); -} -/** - * lws_plat_file_read() - read from file - * - * \param fop_fd: file handle - * \param amount: how much to read (rewritten by call) - * \param buf: buffer to write to - * \param len: max length - */ -static LWS_INLINE int LWS_WARN_UNUSED_RESULT -lws_vfs_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, - uint8_t *buf, lws_filepos_t len) -{ - return fop_fd->fops->LWS_FOP_READ(fop_fd, amount, buf, len); -} -/** - * lws_plat_file_write() - write from file - * - * \param fop_fd: file handle - * \param amount: how much to write (rewritten by call) - * \param buf: buffer to read from - * \param len: max length - */ -static LWS_INLINE int LWS_WARN_UNUSED_RESULT -lws_vfs_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, - uint8_t *buf, lws_filepos_t len) -{ - return fop_fd->fops->LWS_FOP_WRITE(fop_fd, amount, buf, len); -} - -/* these are the platform file operations implementations... they can - * be called directly and used in fops arrays - */ - -LWS_VISIBLE LWS_EXTERN lws_fop_fd_t -_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, - const char *vpath, lws_fop_flags_t *flags); -LWS_VISIBLE LWS_EXTERN int -_lws_plat_file_close(lws_fop_fd_t *fop_fd); -LWS_VISIBLE LWS_EXTERN lws_fileofs_t -_lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset); -LWS_VISIBLE LWS_EXTERN int -_lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, - uint8_t *buf, lws_filepos_t len); -LWS_VISIBLE LWS_EXTERN int -_lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, - uint8_t *buf, lws_filepos_t len); - -LWS_VISIBLE LWS_EXTERN int -lws_alloc_vfs_file(struct lws_context *context, const char *filename, - uint8_t **buf, lws_filepos_t *amount); -//@} - -/** \defgroup smtp SMTP related functions - * ##SMTP related functions - * \ingroup lwsapi - * - * These apis let you communicate with a local SMTP server to send email from - * lws. It handles all the SMTP sequencing and protocol actions. - * - * Your system should have postfix, sendmail or another MTA listening on port - * 25 and able to send email using the "mail" commandline app. Usually distro - * MTAs are configured for this by default. - * - * It runs via its own libuv events if initialized (which requires giving it - * a libuv loop to attach to). - * - * It operates using three callbacks, on_next() queries if there is a new email - * to send, on_get_body() asks for the body of the email, and on_sent() is - * called after the email is successfully sent. - * - * To use it - * - * - create an lws_email struct - * - * - initialize data, loop, the email_* strings, max_content_size and - * the callbacks - * - * - call lws_email_init() - * - * When you have at least one email to send, call lws_email_check() to - * schedule starting to send it. - */ -//@{ -#ifdef LWS_WITH_SMTP - -/** enum lwsgs_smtp_states - where we are in SMTP protocol sequence */ -enum lwsgs_smtp_states { - LGSSMTP_IDLE, /**< awaiting new email */ - LGSSMTP_CONNECTING, /**< opening tcp connection to MTA */ - LGSSMTP_CONNECTED, /**< tcp connection to MTA is connected */ - LGSSMTP_SENT_HELO, /**< sent the HELO */ - LGSSMTP_SENT_FROM, /**< sent FROM */ - LGSSMTP_SENT_TO, /**< sent TO */ - LGSSMTP_SENT_DATA, /**< sent DATA request */ - LGSSMTP_SENT_BODY, /**< sent the email body */ - LGSSMTP_SENT_QUIT, /**< sent the session quit */ -}; - -/** struct lws_email - abstract context for performing SMTP operations */ -struct lws_email { - void *data; - /**< opaque pointer set by user code and available to the callbacks */ - uv_loop_t *loop; - /**< the libuv loop we will work on */ - - char email_smtp_ip[32]; /**< Fill before init, eg, "127.0.0.1" */ - char email_helo[32]; /**< Fill before init, eg, "myserver.com" */ - char email_from[100]; /**< Fill before init or on_next */ - char email_to[100]; /**< Fill before init or on_next */ - - unsigned int max_content_size; - /**< largest possible email body size */ - - /* Fill all the callbacks before init */ - - int (*on_next)(struct lws_email *email); - /**< (Fill in before calling lws_email_init) - * called when idle, 0 = another email to send, nonzero is idle. - * If you return 0, all of the email_* char arrays must be set - * to something useful. */ - int (*on_sent)(struct lws_email *email); - /**< (Fill in before calling lws_email_init) - * called when transfer of the email to the SMTP server was - * successful, your callback would remove the current email - * from its queue */ - int (*on_get_body)(struct lws_email *email, char *buf, int len); - /**< (Fill in before calling lws_email_init) - * called when the body part of the queued email is about to be - * sent to the SMTP server. */ - - - /* private things */ - uv_timer_t timeout_email; /**< private */ - enum lwsgs_smtp_states estate; /**< private */ - uv_connect_t email_connect_req; /**< private */ - uv_tcp_t email_client; /**< private */ - time_t email_connect_started; /**< private */ - char email_buf[256]; /**< private */ - char *content; /**< private */ -}; - -/** - * lws_email_init() - Initialize a struct lws_email - * - * \param email: struct lws_email to init - * \param loop: libuv loop to use - * \param max_content: max email content size - * - * Prepares a struct lws_email for use ending SMTP - */ -LWS_VISIBLE LWS_EXTERN int -lws_email_init(struct lws_email *email, uv_loop_t *loop, int max_content); - -/** - * lws_email_check() - Request check for new email - * - * \param email: struct lws_email context to check - * - * Schedules a check for new emails in 1s... call this when you have queued an - * email for send. - */ -LWS_VISIBLE LWS_EXTERN void -lws_email_check(struct lws_email *email); -/** - * lws_email_destroy() - stop using the struct lws_email - * - * \param email: the struct lws_email context - * - * Stop sending email using email and free allocations - */ -LWS_VISIBLE LWS_EXTERN void -lws_email_destroy(struct lws_email *email); - -#endif -//@} - - -/** \defgroup lejp JSON parser - * ##JSON parsing related functions - * \ingroup lwsapi - * - * LEJP is an extremely lightweight JSON stream parser included in lws. - */ -//@{ -struct lejp_ctx; - -#define LWS_ARRAY_SIZE(_x) (sizeof(_x) / sizeof(_x[0])) -#define LEJP_FLAG_WS_KEEP 64 -#define LEJP_FLAG_WS_COMMENTLINE 32 - -enum lejp_states { - LEJP_IDLE = 0, - LEJP_MEMBERS = 1, - LEJP_M_P = 2, - LEJP_MP_STRING = LEJP_FLAG_WS_KEEP | 3, - LEJP_MP_STRING_ESC = LEJP_FLAG_WS_KEEP | 4, - LEJP_MP_STRING_ESC_U1 = LEJP_FLAG_WS_KEEP | 5, - LEJP_MP_STRING_ESC_U2 = LEJP_FLAG_WS_KEEP | 6, - LEJP_MP_STRING_ESC_U3 = LEJP_FLAG_WS_KEEP | 7, - LEJP_MP_STRING_ESC_U4 = LEJP_FLAG_WS_KEEP | 8, - LEJP_MP_DELIM = 9, - LEJP_MP_VALUE = 10, - LEJP_MP_VALUE_NUM_INT = LEJP_FLAG_WS_KEEP | 11, - LEJP_MP_VALUE_NUM_EXP = LEJP_FLAG_WS_KEEP | 12, - LEJP_MP_VALUE_TOK = LEJP_FLAG_WS_KEEP | 13, - LEJP_MP_COMMA_OR_END = 14, - LEJP_MP_ARRAY_END = 15, -}; - -enum lejp_reasons { - LEJP_CONTINUE = -1, - LEJP_REJECT_IDLE_NO_BRACE = -2, - LEJP_REJECT_MEMBERS_NO_CLOSE = -3, - LEJP_REJECT_MP_NO_OPEN_QUOTE = -4, - LEJP_REJECT_MP_STRING_UNDERRUN = -5, - LEJP_REJECT_MP_ILLEGAL_CTRL = -6, - LEJP_REJECT_MP_STRING_ESC_ILLEGAL_ESC = -7, - LEJP_REJECT_ILLEGAL_HEX = -8, - LEJP_REJECT_MP_DELIM_MISSING_COLON = -9, - LEJP_REJECT_MP_DELIM_BAD_VALUE_START = -10, - LEJP_REJECT_MP_VAL_NUM_INT_NO_FRAC = -11, - LEJP_REJECT_MP_VAL_NUM_FORMAT = -12, - LEJP_REJECT_MP_VAL_NUM_EXP_BAD_EXP = -13, - LEJP_REJECT_MP_VAL_TOK_UNKNOWN = -14, - LEJP_REJECT_MP_C_OR_E_UNDERF = -15, - LEJP_REJECT_MP_C_OR_E_NOTARRAY = -16, - LEJP_REJECT_MP_ARRAY_END_MISSING = -17, - LEJP_REJECT_STACK_OVERFLOW = -18, - LEJP_REJECT_MP_DELIM_ISTACK = -19, - LEJP_REJECT_NUM_TOO_LONG = -20, - LEJP_REJECT_MP_C_OR_E_NEITHER = -21, - LEJP_REJECT_UNKNOWN = -22, - LEJP_REJECT_CALLBACK = -23 -}; - -#define LEJP_FLAG_CB_IS_VALUE 64 - -enum lejp_callbacks { - LEJPCB_CONSTRUCTED = 0, - LEJPCB_DESTRUCTED = 1, - - LEJPCB_START = 2, - LEJPCB_COMPLETE = 3, - LEJPCB_FAILED = 4, - - LEJPCB_PAIR_NAME = 5, - - LEJPCB_VAL_TRUE = LEJP_FLAG_CB_IS_VALUE | 6, - LEJPCB_VAL_FALSE = LEJP_FLAG_CB_IS_VALUE | 7, - LEJPCB_VAL_NULL = LEJP_FLAG_CB_IS_VALUE | 8, - LEJPCB_VAL_NUM_INT = LEJP_FLAG_CB_IS_VALUE | 9, - LEJPCB_VAL_NUM_FLOAT = LEJP_FLAG_CB_IS_VALUE | 10, - LEJPCB_VAL_STR_START = 11, /* notice handle separately */ - LEJPCB_VAL_STR_CHUNK = LEJP_FLAG_CB_IS_VALUE | 12, - LEJPCB_VAL_STR_END = LEJP_FLAG_CB_IS_VALUE | 13, - - LEJPCB_ARRAY_START = 14, - LEJPCB_ARRAY_END = 15, - - LEJPCB_OBJECT_START = 16, - LEJPCB_OBJECT_END = 17 -}; - -/** - * _lejp_callback() - User parser actions - * \param ctx: LEJP context - * \param reason: Callback reason - * - * Your user callback is associated with the context at construction time, - * and receives calls as the parsing progresses. - * - * All of the callbacks may be ignored and just return 0. - * - * The reasons it might get called, found in @reason, are: - * - * LEJPCB_CONSTRUCTED: The context was just constructed... you might want to - * perform one-time allocation for the life of the context. - * - * LEJPCB_DESTRUCTED: The context is being destructed... if you made any - * allocations at construction-time, you can free them now - * - * LEJPCB_START: Parsing is beginning at the first byte of input - * - * LEJPCB_COMPLETE: Parsing has completed successfully. You'll get a 0 or - * positive return code from lejp_parse indicating the - * amount of unused bytes left in the input buffer - * - * LEJPCB_FAILED: Parsing failed. You'll get a negative error code - * returned from lejp_parse - * - * LEJPCB_PAIR_NAME: When a "name":"value" pair has had the name parsed, - * this callback occurs. You can find the new name at - * the end of ctx->path[] - * - * LEJPCB_VAL_TRUE: The "true" value appeared - * - * LEJPCB_VAL_FALSE: The "false" value appeared - * - * LEJPCB_VAL_NULL: The "null" value appeared - * - * LEJPCB_VAL_NUM_INT: A string representing an integer is in ctx->buf - * - * LEJPCB_VAL_NUM_FLOAT: A string representing a float is in ctx->buf - * - * LEJPCB_VAL_STR_START: We are starting to parse a string, no data yet - * - * LEJPCB_VAL_STR_CHUNK: We parsed LEJP_STRING_CHUNK -1 bytes of string data in - * ctx->buf, which is as much as we can buffer, so we are - * spilling it. If all your strings are less than - * LEJP_STRING_CHUNK - 1 bytes, you will never see this - * callback. - * - * LEJPCB_VAL_STR_END: String parsing has completed, the last chunk of the - * string is in ctx->buf. - * - * LEJPCB_ARRAY_START: An array started - * - * LEJPCB_ARRAY_END: An array ended - * - * LEJPCB_OBJECT_START: An object started - * - * LEJPCB_OBJECT_END: An object ended - */ -LWS_EXTERN signed char _lejp_callback(struct lejp_ctx *ctx, char reason); - -typedef signed char (*lejp_callback)(struct lejp_ctx *ctx, char reason); - -#ifndef LEJP_MAX_DEPTH -#define LEJP_MAX_DEPTH 12 -#endif -#ifndef LEJP_MAX_INDEX_DEPTH -#define LEJP_MAX_INDEX_DEPTH 5 -#endif -#ifndef LEJP_MAX_PATH -#define LEJP_MAX_PATH 128 -#endif -#ifndef LEJP_STRING_CHUNK -/* must be >= 30 to assemble floats */ -#define LEJP_STRING_CHUNK 254 -#endif - -enum num_flags { - LEJP_SEEN_MINUS = (1 << 0), - LEJP_SEEN_POINT = (1 << 1), - LEJP_SEEN_POST_POINT = (1 << 2), - LEJP_SEEN_EXP = (1 << 3) -}; - -struct _lejp_stack { - char s; /* lejp_state stack*/ - char p; /* path length */ - char i; /* index array length */ - char b; /* user bitfield */ -}; - -struct lejp_ctx { - - /* sorted by type for most compact alignment - * - * pointers - */ - - signed char (*callback)(struct lejp_ctx *ctx, char reason); - void *user; - const char * const *paths; - - /* arrays */ - - struct _lejp_stack st[LEJP_MAX_DEPTH]; - uint16_t i[LEJP_MAX_INDEX_DEPTH]; /* index array */ - uint16_t wild[LEJP_MAX_INDEX_DEPTH]; /* index array */ - char path[LEJP_MAX_PATH]; - char buf[LEJP_STRING_CHUNK + 1]; - - /* int */ - - uint32_t line; - - /* short */ - - uint16_t uni; - - /* char */ - - uint8_t npos; - uint8_t dcount; - uint8_t f; - uint8_t sp; /* stack head */ - uint8_t ipos; /* index stack depth */ - uint8_t ppos; - uint8_t count_paths; - uint8_t path_match; - uint8_t path_match_len; - uint8_t wildcount; -}; - -LWS_VISIBLE LWS_EXTERN void -lejp_construct(struct lejp_ctx *ctx, - signed char (*callback)(struct lejp_ctx *ctx, char reason), - void *user, const char * const *paths, unsigned char paths_count); - -LWS_VISIBLE LWS_EXTERN void -lejp_destruct(struct lejp_ctx *ctx); - -LWS_VISIBLE LWS_EXTERN int -lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len); - -LWS_VISIBLE LWS_EXTERN void -lejp_change_callback(struct lejp_ctx *ctx, - signed char (*callback)(struct lejp_ctx *ctx, char reason)); - -LWS_VISIBLE LWS_EXTERN int -lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len); -//@} - -/* - * Stats are all uint64_t numbers that start at 0. - * Index names here have the convention - * - * _C_ counter - * _B_ byte count - * _MS_ millisecond count - */ - -enum { - LWSSTATS_C_CONNECTIONS, /**< count incoming connections */ - LWSSTATS_C_API_CLOSE, /**< count calls to close api */ - LWSSTATS_C_API_READ, /**< count calls to read from socket api */ - LWSSTATS_C_API_LWS_WRITE, /**< count calls to lws_write API */ - LWSSTATS_C_API_WRITE, /**< count calls to write API */ - LWSSTATS_C_WRITE_PARTIALS, /**< count of partial writes */ - LWSSTATS_C_WRITEABLE_CB_REQ, /**< count of writable callback requests */ - LWSSTATS_C_WRITEABLE_CB_EFF_REQ, /**< count of effective writable callback requests */ - LWSSTATS_C_WRITEABLE_CB, /**< count of writable callbacks */ - LWSSTATS_C_SSL_CONNECTIONS_FAILED, /**< count of failed SSL connections */ - LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, /**< count of accepted SSL connections */ - LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN, /**< count of SSL_accept() attempts */ - LWSSTATS_C_SSL_CONNS_HAD_RX, /**< count of accepted SSL conns that have had some RX */ - LWSSTATS_C_TIMEOUTS, /**< count of timed-out connections */ - LWSSTATS_C_SERVICE_ENTRY, /**< count of entries to lws service loop */ - LWSSTATS_B_READ, /**< aggregate bytes read */ - LWSSTATS_B_WRITE, /**< aggregate bytes written */ - LWSSTATS_B_PARTIALS_ACCEPTED_PARTS, /**< aggreate of size of accepted write data from new partials */ - LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY, /**< aggregate delay in accepting connection */ - LWSSTATS_MS_WRITABLE_DELAY, /**< aggregate delay between asking for writable and getting cb */ - LWSSTATS_MS_WORST_WRITABLE_DELAY, /**< single worst delay between asking for writable and getting cb */ - LWSSTATS_MS_SSL_RX_DELAY, /**< aggregate delay between ssl accept complete and first RX */ - LWSSTATS_C_PEER_LIMIT_AH_DENIED, /**< number of times we would have given an ah but for the peer limit */ - LWSSTATS_C_PEER_LIMIT_WSI_DENIED, /**< number of times we would have given a wsi but for the peer limit */ - - /* Add new things just above here ---^ - * This is part of the ABI, don't needlessly break compatibility */ - LWSSTATS_SIZE -}; - -#if defined(LWS_WITH_STATS) - -LWS_VISIBLE LWS_EXTERN uint64_t -lws_stats_get(struct lws_context *context, int index); -LWS_VISIBLE LWS_EXTERN void -lws_stats_log_dump(struct lws_context *context); -#else -static LWS_INLINE uint64_t -lws_stats_get(struct lws_context *context, int index) { (void)context; (void)index; return 0; } -static LWS_INLINE void -lws_stats_log_dump(struct lws_context *context) { (void)context; } -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/lws_config.h b/thirdparty/libwebsockets/lws_config.h deleted file mode 100644 index fdf02157cc..0000000000 --- a/thirdparty/libwebsockets/lws_config.h +++ /dev/null @@ -1,195 +0,0 @@ -/* lws_config.h Generated from lws_config.h.in */ - -/* GODOT ADDITION */ -#ifndef DEBUG_ENABLED -#define LWS_WITH_NO_LOGS -#endif -/* END GODOT ADDITION */ - -#ifndef NDEBUG - #ifndef _DEBUG - #define _DEBUG - #endif -#endif - -#define LWS_INSTALL_DATADIR "/usr/local/share" - -#define LWS_ROLE_H1 -#define LWS_ROLE_WS -#define LWS_ROLE_RAW -/* #undef LWS_ROLE_H2 */ -/* #undef LWS_ROLE_CGI */ - -/* Define to 1 to use wolfSSL/CyaSSL as a replacement for OpenSSL. - * LWS_OPENSSL_SUPPORT needs to be set also for this to work. */ -/* #undef USE_WOLFSSL */ - -/* Also define to 1 (in addition to USE_WOLFSSL) when using the - (older) CyaSSL library */ -/* #undef USE_OLD_CYASSL */ -/* #undef LWS_WITH_BORINGSSL */ - -#define LWS_WITH_MBEDTLS -/* #undef LWS_WITH_POLARSSL */ -/* #undef LWS_WITH_ESP32 */ - -/* #undef LWS_WITH_PLUGINS */ -/* #undef LWS_WITH_NO_LOGS */ - -/* The Libwebsocket version */ -#define LWS_LIBRARY_VERSION "3.0.0" - -#define LWS_LIBRARY_VERSION_MAJOR 3 -#define LWS_LIBRARY_VERSION_MINOR 0 -#define LWS_LIBRARY_VERSION_PATCH 0 -/* LWS_LIBRARY_VERSION_NUMBER looks like 1005001 for e.g. version 1.5.1 */ -#define LWS_LIBRARY_VERSION_NUMBER (LWS_LIBRARY_VERSION_MAJOR*1000000)+(LWS_LIBRARY_VERSION_MINOR*1000)+LWS_LIBRARY_VERSION_PATCH - -/* The current git commit hash that we're building from */ -#define LWS_BUILD_HASH "v2.0.0-948-geaa935a8" - -/* Build with OpenSSL support ... alias of LWS_WITH_TLS for compatibility*/ -#define LWS_OPENSSL_SUPPORT -#define LWS_WITH_TLS - -/* The client should load and trust CA root certs it finds in the OS */ -/* #undef LWS_SSL_CLIENT_USE_OS_CA_CERTS */ - -/* Sets the path where the client certs should be installed. */ -/* #undef LWS_OPENSSL_CLIENT_CERTS "../share" */ - -/* Turn off websocket extensions */ -#define LWS_WITHOUT_EXTENSIONS - -/* notice if client or server gone */ -/* #undef LWS_WITHOUT_SERVER */ -/* #undef LWS_WITHOUT_CLIENT */ - -#define LWS_WITH_POLL - -/* Enable libev io loop */ -/* #undef LWS_WITH_LIBEV */ - -/* Enable libuv io loop */ -/* #undef LWS_WITH_LIBUV */ - -/* Enable libevent io loop */ -/* #undef LWS_WITH_LIBEVENT */ - -/* Build with support for ipv6 */ -/* Everywhere, except in OpenBSD which does not support dual stacking */ -#if !defined(__OpenBSD__) -#define LWS_WITH_IPV6 -#endif - -/* Build with support for UNIX domain socket */ -/* #undef LWS_WITH_UNIX_SOCK */ - -/* Build with support for HTTP2 */ -/* #undef LWS_WITH_HTTP2 */ - -/* Turn on latency measuring code */ -/* #undef LWS_LATENCY */ - -/* Don't build the daemonizeation api */ -#define LWS_NO_DAEMONIZE - -/* Build without server support */ -/* #undef LWS_NO_SERVER */ - -/* Build without client support */ -/* #undef LWS_NO_CLIENT */ - -/* If we should compile with MinGW support */ -/* #undef LWS_MINGW_SUPPORT */ - -/* Use the BSD getifaddrs that comes with libwebsocket, for uclibc support */ -/* #undef LWS_BUILTIN_GETIFADDRS */ - -/* use SHA1() not internal libwebsockets_SHA1 */ -/* #undef LWS_SHA1_USE_OPENSSL_NAME */ - -/* SSL server using ECDH certificate */ -/* #undef LWS_SSL_SERVER_WITH_ECDH_CERT */ -/* #undef LWS_HAVE_SSL_CTX_set1_param */ -#define LWS_HAVE_X509_VERIFY_PARAM_set1_host -/* #undef LWS_HAVE_RSA_SET0_KEY */ -/* #undef LWS_HAVE_X509_get_key_usage */ -/* #undef LWS_HAVE_SSL_CTX_get0_certificate */ - -/* #undef LWS_HAVE_UV_VERSION_H */ -/* #undef LWS_HAVE_PTHREAD_H */ - -/* CGI apis */ -/* #undef LWS_WITH_CGI */ - -/* whether the Openssl is recent enough, and / or built with, ecdh */ -/* #undef LWS_HAVE_OPENSSL_ECDH_H */ - -/* HTTP Proxy support */ -/* #undef LWS_WITH_HTTP_PROXY */ - -/* HTTP Ranges support */ -/* #undef LWS_WITH_RANGES */ - -/* Http access log support */ -/* #undef LWS_WITH_ACCESS_LOG */ -/* #undef LWS_WITH_SERVER_STATUS */ - -/* #undef LWS_WITH_STATEFUL_URLDECODE */ -/* #undef LWS_WITH_PEER_LIMITS */ - -/* Maximum supported service threads */ -#define LWS_MAX_SMP 1 - -/* Lightweight JSON Parser */ -/* #undef LWS_WITH_LEJP */ - -/* SMTP */ -/* #undef LWS_WITH_SMTP */ - -/* OPTEE */ -/* #undef LWS_PLAT_OPTEE */ - -/* ZIP FOPS */ -/* #undef LWS_WITH_ZIP_FOPS */ -#define LWS_HAVE_STDINT_H - -/* #undef LWS_AVOID_SIGPIPE_IGN */ - -/* #undef LWS_FALLBACK_GETHOSTBYNAME */ - -/* #undef LWS_WITH_STATS */ -/* #undef LWS_WITH_SOCKS5 */ - -/* #undef LWS_HAVE_SYS_CAPABILITY_H */ -/* #undef LWS_HAVE_LIBCAP */ - -#define LWS_HAVE_ATOLL -/* #undef LWS_HAVE__ATOI64 */ -/* #undef LWS_HAVE__STAT32I64 */ - -/* #undef LWS_WITH_JWS */ -/* #undef LWS_WITH_ACME */ -/* #undef LWS_WITH_SELFTESTS */ - -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__OpenBSD__) -#define LWS_HAVE_MALLOC_H -#endif - -#if !defined(__APPLE__) && !defined(__HAIKU__) -#define LWS_HAVE_PIPE2 -#endif - -/* OpenSSL various APIs */ - -#define LWS_HAVE_TLS_CLIENT_METHOD -/* #undef LWS_HAVE_TLSV1_2_CLIENT_METHOD */ -/* #undef LWS_HAVE_SSL_SET_INFO_CALLBACK */ -/* #undef LWS_HAVE_SSL_EXTRA_CHAIN_CERTS */ -/* #undef LWS_HAVE_SSL_get0_alpn_selected */ -/* #undef LWS_HAVE_SSL_set_alpn_protos */ - -#define LWS_HAS_INTPTR_T - - diff --git a/thirdparty/libwebsockets/lws_config_private.h b/thirdparty/libwebsockets/lws_config_private.h deleted file mode 100644 index e531777624..0000000000 --- a/thirdparty/libwebsockets/lws_config_private.h +++ /dev/null @@ -1,145 +0,0 @@ -/* lws_config_private.h.in. Private compilation options. */ -#ifndef DEBUG_ENABLED -#define NDEBUG -#endif - -#ifndef NDEBUG - #ifndef _DEBUG - #define _DEBUG - #endif -#endif - -/* Define to 1 to use CyaSSL as a replacement for OpenSSL. - * LWS_OPENSSL_SUPPORT needs to be set also for this to work. */ -/* #undef USE_CYASSL */ - -/* Define to 1 if you have the `bzero' function. */ -#define LWS_HAVE_BZERO -/* Windows has no bzero function */ -#ifdef WINDOWS_ENABLED -#undef LWS_HAVE_BZERO -#endif - -/* Define to 1 if you have the <dlfcn.h> header file. */ -#define LWS_HAVE_DLFCN_H - -/* Define to 1 if you have the <fcntl.h> header file. */ -#define LWS_HAVE_FCNTL_H -#ifdef NO_FCNTL -#undef LWS_HAVE_FCNTL_H -#endif - -/* Define to 1 if you have the `fork' function. */ -#define LWS_HAVE_FORK - -/* Define to 1 if you have the `getenv’ function. */ -#define LWS_HAVE_GETENV - -/* Define to 1 if you have the <in6addr.h> header file. */ -/* #undef LWS_HAVE_IN6ADDR_H */ - -/* Define to 1 if you have the <inttypes.h> header file. */ -#define LWS_HAVE_INTTYPES_H - -/* Define to 1 if you have the `ssl' library (-lssl). */ -/* #undef LWS_HAVE_LIBSSL */ - -/* Define to 1 if your system has a GNU libc compatible `malloc' function, and - to 0 otherwise. */ -#define LWS_HAVE_MALLOC - -/* Define to 1 if you have the <memory.h> header file. */ -#define LWS_HAVE_MEMORY_H - -/* Define to 1 if you have the `memset' function. */ -#define LWS_HAVE_MEMSET - -/* Define to 1 if you have the <netinet/in.h> header file. */ -#define LWS_HAVE_NETINET_IN_H - -/* Define to 1 if your system has a GNU libc compatible `realloc' function, - and to 0 otherwise. */ -#define LWS_HAVE_REALLOC - -/* Define to 1 if you have the `socket' function. */ -#define LWS_HAVE_SOCKET - -/* Define to 1 if you have the <stdint.h> header file. */ -#define LWS_HAVE_STDINT_H - -/* Define to 1 if you have the <stdlib.h> header file. */ -#define LWS_HAVE_STDLIB_H - -/* Define to 1 if you have the `strerror' function. */ -#define LWS_HAVE_STRERROR - -/* Define to 1 if you have the <strings.h> header file. */ -#define LWS_HAVE_STRINGS_H - -/* Define to 1 if you have the <string.h> header file. */ -#define LWS_HAVE_STRING_H - -/* Define to 1 if you have the <sys/prctl.h> header file. */ -#define LWS_HAVE_SYS_PRCTL_H -#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__HAIKU__) -#undef LWS_HAVE_SYS_PRCTL_H -#endif - -/* Define to 1 if you have the <sys/socket.h> header file. */ -#define LWS_HAVE_SYS_SOCKET_H - -/* Define to 1 if you have the <sys/sockio.h> header file. */ -/* #undef LWS_HAVE_SYS_SOCKIO_H */ - -/* Define to 1 if you have the <sys/stat.h> header file. */ -#define LWS_HAVE_SYS_STAT_H - -/* Define to 1 if you have the <sys/types.h> header file. */ -#define LWS_HAVE_SYS_TYPES_H - -/* Define to 1 if you have the <unistd.h> header file. */ -#define LWS_HAVE_UNISTD_H - -#define LWS_HAVE_TCP_USER_TIMEOUT - -/* Define to 1 if you have the `vfork' function. */ -#define LWS_HAVE_VFORK - -/* Define to 1 if you have the <vfork.h> header file. */ -/* #undef LWS_HAVE_VFORK_H */ - -/* Define to 1 if `fork' works. */ -#define LWS_HAVE_WORKING_FORK - -/* Define to 1 if `vfork' works. */ -#define LWS_HAVE_WORKING_VFORK - -/* Define to 1 if execvpe() exists */ -#define LWS_HAVE_EXECVPE - -/* Define to 1 if you have the <zlib.h> header file. */ -#define LWS_HAVE_ZLIB_H - -#define LWS_HAVE_GETLOADAVG - -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR // We're not using libtool - -/* Define to rpl_malloc if the replacement function should be used. */ -/* #undef malloc */ - -/* Define to rpl_realloc if the replacement function should be used. */ -/* #undef realloc */ - -/* Define to 1 if we have getifaddrs */ -#define LWS_HAVE_GETIFADDRS -#if defined(ANDROID_ENABLED) -#undef LWS_HAVE_GETIFADDRS -#define LWS_BUILTIN_GETIFADDRS -#endif - -/* Define if the inline keyword doesn't exist. */ -/* #undef inline */ - - diff --git a/thirdparty/libwebsockets/misc/base64-decode.c b/thirdparty/libwebsockets/misc/base64-decode.c deleted file mode 100644 index 64b84d78fa..0000000000 --- a/thirdparty/libwebsockets/misc/base64-decode.c +++ /dev/null @@ -1,242 +0,0 @@ -/* - * This code originally came from here - * - * http://base64.sourceforge.net/b64.c - * - * with the following license: - * - * LICENCE: Copyright (c) 2001 Bob Trower, Trantor Standard Systems Inc. - * - * 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. - * - * VERSION HISTORY: - * Bob Trower 08/04/01 -- Create Version 0.00.00B - * - * I cleaned it up quite a bit to match the (linux kernel) style of the rest - * of libwebsockets; this version is under LGPL2.1 + SLE like the rest of lws - * since he explicitly allows sublicensing, but I give the URL above so you can - * get the original with Bob's super-liberal terms directly if you prefer. - */ - -#include <stdio.h> -#include <string.h> -#include "core/private.h" - -static const char encode_orig[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz0123456789+/"; -static const char encode_url[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz0123456789-_"; -static const char decode[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW" - "$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; - -static int -_lws_b64_encode_string(const char *encode, const char *in, int in_len, - char *out, int out_size) -{ - unsigned char triple[3]; - int i; - int len; - int line = 0; - int done = 0; - - while (in_len) { - len = 0; - for (i = 0; i < 3; i++) { - if (in_len) { - triple[i] = *in++; - len++; - in_len--; - } else - triple[i] = 0; - } - - if (done + 4 >= out_size) - return -1; - - *out++ = encode[triple[0] >> 2]; - *out++ = encode[((triple[0] & 0x03) << 4) | - ((triple[1] & 0xf0) >> 4)]; - *out++ = (len > 1 ? encode[((triple[1] & 0x0f) << 2) | - ((triple[2] & 0xc0) >> 6)] : '='); - *out++ = (len > 2 ? encode[triple[2] & 0x3f] : '='); - - done += 4; - line += 4; - } - - if (done + 1 >= out_size) - return -1; - - *out++ = '\0'; - - return done; -} - -LWS_VISIBLE int -lws_b64_encode_string(const char *in, int in_len, char *out, int out_size) -{ - return _lws_b64_encode_string(encode_orig, in, in_len, out, out_size); -} - -LWS_VISIBLE int -lws_b64_encode_string_url(const char *in, int in_len, char *out, int out_size) -{ - return _lws_b64_encode_string(encode_url, in, in_len, out, out_size); -} - -/* - * returns length of decoded string in out, or -1 if out was too small - * according to out_size - * - * Only reads up to in_len chars, otherwise if in_len is -1 on entry reads until - * the first NUL in the input. - */ - -static int -_lws_b64_decode_string(const char *in, int in_len, char *out, int out_size) -{ - int len, i, c = 0, done = 0; - unsigned char v, quad[4]; - - while (in_len && *in) { - - len = 0; - for (i = 0; i < 4 && in_len && *in; i++) { - - v = 0; - c = 0; - while (in_len && *in && !v) { - c = v = *in++; - in_len--; - /* support the url base64 variant too */ - if (v == '-') - c = v = '+'; - if (v == '_') - c = v = '/'; - v = (v < 43 || v > 122) ? 0 : decode[v - 43]; - if (v) - v = (v == '$') ? 0 : v - 61; - } - if (c) { - len++; - if (v) - quad[i] = v - 1; - } else - quad[i] = 0; - } - - if (out_size < (done + len - 1)) - /* out buffer is too small */ - return -1; - - /* - * "The '==' sequence indicates that the last group contained - * only one byte, and '=' indicates that it contained two - * bytes." (wikipedia) - */ - - if ((!in_len || !*in) && c == '=') - len--; - - if (len >= 2) - *out++ = quad[0] << 2 | quad[1] >> 4; - if (len >= 3) - *out++ = quad[1] << 4 | quad[2] >> 2; - if (len >= 4) - *out++ = ((quad[2] << 6) & 0xc0) | quad[3]; - - done += len - 1; - } - - if (done + 1 >= out_size) - return -1; - - *out = '\0'; - - return done; -} - -LWS_VISIBLE int -lws_b64_decode_string(const char *in, char *out, int out_size) -{ - return _lws_b64_decode_string(in, -1, out, out_size); -} - -LWS_VISIBLE int -lws_b64_decode_string_len(const char *in, int in_len, char *out, int out_size) -{ - return _lws_b64_decode_string(in, in_len, out, out_size); -} - -#if 0 -int -lws_b64_selftest(void) -{ - char buf[64]; - unsigned int n, r = 0; - unsigned int test; - /* examples from https://en.wikipedia.org/wiki/Base64 */ - static const char * const plaintext[] = { - "any carnal pleasure.", - "any carnal pleasure", - "any carnal pleasur", - "any carnal pleasu", - "any carnal pleas", - "Admin:kloikloi" - }; - static const char * const coded[] = { - "YW55IGNhcm5hbCBwbGVhc3VyZS4=", - "YW55IGNhcm5hbCBwbGVhc3VyZQ==", - "YW55IGNhcm5hbCBwbGVhc3Vy", - "YW55IGNhcm5hbCBwbGVhc3U=", - "YW55IGNhcm5hbCBwbGVhcw==", - "QWRtaW46a2xvaWtsb2k=" - }; - - for (test = 0; test < sizeof plaintext / sizeof(plaintext[0]); test++) { - - buf[sizeof(buf) - 1] = '\0'; - n = lws_b64_encode_string(plaintext[test], - strlen(plaintext[test]), buf, sizeof buf); - if (n != strlen(coded[test]) || strcmp(buf, coded[test])) { - lwsl_err("Failed lws_b64 encode selftest " - "%d result '%s' %d\n", test, buf, n); - r = -1; - } - - buf[sizeof(buf) - 1] = '\0'; - n = lws_b64_decode_string(coded[test], buf, sizeof buf); - if (n != strlen(plaintext[test]) || - strcmp(buf, plaintext[test])) { - lwsl_err("Failed lws_b64 decode selftest " - "%d result '%s' / '%s', %d / %d\n", - test, buf, plaintext[test], n, strlen(plaintext[test])); - r = -1; - } - } - - lwsl_notice("Base 64 selftests passed\n"); - - return r; -} -#endif diff --git a/thirdparty/libwebsockets/misc/getifaddrs.c b/thirdparty/libwebsockets/misc/getifaddrs.c deleted file mode 100644 index 735b899f48..0000000000 --- a/thirdparty/libwebsockets/misc/getifaddrs.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2000 - 2001 Kungliga Tekniska H�gskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * 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. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. - * - * originally downloaded from - * - * http://ftp.uninett.no/pub/OpenBSD/src/kerberosV/src/lib/roken/getifaddrs.c - */ - -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <net/if.h> -#include <stdlib.h> -#include <string.h> -#include <sys/ioctl.h> -#include <unistd.h> -#include "core/private.h" - -#ifdef LWS_HAVE_SYS_SOCKIO_H -#include <sys/sockio.h> -#endif - -#ifdef LWS_HAVE_NETINET_IN6_VAR_H -#include <netinet/in6_var.h> -#endif - -#ifndef max -#define max(a, b) ((a) > (b) ? (a) : (b)) -#endif - -#include "getifaddrs.h" - -static int -getifaddrs2(struct ifaddrs **ifap, int af, int siocgifconf, int siocgifflags, - size_t ifreq_sz) -{ - int ret; - int fd; - size_t buf_size; - char *buf; - struct ifconf ifconf; - char *p; - size_t sz; - struct sockaddr sa_zero; - struct ifreq *ifr; - struct ifaddrs *start, **end = &start; - - buf = NULL; - - memset(&sa_zero, 0, sizeof(sa_zero)); - fd = socket(af, SOCK_DGRAM, 0); - if (fd < 0) - return -1; - - buf_size = 8192; - for (;;) { - buf = lws_zalloc(buf_size, "getifaddrs2"); - if (buf == NULL) { - ret = ENOMEM; - goto error_out; - } - ifconf.ifc_len = buf_size; - ifconf.ifc_buf = buf; - - /* - * Solaris returns EINVAL when the buffer is too small. - */ - if (ioctl(fd, siocgifconf, &ifconf) < 0 && errno != EINVAL) { - ret = errno; - goto error_out; - } - /* - * Can the difference between a full and a overfull buf - * be determined? - */ - - if (ifconf.ifc_len < (int)buf_size) - break; - lws_free(buf); - buf_size *= 2; - } - - for (p = ifconf.ifc_buf; p < ifconf.ifc_buf + ifconf.ifc_len; p += sz) { - struct ifreq ifreq; - struct sockaddr *sa; - size_t salen; - - ifr = (struct ifreq *)p; - sa = &ifr->ifr_addr; - - sz = ifreq_sz; - salen = sizeof(struct sockaddr); -#ifdef LWS_HAVE_STRUCT_SOCKADDR_SA_LEN - salen = sa->sa_len; - sz = max(sz, sizeof(ifr->ifr_name) + sa->sa_len); -#endif -#ifdef SA_LEN - salen = SA_LEN(sa); - sz = max(sz, sizeof(ifr->ifr_name) + SA_LEN(sa)); -#endif - memset(&ifreq, 0, sizeof(ifreq)); - memcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifr->ifr_name)); - - if (ioctl(fd, siocgifflags, &ifreq) < 0) { - ret = errno; - goto error_out; - } - - *end = lws_malloc(sizeof(**end), "getifaddrs"); - - (*end)->ifa_next = NULL; - (*end)->ifa_name = strdup(ifr->ifr_name); - (*end)->ifa_flags = ifreq.ifr_flags; - (*end)->ifa_addr = lws_malloc(salen, "getifaddrs"); - memcpy((*end)->ifa_addr, sa, salen); - (*end)->ifa_netmask = NULL; - -#if 0 - /* fix these when we actually need them */ - if (ifreq.ifr_flags & IFF_BROADCAST) { - (*end)->ifa_broadaddr = - lws_malloc(sizeof(ifr->ifr_broadaddr), "getifaddrs"); - memcpy((*end)->ifa_broadaddr, &ifr->ifr_broadaddr, - sizeof(ifr->ifr_broadaddr)); - } else if (ifreq.ifr_flags & IFF_POINTOPOINT) { - (*end)->ifa_dstaddr = - lws_malloc(sizeof(ifr->ifr_dstaddr), "getifaddrs"); - memcpy((*end)->ifa_dstaddr, &ifr->ifr_dstaddr, - sizeof(ifr->ifr_dstaddr)); - } else - (*end)->ifa_dstaddr = NULL; -#else - (*end)->ifa_dstaddr = NULL; -#endif - (*end)->ifa_data = NULL; - - end = &(*end)->ifa_next; - - } - *ifap = start; - close(fd); - lws_free(buf); - return 0; - -error_out: - close(fd); - lws_free(buf); - errno = ret; - - return -1; -} - -int -getifaddrs(struct ifaddrs **ifap) -{ - int ret = -1; - errno = ENXIO; -#if defined(AF_INET6) && defined(SIOCGIF6CONF) && defined(SIOCGIF6FLAGS) - if (ret) - ret = getifaddrs2(ifap, AF_INET6, SIOCGIF6CONF, SIOCGIF6FLAGS, - sizeof(struct in6_ifreq)); -#endif -#if defined(LWS_HAVE_IPV6) && defined(SIOCGIFCONF) - if (ret) - ret = getifaddrs2(ifap, AF_INET6, SIOCGIFCONF, SIOCGIFFLAGS, - sizeof(struct ifreq)); -#endif -#if defined(AF_INET) && defined(SIOCGIFCONF) && defined(SIOCGIFFLAGS) - if (ret) - ret = getifaddrs2(ifap, AF_INET, SIOCGIFCONF, SIOCGIFFLAGS, - sizeof(struct ifreq)); -#endif - return ret; -} - -void -freeifaddrs(struct ifaddrs *ifp) -{ - struct ifaddrs *p, *q; - - for (p = ifp; p; ) { - lws_free(p->ifa_name); - lws_free(p->ifa_addr); - lws_free(p->ifa_dstaddr); - lws_free(p->ifa_netmask); - lws_free(p->ifa_data); - q = p; - p = p->ifa_next; - lws_free(q); - } -} - -#ifdef TEST - -void -print_addr(const char *s, struct sockaddr *sa) -{ - int i; - printf(" %s=%d/", s, sa->sa_family); -#ifdef LWS_HAVE_STRUCT_SOCKADDR_SA_LEN - for (i = 0; - i < sa->sa_len - ((lws_intptr_t)sa->sa_data - (lws_intptr_t)&sa->sa_family); i++) - printf("%02x", ((unsigned char *)sa->sa_data)[i]); -#else - for (i = 0; i < sizeof(sa->sa_data); i++) - printf("%02x", ((unsigned char *)sa->sa_data)[i]); -#endif - printf("\n"); -} - -void -print_ifaddrs(struct ifaddrs *x) -{ - struct ifaddrs *p; - - for (p = x; p; p = p->ifa_next) { - printf("%s\n", p->ifa_name); - printf(" flags=%x\n", p->ifa_flags); - if (p->ifa_addr) - print_addr("addr", p->ifa_addr); - if (p->ifa_dstaddr) - print_addr("dstaddr", p->ifa_dstaddr); - if (p->ifa_netmask) - print_addr("netmask", p->ifa_netmask); - printf(" %p\n", p->ifa_data); - } -} - -int -main() -{ - struct ifaddrs *a = NULL, *b; - getifaddrs2(&a, AF_INET, SIOCGIFCONF, SIOCGIFFLAGS, - sizeof(struct ifreq)); - print_ifaddrs(a); - printf("---\n"); - getifaddrs(&b); - print_ifaddrs(b); - return 0; -} -#endif diff --git a/thirdparty/libwebsockets/misc/getifaddrs.h b/thirdparty/libwebsockets/misc/getifaddrs.h deleted file mode 100644 index d26670c082..0000000000 --- a/thirdparty/libwebsockets/misc/getifaddrs.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef LWS_HAVE_GETIFADDRS -#define LWS_HAVE_GETIFADDRS 0 -#endif - -#if LWS_HAVE_GETIFADDRS -#include <sys/types.h> -#include <ifaddrs.h> -#else -#ifdef __cplusplus -extern "C" { -#endif -/* - * Copyright (c) 2000 Kungliga Tekniska H�gskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * 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. - * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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. - */ - -/* $KTH: ifaddrs.hin,v 1.3 2000/12/11 00:01:13 assar Exp $ */ - -#ifndef ifaddrs_h_7467027A95AD4B5C8DDD40FE7D973791 -#define ifaddrs_h_7467027A95AD4B5C8DDD40FE7D973791 - -/* - * the interface is defined in terms of the fields below, and this is - * sometimes #define'd, so there seems to be no simple way of solving - * this and this seemed the best. */ - -#undef ifa_dstaddr - -struct ifaddrs { - struct ifaddrs *ifa_next; - char *ifa_name; - unsigned int ifa_flags; - struct sockaddr *ifa_addr; - struct sockaddr *ifa_netmask; - struct sockaddr *ifa_dstaddr; - void *ifa_data; -}; - -#ifndef ifa_broadaddr -#define ifa_broadaddr ifa_dstaddr -#endif - -int getifaddrs(struct ifaddrs **); - -void freeifaddrs(struct ifaddrs *); - -#endif /* __ifaddrs_h__ */ - -#ifdef __cplusplus -} -#endif -#endif diff --git a/thirdparty/libwebsockets/misc/lejp.c b/thirdparty/libwebsockets/misc/lejp.c deleted file mode 100644 index 99142b9553..0000000000 --- a/thirdparty/libwebsockets/misc/lejp.c +++ /dev/null @@ -1,753 +0,0 @@ -/* - * Lightweight Embedded JSON Parser - * - * Copyright (C) 2013-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include <libwebsockets.h> -#include "core/private.h" -#include <string.h> -#include <stdio.h> - -/** - * lejp_construct - prepare a struct lejp_ctx for use - * - * \param ctx: pointer to your struct lejp_ctx - * \param callback: your user callback which will received parsed tokens - * \param user: optional user data pointer untouched by lejp - * \param paths: your array of name elements you are interested in - * \param count_paths: LWS_ARRAY_SIZE() of @paths - * - * Prepares your context struct for use with lejp - */ - -void -lejp_construct(struct lejp_ctx *ctx, - signed char (*callback)(struct lejp_ctx *ctx, char reason), void *user, - const char * const *paths, unsigned char count_paths) -{ - ctx->st[0].s = 0; - ctx->st[0].p = 0; - ctx->st[0].i = 0; - ctx->st[0].b = 0; - ctx->sp = 0; - ctx->ipos = 0; - ctx->ppos = 0; - ctx->path_match = 0; - ctx->path[0] = '\0'; - ctx->callback = callback; - ctx->user = user; - ctx->paths = paths; - ctx->count_paths = count_paths; - ctx->line = 1; - ctx->callback(ctx, LEJPCB_CONSTRUCTED); -} - -/** - * lejp_destruct - retire a previously constructed struct lejp_ctx - * - * \param ctx: pointer to your struct lejp_ctx - * - * lejp does not perform any allocations, but since your user code might, this - * provides a one-time LEJPCB_DESTRUCTED callback at destruction time where - * you can clean up in your callback. - */ - -void -lejp_destruct(struct lejp_ctx *ctx) -{ - /* no allocations... just let callback know what it happening */ - ctx->callback(ctx, LEJPCB_DESTRUCTED); -} - -/** - * lejp_change_callback - switch to a different callback from now on - * - * \param ctx: pointer to your struct lejp_ctx - * \param callback: your user callback which will received parsed tokens - * - * This tells the old callback it was destroyed, in case you want to take any - * action because that callback "lost focus", then changes to the new - * callback and tells it first that it was constructed, and then started. - * - * Changing callback is a cheap and powerful trick to split out handlers - * according to information earlier in the parse. For example you may have - * a JSON pair "schema" whose value defines what can be expected for the rest - * of the JSON. Rather than having one huge callback for all cases, you can - * have an initial one looking for "schema" which then calls - * lejp_change_callback() to a handler specific for the schema. - * - * Notice that afterwards, you need to construct the context again anyway to - * parse another JSON object, and the callback is reset then to the main, - * schema-interpreting one. The construction action is very lightweight. - */ - -void -lejp_change_callback(struct lejp_ctx *ctx, - signed char (*callback)(struct lejp_ctx *ctx, char reason)) -{ - ctx->callback(ctx, LEJPCB_DESTRUCTED); - ctx->callback = callback; - ctx->callback(ctx, LEJPCB_CONSTRUCTED); - ctx->callback(ctx, LEJPCB_START); -} - -static void -lejp_check_path_match(struct lejp_ctx *ctx) -{ - const char *p, *q; - int n; - - /* we only need to check if a match is not active */ - for (n = 0; !ctx->path_match && n < ctx->count_paths; n++) { - ctx->wildcount = 0; - p = ctx->path; - q = ctx->paths[n]; - while (*p && *q) { - if (*q != '*') { - if (*p != *q) - break; - p++; - q++; - continue; - } - ctx->wild[ctx->wildcount++] = p - ctx->path; - q++; - /* - * if * has something after it, match to . - * if ends with *, eat everything. - * This implies match sequences must be ordered like - * x.*.* - * x.* - * if both options are possible - */ - while (*p && (*p != '.' || !*q)) - p++; - } - if (*p || *q) - continue; - - ctx->path_match = n + 1; - ctx->path_match_len = ctx->ppos; - return; - } - - if (!ctx->path_match) - ctx->wildcount = 0; -} - -int -lejp_get_wildcard(struct lejp_ctx *ctx, int wildcard, char *dest, int len) -{ - int n; - - if (wildcard >= ctx->wildcount || !len) - return 0; - - n = ctx->wild[wildcard]; - - while (--len && n < ctx->ppos && - (n == ctx->wild[wildcard] || ctx->path[n] != '.')) - *dest++ = ctx->path[n++]; - - *dest = '\0'; - n++; - - return n - ctx->wild[wildcard]; -} - -/** - * lejp_parse - interpret some more incoming data incrementally - * - * \param ctx: previously constructed parsing context - * \param json: char buffer with the new data to interpret - * \param len: amount of data in the buffer - * - * Because lejp is a stream parser, it incrementally parses as new data - * becomes available, maintaining all state in the context struct. So an - * incomplete JSON is a normal situation, getting you a LEJP_CONTINUE - * return, signalling there's no error but to call again with more data when - * it comes to complete the parsing. Successful parsing completes with a - * 0 or positive integer indicating how much of the last input buffer was - * unused. - */ - -int -lejp_parse(struct lejp_ctx *ctx, const unsigned char *json, int len) -{ - unsigned char c, n, s, ret = LEJP_REJECT_UNKNOWN; - static const char esc_char[] = "\"\\/bfnrt"; - static const char esc_tran[] = "\"\\/\b\f\n\r\t"; - static const char tokens[] = "rue alse ull "; - - if (!ctx->sp && !ctx->ppos) - ctx->callback(ctx, LEJPCB_START); - - while (len--) { - c = *json++; - s = ctx->st[ctx->sp].s; - - /* skip whitespace unless we should care */ - if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '#') { - if (c == '\n') { - ctx->line++; - ctx->st[ctx->sp].s &= ~LEJP_FLAG_WS_COMMENTLINE; - } - if (!(s & LEJP_FLAG_WS_KEEP)) { - if (c == '#') - ctx->st[ctx->sp].s |= - LEJP_FLAG_WS_COMMENTLINE; - continue; - } - } - - if (ctx->st[ctx->sp].s & LEJP_FLAG_WS_COMMENTLINE) - continue; - - switch (s) { - case LEJP_IDLE: - if (c != '{') { - ret = LEJP_REJECT_IDLE_NO_BRACE; - goto reject; - } - if (ctx->callback(ctx, LEJPCB_OBJECT_START)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - ctx->st[ctx->sp].s = LEJP_MEMBERS; - break; - case LEJP_MEMBERS: - if (c == '}') { - ctx->st[ctx->sp].s = LEJP_IDLE; - ret = LEJP_REJECT_MEMBERS_NO_CLOSE; - goto reject; - } - ctx->st[ctx->sp].s = LEJP_M_P; - goto redo_character; - case LEJP_M_P: - if (c != '\"') { - ret = LEJP_REJECT_MP_NO_OPEN_QUOTE; - goto reject; - } - /* push */ - ctx->st[ctx->sp].s = LEJP_MP_DELIM; - c = LEJP_MP_STRING; - goto add_stack_level; - - case LEJP_MP_STRING: - if (c == '\"') { - if (!ctx->sp) { /* JSON can't end on quote */ - ret = LEJP_REJECT_MP_STRING_UNDERRUN; - goto reject; - } - if (ctx->st[ctx->sp - 1].s != LEJP_MP_DELIM) { - ctx->buf[ctx->npos] = '\0'; - if (ctx->callback(ctx, - LEJPCB_VAL_STR_END) < 0) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - } - /* pop */ - ctx->sp--; - break; - } - if (c == '\\') { - ctx->st[ctx->sp].s = LEJP_MP_STRING_ESC; - break; - } - if (c < ' ') {/* "control characters" not allowed */ - ret = LEJP_REJECT_MP_ILLEGAL_CTRL; - goto reject; - } - goto emit_string_char; - - case LEJP_MP_STRING_ESC: - if (c == 'u') { - ctx->st[ctx->sp].s = LEJP_MP_STRING_ESC_U1; - ctx->uni = 0; - break; - } - for (n = 0; n < sizeof(esc_char); n++) { - if (c != esc_char[n]) - continue; - /* found it */ - c = esc_tran[n]; - ctx->st[ctx->sp].s = LEJP_MP_STRING; - goto emit_string_char; - } - ret = LEJP_REJECT_MP_STRING_ESC_ILLEGAL_ESC; - /* illegal escape char */ - goto reject; - - case LEJP_MP_STRING_ESC_U1: - case LEJP_MP_STRING_ESC_U2: - case LEJP_MP_STRING_ESC_U3: - case LEJP_MP_STRING_ESC_U4: - ctx->uni <<= 4; - if (c >= '0' && c <= '9') - ctx->uni |= c - '0'; - else - if (c >= 'a' && c <= 'f') - ctx->uni = c - 'a' + 10; - else - if (c >= 'A' && c <= 'F') - ctx->uni = c - 'A' + 10; - else { - ret = LEJP_REJECT_ILLEGAL_HEX; - goto reject; - } - ctx->st[ctx->sp].s++; - switch (s) { - case LEJP_MP_STRING_ESC_U2: - if (ctx->uni < 0x08) - break; - /* - * 0x08-0xff (0x0800 - 0xffff) - * emit 3-byte UTF-8 - */ - c = 0xe0 | ((ctx->uni >> 4) & 0xf); - goto emit_string_char; - - case LEJP_MP_STRING_ESC_U3: - if (ctx->uni >= 0x080) { - /* - * 0x080 - 0xfff (0x0800 - 0xffff) - * middle 3-byte seq - * send ....XXXXXX.. - */ - c = 0x80 | ((ctx->uni >> 2) & 0x3f); - goto emit_string_char; - } - if (ctx->uni < 0x008) - break; - /* - * 0x008 - 0x7f (0x0080 - 0x07ff) - * start 2-byte seq - */ - c = 0xc0 | (ctx->uni >> 2); - goto emit_string_char; - - case LEJP_MP_STRING_ESC_U4: - if (ctx->uni >= 0x0080) - /* end of 2 or 3-byte seq */ - c = 0x80 | (ctx->uni & 0x3f); - else - /* literal */ - c = (unsigned char)ctx->uni; - - ctx->st[ctx->sp].s = LEJP_MP_STRING; - goto emit_string_char; - default: - break; - } - break; - - case LEJP_MP_DELIM: - if (c != ':') { - ret = LEJP_REJECT_MP_DELIM_MISSING_COLON; - goto reject; - } - ctx->st[ctx->sp].s = LEJP_MP_VALUE; - ctx->path[ctx->ppos] = '\0'; - - lejp_check_path_match(ctx); - if (ctx->callback(ctx, LEJPCB_PAIR_NAME)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - break; - - case LEJP_MP_VALUE: - if (c >= '0' && c <= '9') { - ctx->npos = 0; - ctx->dcount = 0; - ctx->f = 0; - ctx->st[ctx->sp].s = LEJP_MP_VALUE_NUM_INT; - goto redo_character; - } - switch (c) { - case'\"': - /* push */ - ctx->st[ctx->sp].s = LEJP_MP_COMMA_OR_END; - c = LEJP_MP_STRING; - ctx->npos = 0; - ctx->buf[0] = '\0'; - if (ctx->callback(ctx, LEJPCB_VAL_STR_START)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - goto add_stack_level; - - case '{': - /* push */ - ctx->st[ctx->sp].s = LEJP_MP_COMMA_OR_END; - c = LEJP_MEMBERS; - lejp_check_path_match(ctx); - if (ctx->callback(ctx, LEJPCB_OBJECT_START)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - ctx->path_match = 0; - goto add_stack_level; - - case '[': - /* push */ - ctx->st[ctx->sp].s = LEJP_MP_ARRAY_END; - c = LEJP_MP_VALUE; - ctx->path[ctx->ppos++] = '['; - ctx->path[ctx->ppos++] = ']'; - ctx->path[ctx->ppos] = '\0'; - if (ctx->callback(ctx, LEJPCB_ARRAY_START)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - ctx->i[ctx->ipos++] = 0; - if (ctx->ipos > LWS_ARRAY_SIZE(ctx->i)) { - ret = LEJP_REJECT_MP_DELIM_ISTACK; - goto reject; - } - goto add_stack_level; - - case ']': - /* pop */ - if (!ctx->sp) { /* JSON can't end on ] */ - ret = LEJP_REJECT_MP_C_OR_E_UNDERF; - goto reject; - } - ctx->sp--; - if (ctx->st[ctx->sp].s != LEJP_MP_ARRAY_END) { - ret = LEJP_REJECT_MP_C_OR_E_NOTARRAY; - goto reject; - } - /* drop the path [n] bit */ - if (ctx->sp) { - ctx->ppos = ctx->st[ctx->sp - 1].p; - ctx->ipos = ctx->st[ctx->sp - 1].i; - } - ctx->path[ctx->ppos] = '\0'; - if (ctx->path_match && - ctx->ppos <= ctx->path_match_len) - /* - * we shrank the path to be - * smaller than the matching point - */ - ctx->path_match = 0; - goto array_end; - - case 't': /* true */ - ctx->uni = 0; - ctx->st[ctx->sp].s = LEJP_MP_VALUE_TOK; - break; - - case 'f': - ctx->uni = 4; - ctx->st[ctx->sp].s = LEJP_MP_VALUE_TOK; - break; - - case 'n': - ctx->uni = 4 + 5; - ctx->st[ctx->sp].s = LEJP_MP_VALUE_TOK; - break; - default: - ret = LEJP_REJECT_MP_DELIM_BAD_VALUE_START; - goto reject; - } - break; - - case LEJP_MP_VALUE_NUM_INT: - if (!ctx->npos && c == '-') { - ctx->f |= LEJP_SEEN_MINUS; - goto append_npos; - } - - if (ctx->dcount < 10 && c >= '0' && c <= '9') { - if (ctx->f & LEJP_SEEN_POINT) - ctx->f |= LEJP_SEEN_POST_POINT; - ctx->dcount++; - goto append_npos; - } - if (c == '.') { - if (!ctx->dcount || (ctx->f & LEJP_SEEN_POINT)) { - ret = LEJP_REJECT_MP_VAL_NUM_FORMAT; - goto reject; - } - ctx->f |= LEJP_SEEN_POINT; - goto append_npos; - } - /* - * before exponent, if we had . we must have had at - * least one more digit - */ - if ((ctx->f & - (LEJP_SEEN_POINT | LEJP_SEEN_POST_POINT)) == - LEJP_SEEN_POINT) { - ret = LEJP_REJECT_MP_VAL_NUM_INT_NO_FRAC; - goto reject; - } - if (c == 'e' || c == 'E') { - if (ctx->f & LEJP_SEEN_EXP) { - ret = LEJP_REJECT_MP_VAL_NUM_FORMAT; - goto reject; - } - ctx->f |= LEJP_SEEN_EXP; - ctx->st[ctx->sp].s = LEJP_MP_VALUE_NUM_EXP; - goto append_npos; - } - /* if none of the above, did we even have a number? */ - if (!ctx->dcount) { - ret = LEJP_REJECT_MP_VAL_NUM_FORMAT; - goto reject; - } - - ctx->buf[ctx->npos] = '\0'; - if (ctx->f & LEJP_SEEN_POINT) { - if (ctx->callback(ctx, LEJPCB_VAL_NUM_FLOAT)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - } else { - if (ctx->callback(ctx, LEJPCB_VAL_NUM_INT)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - } - - /* then this is the post-number character, loop */ - ctx->st[ctx->sp].s = LEJP_MP_COMMA_OR_END; - goto redo_character; - - case LEJP_MP_VALUE_NUM_EXP: - ctx->st[ctx->sp].s = LEJP_MP_VALUE_NUM_INT; - if (c >= '0' && c <= '9') - goto redo_character; - if (c == '+' || c == '-') - goto append_npos; - ret = LEJP_REJECT_MP_VAL_NUM_EXP_BAD_EXP; - goto reject; - - case LEJP_MP_VALUE_TOK: /* true, false, null */ - if (c != tokens[ctx->uni]) { - ret = LEJP_REJECT_MP_VAL_TOK_UNKNOWN; - goto reject; - } - ctx->uni++; - if (tokens[ctx->uni] != ' ') - break; - switch (ctx->uni) { - case 3: - ctx->buf[0] = '1'; - ctx->buf[1] = '\0'; - if (ctx->callback(ctx, LEJPCB_VAL_TRUE)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - break; - case 8: - ctx->buf[0] = '0'; - ctx->buf[1] = '\0'; - if (ctx->callback(ctx, LEJPCB_VAL_FALSE)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - break; - case 12: - ctx->buf[0] = '\0'; - if (ctx->callback(ctx, LEJPCB_VAL_NULL)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - break; - } - ctx->st[ctx->sp].s = LEJP_MP_COMMA_OR_END; - break; - - case LEJP_MP_COMMA_OR_END: - ctx->path[ctx->ppos] = '\0'; - if (c == ',') { - /* increment this stack level's index */ - ctx->st[ctx->sp].s = LEJP_M_P; - if (!ctx->sp) { - ctx->ppos = 0; - /* - * since we came back to root level, - * no path can still match - */ - ctx->path_match = 0; - break; - } - ctx->ppos = ctx->st[ctx->sp - 1].p; - ctx->path[ctx->ppos] = '\0'; - if (ctx->path_match && - ctx->ppos <= ctx->path_match_len) - /* - * we shrank the path to be - * smaller than the matching point - */ - ctx->path_match = 0; - - if (ctx->st[ctx->sp - 1].s != LEJP_MP_ARRAY_END) - break; - /* top level is definitely an array... */ - if (ctx->ipos) - ctx->i[ctx->ipos - 1]++; - ctx->st[ctx->sp].s = LEJP_MP_VALUE; - break; - } - if (c == ']') { - if (!ctx->sp) { /* JSON can't end on ] */ - ret = LEJP_REJECT_MP_C_OR_E_UNDERF; - goto reject; - } - /* pop */ - ctx->sp--; - if (ctx->st[ctx->sp].s != LEJP_MP_ARRAY_END) { - ret = LEJP_REJECT_MP_C_OR_E_NOTARRAY; - goto reject; - } - /* drop the path [n] bit */ - if (ctx->sp) { - ctx->ppos = ctx->st[ctx->sp - 1].p; - ctx->ipos = ctx->st[ctx->sp - 1].i; - } - ctx->path[ctx->ppos] = '\0'; - if (ctx->path_match && - ctx->ppos <= ctx->path_match_len) - /* - * we shrank the path to be - * smaller than the matching point - */ - ctx->path_match = 0; - - /* do LEJP_MP_ARRAY_END processing */ - goto redo_character; - } - if (c == '}') { - if (!ctx->sp) { - lejp_check_path_match(ctx); - if (ctx->callback(ctx, LEJPCB_OBJECT_END)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - ctx->callback(ctx, LEJPCB_COMPLETE); - /* done, return unused amount */ - return len; - } - /* pop */ - ctx->sp--; - if (ctx->sp) { - ctx->ppos = ctx->st[ctx->sp - 1].p; - ctx->ipos = ctx->st[ctx->sp - 1].i; - } - ctx->path[ctx->ppos] = '\0'; - if (ctx->path_match && - ctx->ppos <= ctx->path_match_len) - /* - * we shrank the path to be - * smaller than the matching point - */ - ctx->path_match = 0; - lejp_check_path_match(ctx); - if (ctx->callback(ctx, LEJPCB_OBJECT_END)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - break; - } - - ret = LEJP_REJECT_MP_C_OR_E_NEITHER; - goto reject; - - case LEJP_MP_ARRAY_END: -array_end: - ctx->path[ctx->ppos] = '\0'; - if (c == ',') { - /* increment this stack level's index */ - if (ctx->ipos) - ctx->i[ctx->ipos - 1]++; - ctx->st[ctx->sp].s = LEJP_MP_VALUE; - if (ctx->sp) - ctx->ppos = ctx->st[ctx->sp - 1].p; - ctx->path[ctx->ppos] = '\0'; - break; - } - if (c != ']') { - ret = LEJP_REJECT_MP_ARRAY_END_MISSING; - goto reject; - } - - ctx->st[ctx->sp].s = LEJP_MP_COMMA_OR_END; - ctx->callback(ctx, LEJPCB_ARRAY_END); - break; - } - - continue; - -emit_string_char: - if (!ctx->sp || ctx->st[ctx->sp - 1].s != LEJP_MP_DELIM) { - /* assemble the string value into chunks */ - ctx->buf[ctx->npos++] = c; - if (ctx->npos == sizeof(ctx->buf) - 1) { - if (ctx->callback(ctx, LEJPCB_VAL_STR_CHUNK)) { - ret = LEJP_REJECT_CALLBACK; - goto reject; - } - ctx->npos = 0; - } - continue; - } - /* name part of name:value pair */ - ctx->path[ctx->ppos++] = c; - continue; - -add_stack_level: - /* push on to the object stack */ - if (ctx->ppos && ctx->st[ctx->sp].s != LEJP_MP_COMMA_OR_END && - ctx->st[ctx->sp].s != LEJP_MP_ARRAY_END) - ctx->path[ctx->ppos++] = '.'; - - ctx->st[ctx->sp].p = ctx->ppos; - ctx->st[ctx->sp].i = ctx->ipos; - if (++ctx->sp == LWS_ARRAY_SIZE(ctx->st)) { - ret = LEJP_REJECT_STACK_OVERFLOW; - goto reject; - } - ctx->path[ctx->ppos] = '\0'; - ctx->st[ctx->sp].s = c; - ctx->st[ctx->sp].b = 0; - continue; - -append_npos: - if (ctx->npos >= sizeof(ctx->buf)) { - ret = LEJP_REJECT_NUM_TOO_LONG; - goto reject; - } - ctx->buf[ctx->npos++] = c; - continue; - -redo_character: - json--; - len++; - } - - return LEJP_CONTINUE; - -reject: - ctx->callback(ctx, LEJPCB_FAILED); - return ret; -} diff --git a/thirdparty/libwebsockets/misc/sha-1.c b/thirdparty/libwebsockets/misc/sha-1.c deleted file mode 100644 index 2e4db52693..0000000000 --- a/thirdparty/libwebsockets/misc/sha-1.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. - * 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. - * 3. Neither the name of the project nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE PROJECT 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 PROJECT 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. - */ -/* - * FIPS pub 180-1: Secure Hash Algorithm (SHA-1) - * based on: http://csrc.nist.gov/fips/fip180-1.txt - * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org> - */ - -#include "core/private.h" - -#ifdef LWS_HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif - -struct sha1_ctxt { - union { - unsigned char b8[20]; - unsigned int b32[5]; - } h; - union { - unsigned char b8[8]; - uint64_t b64[1]; - } c; - union { - unsigned char b8[64]; - unsigned int b32[16]; - } m; - unsigned char count; -}; - -/* sanity check */ -#if !defined(BYTE_ORDER) || !defined(LITTLE_ENDIAN) || !defined(BIG_ENDIAN) -# define unsupported 1 -#elif BYTE_ORDER != BIG_ENDIAN -# if BYTE_ORDER != LITTLE_ENDIAN -# define unsupported 1 -# endif -#endif - -#ifndef unsupported - -/* constant table */ -static const unsigned int _K[] = - { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 }; -#define K(t) _K[(t) / 20] - -#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d))) -#define F1(b, c, d) (((b) ^ (c)) ^ (d)) -#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) -#define F3(b, c, d) (((b) ^ (c)) ^ (d)) - -#define S(n, x) (((x) << (n)) | ((x) >> (32 - n))) - -#define H(n) (ctxt->h.b32[(n)]) -#define COUNT (ctxt->count) -#define BCOUNT (ctxt->c.b64[0] / 8) -#define W(n) (ctxt->m.b32[(n)]) - -#define PUTBYTE(x) { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - ctxt->c.b64[0] += 8; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ - } - -#define PUTPAD(x) { \ - ctxt->m.b8[(COUNT % 64)] = (x); \ - COUNT++; \ - COUNT %= 64; \ - if (COUNT % 64 == 0) \ - sha1_step(ctxt); \ - } - - -static void -sha1_step(struct sha1_ctxt *ctxt) -{ - unsigned int a, b, c, d, e, tmp; - size_t t, s; - -#if BYTE_ORDER == LITTLE_ENDIAN - struct sha1_ctxt tctxt; - - memcpy(&tctxt.m.b8[0], &ctxt->m.b8[0], 64); - ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2]; - ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0]; - ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6]; - ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4]; - ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10]; - ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8]; - ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14]; - ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12]; - ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18]; - ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16]; - ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22]; - ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20]; - ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26]; - ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24]; - ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30]; - ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28]; - ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34]; - ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32]; - ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38]; - ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36]; - ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42]; - ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40]; - ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46]; - ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44]; - ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50]; - ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48]; - ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54]; - ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52]; - ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58]; - ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56]; - ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62]; - ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60]; -#endif - - a = H(0); b = H(1); c = H(2); d = H(3); e = H(4); - - for (t = 0; t < 20; t++) { - s = t & 0x0f; - if (t >= 16) - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - - tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 20; t < 40; t++) { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 40; t < 60; t++) { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - for (t = 60; t < 80; t++) { - s = t & 0x0f; - W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ - W((s+2) & 0x0f) ^ W(s)); - tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t); - e = d; d = c; c = S(30, b); b = a; a = tmp; - } - - H(0) = H(0) + a; - H(1) = H(1) + b; - H(2) = H(2) + c; - H(3) = H(3) + d; - H(4) = H(4) + e; - - bzero(&ctxt->m.b8[0], 64); -} - -/*------------------------------------------------------------*/ - -static void -_sha1_init(struct sha1_ctxt *ctxt) -{ - bzero(ctxt, sizeof(struct sha1_ctxt)); - H(0) = 0x67452301; - H(1) = 0xefcdab89; - H(2) = 0x98badcfe; - H(3) = 0x10325476; - H(4) = 0xc3d2e1f0; -} - -void -sha1_pad(struct sha1_ctxt *ctxt) -{ - size_t padlen; /*pad length in bytes*/ - size_t padstart; - - PUTPAD(0x80); - - padstart = COUNT % 64; - padlen = 64 - padstart; - if (padlen < 8) { - bzero(&ctxt->m.b8[padstart], padlen); - COUNT += (unsigned char)padlen; - COUNT %= 64; - sha1_step(ctxt); - padstart = COUNT % 64; /* should be 0 */ - padlen = 64 - padstart; /* should be 64 */ - } - bzero(&ctxt->m.b8[padstart], padlen - 8); - COUNT += ((unsigned char)padlen - 8); - COUNT %= 64; -#if BYTE_ORDER == BIG_ENDIAN - PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]); - PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]); - PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]); - PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]); -#else - PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]); - PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]); - PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]); - PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]); -#endif -} - -void -sha1_loop(struct sha1_ctxt *ctxt, const unsigned char *input, size_t len) -{ - size_t gaplen; - size_t gapstart; - size_t off; - size_t copysiz; - - off = 0; - - while (off < len) { - gapstart = COUNT % 64; - gaplen = 64 - gapstart; - - copysiz = (gaplen < len - off) ? gaplen : len - off; - memcpy(&ctxt->m.b8[gapstart], &input[off], copysiz); - COUNT += (unsigned char)copysiz; - COUNT %= 64; - ctxt->c.b64[0] += copysiz * 8; - if (COUNT % 64 == 0) - sha1_step(ctxt); - off += copysiz; - } -} - -void -sha1_result(struct sha1_ctxt *ctxt, void *digest0) -{ - unsigned char *digest; - - digest = (unsigned char *)digest0; - sha1_pad(ctxt); -#if BYTE_ORDER == BIG_ENDIAN - memcpy(digest, &ctxt->h.b8[0], 20); -#else - digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2]; - digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0]; - digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6]; - digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4]; - digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10]; - digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8]; - digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14]; - digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12]; - digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18]; - digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16]; -#endif -} - -/* - * This should look and work like the libcrypto implementation - */ - -LWS_VISIBLE unsigned char * -lws_SHA1(const unsigned char *d, size_t n, unsigned char *md) -{ - struct sha1_ctxt ctx; - - _sha1_init(&ctx); - sha1_loop(&ctx, d, n); - sha1_result(&ctx, (void *)md); - - return md; -} - -#endif /*unsupported*/ diff --git a/thirdparty/libwebsockets/plat/lws-plat-unix.c b/thirdparty/libwebsockets/plat/lws-plat-unix.c deleted file mode 100644 index d1bca8b5df..0000000000 --- a/thirdparty/libwebsockets/plat/lws-plat-unix.c +++ /dev/null @@ -1,982 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#define _GNU_SOURCE -#include "core/private.h" - -#include <pwd.h> -#include <grp.h> - -#ifdef LWS_WITH_PLUGINS -#include <dlfcn.h> -#endif -#include <dirent.h> - -void lws_plat_apply_FD_CLOEXEC(int n) -{ - if (n != -1) - fcntl(n, F_SETFD, FD_CLOEXEC ); -} - -int -lws_plat_socket_offset(void) -{ - return 0; -} - -int -lws_plat_pipe_create(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - -#if defined(LWS_HAVE_PIPE2) - return pipe2(pt->dummy_pipe_fds, O_NONBLOCK); -#else - return pipe(pt->dummy_pipe_fds); -#endif -} - -int -lws_plat_pipe_signal(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - char buf = 0; - int n; - - n = write(pt->dummy_pipe_fds[1], &buf, 1); - - return n != 1; -} - -void -lws_plat_pipe_close(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - - if (pt->dummy_pipe_fds[0] && pt->dummy_pipe_fds[0] != -1) - close(pt->dummy_pipe_fds[0]); - if (pt->dummy_pipe_fds[1] && pt->dummy_pipe_fds[1] != -1) - close(pt->dummy_pipe_fds[1]); - - pt->dummy_pipe_fds[0] = pt->dummy_pipe_fds[1] = -1; -} - -#ifdef __QNX__ -# include "netinet/tcp_var.h" -# define TCP_KEEPINTVL TCPCTL_KEEPINTVL -# define TCP_KEEPIDLE TCPCTL_KEEPIDLE -# define TCP_KEEPCNT TCPCTL_KEEPCNT -#endif - -unsigned long long time_in_microseconds(void) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - return ((unsigned long long)tv.tv_sec * 1000000LL) + tv.tv_usec; -} - -LWS_VISIBLE int -lws_get_random(struct lws_context *context, void *buf, int len) -{ - return read(context->fd_random, (char *)buf, len); -} - -LWS_VISIBLE int -lws_send_pipe_choked(struct lws *wsi) -{ - struct lws_pollfd fds; - struct lws *wsi_eff = wsi; - -#if defined(LWS_WITH_HTTP2) - wsi_eff = lws_get_network_wsi(wsi); -#endif - - /* the fact we checked implies we avoided back-to-back writes */ - wsi_eff->could_have_pending = 0; - - /* treat the fact we got a truncated send pending as if we're choked */ - if (wsi_eff->trunc_len) - return 1; - - fds.fd = wsi_eff->desc.sockfd; - fds.events = POLLOUT; - fds.revents = 0; - - if (poll(&fds, 1, 0) != 1) - return 1; - - if ((fds.revents & POLLOUT) == 0) - return 1; - - /* okay to send another packet without blocking */ - - return 0; -} - -LWS_VISIBLE int -lws_poll_listen_fd(struct lws_pollfd *fd) -{ - return poll(fd, 1, 0); -} - -LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line) -{ - int syslog_level = LOG_DEBUG; - - switch (level) { - case LLL_ERR: - syslog_level = LOG_ERR; - break; - case LLL_WARN: - syslog_level = LOG_WARNING; - break; - case LLL_NOTICE: - syslog_level = LOG_NOTICE; - break; - case LLL_INFO: - syslog_level = LOG_INFO; - break; - } - syslog(syslog_level, "%s", line); -} - -LWS_VISIBLE LWS_EXTERN int -_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) -{ - volatile struct lws_foreign_thread_pollfd *ftp, *next; - volatile struct lws_context_per_thread *vpt; - struct lws_context_per_thread *pt; - int n = -1, m, c; - - /* stay dead once we are dead */ - - if (!context || !context->vhost_list) - return 1; - - pt = &context->pt[tsi]; - vpt = (volatile struct lws_context_per_thread *)pt; - - lws_stats_atomic_bump(context, pt, LWSSTATS_C_SERVICE_ENTRY, 1); - - if (timeout_ms < 0) - goto faked_service; - - if (context->event_loop_ops->run_pt) - context->event_loop_ops->run_pt(context, tsi); - - if (!context->service_tid_detected) { - struct lws _lws; - - memset(&_lws, 0, sizeof(_lws)); - _lws.context = context; - - context->service_tid_detected = - context->vhost_list->protocols[0].callback( - &_lws, LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); - context->service_tid = context->service_tid_detected; - context->service_tid_detected = 1; - } - - /* - * is there anybody with pending stuff that needs service forcing? - */ - if (!lws_service_adjust_timeout(context, 1, tsi)) { - /* -1 timeout means just do forced service */ - _lws_plat_service_tsi(context, -1, pt->tid); - /* still somebody left who wants forced service? */ - if (!lws_service_adjust_timeout(context, 1, pt->tid)) - /* yes... come back again quickly */ - timeout_ms = 0; - } - - if (timeout_ms) { - lws_pt_lock(pt, __func__); - /* don't stay in poll wait longer than next hr timeout */ - lws_usec_t t = __lws_hrtimer_service(pt); - if ((lws_usec_t)timeout_ms * 1000 > t) - timeout_ms = t / 1000; - lws_pt_unlock(pt); - } - - vpt->inside_poll = 1; - lws_memory_barrier(); - n = poll(pt->fds, pt->fds_count, timeout_ms); - vpt->inside_poll = 0; - lws_memory_barrier(); - - /* Collision will be rare and brief. Just spin until it completes */ - while (vpt->foreign_spinlock) - ; - - /* - * At this point we are not inside a foreign thread pollfd change, - * and we have marked ourselves as outside the poll() wait. So we - * are the only guys that can modify the lws_foreign_thread_pollfd - * list on the pt. Drain the list and apply the changes to the - * affected pollfds in the correct order. - */ - - lws_pt_lock(pt, __func__); - - ftp = vpt->foreign_pfd_list; - //lwsl_notice("cleared list %p\n", ftp); - while (ftp) { - struct lws *wsi; - struct lws_pollfd *pfd; - - next = ftp->next; - pfd = &vpt->fds[ftp->fd_index]; - if (lws_socket_is_valid(pfd->fd)) { - wsi = wsi_from_fd(context, pfd->fd); - if (wsi) - __lws_change_pollfd(wsi, ftp->_and, ftp->_or); - } - lws_free((void *)ftp); - ftp = next; - } - vpt->foreign_pfd_list = NULL; - lws_memory_barrier(); - - /* we have come out of a poll wait... check the hrtimer list */ - - __lws_hrtimer_service(pt); - - lws_pt_unlock(pt); - - m = 0; -#if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS) - m |= !!pt->ws.rx_draining_ext_list; -#endif - - if (pt->context->tls_ops && - pt->context->tls_ops->fake_POLLIN_for_buffered) - m |= pt->context->tls_ops->fake_POLLIN_for_buffered(pt); - - if (!m && !n) { /* nothing to do */ - lws_service_fd_tsi(context, NULL, tsi); - lws_service_do_ripe_rxflow(pt); - - return 0; - } - -faked_service: - m = lws_service_flag_pending(context, tsi); - if (m) - c = -1; /* unknown limit */ - else - if (n < 0) { - if (LWS_ERRNO != LWS_EINTR) - return -1; - return 0; - } else - c = n; - - /* any socket with events to service? */ - for (n = 0; n < (int)pt->fds_count && c; n++) { - if (!pt->fds[n].revents) - continue; - - c--; - - m = lws_service_fd_tsi(context, &pt->fds[n], tsi); - if (m < 0) - return -1; - /* if something closed, retry this slot */ - if (m) - n--; - } - - lws_service_do_ripe_rxflow(pt); - - return 0; -} - -LWS_VISIBLE int -lws_plat_check_connection_error(struct lws *wsi) -{ - return 0; -} - -LWS_VISIBLE int -lws_plat_service(struct lws_context *context, int timeout_ms) -{ - return _lws_plat_service_tsi(context, timeout_ms, 0); -} - -LWS_VISIBLE int -lws_plat_set_socket_options(struct lws_vhost *vhost, int fd) -{ - int optval = 1; - socklen_t optlen = sizeof(optval); - -#ifdef LWS_WITH_IPV6 - optval = 0; - setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&optval, optlen); -#endif - -#if defined(__APPLE__) || \ - defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \ - defined(__NetBSD__) || \ - defined(__OpenBSD__) || \ - defined(__HAIKU__) - struct protoent *tcp_proto; -#endif - - fcntl(fd, F_SETFD, FD_CLOEXEC); - - if (vhost->ka_time) { - /* enable keepalive on this socket */ - optval = 1; - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, - (const void *)&optval, optlen) < 0) - return 1; - -#if defined(__APPLE__) || \ - defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || \ - defined(__NetBSD__) || \ - defined(__CYGWIN__) || defined(__OpenBSD__) || defined (__sun) || \ - defined(__HAIKU__) - - /* - * didn't find a way to set these per-socket, need to - * tune kernel systemwide values - */ -#else - /* set the keepalive conditions we want on it too */ - -#if defined(LWS_HAVE_TCP_USER_TIMEOUT) - optval = 1000 * (vhost->ka_time + - (vhost->ka_interval * vhost->ka_probes)); - if (setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT, - (const void *)&optval, optlen) < 0) - return 1; -#endif - optval = vhost->ka_time; - if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, - (const void *)&optval, optlen) < 0) - return 1; - - optval = vhost->ka_interval; - if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, - (const void *)&optval, optlen) < 0) - return 1; - - optval = vhost->ka_probes; - if (setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, - (const void *)&optval, optlen) < 0) - return 1; -#endif - } - -#if defined(SO_BINDTODEVICE) - if (vhost->bind_iface && vhost->iface) { - lwsl_info("binding listen skt to %s using SO_BINDTODEVICE\n", vhost->iface); - if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, vhost->iface, - strlen(vhost->iface)) < 0) { - lwsl_warn("Failed to bind to device %s\n", vhost->iface); - return 1; - } - } -#endif - - /* Disable Nagle */ - optval = 1; -#if defined (__sun) || defined(__QNX__) - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void *)&optval, optlen) < 0) - return 1; -#elif !defined(__APPLE__) && \ - !defined(__FreeBSD__) && !defined(__FreeBSD_kernel__) && \ - !defined(__NetBSD__) && \ - !defined(__OpenBSD__) && \ - !defined(__HAIKU__) - if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (const void *)&optval, optlen) < 0) - return 1; -#else - tcp_proto = getprotobyname("TCP"); - if (setsockopt(fd, tcp_proto->p_proto, TCP_NODELAY, &optval, optlen) < 0) - return 1; -#endif - - /* We are nonblocking... */ - if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) - return 1; - - return 0; -} - -#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) -static void -_lws_plat_apply_caps(int mode, const cap_value_t *cv, int count) -{ - cap_t caps; - - if (!count) - return; - - caps = cap_get_proc(); - - cap_set_flag(caps, mode, count, cv, CAP_SET); - cap_set_proc(caps); - prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); - cap_free(caps); -} -#endif - -LWS_VISIBLE void -lws_plat_drop_app_privileges(const struct lws_context_creation_info *info) -{ -#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) - int n; -#endif - - if (info->gid && info->gid != -1) - if (setgid(info->gid)) - lwsl_warn("setgid: %s\n", strerror(LWS_ERRNO)); - - if (info->uid && info->uid != -1) { - struct passwd *p = getpwuid(info->uid); - - if (p) { - -#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) - _lws_plat_apply_caps(CAP_PERMITTED, info->caps, info->count_caps); -#endif - - initgroups(p->pw_name, info->gid); - if (setuid(info->uid)) - lwsl_warn("setuid: %s\n", strerror(LWS_ERRNO)); - else - lwsl_notice("Set privs to user '%s'\n", p->pw_name); - -#if defined(LWS_HAVE_SYS_CAPABILITY_H) && defined(LWS_HAVE_LIBCAP) - _lws_plat_apply_caps(CAP_EFFECTIVE, info->caps, info->count_caps); - - if (info->count_caps) - for (n = 0; n < info->count_caps; n++) - lwsl_notice(" RETAINING CAPABILITY %d\n", (int)info->caps[n]); -#endif - - } else - lwsl_warn("getpwuid: unable to find uid %d", info->uid); - } -} - -#ifdef LWS_WITH_PLUGINS - -#if defined(LWS_WITH_LIBUV) && UV_VERSION_MAJOR > 0 - -/* libuv.c implements these in a cross-platform way */ - -#else - -static int filter(const struct dirent *ent) -{ - if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) - return 0; - - return 1; -} - -LWS_VISIBLE int -lws_plat_plugins_init(struct lws_context * context, const char * const *d) -{ - struct lws_plugin_capability lcaps; - struct lws_plugin *plugin; - lws_plugin_init_func initfunc; - struct dirent **namelist; - int n, i, m, ret = 0; - char path[256]; - void *l; - - lwsl_notice(" Plugins:\n"); - - while (d && *d) { - n = scandir(*d, &namelist, filter, alphasort); - if (n < 0) { - lwsl_err("Scandir on %s failed\n", *d); - return 1; - } - - for (i = 0; i < n; i++) { - if (strlen(namelist[i]->d_name) < 7) - goto inval; - - lwsl_notice(" %s\n", namelist[i]->d_name); - - lws_snprintf(path, sizeof(path) - 1, "%s/%s", *d, - namelist[i]->d_name); - l = dlopen(path, RTLD_NOW); - if (!l) { - lwsl_err("Error loading DSO: %s\n", dlerror()); - while (i++ < n) - free(namelist[i]); - goto bail; - } - /* we could open it, can we get his init function? */ - m = lws_snprintf(path, sizeof(path) - 1, "init_%s", - namelist[i]->d_name + 3 /* snip lib... */); - path[m - 3] = '\0'; /* snip the .so */ - initfunc = dlsym(l, path); - if (!initfunc) { - lwsl_err("Failed to get init on %s: %s", - namelist[i]->d_name, dlerror()); - dlclose(l); - } - lcaps.api_magic = LWS_PLUGIN_API_MAGIC; - m = initfunc(context, &lcaps); - if (m) { - lwsl_err("Initializing %s failed %d\n", - namelist[i]->d_name, m); - dlclose(l); - goto skip; - } - - plugin = lws_malloc(sizeof(*plugin), "plugin"); - if (!plugin) { - lwsl_err("OOM\n"); - goto bail; - } - plugin->list = context->plugin_list; - context->plugin_list = plugin; - lws_strncpy(plugin->name, namelist[i]->d_name, - sizeof(plugin->name)); - plugin->l = l; - plugin->caps = lcaps; - context->plugin_protocol_count += lcaps.count_protocols; - context->plugin_extension_count += lcaps.count_extensions; - - free(namelist[i]); - continue; - - skip: - dlclose(l); - inval: - free(namelist[i]); - } - free(namelist); - d++; - } - -bail: - free(namelist); - - return ret; -} - -LWS_VISIBLE int -lws_plat_plugins_destroy(struct lws_context * context) -{ - struct lws_plugin *plugin = context->plugin_list, *p; - lws_plugin_destroy_func func; - char path[256]; - int m; - - if (!plugin) - return 0; - - lwsl_notice("%s\n", __func__); - - while (plugin) { - p = plugin; - m = lws_snprintf(path, sizeof(path) - 1, "destroy_%s", plugin->name + 3); - path[m - 3] = '\0'; - func = dlsym(plugin->l, path); - if (!func) { - lwsl_err("Failed to get destroy on %s: %s", - plugin->name, dlerror()); - goto next; - } - m = func(context); - if (m) - lwsl_err("Initializing %s failed %d\n", - plugin->name, m); -next: - dlclose(p->l); - plugin = p->list; - p->list = NULL; - free(p); - } - - context->plugin_list = NULL; - - return 0; -} - -#endif -#endif - - -#if 0 -static void -sigabrt_handler(int x) -{ - printf("%s\n", __func__); -} -#endif - -LWS_VISIBLE int -lws_plat_context_early_init(void) -{ -#if !defined(LWS_AVOID_SIGPIPE_IGN) - signal(SIGPIPE, SIG_IGN); -#endif - - return 0; -} - -LWS_VISIBLE void -lws_plat_context_early_destroy(struct lws_context *context) -{ -} - -LWS_VISIBLE void -lws_plat_context_late_destroy(struct lws_context *context) -{ -#ifdef LWS_WITH_PLUGINS - if (context->plugin_list) - lws_plat_plugins_destroy(context); -#endif - - if (context->lws_lookup) - lws_free(context->lws_lookup); - - if (!context->fd_random) - lwsl_err("ZERO RANDOM FD\n"); - if (context->fd_random != LWS_INVALID_FILE) - close(context->fd_random); -} - -/* cast a struct sockaddr_in6 * into addr for ipv6 */ - -LWS_VISIBLE int -lws_interface_to_sa(int ipv6, const char *ifname, struct sockaddr_in *addr, - size_t addrlen) -{ - int rc = LWS_ITOSA_NOT_EXIST; - - struct ifaddrs *ifr; - struct ifaddrs *ifc; -#ifdef LWS_WITH_IPV6 - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; -#endif - - getifaddrs(&ifr); - for (ifc = ifr; ifc != NULL && rc; ifc = ifc->ifa_next) { - if (!ifc->ifa_addr) - continue; - - lwsl_debug(" interface %s vs %s (fam %d) ipv6 %d\n", ifc->ifa_name, ifname, ifc->ifa_addr->sa_family, ipv6); - - if (strcmp(ifc->ifa_name, ifname)) - continue; - - switch (ifc->ifa_addr->sa_family) { -#if defined(AF_PACKET) - case AF_PACKET: - /* interface exists but is not usable */ - rc = LWS_ITOSA_NOT_USABLE; - continue; -#endif - - case AF_INET: -#ifdef LWS_WITH_IPV6 - if (ipv6) { - /* map IPv4 to IPv6 */ - bzero((char *)&addr6->sin6_addr, - sizeof(struct in6_addr)); - addr6->sin6_addr.s6_addr[10] = 0xff; - addr6->sin6_addr.s6_addr[11] = 0xff; - memcpy(&addr6->sin6_addr.s6_addr[12], - &((struct sockaddr_in *)ifc->ifa_addr)->sin_addr, - sizeof(struct in_addr)); - } else -#endif - memcpy(addr, - (struct sockaddr_in *)ifc->ifa_addr, - sizeof(struct sockaddr_in)); - break; -#ifdef LWS_WITH_IPV6 - case AF_INET6: - memcpy(&addr6->sin6_addr, - &((struct sockaddr_in6 *)ifc->ifa_addr)->sin6_addr, - sizeof(struct in6_addr)); - break; -#endif - default: - continue; - } - rc = LWS_ITOSA_USABLE; - } - - freeifaddrs(ifr); - - if (rc) { - /* check if bind to IP address */ -#ifdef LWS_WITH_IPV6 - if (inet_pton(AF_INET6, ifname, &addr6->sin6_addr) == 1) - rc = LWS_ITOSA_USABLE; - else -#endif - if (inet_pton(AF_INET, ifname, &addr->sin_addr) == 1) - rc = LWS_ITOSA_USABLE; - } - - return rc; -} - -LWS_VISIBLE void -lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi) -{ - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - - if (context->event_loop_ops->io) - context->event_loop_ops->io(wsi, LWS_EV_START | LWS_EV_READ); - - pt->fds[pt->fds_count++].revents = 0; -} - -LWS_VISIBLE void -lws_plat_delete_socket_from_fds(struct lws_context *context, - struct lws *wsi, int m) -{ - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - - if (context->event_loop_ops->io) - context->event_loop_ops->io(wsi, - LWS_EV_STOP | LWS_EV_READ | LWS_EV_WRITE); - - pt->fds_count--; -} - -LWS_VISIBLE void -lws_plat_service_periodic(struct lws_context *context) -{ - /* if our parent went down, don't linger around */ - if (context->started_with_parent && - kill(context->started_with_parent, 0) < 0) - kill(getpid(), SIGTERM); -} - -LWS_VISIBLE int -lws_plat_change_pollfd(struct lws_context *context, - struct lws *wsi, struct lws_pollfd *pfd) -{ - return 0; -} - -LWS_VISIBLE const char * -lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt) -{ - return inet_ntop(af, src, dst, cnt); -} - -LWS_VISIBLE int -lws_plat_inet_pton(int af, const char *src, void *dst) -{ - return inet_pton(af, src, dst); -} - -LWS_VISIBLE lws_fop_fd_t -_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, - const char *vpath, lws_fop_flags_t *flags) -{ - struct stat stat_buf; - int ret = open(filename, (*flags) & LWS_FOP_FLAGS_MASK, 0664); - lws_fop_fd_t fop_fd; - - if (ret < 0) - return NULL; - - if (fstat(ret, &stat_buf) < 0) - goto bail; - - fop_fd = malloc(sizeof(*fop_fd)); - if (!fop_fd) - goto bail; - - fop_fd->fops = fops; - fop_fd->flags = *flags; - fop_fd->fd = ret; - fop_fd->filesystem_priv = NULL; /* we don't use it */ - fop_fd->len = stat_buf.st_size; - fop_fd->pos = 0; - - return fop_fd; - -bail: - close(ret); - return NULL; -} - -LWS_VISIBLE int -_lws_plat_file_close(lws_fop_fd_t *fop_fd) -{ - int fd = (*fop_fd)->fd; - - free(*fop_fd); - *fop_fd = NULL; - - return close(fd); -} - -LWS_VISIBLE lws_fileofs_t -_lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset) -{ - lws_fileofs_t r; - - if (offset > 0 && - offset > (lws_fileofs_t)fop_fd->len - (lws_fileofs_t)fop_fd->pos) - offset = fop_fd->len - fop_fd->pos; - - if ((lws_fileofs_t)fop_fd->pos + offset < 0) - offset = -fop_fd->pos; - - r = lseek(fop_fd->fd, offset, SEEK_CUR); - - if (r >= 0) - fop_fd->pos = r; - else - lwsl_err("error seeking from cur %ld, offset %ld\n", - (long)fop_fd->pos, (long)offset); - - return r; -} - -LWS_VISIBLE int -_lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, - uint8_t *buf, lws_filepos_t len) -{ - long n; - - n = read((int)fop_fd->fd, buf, len); - if (n == -1) { - *amount = 0; - return -1; - } - fop_fd->pos += n; - lwsl_debug("%s: read %ld of req %ld, pos %ld, len %ld\n", __func__, n, - (long)len, (long)fop_fd->pos, (long)fop_fd->len); - *amount = n; - - return 0; -} - -LWS_VISIBLE int -_lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, - uint8_t *buf, lws_filepos_t len) -{ - long n; - - n = write((int)fop_fd->fd, buf, len); - if (n == -1) { - *amount = 0; - return -1; - } - - fop_fd->pos += n; - *amount = n; - - return 0; -} - -LWS_VISIBLE int -lws_plat_init(struct lws_context *context, - const struct lws_context_creation_info *info) -{ - int fd; - - /* master context has the global fd lookup array */ - context->lws_lookup = lws_zalloc(sizeof(struct lws *) * - context->max_fds, "lws_lookup"); - if (context->lws_lookup == NULL) { - lwsl_err("OOM on lws_lookup array for %d connections\n", - context->max_fds); - return 1; - } - - lwsl_info(" mem: platform fd map: %5lu bytes\n", - (unsigned long)(sizeof(struct lws *) * context->max_fds)); - fd = open(SYSTEM_RANDOM_FILEPATH, O_RDONLY); - - context->fd_random = fd; - if (context->fd_random < 0) { - lwsl_err("Unable to open random device %s %d\n", - SYSTEM_RANDOM_FILEPATH, context->fd_random); - return 1; - } - -#ifdef LWS_WITH_PLUGINS - if (info->plugin_dirs) - lws_plat_plugins_init(context, info->plugin_dirs); -#endif - - return 0; -} - -LWS_VISIBLE int -lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf, - int len) -{ - int n; - - n = write(fd, buf, len); - - fsync(fd); - lseek(fd, 0, SEEK_SET); - - return n != len; -} - -LWS_VISIBLE int -lws_plat_write_file(const char *filename, void *buf, int len) -{ - int m, fd; - - fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); - - if (fd == -1) - return 1; - - m = write(fd, buf, len); - close(fd); - - return m != len; -} - -LWS_VISIBLE int -lws_plat_read_file(const char *filename, void *buf, int len) -{ - int n, fd = lws_open(filename, O_RDONLY); - if (fd == -1) - return -1; - - n = read(fd, buf, len); - close(fd); - - return n; -} - -LWS_VISIBLE int -lws_plat_recommended_rsa_bits(void) -{ - return 4096; -} diff --git a/thirdparty/libwebsockets/plat/lws-plat-win.c b/thirdparty/libwebsockets/plat/lws-plat-win.c deleted file mode 100644 index 26caab2cde..0000000000 --- a/thirdparty/libwebsockets/plat/lws-plat-win.c +++ /dev/null @@ -1,852 +0,0 @@ -#ifndef _WINSOCK_DEPRECATED_NO_WARNINGS -#define _WINSOCK_DEPRECATED_NO_WARNINGS -#endif -#include "core/private.h" - -void lws_plat_apply_FD_CLOEXEC(int n) -{ -} - -int -lws_plat_socket_offset(void) -{ - return 0; -} - -int -lws_plat_pipe_create(struct lws *wsi) -{ - return 1; -} - -int -lws_plat_pipe_signal(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - - WSASetEvent(pt->events[0]); /* trigger the cancel event */ - - return 0; -} - -void -lws_plat_pipe_close(struct lws *wsi) -{ -} - -unsigned long long -time_in_microseconds() -{ -#ifndef DELTA_EPOCH_IN_MICROSECS -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL -#endif - FILETIME filetime; - ULARGE_INTEGER datetime; - -#ifdef _WIN32_WCE - GetCurrentFT(&filetime); -#else - GetSystemTimeAsFileTime(&filetime); -#endif - - /* - * As per Windows documentation for FILETIME, copy the resulting - * FILETIME structure to a ULARGE_INTEGER structure using memcpy - * (using memcpy instead of direct assignment can prevent alignment - * faults on 64-bit Windows). - */ - memcpy(&datetime, &filetime, sizeof(datetime)); - - /* Windows file times are in 100s of nanoseconds. */ - return (datetime.QuadPart / 10) - DELTA_EPOCH_IN_MICROSECS; -} - -#ifdef _WIN32_WCE -time_t time(time_t *t) -{ - time_t ret = time_in_microseconds() / 1000000; - - if(t != NULL) - *t = ret; - - return ret; -} -#endif - -/* file descriptor hash management */ - -struct lws * -wsi_from_fd(const struct lws_context *context, lws_sockfd_type fd) -{ - int h = LWS_FD_HASH(fd); - int n = 0; - - for (n = 0; n < context->fd_hashtable[h].length; n++) - if (context->fd_hashtable[h].wsi[n]->desc.sockfd == fd) - return context->fd_hashtable[h].wsi[n]; - - return NULL; -} - -int -insert_wsi(struct lws_context *context, struct lws *wsi) -{ - int h = LWS_FD_HASH(wsi->desc.sockfd); - - if (context->fd_hashtable[h].length == (getdtablesize() - 1)) { - lwsl_err("hash table overflow\n"); - return 1; - } - - context->fd_hashtable[h].wsi[context->fd_hashtable[h].length++] = wsi; - - return 0; -} - -int -delete_from_fd(struct lws_context *context, lws_sockfd_type fd) -{ - int h = LWS_FD_HASH(fd); - int n = 0; - - for (n = 0; n < context->fd_hashtable[h].length; n++) - if (context->fd_hashtable[h].wsi[n]->desc.sockfd == fd) { - while (n < context->fd_hashtable[h].length) { - context->fd_hashtable[h].wsi[n] = - context->fd_hashtable[h].wsi[n + 1]; - n++; - } - context->fd_hashtable[h].length--; - - return 0; - } - - lwsl_err("Failed to find fd %d requested for " - "delete in hashtable\n", fd); - return 1; -} - -LWS_VISIBLE int -lws_get_random(struct lws_context *context, void *buf, int len) -{ - int n; - char *p = (char *)buf; - - for (n = 0; n < len; n++) - p[n] = (unsigned char)rand(); - - return n; -} - -LWS_VISIBLE int -lws_send_pipe_choked(struct lws *wsi) -{ struct lws *wsi_eff = wsi; - -#if defined(LWS_WITH_HTTP2) - wsi_eff = lws_get_network_wsi(wsi); -#endif - /* the fact we checked implies we avoided back-to-back writes */ - wsi_eff->could_have_pending = 0; - - /* treat the fact we got a truncated send pending as if we're choked */ - if (wsi_eff->trunc_len) - return 1; - - return (int)wsi_eff->sock_send_blocking; -} - -LWS_VISIBLE int -lws_poll_listen_fd(struct lws_pollfd *fd) -{ - fd_set readfds; - struct timeval tv = { 0, 0 }; - - assert((fd->events & LWS_POLLIN) == LWS_POLLIN); - - FD_ZERO(&readfds); - FD_SET(fd->fd, &readfds); - - return select(((int)fd->fd) + 1, &readfds, NULL, NULL, &tv); -} - -LWS_VISIBLE void -lwsl_emit_syslog(int level, const char *line) -{ - lwsl_emit_stderr(level, line); -} - -LWS_VISIBLE LWS_EXTERN int -_lws_plat_service_tsi(struct lws_context *context, int timeout_ms, int tsi) -{ - struct lws_context_per_thread *pt; - WSANETWORKEVENTS networkevents; - struct lws_pollfd *pfd; - struct lws *wsi; - unsigned int i; - DWORD ev; - int n, m; - - /* stay dead once we are dead */ - if (context == NULL || !context->vhost_list) - return 1; - - pt = &context->pt[tsi]; - - if (!context->service_tid_detected) { - struct lws _lws; - - memset(&_lws, 0, sizeof(_lws)); - _lws.context = context; - - context->service_tid_detected = context->vhost_list-> - protocols[0].callback(&_lws, LWS_CALLBACK_GET_THREAD_ID, - NULL, NULL, 0); - context->service_tid = context->service_tid_detected; - context->service_tid_detected = 1; - } - - if (timeout_ms < 0) { - if (lws_service_flag_pending(context, tsi)) { - /* any socket with events to service? */ - for (n = 0; n < (int)pt->fds_count; n++) { - if (!pt->fds[n].revents) - continue; - - m = lws_service_fd_tsi(context, &pt->fds[n], tsi); - if (m < 0) - return -1; - /* if something closed, retry this slot */ - if (m) - n--; - } - } - return 0; - } - - if (context->event_loop_ops->run_pt) - context->event_loop_ops->run_pt(context, tsi); - - for (i = 0; i < pt->fds_count; ++i) { - pfd = &pt->fds[i]; - - if (!(pfd->events & LWS_POLLOUT)) - continue; - - wsi = wsi_from_fd(context, pfd->fd); - if (!wsi || wsi->listener) - continue; - if (wsi->sock_send_blocking) - continue; - pfd->revents = LWS_POLLOUT; - n = lws_service_fd(context, pfd); - if (n < 0) - return -1; - - /* Force WSAWaitForMultipleEvents() to check events and then return immediately. */ - timeout_ms = 0; - - /* if something closed, retry this slot */ - if (n) - i--; - } - - /* - * is there anybody with pending stuff that needs service forcing? - */ - if (!lws_service_adjust_timeout(context, 1, tsi)) { - /* -1 timeout means just do forced service */ - _lws_plat_service_tsi(context, -1, pt->tid); - /* still somebody left who wants forced service? */ - if (!lws_service_adjust_timeout(context, 1, pt->tid)) - /* yes... come back again quickly */ - timeout_ms = 0; - } - - if (timeout_ms) { - lws_usec_t t; - - lws_pt_lock(pt, __func__); - /* don't stay in poll wait longer than next hr timeout */ - t = __lws_hrtimer_service(pt); - - if ((lws_usec_t)timeout_ms * 1000 > t) - timeout_ms = (int)(t / 1000); - lws_pt_unlock(pt); - } - - ev = WSAWaitForMultipleEvents(1, pt->events, FALSE, timeout_ms, FALSE); - if (ev == WSA_WAIT_EVENT_0) { - unsigned int eIdx, err; - - WSAResetEvent(pt->events[0]); - - if (pt->context->tls_ops && - pt->context->tls_ops->fake_POLLIN_for_buffered) - pt->context->tls_ops->fake_POLLIN_for_buffered(pt); - - for (eIdx = 0; eIdx < pt->fds_count; ++eIdx) { - if (WSAEnumNetworkEvents(pt->fds[eIdx].fd, 0, - &networkevents) == SOCKET_ERROR) { - lwsl_err("WSAEnumNetworkEvents() failed " - "with error %d\n", LWS_ERRNO); - return -1; - } - - pfd = &pt->fds[eIdx]; - pfd->revents = (short)networkevents.lNetworkEvents; - - err = networkevents.iErrorCode[FD_CONNECT_BIT]; - - if ((networkevents.lNetworkEvents & FD_CONNECT) && - err && err != LWS_EALREADY && - err != LWS_EINPROGRESS && err != LWS_EWOULDBLOCK && - err != WSAEINVAL) { - lwsl_debug("Unable to connect errno=%d\n", err); - pfd->revents |= LWS_POLLHUP; - } - - if (pfd->revents & LWS_POLLOUT) { - wsi = wsi_from_fd(context, pfd->fd); - if (wsi) - wsi->sock_send_blocking = 0; - } - /* if something closed, retry this slot */ - if (pfd->revents & LWS_POLLHUP) - --eIdx; - - if (pfd->revents) { - recv(pfd->fd, NULL, 0, 0); - lws_service_fd_tsi(context, pfd, tsi); - } - } - } - - context->service_tid = 0; - - if (ev == WSA_WAIT_TIMEOUT) - lws_service_fd(context, NULL); - - return 0; -} - -LWS_VISIBLE int -lws_plat_service(struct lws_context *context, int timeout_ms) -{ - return _lws_plat_service_tsi(context, timeout_ms, 0); -} - -LWS_VISIBLE int -lws_plat_set_socket_options(struct lws_vhost *vhost, lws_sockfd_type fd) -{ - int optval = 1; - int optlen = sizeof(optval); - u_long optl = 1; - DWORD dwBytesRet; - struct tcp_keepalive alive; - int protonbr; -#ifndef _WIN32_WCE - struct protoent *tcp_proto; -#endif - -#ifdef LWS_WITH_IPV6 - optval = 0; - setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void*)&optval, optlen); -#endif - - if (vhost->ka_time) { - /* enable keepalive on this socket */ - optval = 1; - if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, - (const char *)&optval, optlen) < 0) - return 1; - - alive.onoff = TRUE; - alive.keepalivetime = vhost->ka_time; - alive.keepaliveinterval = vhost->ka_interval; - - if (WSAIoctl(fd, SIO_KEEPALIVE_VALS, &alive, sizeof(alive), - NULL, 0, &dwBytesRet, NULL, NULL)) - return 1; - } - - /* Disable Nagle */ - optval = 1; -#ifndef _WIN32_WCE - tcp_proto = getprotobyname("TCP"); - if (!tcp_proto) { - lwsl_err("getprotobyname() failed with error %d\n", LWS_ERRNO); - return 1; - } - protonbr = tcp_proto->p_proto; -#else - protonbr = 6; -#endif - - setsockopt(fd, protonbr, TCP_NODELAY, (const char *)&optval, optlen); - - /* We are nonblocking... */ - ioctlsocket(fd, FIONBIO, &optl); - - return 0; -} - -LWS_VISIBLE void -lws_plat_drop_app_privileges(const struct lws_context_creation_info *info) -{ -} - -LWS_VISIBLE int -lws_plat_context_early_init(void) -{ - WORD wVersionRequested; - WSADATA wsaData; - int err; - - /* Use the MAKEWORD(lowbyte, highbyte) macro from Windef.h */ - wVersionRequested = MAKEWORD(2, 2); - - err = WSAStartup(wVersionRequested, &wsaData); - if (!err) - return 0; - /* - * Tell the user that we could not find a usable - * Winsock DLL - */ - lwsl_err("WSAStartup failed with error: %d\n", err); - - return 1; -} - -LWS_VISIBLE void -lws_plat_context_early_destroy(struct lws_context *context) -{ - struct lws_context_per_thread *pt = &context->pt[0]; - int n = context->count_threads; - - while (n--) { - if (pt->events) { - WSACloseEvent(pt->events[0]); - lws_free(pt->events); - } - pt++; - } -} - -LWS_VISIBLE void -lws_plat_context_late_destroy(struct lws_context *context) -{ - int n; - - for (n = 0; n < FD_HASHTABLE_MODULUS; n++) { - if (context->fd_hashtable[n].wsi) - lws_free(context->fd_hashtable[n].wsi); - } - - WSACleanup(); -} - -LWS_VISIBLE LWS_EXTERN int -lws_interface_to_sa(int ipv6, - const char *ifname, struct sockaddr_in *addr, size_t addrlen) -{ -#ifdef LWS_WITH_IPV6 - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr; - - if (ipv6) { - if (lws_plat_inet_pton(AF_INET6, ifname, &addr6->sin6_addr) == 1) { - return LWS_ITOSA_USABLE; - } - } -#endif - - long long address = inet_addr(ifname); - - if (address == INADDR_NONE) { - struct hostent *entry = gethostbyname(ifname); - if (entry) - address = ((struct in_addr *)entry->h_addr_list[0])->s_addr; - } - - if (address == INADDR_NONE) - return LWS_ITOSA_NOT_EXIST; - - addr->sin_addr.s_addr = (unsigned long)(lws_intptr_t)address; - - return LWS_ITOSA_USABLE; -} - -LWS_VISIBLE void -lws_plat_insert_socket_into_fds(struct lws_context *context, struct lws *wsi) -{ - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - - pt->fds[pt->fds_count++].revents = 0; - pt->events[pt->fds_count] = pt->events[0]; - WSAEventSelect(wsi->desc.sockfd, pt->events[0], - LWS_POLLIN | LWS_POLLHUP | FD_CONNECT); -} - -LWS_VISIBLE void -lws_plat_delete_socket_from_fds(struct lws_context *context, - struct lws *wsi, int m) -{ - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - - pt->events[m + 1] = pt->events[pt->fds_count--]; -} - -LWS_VISIBLE void -lws_plat_service_periodic(struct lws_context *context) -{ -} - -LWS_VISIBLE int -lws_plat_check_connection_error(struct lws *wsi) -{ - int optVal; - int optLen = sizeof(int); - - if (getsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_ERROR, - (char*)&optVal, &optLen) != SOCKET_ERROR && optVal && - optVal != LWS_EALREADY && optVal != LWS_EINPROGRESS && - optVal != LWS_EWOULDBLOCK && optVal != WSAEINVAL) { - lwsl_debug("Connect failed SO_ERROR=%d\n", optVal); - return 1; - } - - return 0; -} - -LWS_VISIBLE int -lws_plat_change_pollfd(struct lws_context *context, - struct lws *wsi, struct lws_pollfd *pfd) -{ - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - long networkevents = LWS_POLLHUP | FD_CONNECT; - - if ((pfd->events & LWS_POLLIN)) - networkevents |= LWS_POLLIN; - - if ((pfd->events & LWS_POLLOUT)) - networkevents |= LWS_POLLOUT; - - if (WSAEventSelect(wsi->desc.sockfd, - pt->events[0], - networkevents) != SOCKET_ERROR) - return 0; - - lwsl_err("WSAEventSelect() failed with error %d\n", LWS_ERRNO); - - return 1; -} - -LWS_VISIBLE const char * -lws_plat_inet_ntop(int af, const void *src, char *dst, int cnt) -{ - WCHAR *buffer; - DWORD bufferlen = cnt; - BOOL ok = FALSE; - - buffer = lws_malloc(bufferlen * 2, "inet_ntop"); - if (!buffer) { - lwsl_err("Out of memory\n"); - return NULL; - } - - if (af == AF_INET) { - struct sockaddr_in srcaddr; - bzero(&srcaddr, sizeof(srcaddr)); - srcaddr.sin_family = AF_INET; - memcpy(&(srcaddr.sin_addr), src, sizeof(srcaddr.sin_addr)); - - if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen)) - ok = TRUE; -#ifdef LWS_WITH_IPV6 - } else if (af == AF_INET6) { - struct sockaddr_in6 srcaddr; - bzero(&srcaddr, sizeof(srcaddr)); - srcaddr.sin6_family = AF_INET6; - memcpy(&(srcaddr.sin6_addr), src, sizeof(srcaddr.sin6_addr)); - - if (!WSAAddressToStringW((struct sockaddr*)&srcaddr, sizeof(srcaddr), 0, buffer, &bufferlen)) - ok = TRUE; -#endif - } else - lwsl_err("Unsupported type\n"); - - if (!ok) { - int rv = WSAGetLastError(); - lwsl_err("WSAAddressToString() : %d\n", rv); - } else { - if (WideCharToMultiByte(CP_ACP, 0, buffer, bufferlen, dst, cnt, 0, NULL) <= 0) - ok = FALSE; - } - - lws_free(buffer); - return ok ? dst : NULL; -} - -LWS_VISIBLE int -lws_plat_inet_pton(int af, const char *src, void *dst) -{ - WCHAR *buffer; - DWORD bufferlen = (int)strlen(src) + 1; - BOOL ok = FALSE; - - buffer = lws_malloc(bufferlen * 2, "inet_pton"); - if (!buffer) { - lwsl_err("Out of memory\n"); - return -1; - } - - if (MultiByteToWideChar(CP_ACP, 0, src, bufferlen, buffer, bufferlen) <= 0) { - lwsl_err("Failed to convert multi byte to wide char\n"); - lws_free(buffer); - return -1; - } - - if (af == AF_INET) { - struct sockaddr_in dstaddr; - int dstaddrlen = sizeof(dstaddr); - bzero(&dstaddr, sizeof(dstaddr)); - dstaddr.sin_family = AF_INET; - - if (!WSAStringToAddressW(buffer, af, 0, (struct sockaddr *) &dstaddr, &dstaddrlen)) { - ok = TRUE; - memcpy(dst, &dstaddr.sin_addr, sizeof(dstaddr.sin_addr)); - } -#ifdef LWS_WITH_IPV6 - } else if (af == AF_INET6) { - struct sockaddr_in6 dstaddr; - int dstaddrlen = sizeof(dstaddr); - bzero(&dstaddr, sizeof(dstaddr)); - dstaddr.sin6_family = AF_INET6; - - if (!WSAStringToAddressW(buffer, af, 0, (struct sockaddr *) &dstaddr, &dstaddrlen)) { - ok = TRUE; - memcpy(dst, &dstaddr.sin6_addr, sizeof(dstaddr.sin6_addr)); - } -#endif - } else - lwsl_err("Unsupported type\n"); - - if (!ok) { - int rv = WSAGetLastError(); - lwsl_err("WSAAddressToString() : %d\n", rv); - } - - lws_free(buffer); - return ok ? 1 : -1; -} - -LWS_VISIBLE lws_fop_fd_t -_lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, - const char *vpath, lws_fop_flags_t *flags) -{ - HANDLE ret; - WCHAR buf[MAX_PATH]; - lws_fop_fd_t fop_fd; - FILE_STANDARD_INFO fInfo = {0}; - - MultiByteToWideChar(CP_UTF8, 0, filename, -1, buf, LWS_ARRAY_SIZE(buf)); - -#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0602 // Windows 8 (minimum when UWP_ENABLED, but can be used in Windows builds) - CREATEFILE2_EXTENDED_PARAMETERS extParams = {0}; - extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; - - if (((*flags) & 7) == _O_RDONLY) { - ret = CreateFile2(buf, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &extParams); - } else { - ret = CreateFile2(buf, GENERIC_WRITE, 0, CREATE_ALWAYS, &extParams); - } -#else - if (((*flags) & 7) == _O_RDONLY) { - ret = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - } else { - ret = CreateFileW(buf, GENERIC_WRITE, 0, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - } -#endif - - if (ret == LWS_INVALID_FILE) - goto bail; - - fop_fd = malloc(sizeof(*fop_fd)); - if (!fop_fd) - goto bail; - - fop_fd->fops = fops; - fop_fd->fd = ret; - fop_fd->filesystem_priv = NULL; /* we don't use it */ - fop_fd->flags = *flags; - fop_fd->len = 0; - if(GetFileInformationByHandleEx(ret, FileStandardInfo, &fInfo, sizeof(fInfo))) - fop_fd->len = fInfo.EndOfFile.QuadPart; - - fop_fd->pos = 0; - - return fop_fd; - -bail: - return NULL; -} - -LWS_VISIBLE int -_lws_plat_file_close(lws_fop_fd_t *fop_fd) -{ - HANDLE fd = (*fop_fd)->fd; - - free(*fop_fd); - *fop_fd = NULL; - - CloseHandle((HANDLE)fd); - - return 0; -} - -LWS_VISIBLE lws_fileofs_t -_lws_plat_file_seek_cur(lws_fop_fd_t fop_fd, lws_fileofs_t offset) -{ - LARGE_INTEGER l; - - l.QuadPart = offset; - return SetFilePointerEx((HANDLE)fop_fd->fd, l, NULL, FILE_CURRENT); -} - -LWS_VISIBLE int -_lws_plat_file_read(lws_fop_fd_t fop_fd, lws_filepos_t *amount, - uint8_t *buf, lws_filepos_t len) -{ - DWORD _amount; - - if (!ReadFile((HANDLE)fop_fd->fd, buf, (DWORD)len, &_amount, NULL)) { - *amount = 0; - - return 1; - } - - fop_fd->pos += _amount; - *amount = (unsigned long)_amount; - - return 0; -} - -LWS_VISIBLE int -_lws_plat_file_write(lws_fop_fd_t fop_fd, lws_filepos_t *amount, - uint8_t* buf, lws_filepos_t len) -{ - DWORD _amount; - - if (!WriteFile((HANDLE)fop_fd->fd, buf, (DWORD)len, &_amount, NULL)) { - *amount = 0; - - return 1; - } - - fop_fd->pos += _amount; - *amount = (unsigned long)_amount; - - return 0; -} - -LWS_VISIBLE int -lws_plat_init(struct lws_context *context, - const struct lws_context_creation_info *info) -{ - struct lws_context_per_thread *pt = &context->pt[0]; - int i, n = context->count_threads; - - for (i = 0; i < FD_HASHTABLE_MODULUS; i++) { - context->fd_hashtable[i].wsi = - lws_zalloc(sizeof(struct lws*) * context->max_fds, "win hashtable"); - - if (!context->fd_hashtable[i].wsi) - return -1; - } - - while (n--) { - pt->events = lws_malloc(sizeof(WSAEVENT) * - (context->fd_limit_per_thread + 1), "event table"); - if (pt->events == NULL) { - lwsl_err("Unable to allocate events array for %d connections\n", - context->fd_limit_per_thread + 1); - return 1; - } - - pt->fds_count = 0; - pt->events[0] = WSACreateEvent(); /* the cancel event */ - - pt++; - } - - context->fd_random = 0; - -#ifdef LWS_WITH_PLUGINS - if (info->plugin_dirs) - lws_plat_plugins_init(context, info->plugin_dirs); -#endif - - return 0; -} - - -int kill(int pid, int sig) -{ - lwsl_err("Sorry Windows doesn't support kill()."); - exit(0); -} - -int fork(void) -{ - lwsl_err("Sorry Windows doesn't support fork()."); - exit(0); -} - -LWS_VISIBLE int -lws_plat_write_cert(struct lws_vhost *vhost, int is_key, int fd, void *buf, - int len) -{ - int n; - - n = write(fd, buf, len); - - lseek(fd, 0, SEEK_SET); - - return n != len; -} - -LWS_VISIBLE int -lws_plat_write_file(const char *filename, void *buf, int len) -{ - int m, fd; - - fd = lws_open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); - - if (fd == -1) - return -1; - - m = write(fd, buf, len); - close(fd); - - return m != len; -} - -LWS_VISIBLE int -lws_plat_read_file(const char *filename, void *buf, int len) -{ - int n, fd = lws_open(filename, O_RDONLY); - if (fd == -1) - return -1; - - n = read(fd, buf, len); - close(fd); - - return n; -} - -LWS_VISIBLE int -lws_plat_recommended_rsa_bits(void) -{ - return 4096; -} diff --git a/thirdparty/libwebsockets/roles/h1/ops-h1.c b/thirdparty/libwebsockets/roles/h1/ops-h1.c deleted file mode 100644 index 9001c864ea..0000000000 --- a/thirdparty/libwebsockets/roles/h1/ops-h1.c +++ /dev/null @@ -1,701 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include <core/private.h> - -#ifndef min -#define min(a, b) ((a) < (b) ? (a) : (b)) -#endif - - -/* - * We have to take care about parsing because the headers may be split - * into multiple fragments. They may contain unknown headers with arbitrary - * argument lengths. So, we parse using a single-character at a time state - * machine that is completely independent of packet size. - * - * Returns <0 for error or length of chars consumed from buf (up to len) - */ - -int -lws_read_h1(struct lws *wsi, unsigned char *buf, lws_filepos_t len) -{ - unsigned char *last_char, *oldbuf = buf; - lws_filepos_t body_chunk_len; - size_t n; - - // lwsl_notice("%s: h1 path: wsi state 0x%x\n", __func__, lwsi_state(wsi)); - - switch (lwsi_state(wsi)) { - - case LRS_ISSUING_FILE: - return 0; - - case LRS_ESTABLISHED: - - if (lwsi_role_ws(wsi)) - goto ws_mode; - - if (lwsi_role_client(wsi)) - break; - - wsi->hdr_parsing_completed = 0; - - /* fallthru */ - - case LRS_HEADERS: - if (!wsi->http.ah) { - lwsl_err("%s: LRS_HEADERS: NULL ah\n", __func__); - assert(0); - } - lwsl_parser("issuing %d bytes to parser\n", (int)len); -#if defined(LWS_ROLE_WS) && !defined(LWS_NO_CLIENT) - if (lws_ws_handshake_client(wsi, &buf, (size_t)len)) - goto bail; -#endif - last_char = buf; - if (lws_handshake_server(wsi, &buf, (size_t)len)) - /* Handshake indicates this session is done. */ - goto bail; - - /* we might have transitioned to RAW */ - if (wsi->role_ops == &role_ops_raw_skt || - wsi->role_ops == &role_ops_raw_file) - /* we gave the read buffer to RAW handler already */ - goto read_ok; - - /* - * It's possible that we've exhausted our data already, or - * rx flow control has stopped us dealing with this early, - * but lws_handshake_server doesn't update len for us. - * Figure out how much was read, so that we can proceed - * appropriately: - */ - len -= (buf - last_char); -// lwsl_debug("%s: thinks we have used %ld\n", __func__, (long)len); - - if (!wsi->hdr_parsing_completed) - /* More header content on the way */ - goto read_ok; - - switch (lwsi_state(wsi)) { - case LRS_ESTABLISHED: - case LRS_HEADERS: - goto read_ok; - case LRS_ISSUING_FILE: - goto read_ok; - case LRS_BODY: - wsi->http.rx_content_remain = - wsi->http.rx_content_length; - if (wsi->http.rx_content_remain) - goto http_postbody; - - /* there is no POST content */ - goto postbody_completion; - default: - break; - } - break; - - case LRS_BODY: -http_postbody: - lwsl_debug("%s: http post body: remain %d\n", __func__, - (int)wsi->http.rx_content_remain); - while (len && wsi->http.rx_content_remain) { - /* Copy as much as possible, up to the limit of: - * what we have in the read buffer (len) - * remaining portion of the POST body (content_remain) - */ - body_chunk_len = min(wsi->http.rx_content_remain, len); - wsi->http.rx_content_remain -= body_chunk_len; - len -= body_chunk_len; -#ifdef LWS_WITH_CGI - if (wsi->http.cgi) { - struct lws_cgi_args args; - - args.ch = LWS_STDIN; - args.stdwsi = &wsi->http.cgi->stdwsi[0]; - args.data = buf; - args.len = body_chunk_len; - - /* returns how much used */ - n = user_callback_handle_rxflow( - wsi->protocol->callback, - wsi, LWS_CALLBACK_CGI_STDIN_DATA, - wsi->user_space, - (void *)&args, 0); - if ((int)n < 0) - goto bail; - } else { -#endif - n = wsi->protocol->callback(wsi, - LWS_CALLBACK_HTTP_BODY, wsi->user_space, - buf, (size_t)body_chunk_len); - if (n) - goto bail; - n = (size_t)body_chunk_len; -#ifdef LWS_WITH_CGI - } -#endif - buf += n; - - if (wsi->http.rx_content_remain) { - lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, - wsi->context->timeout_secs); - break; - } - /* he sent all the content in time */ -postbody_completion: -#ifdef LWS_WITH_CGI - /* - * If we're running a cgi, we can't let him off the - * hook just because he sent his POST data - */ - if (wsi->http.cgi) - lws_set_timeout(wsi, PENDING_TIMEOUT_CGI, - wsi->context->timeout_secs); - else -#endif - lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); -#ifdef LWS_WITH_CGI - if (!wsi->http.cgi) -#endif - { - lwsl_info("HTTP_BODY_COMPLETION: %p (%s)\n", - wsi, wsi->protocol->name); - n = wsi->protocol->callback(wsi, - LWS_CALLBACK_HTTP_BODY_COMPLETION, - wsi->user_space, NULL, 0); - if (n) - goto bail; - - if (wsi->http2_substream) - lwsi_set_state(wsi, LRS_ESTABLISHED); - } - - break; - } - break; - - case LRS_RETURNED_CLOSE: - case LRS_AWAITING_CLOSE_ACK: - case LRS_WAITING_TO_SEND_CLOSE: - case LRS_SHUTDOWN: - -ws_mode: -#if !defined(LWS_NO_CLIENT) && defined(LWS_ROLE_WS) - // lwsl_notice("%s: ws_mode\n", __func__); - if (lws_ws_handshake_client(wsi, &buf, (size_t)len)) - goto bail; -#endif -#if defined(LWS_ROLE_WS) - if (lwsi_role_ws(wsi) && lwsi_role_server(wsi) && - /* - * for h2 we are on the swsi - */ - lws_parse_ws(wsi, &buf, (size_t)len) < 0) { - lwsl_info("%s: lws_parse_ws bailed\n", __func__); - goto bail; - } -#endif - // lwsl_notice("%s: ws_mode: buf moved on by %d\n", __func__, - // lws_ptr_diff(buf, oldbuf)); - break; - - case LRS_DEFERRING_ACTION: - lwsl_debug("%s: LRS_DEFERRING_ACTION\n", __func__); - break; - - case LRS_SSL_ACK_PENDING: - break; - - case LRS_DEAD_SOCKET: - lwsl_err("%s: Unhandled state LRS_DEAD_SOCKET\n", __func__); - goto bail; - // assert(0); - /* fallthru */ - - default: - lwsl_err("%s: Unhandled state %d\n", __func__, lwsi_state(wsi)); - assert(0); - goto bail; - } - -read_ok: - /* Nothing more to do for now */ -// lwsl_info("%s: %p: read_ok, used %ld (len %d, state %d)\n", __func__, -// wsi, (long)(buf - oldbuf), (int)len, wsi->state); - - return lws_ptr_diff(buf, oldbuf); - -bail: - /* - * h2 / h2-ws calls us recursively in - * - * lws_read_h1()-> - * lws_h2_parser()-> - * lws_read_h1() - * - * pattern, having stripped the h2 framing in the middle. - * - * When taking down the whole connection, make sure that only the - * outer lws_read() does the wsi close. - */ - if (!wsi->outer_will_close) - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, - "lws_read_h1 bail"); - - return -1; -} -#if !defined(LWS_NO_SERVER) -static int -lws_h1_server_socket_service(struct lws *wsi, struct lws_pollfd *pollfd) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - struct lws_tokens ebuf; - int n, buffered; - - if (lwsi_state(wsi) == LRS_DEFERRING_ACTION) - goto try_pollout; - - /* any incoming data ready? */ - - if (!(pollfd->revents & pollfd->events & LWS_POLLIN)) - goto try_pollout; - - /* - * If we previously just did POLLIN when IN and OUT were signaled - * (because POLLIN processing may have used up the POLLOUT), don't let - * that happen twice in a row... next time we see the situation favour - * POLLOUT - */ - - if (wsi->favoured_pollin && - (pollfd->revents & pollfd->events & LWS_POLLOUT)) { - // lwsl_notice("favouring pollout\n"); - wsi->favoured_pollin = 0; - goto try_pollout; - } - - /* - * We haven't processed that the tunnel is set up yet, so - * defer reading - */ - - if (lwsi_state(wsi) == LRS_SSL_ACK_PENDING) - return LWS_HPI_RET_HANDLED; - - /* these states imply we MUST have an ah attached */ - - if ((lwsi_state(wsi) == LRS_ESTABLISHED || - lwsi_state(wsi) == LRS_ISSUING_FILE || - lwsi_state(wsi) == LRS_HEADERS || - lwsi_state(wsi) == LRS_BODY)) { - - if (!wsi->http.ah && lws_header_table_attach(wsi, 0)) { - lwsl_info("%s: wsi %p: ah not available\n", __func__, wsi); - goto try_pollout; - } - - /* - * We got here because there was specifically POLLIN... - * regardless of our buflist state, we need to get it, - * and either use it, or append to the buflist and use - * buflist head material. - * - * We will not notice a connection close until the buflist is - * exhausted and we tried to do a read of some kind. - */ - - buffered = lws_buflist_aware_read(pt, wsi, &ebuf); - switch (ebuf.len) { - case 0: - lwsl_info("%s: read 0 len a\n", __func__); - wsi->seen_zero_length_recv = 1; - lws_change_pollfd(wsi, LWS_POLLIN, 0); -#if !defined(LWS_WITHOUT_EXTENSIONS) - /* - * autobahn requires us to win the race between close - * and draining the extensions - */ - if (wsi->ws && - (wsi->ws->rx_draining_ext || wsi->ws->tx_draining_ext)) - goto try_pollout; -#endif - /* - * normally, we respond to close with logically closing - * our side immediately - */ - goto fail; - - case LWS_SSL_CAPABLE_ERROR: - goto fail; - case LWS_SSL_CAPABLE_MORE_SERVICE: - goto try_pollout; - } - - /* just ignore incoming if waiting for close */ - if (lwsi_state(wsi) == LRS_FLUSHING_BEFORE_CLOSE) { - lwsl_notice("%s: just ignoring\n", __func__); - goto try_pollout; - } - - if (lwsi_state(wsi) == LRS_ISSUING_FILE) { - // lwsl_notice("stashing: wsi %p: bd %d\n", wsi, buffered); - if (lws_buflist_aware_consume(wsi, &ebuf, 0, buffered)) - return LWS_HPI_RET_PLEASE_CLOSE_ME; - - goto try_pollout; - } - - /* - * Otherwise give it to whoever wants it according to the - * connection state - */ -#if defined(LWS_ROLE_H2) - if (lwsi_role_h2(wsi) && lwsi_state(wsi) != LRS_BODY) - n = lws_read_h2(wsi, (uint8_t *)ebuf.token, ebuf.len); - else -#endif - n = lws_read_h1(wsi, (uint8_t *)ebuf.token, ebuf.len); - if (n < 0) /* we closed wsi */ - return LWS_HPI_RET_WSI_ALREADY_DIED; - - lwsl_debug("%s: consumed %d\n", __func__, n); - - if (lws_buflist_aware_consume(wsi, &ebuf, n, buffered)) - return LWS_HPI_RET_PLEASE_CLOSE_ME; - - /* - * during the parsing our role changed to something non-http, - * so the ah has no further meaning - */ - - if (wsi->http.ah && - !lwsi_role_h1(wsi) && - !lwsi_role_h2(wsi) && - !lwsi_role_cgi(wsi)) - lws_header_table_detach(wsi, 0); - - /* - * He may have used up the writability above, if we will defer - * POLLOUT processing in favour of POLLIN, note it - */ - - if (pollfd->revents & LWS_POLLOUT) - wsi->favoured_pollin = 1; - - return LWS_HPI_RET_HANDLED; - } - - /* - * He may have used up the writability above, if we will defer POLLOUT - * processing in favour of POLLIN, note it - */ - - if (pollfd->revents & LWS_POLLOUT) - wsi->favoured_pollin = 1; - -try_pollout: - - /* this handles POLLOUT for http serving fragments */ - - if (!(pollfd->revents & LWS_POLLOUT)) - return LWS_HPI_RET_HANDLED; - - /* one shot */ - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) { - lwsl_notice("%s a\n", __func__); - goto fail; - } - - /* clear back-to-back write detection */ - wsi->could_have_pending = 0; - - if (lwsi_state(wsi) == LRS_DEFERRING_ACTION) { - lwsl_debug("%s: LRS_DEFERRING_ACTION now writable\n", __func__); - - lwsi_set_state(wsi, LRS_ESTABLISHED); - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) { - lwsl_info("failed at set pollfd\n"); - goto fail; - } - } - - if (!wsi->hdr_parsing_completed) - return LWS_HPI_RET_HANDLED; - - if (lwsi_state(wsi) != LRS_ISSUING_FILE) { - - if (wsi->trunc_len) { - //lwsl_notice("%s: completing partial\n", __func__); - if (lws_issue_raw(wsi, wsi->trunc_alloc + wsi->trunc_offset, - wsi->trunc_len) < 0) { - lwsl_info("%s signalling to close\n", __func__); - goto fail; - } - return LWS_HPI_RET_HANDLED; - } - - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_C_WRITEABLE_CB, 1); -#if defined(LWS_WITH_STATS) - if (wsi->active_writable_req_us) { - uint64_t ul = time_in_microseconds() - - wsi->active_writable_req_us; - - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_MS_WRITABLE_DELAY, ul); - lws_stats_atomic_max(wsi->context, pt, - LWSSTATS_MS_WORST_WRITABLE_DELAY, ul); - wsi->active_writable_req_us = 0; - } -#endif - - n = user_callback_handle_rxflow(wsi->protocol->callback, wsi, - LWS_CALLBACK_HTTP_WRITEABLE, - wsi->user_space, NULL, 0); - if (n < 0) { - lwsl_info("writeable_fail\n"); - goto fail; - } - - return LWS_HPI_RET_HANDLED; - } - - /* >0 == completion, <0 == error - * - * We'll get a LWS_CALLBACK_HTTP_FILE_COMPLETION callback when - * it's done. That's the case even if we just completed the - * send, so wait for that. - */ - n = lws_serve_http_file_fragment(wsi); - if (n < 0) - goto fail; - - return LWS_HPI_RET_HANDLED; - - -fail: - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, - "server socket svc fail"); - - return LWS_HPI_RET_WSI_ALREADY_DIED; -} -#endif - -static int -rops_handle_POLLIN_h1(struct lws_context_per_thread *pt, struct lws *wsi, - struct lws_pollfd *pollfd) -{ - -// lwsl_notice("%s: %p: wsistate 0x%x %s, revents 0x%x\n", __func__, wsi, -// wsi->wsistate, wsi->role_ops->name, pollfd->revents); - -#ifdef LWS_WITH_CGI - if (wsi->http.cgi && (pollfd->revents & LWS_POLLOUT)) { - if (lws_handle_POLLOUT_event(wsi, pollfd)) - return LWS_HPI_RET_PLEASE_CLOSE_ME; - - return LWS_HPI_RET_HANDLED; - } -#endif - - if (lws_is_flowcontrolled(wsi)) - /* We cannot deal with any kind of new RX because we are - * RX-flowcontrolled. - */ - return LWS_HPI_RET_HANDLED; - -#if !defined(LWS_NO_SERVER) - if (!lwsi_role_client(wsi)) { - int n; - - lwsl_debug("%s: %p: wsistate 0x%x\n", __func__, wsi, wsi->wsistate); - n = lws_h1_server_socket_service(wsi, pollfd); - if (n != LWS_HPI_RET_HANDLED) - return n; - if (lwsi_state(wsi) != LRS_SSL_INIT) - if (lws_server_socket_service_ssl(wsi, LWS_SOCK_INVALID)) - return LWS_HPI_RET_PLEASE_CLOSE_ME; - - return LWS_HPI_RET_HANDLED; - } -#endif - -#ifndef LWS_NO_CLIENT - if ((pollfd->revents & LWS_POLLIN) && - wsi->hdr_parsing_completed && !wsi->told_user_closed) { - - /* - * In SSL mode we get POLLIN notification about - * encrypted data in. - * - * But that is not necessarily related to decrypted - * data out becoming available; in may need to perform - * other in or out before that happens. - * - * simply mark ourselves as having readable data - * and turn off our POLLIN - */ - wsi->client_rx_avail = 1; - lws_change_pollfd(wsi, LWS_POLLIN, 0); - - //lwsl_notice("calling back %s\n", wsi->protocol->name); - - /* let user code know, he'll usually ask for writeable - * callback and drain / re-enable it there - */ - if (user_callback_handle_rxflow( - wsi->protocol->callback, - wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP, - wsi->user_space, NULL, 0)) { - lwsl_info("RECEIVE_CLIENT_HTTP closed it\n"); - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } - - return LWS_HPI_RET_HANDLED; - } -#endif - -// if (lwsi_state(wsi) == LRS_ESTABLISHED) -// return LWS_HPI_RET_HANDLED; - -#if !defined(LWS_NO_CLIENT) - if ((pollfd->revents & LWS_POLLOUT) && - lws_handle_POLLOUT_event(wsi, pollfd)) { - lwsl_debug("POLLOUT event closed it\n"); - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } - - if (lws_client_socket_service(wsi, pollfd, NULL)) - return LWS_HPI_RET_WSI_ALREADY_DIED; -#endif - - return LWS_HPI_RET_HANDLED; -} - -int rops_handle_POLLOUT_h1(struct lws *wsi) -{ - if (lwsi_state(wsi) == LRS_ISSUE_HTTP_BODY) - return LWS_HP_RET_USER_SERVICE; - - if (lwsi_role_client(wsi)) - return LWS_HP_RET_USER_SERVICE; - - return LWS_HP_RET_BAIL_OK; -} - -static int -rops_write_role_protocol_h1(struct lws *wsi, unsigned char *buf, size_t len, - enum lws_write_protocol *wp) -{ -#if 0 - /* if not in a state to send stuff, then just send nothing */ - - if ((lwsi_state(wsi) != LRS_RETURNED_CLOSE && - lwsi_state(wsi) != LRS_WAITING_TO_SEND_CLOSE && - lwsi_state(wsi) != LRS_AWAITING_CLOSE_ACK)) { - //assert(0); - lwsl_debug("binning %d %d\n", lwsi_state(wsi), *wp); - return 0; - } -#endif - - return lws_issue_raw(wsi, (unsigned char *)buf, len); -} - -static int -rops_alpn_negotiated_h1(struct lws *wsi, const char *alpn) -{ - lwsl_debug("%s: client %d\n", __func__, lwsi_role_client(wsi)); -#if !defined(LWS_NO_CLIENT) - if (lwsi_role_client(wsi)) { - /* - * If alpn asserts it is http/1.1, server support for KA is - * mandatory. - * - * Knowing this lets us proceed with sending pipelined headers - * before we received the first response headers. - */ - wsi->keepalive_active = 1; - } -#endif - - return 0; -} - -static int -rops_destroy_role_h1(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - struct allocated_headers *ah; - - /* we may not have an ah, but may be on the waiting list... */ - lwsl_info("%s: ah det due to close\n", __func__); - __lws_header_table_detach(wsi, 0); - - ah = pt->http.ah_list; - - while (ah) { - if (ah->in_use && ah->wsi == wsi) { - lwsl_err("%s: ah leak: wsi %p\n", __func__, wsi); - ah->in_use = 0; - ah->wsi = NULL; - pt->http.ah_count_in_use--; - break; - } - ah = ah->next; - } - -#ifdef LWS_ROLE_WS - lws_free_set_NULL(wsi->ws); -#endif - return 0; -} - -struct lws_role_ops role_ops_h1 = { - /* role name */ "h1", - /* alpn id */ "http/1.1", - /* check_upgrades */ NULL, - /* init_context */ NULL, - /* init_vhost */ NULL, - /* destroy_vhost */ NULL, - /* periodic_checks */ NULL, - /* service_flag_pending */ NULL, - /* handle_POLLIN */ rops_handle_POLLIN_h1, - /* handle_POLLOUT */ rops_handle_POLLOUT_h1, - /* perform_user_POLLOUT */ NULL, - /* callback_on_writable */ NULL, - /* tx_credit */ NULL, - /* write_role_protocol */ rops_write_role_protocol_h1, - /* encapsulation_parent */ NULL, - /* alpn_negotiated */ rops_alpn_negotiated_h1, - /* close_via_role_protocol */ NULL, - /* close_role */ NULL, - /* close_kill_connection */ NULL, - /* destroy_role */ rops_destroy_role_h1, - /* writeable cb clnt, srv */ { LWS_CALLBACK_CLIENT_HTTP_WRITEABLE, - LWS_CALLBACK_HTTP_WRITEABLE }, - /* close cb clnt, srv */ { LWS_CALLBACK_CLOSED_CLIENT_HTTP, - LWS_CALLBACK_CLOSED_HTTP }, - /* file_handle */ 0, -}; diff --git a/thirdparty/libwebsockets/roles/h1/private.h b/thirdparty/libwebsockets/roles/h1/private.h deleted file mode 100644 index 3f53954d33..0000000000 --- a/thirdparty/libwebsockets/roles/h1/private.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * This is included from core/private.h if LWS_ROLE_H1 - * - * Most of the h1 business is defined in the h1 / h2 common roles/http dir - */ - -extern struct lws_role_ops role_ops_h1; -#define lwsi_role_h1(wsi) (wsi->role_ops == &role_ops_h1) diff --git a/thirdparty/libwebsockets/roles/http/client/client-handshake.c b/thirdparty/libwebsockets/roles/http/client/client-handshake.c deleted file mode 100644 index 0095c79a69..0000000000 --- a/thirdparty/libwebsockets/roles/http/client/client-handshake.c +++ /dev/null @@ -1,1284 +0,0 @@ -#include "core/private.h" - -static int -lws_getaddrinfo46(struct lws *wsi, const char *ads, struct addrinfo **result) -{ - struct addrinfo hints; - - memset(&hints, 0, sizeof(hints)); - *result = NULL; - -#ifdef LWS_WITH_IPV6 - if (wsi->ipv6) { - -#if !defined(__ANDROID__) - hints.ai_family = AF_INET6; - hints.ai_flags = AI_V4MAPPED; -#endif - } else -#endif - { - hints.ai_family = PF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - } - - return getaddrinfo(ads, NULL, &hints, result); -} - -struct lws * -lws_client_connect_2(struct lws *wsi) -{ -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - const char *adsin; - struct lws *wsi_piggyback = NULL; - struct lws_pollfd pfd; - ssize_t plen = 0; -#endif - struct addrinfo *result; - const char *ads; - sockaddr46 sa46; - int n, port; - const char *cce = "", *iface; - const char *meth = NULL; -#ifdef LWS_WITH_IPV6 - char ipv6only = lws_check_opt(wsi->vhost->options, - LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY | - LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE); - -#if defined(__ANDROID__) - ipv6only = 0; -#endif -#endif - - lwsl_client("%s: %p\n", __func__, wsi); - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - if (!wsi->http.ah) { - cce = "ah was NULL at cc2"; - lwsl_err("%s\n", cce); - goto oom4; - } - - /* we can only piggyback GET or POST */ - - meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD); - if (meth && strcmp(meth, "GET") && strcmp(meth, "POST")) - goto create_new_conn; - - /* we only pipeline connections that said it was okay */ - - if (!wsi->client_pipeline) - goto create_new_conn; - - /* - * let's take a look first and see if there are any already-active - * client connections we can piggy-back on. - */ - - adsin = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS); - - lws_vhost_lock(wsi->vhost); /* ----------------------------------- { */ - - lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, - wsi->vhost->dll_active_client_conns.next) { - struct lws *w = lws_container_of(d, struct lws, - dll_active_client_conns); - - lwsl_debug("%s: check %s %s %d %d\n", __func__, adsin, - w->client_hostname_copy, wsi->c_port, w->c_port); - - if (w != wsi && w->client_hostname_copy && - !strcmp(adsin, w->client_hostname_copy) && -#if defined(LWS_WITH_TLS) - (wsi->tls.use_ssl & LCCSCF_USE_SSL) == - (w->tls.use_ssl & LCCSCF_USE_SSL) && -#endif - wsi->c_port == w->c_port) { - - /* someone else is already connected to the right guy */ - - /* do we know for a fact pipelining won't fly? */ - if (w->keepalive_rejected) { - lwsl_info("defeating pipelining due to no " - "keepalive on server\n"); - lws_vhost_unlock(wsi->vhost); /* } ---------- */ - goto create_new_conn; - } -#if defined (LWS_WITH_HTTP2) - /* - * h2: in usable state already: just use it without - * going through the queue - */ - if (w->client_h2_alpn && - (lwsi_state(w) == LRS_H2_WAITING_TO_SEND_HEADERS || - lwsi_state(w) == LRS_ESTABLISHED)) { - - lwsl_info("%s: just join h2 directly\n", - __func__); - - wsi->client_h2_alpn = 1; - lws_wsi_h2_adopt(w, wsi); - lws_vhost_unlock(wsi->vhost); /* } ---------- */ - - return wsi; - } -#endif - - lwsl_info("applying %p to txn queue on %p (wsistate 0x%x)\n", - wsi, w, w->wsistate); - /* - * ...let's add ourselves to his transaction queue... - * we are adding ourselves at the HEAD - */ - lws_dll_lws_add_front(&wsi->dll_client_transaction_queue, - &w->dll_client_transaction_queue_head); - - /* - * h1: pipeline our headers out on him, - * and wait for our turn at client transaction_complete - * to take over parsing the rx. - */ - - wsi_piggyback = w; - - lws_vhost_unlock(wsi->vhost); /* } ---------- */ - goto send_hs; - } - - } lws_end_foreach_dll_safe(d, d1); - - lws_vhost_unlock(wsi->vhost); /* } ---------------------------------- */ - -create_new_conn: -#endif - - /* - * clients who will create their own fresh connection keep a copy of - * the hostname they originally connected to, in case other connections - * want to use it too - */ - - if (!wsi->client_hostname_copy) - wsi->client_hostname_copy = - lws_strdup(lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_PEER_ADDRESS)); - - /* - * If we made our own connection, and we're doing a method that can take - * a pipeline, we are an "active client connection". - * - * Add ourselves to the vhost list of those so that others can - * piggyback on our transaction queue - */ - - if (meth && (!strcmp(meth, "GET") || !strcmp(meth, "POST")) && - lws_dll_is_null(&wsi->dll_client_transaction_queue) && - lws_dll_is_null(&wsi->dll_active_client_conns)) { - lws_vhost_lock(wsi->vhost); - lws_dll_lws_add_front(&wsi->dll_active_client_conns, - &wsi->vhost->dll_active_client_conns); - lws_vhost_unlock(wsi->vhost); - } - - /* - * start off allowing ipv6 on connection if vhost allows it - */ - wsi->ipv6 = LWS_IPV6_ENABLED(wsi->vhost); - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - - /* Decide what it is we need to connect to: - * - * Priority 1: connect to http proxy */ - - if (wsi->vhost->http.http_proxy_port) { - plen = sprintf((char *)pt->serv_buf, - "CONNECT %s:%u HTTP/1.0\x0d\x0a" - "User-agent: libwebsockets\x0d\x0a", - lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS), - wsi->c_port); - - if (wsi->vhost->proxy_basic_auth_token[0]) - plen += sprintf((char *)pt->serv_buf + plen, - "Proxy-authorization: basic %s\x0d\x0a", - wsi->vhost->proxy_basic_auth_token); - - plen += sprintf((char *)pt->serv_buf + plen, "\x0d\x0a"); - ads = wsi->vhost->http.http_proxy_address; - port = wsi->vhost->http.http_proxy_port; -#else - if (0) { -#endif - -#if defined(LWS_WITH_SOCKS5) - - /* Priority 2: Connect to SOCK5 Proxy */ - - } else if (wsi->vhost->socks_proxy_port) { - socks_generate_msg(wsi, SOCKS_MSG_GREETING, &plen); - lwsl_client("Sending SOCKS Greeting\n"); - ads = wsi->vhost->socks_proxy_address; - port = wsi->vhost->socks_proxy_port; -#endif - } else { - - /* Priority 3: Connect directly */ - - ads = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS); - port = wsi->c_port; - } - - /* - * prepare the actual connection - * to whatever we decided to connect to - */ - - lwsl_info("%s: %p: address %s\n", __func__, wsi, ads); - - n = lws_getaddrinfo46(wsi, ads, &result); - -#ifdef LWS_WITH_IPV6 - if (wsi->ipv6) { - struct sockaddr_in6 *sa6 = - ((struct sockaddr_in6 *)result->ai_addr); - - if (n) { - /* lws_getaddrinfo46 failed, there is no usable result */ - lwsl_notice("%s: lws_getaddrinfo46 failed %d\n", - __func__, n); - cce = "ipv6 lws_getaddrinfo46 failed"; - goto oom4; - } - - memset(&sa46, 0, sizeof(sa46)); - - sa46.sa6.sin6_family = AF_INET6; - switch (result->ai_family) { - case AF_INET: - if (ipv6only) - break; - /* map IPv4 to IPv6 */ - bzero((char *)&sa46.sa6.sin6_addr, - sizeof(sa46.sa6.sin6_addr)); - sa46.sa6.sin6_addr.s6_addr[10] = 0xff; - sa46.sa6.sin6_addr.s6_addr[11] = 0xff; - memcpy(&sa46.sa6.sin6_addr.s6_addr[12], - &((struct sockaddr_in *)result->ai_addr)->sin_addr, - sizeof(struct in_addr)); - lwsl_notice("uplevelling AF_INET to AF_INET6\n"); - break; - - case AF_INET6: - memcpy(&sa46.sa6.sin6_addr, &sa6->sin6_addr, - sizeof(struct in6_addr)); - sa46.sa6.sin6_scope_id = sa6->sin6_scope_id; - sa46.sa6.sin6_flowinfo = sa6->sin6_flowinfo; - break; - default: - lwsl_err("Unknown address family\n"); - freeaddrinfo(result); - cce = "unknown address family"; - goto oom4; - } - } else -#endif /* use ipv6 */ - - /* use ipv4 */ - { - void *p = NULL; - - if (!n) { - struct addrinfo *res = result; - - /* pick the first AF_INET (IPv4) result */ - - while (!p && res) { - switch (res->ai_family) { - case AF_INET: - p = &((struct sockaddr_in *)res->ai_addr)->sin_addr; - break; - } - - res = res->ai_next; - } -#if defined(LWS_FALLBACK_GETHOSTBYNAME) - } else if (n == EAI_SYSTEM) { - struct hostent *host; - - lwsl_info("getaddrinfo (ipv4) failed, trying gethostbyname\n"); - host = gethostbyname(ads); - if (host) { - p = host->h_addr; - } else { - lwsl_err("gethostbyname failed\n"); - cce = "gethostbyname (ipv4) failed"; - goto oom4; - } -#endif - } else { - lwsl_err("getaddrinfo failed\n"); - cce = "getaddrinfo failed"; - goto oom4; - } - - if (!p) { - if (result) - freeaddrinfo(result); - lwsl_err("Couldn't identify address\n"); - cce = "unable to lookup address"; - goto oom4; - } - - sa46.sa4.sin_family = AF_INET; - sa46.sa4.sin_addr = *((struct in_addr *)p); - bzero(&sa46.sa4.sin_zero, 8); - } - - if (result) - freeaddrinfo(result); - - /* now we decided on ipv4 or ipv6, set the port */ - - if (!lws_socket_is_valid(wsi->desc.sockfd)) { - - if (wsi->context->event_loop_ops->check_client_connect_ok && - wsi->context->event_loop_ops->check_client_connect_ok(wsi)) { - cce = "waiting for event loop watcher to close"; - goto oom4; - } - -#ifdef LWS_WITH_IPV6 - if (wsi->ipv6) - wsi->desc.sockfd = socket(AF_INET6, SOCK_STREAM, 0); - else -#endif - wsi->desc.sockfd = socket(AF_INET, SOCK_STREAM, 0); - - if (!lws_socket_is_valid(wsi->desc.sockfd)) { - lwsl_warn("Unable to open socket\n"); - cce = "unable to open socket"; - goto oom4; - } - - if (lws_plat_set_socket_options(wsi->vhost, wsi->desc.sockfd)) { - lwsl_err("Failed to set wsi socket options\n"); - compatible_close(wsi->desc.sockfd); - cce = "set socket opts failed"; - goto oom4; - } - - lwsi_set_state(wsi, LRS_WAITING_CONNECT); - - if (wsi->context->event_loop_ops->accept) - wsi->context->event_loop_ops->accept(wsi); - - if (__insert_wsi_socket_into_fds(wsi->context, wsi)) { - compatible_close(wsi->desc.sockfd); - cce = "insert wsi failed"; - goto oom4; - } - - lws_change_pollfd(wsi, 0, LWS_POLLIN); - - /* - * past here, we can't simply free the structs as error - * handling as oom4 does. We have to run the whole close flow. - */ - - if (!wsi->protocol) - wsi->protocol = &wsi->vhost->protocols[0]; - - wsi->protocol->callback(wsi, LWS_CALLBACK_WSI_CREATE, - wsi->user_space, NULL, 0); - - lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CONNECT_RESPONSE, - AWAITING_TIMEOUT); - - iface = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE); - - if (iface) { - n = lws_socket_bind(wsi->vhost, wsi->desc.sockfd, 0, iface); - if (n < 0) { - cce = "unable to bind socket"; - goto failed; - } - } - } - -#ifdef LWS_WITH_IPV6 - if (wsi->ipv6) { - sa46.sa6.sin6_port = htons(port); - n = sizeof(struct sockaddr_in6); - } else -#endif - { - sa46.sa4.sin_port = htons(port); - n = sizeof(struct sockaddr); - } - - if (connect(wsi->desc.sockfd, (const struct sockaddr *)&sa46, n) == -1 || - LWS_ERRNO == LWS_EISCONN) { - if (LWS_ERRNO == LWS_EALREADY || - LWS_ERRNO == LWS_EINPROGRESS || - LWS_ERRNO == LWS_EWOULDBLOCK -#ifdef _WIN32 - || LWS_ERRNO == WSAEINVAL -#endif - ) { - lwsl_client("nonblocking connect retry (errno = %d)\n", - LWS_ERRNO); - - if (lws_plat_check_connection_error(wsi)) { - cce = "socket connect failed"; - goto failed; - } - - /* - * must do specifically a POLLOUT poll to hear - * about the connect completion - */ - if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) { - cce = "POLLOUT set failed"; - goto failed; - } - - return wsi; - } - - if (LWS_ERRNO != LWS_EISCONN) { - lwsl_notice("Connect failed errno=%d\n", LWS_ERRNO); - cce = "connect failed"; - goto failed; - } - } - - lwsl_client("connected\n"); - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - /* we are connected to server, or proxy */ - - /* http proxy */ - if (wsi->vhost->http.http_proxy_port) { - - /* - * OK from now on we talk via the proxy, so connect to that - * - * (will overwrite existing pointer, - * leaving old string/frag there but unreferenced) - */ - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, - wsi->vhost->http.http_proxy_address)) - goto failed; - wsi->c_port = wsi->vhost->http.http_proxy_port; - - n = send(wsi->desc.sockfd, (char *)pt->serv_buf, (int)plen, - MSG_NOSIGNAL); - if (n < 0) { - lwsl_debug("ERROR writing to proxy socket\n"); - cce = "proxy write failed"; - goto failed; - } - - lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_PROXY_RESPONSE, - AWAITING_TIMEOUT); - - lwsi_set_state(wsi, LRS_WAITING_PROXY_REPLY); - - return wsi; - } -#endif -#if defined(LWS_WITH_SOCKS5) - /* socks proxy */ - else if (wsi->vhost->socks_proxy_port) { - n = send(wsi->desc.sockfd, (char *)pt->serv_buf, plen, - MSG_NOSIGNAL); - if (n < 0) { - lwsl_debug("ERROR writing socks greeting\n"); - cce = "socks write failed"; - goto failed; - } - - lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SOCKS_GREETING_REPLY, - AWAITING_TIMEOUT); - - lwsi_set_state(wsi, LRS_WAITING_SOCKS_GREETING_REPLY); - - return wsi; - } -#endif -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) -send_hs: - - if (wsi_piggyback && - !lws_dll_is_null(&wsi->dll_client_transaction_queue)) { - /* - * We are pipelining on an already-established connection... - * we can skip tls establishment. - */ - - lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE2); - - /* - * we can't send our headers directly, because they have to - * be sent when the parent is writeable. The parent will check - * for anybody on his client transaction queue that is in - * LRS_H1C_ISSUE_HANDSHAKE2, and let them write. - * - * If we are trying to do this too early, before the master - * connection has written his own headers, then it will just - * wait in the queue until it's possible to send them. - */ - lws_callback_on_writable(wsi_piggyback); - lwsl_info("%s: wsi %p: waiting to send headers (parent state %x)\n", - __func__, wsi, lwsi_state(wsi_piggyback)); - } else { - lwsl_info("%s: wsi %p: client creating own connection\n", - __func__, wsi); - - /* we are making our own connection */ - lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE); - - /* - * provoke service to issue the handshake directly. - * - * we need to do it this way because in the proxy case, this is - * the next state and executed only if and when we get a good - * proxy response inside the state machine... but notice in - * SSL case this may not have sent anything yet with 0 return, - * and won't until many retries from main loop. To stop that - * becoming endless, cover with a timeout. - */ - - lws_set_timeout(wsi, PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE, - AWAITING_TIMEOUT); - - pfd.fd = wsi->desc.sockfd; - pfd.events = LWS_POLLIN; - pfd.revents = LWS_POLLIN; - - n = lws_service_fd(context, &pfd); - if (n < 0) { - cce = "first service failed"; - goto failed; - } - if (n) /* returns 1 on failure after closing wsi */ - return NULL; - } -#endif - return wsi; - -oom4: - if (lwsi_role_client(wsi) && lwsi_state_est(wsi)) { - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, (void *)cce, strlen(cce)); - wsi->already_did_cce = 1; - } - /* take care that we might be inserted in fds already */ - if (wsi->position_in_fds_table != LWS_NO_FDS_POS) - goto failed1; - lws_remove_from_timeout_list(wsi); -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - lws_header_table_detach(wsi, 0); -#endif - lws_client_stash_destroy(wsi); - lws_free_set_NULL(wsi->client_hostname_copy); - lws_free(wsi); - - return NULL; - -failed: - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, (void *)cce, strlen(cce)); - wsi->already_did_cce = 1; -failed1: - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "client_connect2"); - - return NULL; -} - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - -/** - * lws_client_reset() - retarget a connected wsi to start over with a new connection (ie, redirect) - * this only works if still in HTTP, ie, not upgraded yet - * wsi: connection to reset - * address: network address of the new server - * port: port to connect to - * path: uri path to connect to on the new server - * host: host header to send to the new server - */ -LWS_VISIBLE struct lws * -lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port, - const char *path, const char *host) -{ - char origin[300] = "", protocol[300] = "", method[32] = "", - iface[16] = "", alpn[32] = "", *p; - struct lws *wsi = *pwsi; - - if (wsi->redirects == 3) { - lwsl_err("%s: Too many redirects\n", __func__); - return NULL; - } - wsi->redirects++; - - p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN); - if (p) - lws_strncpy(origin, p, sizeof(origin)); - - p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS); - if (p) - lws_strncpy(protocol, p, sizeof(protocol)); - - p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD); - if (p) - lws_strncpy(method, p, sizeof(method)); - - p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_IFACE); - if (p) - lws_strncpy(iface, p, sizeof(iface)); - - p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ALPN); - if (p) - lws_strncpy(alpn, p, sizeof(alpn)); - - lwsl_info("redirect ads='%s', port=%d, path='%s', ssl = %d\n", - address, port, path, ssl); - - /* close the connection by hand */ - -#if defined(LWS_WITH_TLS) - lws_ssl_close(wsi); -#endif - - __remove_wsi_socket_from_fds(wsi); - - if (wsi->context->event_loop_ops->close_handle_manually) - wsi->context->event_loop_ops->close_handle_manually(wsi); - else - compatible_close(wsi->desc.sockfd); - -#if defined(LWS_WITH_TLS) - wsi->tls.use_ssl = ssl; -#else - if (ssl) { - lwsl_err("%s: not configured for ssl\n", __func__); - return NULL; - } -#endif - - wsi->desc.sockfd = LWS_SOCK_INVALID; - lwsi_set_state(wsi, LRS_UNCONNECTED); - wsi->protocol = NULL; - wsi->pending_timeout = NO_PENDING_TIMEOUT; - wsi->c_port = port; - wsi->hdr_parsing_completed = 0; - _lws_header_table_reset(wsi->http.ah); - - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address)) - return NULL; - - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host)) - return NULL; - - if (origin[0]) - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN, - origin)) - return NULL; - if (protocol[0]) - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, - protocol)) - return NULL; - if (method[0]) - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD, - method)) - return NULL; - - if (iface[0]) - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_IFACE, - iface)) - return NULL; - if (alpn[0]) - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ALPN, - alpn)) - return NULL; - - origin[0] = '/'; - strncpy(&origin[1], path, sizeof(origin) - 2); - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, origin)) - return NULL; - - *pwsi = lws_client_connect_2(wsi); - - return *pwsi; -} - -#ifdef LWS_WITH_HTTP_PROXY -hubbub_error -html_parser_cb(const hubbub_token *token, void *pw) -{ - struct lws_rewrite *r = (struct lws_rewrite *)pw; - char buf[1024], *start = buf + LWS_PRE, *p = start, - *end = &buf[sizeof(buf) - 1]; - size_t i; - - switch (token->type) { - case HUBBUB_TOKEN_DOCTYPE: - - p += lws_snprintf(p, end - p, "<!DOCTYPE %.*s %s ", - (int) token->data.doctype.name.len, - token->data.doctype.name.ptr, - token->data.doctype.force_quirks ? - "(force-quirks) " : ""); - - if (token->data.doctype.public_missing) - lwsl_debug("\tpublic: missing\n"); - else - p += lws_snprintf(p, end - p, "PUBLIC \"%.*s\"\n", - (int) token->data.doctype.public_id.len, - token->data.doctype.public_id.ptr); - - if (token->data.doctype.system_missing) - lwsl_debug("\tsystem: missing\n"); - else - p += lws_snprintf(p, end - p, " \"%.*s\">\n", - (int) token->data.doctype.system_id.len, - token->data.doctype.system_id.ptr); - - break; - case HUBBUB_TOKEN_START_TAG: - p += lws_snprintf(p, end - p, "<%.*s", (int)token->data.tag.name.len, - token->data.tag.name.ptr); - -/* (token->data.tag.self_closing) ? - "(self-closing) " : "", - (token->data.tag.n_attributes > 0) ? - "attributes:" : ""); -*/ - for (i = 0; i < token->data.tag.n_attributes; i++) { - if (!hstrcmp(&token->data.tag.attributes[i].name, "href", 4) || - !hstrcmp(&token->data.tag.attributes[i].name, "action", 6) || - !hstrcmp(&token->data.tag.attributes[i].name, "src", 3)) { - const char *pp = (const char *)token->data.tag.attributes[i].value.ptr; - int plen = (int) token->data.tag.attributes[i].value.len; - - if (strncmp(pp, "http:", 5) && strncmp(pp, "https:", 6)) { - - if (!hstrcmp(&token->data.tag.attributes[i].value, - r->from, r->from_len)) { - pp += r->from_len; - plen -= r->from_len; - } - p += lws_snprintf(p, end - p, " %.*s=\"%s/%.*s\"", - (int) token->data.tag.attributes[i].name.len, - token->data.tag.attributes[i].name.ptr, - r->to, plen, pp); - continue; - } - } - - p += lws_snprintf(p, end - p, " %.*s=\"%.*s\"", - (int) token->data.tag.attributes[i].name.len, - token->data.tag.attributes[i].name.ptr, - (int) token->data.tag.attributes[i].value.len, - token->data.tag.attributes[i].value.ptr); - } - p += lws_snprintf(p, end - p, ">"); - break; - case HUBBUB_TOKEN_END_TAG: - p += lws_snprintf(p, end - p, "</%.*s", (int) token->data.tag.name.len, - token->data.tag.name.ptr); -/* - (token->data.tag.self_closing) ? - "(self-closing) " : "", - (token->data.tag.n_attributes > 0) ? - "attributes:" : ""); -*/ - for (i = 0; i < token->data.tag.n_attributes; i++) { - p += lws_snprintf(p, end - p, " %.*s='%.*s'\n", - (int) token->data.tag.attributes[i].name.len, - token->data.tag.attributes[i].name.ptr, - (int) token->data.tag.attributes[i].value.len, - token->data.tag.attributes[i].value.ptr); - } - p += lws_snprintf(p, end - p, ">"); - break; - case HUBBUB_TOKEN_COMMENT: - p += lws_snprintf(p, end - p, "<!-- %.*s -->\n", - (int) token->data.comment.len, - token->data.comment.ptr); - break; - case HUBBUB_TOKEN_CHARACTER: - if (token->data.character.len == 1) { - if (*token->data.character.ptr == '<') { - p += lws_snprintf(p, end - p, "<"); - break; - } - if (*token->data.character.ptr == '>') { - p += lws_snprintf(p, end - p, ">"); - break; - } - if (*token->data.character.ptr == '&') { - p += lws_snprintf(p, end - p, "&"); - break; - } - } - - p += lws_snprintf(p, end - p, "%.*s", (int) token->data.character.len, - token->data.character.ptr); - break; - case HUBBUB_TOKEN_EOF: - p += lws_snprintf(p, end - p, "\n"); - break; - } - - if (user_callback_handle_rxflow(r->wsi->protocol->callback, - r->wsi, LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ, - r->wsi->user_space, start, p - start)) - return -1; - - return HUBBUB_OK; -} -#endif - -#endif - -char * -lws_strdup(const char *s) -{ - char *d = lws_malloc(strlen(s) + 1, "strdup"); - - if (d) - strcpy(d, s); - - return d; -} - -void -lws_client_stash_destroy(struct lws *wsi) -{ - if (!wsi || !wsi->stash) - return; - - lws_free_set_NULL(wsi->stash->address); - lws_free_set_NULL(wsi->stash->path); - lws_free_set_NULL(wsi->stash->host); - lws_free_set_NULL(wsi->stash->origin); - lws_free_set_NULL(wsi->stash->protocol); - lws_free_set_NULL(wsi->stash->method); - lws_free_set_NULL(wsi->stash->iface); - lws_free_set_NULL(wsi->stash->alpn); - - lws_free_set_NULL(wsi->stash); -} - -LWS_VISIBLE struct lws * -lws_client_connect_via_info(struct lws_client_connect_info *i) -{ - struct lws *wsi; - const struct lws_protocols *p; - const char *local = i->protocol; - - if (i->context->requested_kill) - return NULL; - - if (!i->context->protocol_init_done) - lws_protocol_init(i->context); - /* - * If we have .local_protocol_name, use it to select the - * local protocol handler to bind to. Otherwise use .protocol if - * http[s]. - */ - if (i->local_protocol_name) - local = i->local_protocol_name; - - wsi = lws_zalloc(sizeof(struct lws), "client wsi"); - if (wsi == NULL) - goto bail; - - wsi->context = i->context; -#if defined(LWS_ROLE_H1) - /* assert the mode and union status (hdr) clearly */ - lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED, &role_ops_h1); -#else - lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED, &role_ops_raw_skt); -#endif - wsi->desc.sockfd = LWS_SOCK_INVALID; - - /* 1) fill up the wsi with stuff from the connect_info as far as it - * can go. It's because not only is our connection async, we might - * not even be able to get ahold of an ah at this point. - */ - - if (!i->method) /* ie, ws */ -#if defined(LWS_ROLE_WS) - if (lws_create_client_ws_object(i, wsi)) - return NULL; -#else - return NULL; -#endif - - wsi->user_space = NULL; - wsi->pending_timeout = NO_PENDING_TIMEOUT; - wsi->position_in_fds_table = LWS_NO_FDS_POS; - wsi->c_port = i->port; - wsi->vhost = i->vhost; - if (!wsi->vhost) - wsi->vhost = i->context->vhost_list; - - if (!wsi->vhost) { - lwsl_err("At least one vhost in the context is required\n"); - - goto bail; - } - - wsi->protocol = &wsi->vhost->protocols[0]; - wsi->client_pipeline = !!(i->ssl_connection & LCCSCF_PIPELINE); - - /* reasonable place to start */ - lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED, -#if defined(LWS_ROLE_H1) - &role_ops_h1); -#else - &role_ops_raw_skt); -#endif - - /* - * 1) for http[s] connection, allow protocol selection by name - * 2) for ws[s], if local_protocol_name given also use it for - * local protocol binding... this defeats the server - * protocol negotiation if so - * - * Otherwise leave at protocols[0]... the server will tell us - * which protocol we are associated with since we can give it a - * list. - */ - if (/*(i->method || i->local_protocol_name) && */local) { - lwsl_info("binding to %s\n", local); - p = lws_vhost_name_to_protocol(wsi->vhost, local); - if (p) - wsi->protocol = p; - } - - if (wsi && !wsi->user_space && i->userdata) { - wsi->user_space_externally_allocated = 1; - wsi->user_space = i->userdata; - } else - /* if we stay in http, we can assign the user space now, - * otherwise do it after the protocol negotiated - */ - if (i->method) - if (lws_ensure_user_space(wsi)) - goto bail; - -#if defined(LWS_WITH_TLS) - wsi->tls.use_ssl = i->ssl_connection; -#else - if (i->ssl_connection & LCCSCF_USE_SSL) { - lwsl_err("libwebsockets not configured for ssl\n"); - goto bail; - } -#endif - - /* 2) stash the things from connect_info that we can't process without - * an ah. Because if no ah, we will go on the ah waiting list and - * process those things later (after the connect_info and maybe the - * things pointed to have gone out of scope. - */ - - wsi->stash = lws_zalloc(sizeof(*wsi->stash), "client stash"); - if (!wsi->stash) { - lwsl_err("%s: OOM\n", __func__); - goto bail1; - } - - wsi->stash->address = lws_strdup(i->address); - wsi->stash->path = lws_strdup(i->path); - wsi->stash->host = lws_strdup(i->host); - - if (!wsi->stash->address || !wsi->stash->path || !wsi->stash->host) - goto bail1; - - if (i->origin) { - wsi->stash->origin = lws_strdup(i->origin); - if (!wsi->stash->origin) - goto bail1; - } - if (i->protocol) { - wsi->stash->protocol = lws_strdup(i->protocol); - if (!wsi->stash->protocol) - goto bail1; - } - if (i->method) { - wsi->stash->method = lws_strdup(i->method); - if (!wsi->stash->method) - goto bail1; - } - if (i->iface) { - wsi->stash->iface = lws_strdup(i->iface); - if (!wsi->stash->iface) - goto bail1; - } - /* - * For ws, default to http/1.1 only. If i->alpn is set, defer to - * whatever he has set in there (eg, "h2"). - * - * The problem is he has to commit to h2 before he can find out if the - * server has the SETTINGS for ws-over-h2 enabled; if not then ws is - * not possible on that connection. So we only try it if he - * assertively said to use h2 alpn. - */ - if (!i->method && !i->alpn) { - wsi->stash->alpn = lws_strdup("http/1.1"); - if (!wsi->stash->alpn) - goto bail1; - } else - if (i->alpn) { - wsi->stash->alpn = lws_strdup(i->alpn); - if (!wsi->stash->alpn) - goto bail1; - } - - if (i->pwsi) - *i->pwsi = wsi; - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - /* if we went on the waiting list, no probs just return the wsi - * when we get the ah, now or later, he will call - * lws_client_connect_via_info2() below. - */ - if (lws_header_table_attach(wsi, 0) < 0) { - /* - * if we failed here, the connection is already closed - * and freed. - */ - goto bail2; - } - -#endif - - if (i->parent_wsi) { - lwsl_info("%s: created child %p of parent %p\n", __func__, - wsi, i->parent_wsi); - wsi->parent = i->parent_wsi; - wsi->sibling_list = i->parent_wsi->child_list; - i->parent_wsi->child_list = wsi; - } -#ifdef LWS_WITH_HTTP_PROXY - if (i->uri_replace_to) - wsi->http.rw = lws_rewrite_create(wsi, html_parser_cb, - i->uri_replace_from, - i->uri_replace_to); -#endif - - return wsi; - -bail1: - lws_client_stash_destroy(wsi); - -bail: - lws_free(wsi); -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) -bail2: -#endif - if (i->pwsi) - *i->pwsi = NULL; - - return NULL; -} - -struct lws * -lws_client_connect_via_info2(struct lws *wsi) -{ - struct client_info_stash *stash = wsi->stash; - - if (!stash) - return wsi; - - /* - * we're not necessarily in a position to action these right away, - * stash them... we only need during connect phase so into a temp - * allocated stash - */ - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, - stash->address)) - goto bail1; - - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, stash->path)) - goto bail1; - - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, stash->host)) - goto bail1; - - if (stash->origin) - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN, - stash->origin)) - goto bail1; - /* - * this is a list of protocols we tell the server we're okay with - * stash it for later when we compare server response with it - */ - if (stash->protocol) - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, - stash->protocol)) - goto bail1; - if (stash->method) - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD, - stash->method)) - goto bail1; - if (stash->iface) - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_IFACE, - stash->iface)) - goto bail1; - if (stash->alpn) - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ALPN, - stash->alpn)) - goto bail1; - -#if defined(LWS_WITH_SOCKS5) - if (!wsi->vhost->socks_proxy_port) - lws_client_stash_destroy(wsi); -#endif - - wsi->context->count_wsi_allocated++; - - return lws_client_connect_2(wsi); - -bail1: -#if defined(LWS_WITH_SOCKS5) - if (!wsi->vhost->socks_proxy_port) - lws_free_set_NULL(wsi->stash); -#endif - - return NULL; -} - -LWS_VISIBLE struct lws * -lws_client_connect_extended(struct lws_context *context, const char *address, - int port, int ssl_connection, const char *path, - const char *host, const char *origin, - const char *protocol, int ietf_version_or_minus_one, - void *userdata) -{ - struct lws_client_connect_info i; - - memset(&i, 0, sizeof(i)); - - i.context = context; - i.address = address; - i.port = port; - i.ssl_connection = ssl_connection; - i.path = path; - i.host = host; - i.origin = origin; - i.protocol = protocol; - i.ietf_version_or_minus_one = ietf_version_or_minus_one; - i.userdata = userdata; - - return lws_client_connect_via_info(&i); -} - -LWS_VISIBLE struct lws * -lws_client_connect(struct lws_context *context, const char *address, - int port, int ssl_connection, const char *path, - const char *host, const char *origin, - const char *protocol, int ietf_version_or_minus_one) -{ - struct lws_client_connect_info i; - - memset(&i, 0, sizeof(i)); - - i.context = context; - i.address = address; - i.port = port; - i.ssl_connection = ssl_connection; - i.path = path; - i.host = host; - i.origin = origin; - i.protocol = protocol; - i.ietf_version_or_minus_one = ietf_version_or_minus_one; - i.userdata = NULL; - - return lws_client_connect_via_info(&i); -} - -#if defined(LWS_WITH_SOCKS5) -void socks_generate_msg(struct lws *wsi, enum socks_msg_type type, - ssize_t *msg_len) -{ - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - ssize_t len = 0, n, passwd_len; - short net_num; - char *p; - - switch (type) { - case SOCKS_MSG_GREETING: - /* socks version, version 5 only */ - pt->serv_buf[len++] = SOCKS_VERSION_5; - /* number of methods */ - pt->serv_buf[len++] = 2; - /* username password method */ - pt->serv_buf[len++] = SOCKS_AUTH_USERNAME_PASSWORD; - /* no authentication method */ - pt->serv_buf[len++] = SOCKS_AUTH_NO_AUTH; - break; - - case SOCKS_MSG_USERNAME_PASSWORD: - n = strlen(wsi->vhost->socks_user); - passwd_len = strlen(wsi->vhost->socks_password); - - /* the subnegotiation version */ - pt->serv_buf[len++] = SOCKS_SUBNEGOTIATION_VERSION_1; - /* length of the user name */ - pt->serv_buf[len++] = n; - /* user name */ - lws_strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_user, - context->pt_serv_buf_size - len + 1); - len += n; - /* length of the password */ - pt->serv_buf[len++] = passwd_len; - /* password */ - lws_strncpy((char *)&pt->serv_buf[len], wsi->vhost->socks_password, - context->pt_serv_buf_size - len + 1); - len += passwd_len; - break; - - case SOCKS_MSG_CONNECT: - p = (char*)&net_num; - - /* socks version */ - pt->serv_buf[len++] = SOCKS_VERSION_5; - /* socks command */ - pt->serv_buf[len++] = SOCKS_COMMAND_CONNECT; - /* reserved */ - pt->serv_buf[len++] = 0; - /* address type */ - pt->serv_buf[len++] = SOCKS_ATYP_DOMAINNAME; - /* skip length, we fill it in at the end */ - n = len++; - - /* the address we tell SOCKS proxy to connect to */ - lws_strncpy((char *)&(pt->serv_buf[len]), wsi->stash->address, - context->pt_serv_buf_size - len + 1); - len += strlen(wsi->stash->address); - net_num = htons(wsi->c_port); - - /* the port we tell SOCKS proxy to connect to */ - pt->serv_buf[len++] = p[0]; - pt->serv_buf[len++] = p[1]; - - /* the length of the address, excluding port */ - pt->serv_buf[n] = strlen(wsi->stash->address); - break; - - default: - return; - } - - *msg_len = len; -} -#endif diff --git a/thirdparty/libwebsockets/roles/http/client/client.c b/thirdparty/libwebsockets/roles/http/client/client.c deleted file mode 100644 index 5645fa2b7a..0000000000 --- a/thirdparty/libwebsockets/roles/http/client/client.c +++ /dev/null @@ -1,1243 +0,0 @@ -/* - * libwebsockets - lib/client/client.c - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -LWS_VISIBLE LWS_EXTERN void -lws_client_http_body_pending(struct lws *wsi, int something_left_to_send) -{ - wsi->client_http_body_pending = !!something_left_to_send; -} - -/* - * return self, or queued client wsi we are acting on behalf of - * - * That is the TAIL of the queue (new queue elements are added at the HEAD) - */ - -struct lws * -lws_client_wsi_effective(struct lws *wsi) -{ - struct lws_dll_lws *tail = NULL; - - if (!wsi->transaction_from_pipeline_queue || - !wsi->dll_client_transaction_queue_head.next) - return wsi; - - lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, - wsi->dll_client_transaction_queue_head.next) { - tail = d; - } lws_end_foreach_dll_safe(d, d1); - - return lws_container_of(tail, struct lws, - dll_client_transaction_queue); -} - -/* - * return self or the guy we are queued under - * - * REQUIRES VHOST LOCK HELD - */ - -static struct lws * -_lws_client_wsi_master(struct lws *wsi) -{ - struct lws *wsi_eff = wsi; - struct lws_dll_lws *d; - - d = wsi->dll_client_transaction_queue.prev; - while (d) { - wsi_eff = lws_container_of(d, struct lws, - dll_client_transaction_queue_head); - - d = d->prev; - } - - return wsi_eff; -} - -int -lws_client_socket_service(struct lws *wsi, struct lws_pollfd *pollfd, - struct lws *wsi_conn) -{ - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - char *p = (char *)&pt->serv_buf[0]; - struct lws *w; -#if defined(LWS_WITH_TLS) - char ebuf[128]; -#endif - const char *cce = NULL; -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - ssize_t len = 0; - unsigned char c; -#endif - char *sb = p; - int n = 0; -#if defined(LWS_WITH_SOCKS5) - int conn_mode = 0, pending_timeout = 0; -#endif - - if ((pollfd->revents & LWS_POLLOUT) && - wsi->keepalive_active && - wsi->dll_client_transaction_queue_head.next) { - struct lws *wfound = NULL; - - lwsl_debug("%s: pollout HANDSHAKE2\n", __func__); - - /* - * We have a transaction queued that wants to pipeline. - * - * We have to allow it to send headers strictly in the order - * that it was queued, ie, tail-first. - */ - lws_vhost_lock(wsi->vhost); - lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, - wsi->dll_client_transaction_queue_head.next) { - struct lws *w = lws_container_of(d, struct lws, - dll_client_transaction_queue); - - lwsl_debug("%s: %p states 0x%x\n", __func__, w, w->wsistate); - if (lwsi_state(w) == LRS_H1C_ISSUE_HANDSHAKE2) - wfound = w; - } lws_end_foreach_dll_safe(d, d1); - - if (wfound) { - /* - * pollfd has the master sockfd in it... we - * need to use that in HANDSHAKE2 to understand - * which wsi to actually write on - */ - lws_client_socket_service(wfound, pollfd, wsi); - lws_callback_on_writable(wsi); - } else - lwsl_debug("%s: didn't find anything in txn q in HS2\n", - __func__); - - lws_vhost_unlock(wsi->vhost); - - return 0; - } - - switch (lwsi_state(wsi)) { - - case LRS_WAITING_CONNECT: - - /* - * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE - * timeout protection set in client-handshake.c - */ - - if (!lws_client_connect_2(wsi)) { - /* closed */ - lwsl_client("closed\n"); - return -1; - } - - /* either still pending connection, or changed mode */ - return 0; - -#if defined(LWS_WITH_SOCKS5) - /* SOCKS Greeting Reply */ - case LRS_WAITING_SOCKS_GREETING_REPLY: - case LRS_WAITING_SOCKS_AUTH_REPLY: - case LRS_WAITING_SOCKS_CONNECT_REPLY: - - /* handle proxy hung up on us */ - - if (pollfd->revents & LWS_POLLHUP) { - lwsl_warn("SOCKS connection %p (fd=%d) dead\n", - (void *)wsi, pollfd->fd); - goto bail3; - } - - n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0); - if (n < 0) { - if (LWS_ERRNO == LWS_EAGAIN) { - lwsl_debug("SOCKS read EAGAIN, retrying\n"); - return 0; - } - lwsl_err("ERROR reading from SOCKS socket\n"); - goto bail3; - } - - switch (lwsi_state(wsi)) { - - case LRS_WAITING_SOCKS_GREETING_REPLY: - if (pt->serv_buf[0] != SOCKS_VERSION_5) - goto socks_reply_fail; - - if (pt->serv_buf[1] == SOCKS_AUTH_NO_AUTH) { - lwsl_client("SOCKS GR: No Auth Method\n"); - socks_generate_msg(wsi, SOCKS_MSG_CONNECT, &len); - conn_mode = LRS_WAITING_SOCKS_CONNECT_REPLY; - pending_timeout = - PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY; - goto socks_send; - } - - if (pt->serv_buf[1] == SOCKS_AUTH_USERNAME_PASSWORD) { - lwsl_client("SOCKS GR: User/Pw Method\n"); - socks_generate_msg(wsi, - SOCKS_MSG_USERNAME_PASSWORD, - &len); - conn_mode = LRS_WAITING_SOCKS_AUTH_REPLY; - pending_timeout = - PENDING_TIMEOUT_AWAITING_SOCKS_AUTH_REPLY; - goto socks_send; - } - goto socks_reply_fail; - - case LRS_WAITING_SOCKS_AUTH_REPLY: - if (pt->serv_buf[0] != SOCKS_SUBNEGOTIATION_VERSION_1 || - pt->serv_buf[1] != SOCKS_SUBNEGOTIATION_STATUS_SUCCESS) - goto socks_reply_fail; - - lwsl_client("SOCKS password OK, sending connect\n"); - socks_generate_msg(wsi, SOCKS_MSG_CONNECT, &len); - conn_mode = LRS_WAITING_SOCKS_CONNECT_REPLY; - pending_timeout = - PENDING_TIMEOUT_AWAITING_SOCKS_CONNECT_REPLY; -socks_send: - n = send(wsi->desc.sockfd, (char *)pt->serv_buf, len, - MSG_NOSIGNAL); - if (n < 0) { - lwsl_debug("ERROR writing to socks proxy\n"); - goto bail3; - } - - lws_set_timeout(wsi, pending_timeout, AWAITING_TIMEOUT); - lwsi_set_state(wsi, conn_mode); - break; - -socks_reply_fail: - lwsl_notice("socks reply: v%d, err %d\n", - pt->serv_buf[0], pt->serv_buf[1]); - goto bail3; - - case LRS_WAITING_SOCKS_CONNECT_REPLY: - if (pt->serv_buf[0] != SOCKS_VERSION_5 || - pt->serv_buf[1] != SOCKS_REQUEST_REPLY_SUCCESS) - goto socks_reply_fail; - - lwsl_client("socks connect OK\n"); - - /* free stash since we are done with it */ - lws_client_stash_destroy(wsi); - if (lws_hdr_simple_create(wsi, - _WSI_TOKEN_CLIENT_PEER_ADDRESS, - wsi->vhost->socks_proxy_address)) - goto bail3; - - wsi->c_port = wsi->vhost->socks_proxy_port; - - /* clear his proxy connection timeout */ - lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - goto start_ws_handshake; - default: - break; - } - break; -#endif - - case LRS_WAITING_PROXY_REPLY: - - /* handle proxy hung up on us */ - - if (pollfd->revents & LWS_POLLHUP) { - - lwsl_warn("Proxy connection %p (fd=%d) dead\n", - (void *)wsi, pollfd->fd); - - goto bail3; - } - - n = recv(wsi->desc.sockfd, sb, context->pt_serv_buf_size, 0); - if (n < 0) { - if (LWS_ERRNO == LWS_EAGAIN) { - lwsl_debug("Proxy read EAGAIN... retrying\n"); - return 0; - } - lwsl_err("ERROR reading from proxy socket\n"); - goto bail3; - } - - pt->serv_buf[13] = '\0'; - if (strcmp(sb, "HTTP/1.0 200 ") && - strcmp(sb, "HTTP/1.1 200 ")) { - lwsl_err("ERROR proxy: %s\n", sb); - goto bail3; - } - - /* clear his proxy connection timeout */ - - lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - - /* fallthru */ - - case LRS_H1C_ISSUE_HANDSHAKE: - - /* - * we are under PENDING_TIMEOUT_SENT_CLIENT_HANDSHAKE - * timeout protection set in client-handshake.c - * - * take care of our lws_callback_on_writable - * happening at a time when there's no real connection yet - */ -#if defined(LWS_WITH_SOCKS5) -start_ws_handshake: -#endif - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) - return -1; - -#if defined(LWS_WITH_TLS) - /* we can retry this... just cook the SSL BIO the first time */ - - if ((wsi->tls.use_ssl & LCCSCF_USE_SSL) && !wsi->tls.ssl && - lws_ssl_client_bio_create(wsi) < 0) { - cce = "bio_create failed"; - goto bail3; - } - - if (wsi->tls.use_ssl & LCCSCF_USE_SSL) { - n = lws_ssl_client_connect1(wsi); - if (!n) - return 0; - if (n < 0) { - cce = "lws_ssl_client_connect1 failed"; - goto bail3; - } - } else - wsi->tls.ssl = NULL; - - /* fallthru */ - - case LRS_WAITING_SSL: - - if (wsi->tls.use_ssl & LCCSCF_USE_SSL) { - n = lws_ssl_client_connect2(wsi, ebuf, sizeof(ebuf)); - if (!n) - return 0; - if (n < 0) { - cce = ebuf; - goto bail3; - } - } else - wsi->tls.ssl = NULL; -#endif -#if defined (LWS_WITH_HTTP2) - if (wsi->client_h2_alpn) { - /* - * We connected to the server and set up tls, and - * negotiated "h2". - * - * So this is it, we are an h2 master client connection - * now, not an h1 client connection. - */ - lws_tls_server_conn_alpn(wsi); - - /* send the H2 preface to legitimize the connection */ - if (lws_h2_issue_preface(wsi)) { - cce = "error sending h2 preface"; - goto bail3; - } - - break; - } -#endif - lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE2); - lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND, - context->timeout_secs); - - /* fallthru */ - - case LRS_H1C_ISSUE_HANDSHAKE2: - p = lws_generate_client_handshake(wsi, p); - if (p == NULL) { - if (wsi->role_ops == &role_ops_raw_skt || - wsi->role_ops == &role_ops_raw_file) - return 0; - - lwsl_err("Failed to generate handshake for client\n"); - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "chs"); - return 0; - } - - /* send our request to the server */ - lws_latency_pre(context, wsi); - - w = _lws_client_wsi_master(wsi); - lwsl_info("%s: HANDSHAKE2: %p: sending headers on %p (wsistate 0x%x 0x%x)\n", - __func__, wsi, w, wsi->wsistate, w->wsistate); - - n = lws_ssl_capable_write(w, (unsigned char *)sb, (int)(p - sb)); - lws_latency(context, wsi, "send lws_issue_raw", n, - n == p - sb); - switch (n) { - case LWS_SSL_CAPABLE_ERROR: - lwsl_debug("ERROR writing to client socket\n"); - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "cws"); - return 0; - case LWS_SSL_CAPABLE_MORE_SERVICE: - lws_callback_on_writable(wsi); - break; - } - - if (wsi->client_http_body_pending) { - lwsi_set_state(wsi, LRS_ISSUE_HTTP_BODY); - lws_set_timeout(wsi, - PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD, - context->timeout_secs); - /* user code must ask for writable callback */ - break; - } - - lwsi_set_state(wsi, LRS_WAITING_SERVER_REPLY); - wsi->hdr_parsing_completed = 0; - - if (lwsi_state(w) == LRS_IDLING) { - lwsi_set_state(w, LRS_WAITING_SERVER_REPLY); - w->hdr_parsing_completed = 0; -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - w->http.ah->parser_state = WSI_TOKEN_NAME_PART; - w->http.ah->lextable_pos = 0; - /* If we're (re)starting on headers, need other implied init */ - wsi->http.ah->ues = URIES_IDLE; -#endif - } - - lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, - wsi->context->timeout_secs); - - lws_callback_on_writable(w); - - goto client_http_body_sent; - - case LRS_ISSUE_HTTP_BODY: - if (wsi->client_http_body_pending) { - //lws_set_timeout(wsi, - // PENDING_TIMEOUT_CLIENT_ISSUE_PAYLOAD, - // context->timeout_secs); - /* user code must ask for writable callback */ - break; - } -client_http_body_sent: -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - /* prepare ourselves to do the parsing */ - wsi->http.ah->parser_state = WSI_TOKEN_NAME_PART; - wsi->http.ah->lextable_pos = 0; -#endif - lwsi_set_state(wsi, LRS_WAITING_SERVER_REPLY); - lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, - context->timeout_secs); - break; - - case LRS_WAITING_SERVER_REPLY: - /* - * handle server hanging up on us... - * but if there is POLLIN waiting, handle that first - */ - if ((pollfd->revents & (LWS_POLLIN | LWS_POLLHUP)) == - LWS_POLLHUP) { - - lwsl_debug("Server connection %p (fd=%d) dead\n", - (void *)wsi, pollfd->fd); - cce = "Peer hung up"; - goto bail3; - } - - if (!(pollfd->revents & LWS_POLLIN)) - break; - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - /* interpret the server response - * - * HTTP/1.1 101 Switching Protocols - * Upgrade: websocket - * Connection: Upgrade - * Sec-WebSocket-Accept: me89jWimTRKTWwrS3aRrL53YZSo= - * Sec-WebSocket-Nonce: AQIDBAUGBwgJCgsMDQ4PEC== - * Sec-WebSocket-Protocol: chat - * - * we have to take some care here to only take from the - * socket bytewise. The browser may (and has been seen to - * in the case that onopen() performs websocket traffic) - * coalesce both handshake response and websocket traffic - * in one packet, since at that point the connection is - * definitively ready from browser pov. - */ - len = 1; - while (wsi->http.ah->parser_state != WSI_PARSING_COMPLETE && - len > 0) { - int plen = 1; - - n = lws_ssl_capable_read(wsi, &c, 1); - lws_latency(context, wsi, "send lws_issue_raw", n, - n == 1); - switch (n) { - case 0: - case LWS_SSL_CAPABLE_ERROR: - cce = "read failed"; - goto bail3; - case LWS_SSL_CAPABLE_MORE_SERVICE: - return 0; - } - - if (lws_parse(wsi, &c, &plen)) { - lwsl_warn("problems parsing header\n"); - goto bail3; - } - } - - /* - * hs may also be coming in multiple packets, there is a 5-sec - * libwebsocket timeout still active here too, so if parsing did - * not complete just wait for next packet coming in this state - */ - if (wsi->http.ah->parser_state != WSI_PARSING_COMPLETE) - break; - -#endif - - /* - * otherwise deal with the handshake. If there's any - * packet traffic already arrived we'll trigger poll() again - * right away and deal with it that way - */ - return lws_client_interpret_server_handshake(wsi); - -bail3: - lwsl_info("closing conn at LWS_CONNMODE...SERVER_REPLY\n"); - if (cce) - lwsl_info("reason: %s\n", cce); - wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - wsi->user_space, (void *)cce, cce ? strlen(cce) : 0); - wsi->already_did_cce = 1; - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "cbail3"); - return -1; - - default: - break; - } - - return 0; -} - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - -int LWS_WARN_UNUSED_RESULT -lws_http_transaction_completed_client(struct lws *wsi) -{ - struct lws *wsi_eff = lws_client_wsi_effective(wsi); - - lwsl_info("%s: wsi: %p, wsi_eff: %p\n", __func__, wsi, wsi_eff); - - if (user_callback_handle_rxflow(wsi_eff->protocol->callback, - wsi_eff, LWS_CALLBACK_COMPLETED_CLIENT_HTTP, - wsi_eff->user_space, NULL, 0)) { - lwsl_debug("%s: Completed call returned nonzero (role 0x%x)\n", - __func__, lwsi_role(wsi_eff)); - return -1; - } - - /* - * Are we constitutionally capable of having a queue, ie, we are on - * the "active client connections" list? - * - * If not, that's it for us. - */ - - if (lws_dll_is_null(&wsi->dll_active_client_conns)) - return -1; - - /* if this was a queued guy, close him and remove from queue */ - - if (wsi->transaction_from_pipeline_queue) { - lwsl_debug("closing queued wsi %p\n", wsi_eff); - /* so the close doesn't trigger a CCE */ - wsi_eff->already_did_cce = 1; - __lws_close_free_wsi(wsi_eff, - LWS_CLOSE_STATUS_CLIENT_TRANSACTION_DONE, - "queued client done"); - } - - _lws_header_table_reset(wsi->http.ah); - - /* after the first one, they can only be coming from the queue */ - wsi->transaction_from_pipeline_queue = 1; - - wsi->http.rx_content_length = 0; - wsi->hdr_parsing_completed = 0; - - /* is there a new tail after removing that one? */ - wsi_eff = lws_client_wsi_effective(wsi); - - /* - * Do we have something pipelined waiting? - * it's OK if he hasn't managed to send his headers yet... he's next - * in line to do that... - */ - if (wsi_eff == wsi) { - /* - * Nothing pipelined... we should hang around a bit - * in case something turns up... - */ - lwsl_info("%s: nothing pipelined waiting\n", __func__); - lwsi_set_state(wsi, LRS_IDLING); - - lws_set_timeout(wsi, PENDING_TIMEOUT_CLIENT_CONN_IDLE, 5); - - return 0; - } - - /* - * H1: we can serialize the queued guys into the same ah - * H2: everybody needs their own ah until their own STREAM_END - */ - - /* otherwise set ourselves up ready to go again */ - lwsi_set_state(wsi, LRS_WAITING_SERVER_REPLY); - - wsi->http.ah->parser_state = WSI_TOKEN_NAME_PART; - wsi->http.ah->lextable_pos = 0; - - lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, - wsi->context->timeout_secs); - - /* If we're (re)starting on headers, need other implied init */ - wsi->http.ah->ues = URIES_IDLE; - - lwsl_info("%s: %p: new queued transaction as %p\n", __func__, wsi, wsi_eff); - lws_callback_on_writable(wsi); - - return 0; -} - -LWS_VISIBLE LWS_EXTERN unsigned int -lws_http_client_http_response(struct lws *_wsi) -{ - struct lws *wsi; - unsigned int resp; - - if (_wsi->http.ah && _wsi->http.ah->http_response) - return _wsi->http.ah->http_response; - - lws_vhost_lock(_wsi->vhost); - wsi = _lws_client_wsi_master(_wsi); - resp = wsi->http.ah->http_response; - lws_vhost_unlock(_wsi->vhost); - - return resp; -} -#endif -#if defined(LWS_PLAT_OPTEE) -char * -strrchr(const char *s, int c) -{ - char *hit = NULL; - - while (*s) - if (*(s++) == (char)c) - hit = (char *)s - 1; - - return hit; -} - -#define atoll atoi -#endif - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) -int -lws_client_interpret_server_handshake(struct lws *wsi) -{ - int n, port = 0, ssl = 0; - int close_reason = LWS_CLOSE_STATUS_PROTOCOL_ERR; - const char *prot, *ads = NULL, *path, *cce = NULL; - struct allocated_headers *ah = NULL; - struct lws *w = lws_client_wsi_effective(wsi); - char *p, *q; - char new_path[300]; - - lws_client_stash_destroy(wsi); - - ah = wsi->http.ah; - if (!wsi->do_ws) { - /* we are being an http client... - */ -#if defined(LWS_ROLE_H2) - if (wsi->client_h2_alpn || wsi->client_h2_substream) { - lwsl_debug("%s: %p: transitioning to h2 client\n", __func__, wsi); - lws_role_transition(wsi, LWSIFR_CLIENT, - LRS_ESTABLISHED, &role_ops_h2); - } else -#endif - { -#if defined(LWS_ROLE_H1) - { - lwsl_debug("%s: %p: transitioning to h1 client\n", __func__, wsi); - lws_role_transition(wsi, LWSIFR_CLIENT, - LRS_ESTABLISHED, &role_ops_h1); - } -#else - return -1; -#endif - } - - wsi->http.ah = ah; - ah->http_response = 0; - } - - /* - * well, what the server sent looked reasonable for syntax. - * Now let's confirm it sent all the necessary headers - * - * http (non-ws) client will expect something like this - * - * HTTP/1.0.200 - * server:.libwebsockets - * content-type:.text/html - * content-length:.17703 - * set-cookie:.test=LWS_1456736240_336776_COOKIE;Max-Age=360000 - */ - - wsi->http.connection_type = HTTP_CONNECTION_KEEP_ALIVE; - if (!wsi->client_h2_substream) { - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP); - if (wsi->do_ws && !p) { - lwsl_info("no URI\n"); - cce = "HS: URI missing"; - goto bail3; - } - if (!p) { - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP1_0); - wsi->http.connection_type = HTTP_CONNECTION_CLOSE; - } - if (!p) { - cce = "HS: URI missing"; - lwsl_info("no URI\n"); - goto bail3; - } - } else { - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_STATUS); - if (!p) { - cce = "HS: :status missing"; - lwsl_info("no status\n"); - goto bail3; - } - } - n = atoi(p); - if (ah) - ah->http_response = n; - - if (n == 301 || n == 302 || n == 303 || n == 307 || n == 308) { - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_LOCATION); - if (!p) { - cce = "HS: Redirect code but no Location"; - goto bail3; - } - - /* Relative reference absolute path */ - if (p[0] == '/') { -#if defined(LWS_WITH_TLS) - ssl = wsi->tls.use_ssl & LCCSCF_USE_SSL; -#endif - ads = lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_PEER_ADDRESS); - port = wsi->c_port; - /* +1 as lws_client_reset expects leading / omitted */ - path = p + 1; - } - /* Absolute (Full) URI */ - else if (strchr(p, ':')) { - if (lws_parse_uri(p, &prot, &ads, &port, &path)) { - cce = "HS: URI did not parse"; - goto bail3; - } - - if (!strcmp(prot, "wss") || !strcmp(prot, "https")) - ssl = 1; - } - /* Relative reference relative path */ - else { - /* This doesn't try to calculate an absolute path, - * that will be left to the server */ -#if defined(LWS_WITH_TLS) - ssl = wsi->tls.use_ssl & LCCSCF_USE_SSL; -#endif - ads = lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_PEER_ADDRESS); - port = wsi->c_port; - /* +1 as lws_client_reset expects leading / omitted */ - path = new_path + 1; - lws_strncpy(new_path, lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_URI), sizeof(new_path)); - q = strrchr(new_path, '/'); - if (q) - lws_strncpy(q + 1, p, sizeof(new_path) - - (q - new_path) - 1); - else - path = p; - } - -#if defined(LWS_WITH_TLS) - if ((wsi->tls.use_ssl & LCCSCF_USE_SSL) && !ssl) { - cce = "HS: Redirect attempted SSL downgrade"; - goto bail3; - } -#endif - - if (!lws_client_reset(&wsi, ssl, ads, port, path, ads)) { - /* there are two ways to fail out with NULL return... - * simple, early problem where the wsi is intact, or - * we went through with the reconnect attempt and the - * wsi is already closed. In the latter case, the wsi - * has beet set to NULL additionally. - */ - lwsl_err("Redirect failed\n"); - cce = "HS: Redirect failed"; - if (wsi) - goto bail3; - - return 1; - } - return 0; - } - - if (!wsi->do_ws) { - - /* if h1 KA is allowed, enable the queued pipeline guys */ - - if (!wsi->client_h2_alpn && !wsi->client_h2_substream && w == wsi) { /* ie, coming to this for the first time */ - if (wsi->http.connection_type == HTTP_CONNECTION_KEEP_ALIVE) - wsi->keepalive_active = 1; - else { - /* - * Ugh... now the main http connection has seen - * both sides, we learn the server doesn't - * support keepalive. - * - * That means any guys queued on us are going - * to have to be restarted from connect2 with - * their own connections. - */ - - /* - * stick around telling any new guys they can't - * pipeline to this server - */ - wsi->keepalive_rejected = 1; - - lws_vhost_lock(wsi->vhost); - lws_start_foreach_dll_safe(struct lws_dll_lws *, d, d1, - wsi->dll_client_transaction_queue_head.next) { - struct lws *ww = lws_container_of(d, struct lws, - dll_client_transaction_queue); - - /* remove him from our queue */ - lws_dll_lws_remove(&ww->dll_client_transaction_queue); - /* give up on pipelining */ - ww->client_pipeline = 0; - - /* go back to "trying to connect" state */ - lws_role_transition(ww, LWSIFR_CLIENT, - LRS_UNCONNECTED, -#if defined(LWS_ROLE_H1) - &role_ops_h1); -#else -#if defined (LWS_ROLE_H2) - &role_ops_h2); -#else - &role_ops_raw); -#endif -#endif - ww->user_space = NULL; - } lws_end_foreach_dll_safe(d, d1); - lws_vhost_unlock(wsi->vhost); - } - } - -#ifdef LWS_WITH_HTTP_PROXY - wsi->http.perform_rewrite = 0; - if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE)) { - if (!strncmp(lws_hdr_simple_ptr(wsi, - WSI_TOKEN_HTTP_CONTENT_TYPE), - "text/html", 9)) - wsi->http.perform_rewrite = 1; - } -#endif - - /* allocate the per-connection user memory (if any) */ - if (lws_ensure_user_space(wsi)) { - lwsl_err("Problem allocating wsi user mem\n"); - cce = "HS: OOM"; - goto bail2; - } - - /* he may choose to send us stuff in chunked transfer-coding */ - wsi->chunked = 0; - wsi->chunk_remaining = 0; /* ie, next thing is chunk size */ - if (lws_hdr_total_length(wsi, - WSI_TOKEN_HTTP_TRANSFER_ENCODING)) { - wsi->chunked = !strcmp(lws_hdr_simple_ptr(wsi, - WSI_TOKEN_HTTP_TRANSFER_ENCODING), - "chunked"); - /* first thing is hex, after payload there is crlf */ - wsi->chunk_parser = ELCP_HEX; - } - - if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) { - wsi->http.rx_content_length = - atoll(lws_hdr_simple_ptr(wsi, - WSI_TOKEN_HTTP_CONTENT_LENGTH)); - lwsl_info("%s: incoming content length %llu\n", - __func__, (unsigned long long) - wsi->http.rx_content_length); - wsi->http.rx_content_remain = - wsi->http.rx_content_length; - } else /* can't do 1.1 without a content length or chunked */ - if (!wsi->chunked) - wsi->http.connection_type = - HTTP_CONNECTION_CLOSE; - - /* - * we seem to be good to go, give client last chance to check - * headers and OK it - */ - if (w->protocol->callback(w, - LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH, - w->user_space, NULL, 0)) { - - cce = "HS: disallowed by client filter"; - goto bail2; - } - - /* clear his proxy connection timeout */ - lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - - wsi->rxflow_change_to = LWS_RXFLOW_ALLOW; - - /* call him back to inform him he is up */ - if (w->protocol->callback(w, - LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP, - w->user_space, NULL, 0)) { - cce = "HS: disallowed at ESTABLISHED"; - goto bail3; - } - - /* - * for pipelining, master needs to keep his ah... guys who - * queued on him can drop it now though. - */ - - if (w != wsi) - /* free up parsing allocations for queued guy */ - lws_header_table_detach(w, 0); - - lwsl_info("%s: client connection up\n", __func__); - - return 0; - } - -#if defined(LWS_ROLE_WS) - switch (lws_client_ws_upgrade(wsi, &cce)) { - case 2: - goto bail2; - case 3: - goto bail3; - } - - return 0; -#endif - -bail3: - close_reason = LWS_CLOSE_STATUS_NOSTATUS; - -bail2: - if (wsi->protocol) { - n = 0; - if (cce) - n = (int)strlen(cce); - w->protocol->callback(w, - LWS_CALLBACK_CLIENT_CONNECTION_ERROR, - w->user_space, (void *)cce, - (unsigned int)n); - } - wsi->already_did_cce = 1; - - lwsl_info("closing connection due to bail2 connection error\n"); - - /* closing will free up his parsing allocations */ - lws_close_free_wsi(wsi, close_reason, "c hs interp"); - - return 1; -} -#endif - -char * -lws_generate_client_handshake(struct lws *wsi, char *pkt) -{ - char *p = pkt; - const char *meth; - const char *pp = lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_SENT_PROTOCOLS); - - meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD); - if (!meth) { - meth = "GET"; - wsi->do_ws = 1; - } else { - wsi->do_ws = 0; - } - - if (!strcmp(meth, "RAW")) { - lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - lwsl_notice("client transition to raw\n"); - - if (pp) { - const struct lws_protocols *pr; - - pr = lws_vhost_name_to_protocol(wsi->vhost, pp); - - if (!pr) { - lwsl_err("protocol %s not enabled on vhost\n", - pp); - return NULL; - } - - lws_bind_protocol(wsi, pr); - } - - if ((wsi->protocol->callback)(wsi, LWS_CALLBACK_RAW_ADOPT, - wsi->user_space, NULL, 0)) - return NULL; - - lws_role_transition(wsi, 0, LRS_ESTABLISHED, &role_ops_raw_skt); - lws_header_table_detach(wsi, 1); - - return NULL; - } - - /* - * 04 example client handshake - * - * GET /chat HTTP/1.1 - * Host: server.example.com - * Upgrade: websocket - * Connection: Upgrade - * Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== - * Sec-WebSocket-Origin: http://example.com - * Sec-WebSocket-Protocol: chat, superchat - * Sec-WebSocket-Version: 4 - */ - - p += sprintf(p, "%s %s HTTP/1.1\x0d\x0a", meth, - lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI)); - - p += sprintf(p, "Pragma: no-cache\x0d\x0a" - "Cache-Control: no-cache\x0d\x0a"); - - p += sprintf(p, "Host: %s\x0d\x0a", - lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST)); - - if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN)) { - if (lws_check_opt(wsi->context->options, - LWS_SERVER_OPTION_JUST_USE_RAW_ORIGIN)) - p += sprintf(p, "Origin: %s\x0d\x0a", - lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_ORIGIN)); - else - p += sprintf(p, "Origin: http://%s\x0d\x0a", - lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_ORIGIN)); - } -#if defined(LWS_ROLE_WS) - if (wsi->do_ws) - p = lws_generate_client_ws_handshake(wsi, p); -#endif - - /* give userland a chance to append, eg, cookies */ - - if (wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER, - wsi->user_space, &p, - (pkt + wsi->context->pt_serv_buf_size) - p - 12)) - return NULL; - - p += sprintf(p, "\x0d\x0a"); - - return p; -} - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - -LWS_VISIBLE int -lws_http_client_read(struct lws *wsi, char **buf, int *len) -{ - int rlen, n; - - rlen = lws_ssl_capable_read(wsi, (unsigned char *)*buf, *len); - *len = 0; - - // lwsl_notice("%s: rlen %d\n", __func__, rlen); - - /* allow the source to signal he has data again next time */ - lws_change_pollfd(wsi, 0, LWS_POLLIN); - - if (rlen == LWS_SSL_CAPABLE_ERROR) { - lwsl_notice("%s: SSL capable error\n", __func__); - return -1; - } - - if (rlen == 0) - return -1; - - if (rlen < 0) - return 0; - - *len = rlen; - wsi->client_rx_avail = 0; - - /* - * server may insist on transfer-encoding: chunked, - * so http client must deal with it - */ -spin_chunks: - while (wsi->chunked && (wsi->chunk_parser != ELCP_CONTENT) && *len) { - switch (wsi->chunk_parser) { - case ELCP_HEX: - if ((*buf)[0] == '\x0d') { - wsi->chunk_parser = ELCP_CR; - break; - } - n = char_to_hex((*buf)[0]); - if (n < 0) { - lwsl_debug("chunking failure\n"); - return -1; - } - wsi->chunk_remaining <<= 4; - wsi->chunk_remaining |= n; - break; - case ELCP_CR: - if ((*buf)[0] != '\x0a') { - lwsl_debug("chunking failure\n"); - return -1; - } - wsi->chunk_parser = ELCP_CONTENT; - lwsl_info("chunk %d\n", wsi->chunk_remaining); - if (wsi->chunk_remaining) - break; - lwsl_info("final chunk\n"); - goto completed; - - case ELCP_CONTENT: - break; - - case ELCP_POST_CR: - if ((*buf)[0] != '\x0d') { - lwsl_debug("chunking failure\n"); - - return -1; - } - - wsi->chunk_parser = ELCP_POST_LF; - break; - - case ELCP_POST_LF: - if ((*buf)[0] != '\x0a') - return -1; - - wsi->chunk_parser = ELCP_HEX; - wsi->chunk_remaining = 0; - break; - } - (*buf)++; - (*len)--; - } - - if (wsi->chunked && !wsi->chunk_remaining) - return 0; - - if (wsi->http.rx_content_remain && - wsi->http.rx_content_remain < (unsigned int)*len) - n = (int)wsi->http.rx_content_remain; - else - n = *len; - - if (wsi->chunked && wsi->chunk_remaining && - wsi->chunk_remaining < n) - n = wsi->chunk_remaining; - -#ifdef LWS_WITH_HTTP_PROXY - /* hubbub */ - if (wsi->http.perform_rewrite) - lws_rewrite_parse(wsi->http.rw, (unsigned char *)*buf, n); - else -#endif - { - struct lws *wsi_eff = lws_client_wsi_effective(wsi); - - if (user_callback_handle_rxflow(wsi_eff->protocol->callback, - wsi_eff, LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ, - wsi_eff->user_space, *buf, n)) { - lwsl_debug("%s: RECEIVE_CLIENT_HTTP_READ returned -1\n", - __func__); - - return -1; - } - } - - if (wsi->chunked && wsi->chunk_remaining) { - (*buf) += n; - wsi->chunk_remaining -= n; - *len -= n; - } - - if (wsi->chunked && !wsi->chunk_remaining) - wsi->chunk_parser = ELCP_POST_CR; - - if (wsi->chunked && *len) - goto spin_chunks; - - if (wsi->chunked) - return 0; - - /* if we know the content length, decrement the content remaining */ - if (wsi->http.rx_content_length > 0) - wsi->http.rx_content_remain -= n; - - // lwsl_notice("rx_content_remain %lld, rx_content_length %lld\n", - // wsi->http.rx_content_remain, wsi->http.rx_content_length); - - if (wsi->http.rx_content_remain || !wsi->http.rx_content_length) - return 0; - -completed: - - if (lws_http_transaction_completed_client(wsi)) { - lwsl_notice("%s: transaction completed says -1\n", __func__); - return -1; - } - - return 0; -} - -#endif diff --git a/thirdparty/libwebsockets/roles/http/header.c b/thirdparty/libwebsockets/roles/http/header.c deleted file mode 100644 index dbcf27cbd1..0000000000 --- a/thirdparty/libwebsockets/roles/http/header.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" -#include "lextable-strings.h" - - -const unsigned char * -lws_token_to_string(enum lws_token_indexes token) -{ - if ((unsigned int)token >= LWS_ARRAY_SIZE(set)) - return NULL; - - return (unsigned char *)set[token]; -} - -int -lws_add_http_header_by_name(struct lws *wsi, const unsigned char *name, - const unsigned char *value, int length, - unsigned char **p, unsigned char *end) -{ -#ifdef LWS_WITH_HTTP2 - if (lwsi_role_h2(wsi) || lwsi_role_h2_ENCAPSULATION(wsi)) - return lws_add_http2_header_by_name(wsi, name, - value, length, p, end); -#else - (void)wsi; -#endif - if (name) { - while (*p < end && *name) - *((*p)++) = *name++; - if (*p == end) - return 1; - *((*p)++) = ' '; - } - if (*p + length + 3 >= end) - return 1; - - memcpy(*p, value, length); - *p += length; - *((*p)++) = '\x0d'; - *((*p)++) = '\x0a'; - - return 0; -} - -int lws_finalize_http_header(struct lws *wsi, unsigned char **p, - unsigned char *end) -{ -#ifdef LWS_WITH_HTTP2 - if (lwsi_role_h2(wsi) || lwsi_role_h2_ENCAPSULATION(wsi)) - return 0; -#else - (void)wsi; -#endif - if ((lws_intptr_t)(end - *p) < 3) - return 1; - *((*p)++) = '\x0d'; - *((*p)++) = '\x0a'; - - return 0; -} - -int -lws_finalize_write_http_header(struct lws *wsi, unsigned char *start, - unsigned char **pp, unsigned char *end) -{ - unsigned char *p; - int len; - - if (lws_finalize_http_header(wsi, pp, end)) - return 1; - - p = *pp; - len = lws_ptr_diff(p, start); - - if (lws_write(wsi, start, len, LWS_WRITE_HTTP_HEADERS) != len) - return 1; - - return 0; -} - -int -lws_add_http_header_by_token(struct lws *wsi, enum lws_token_indexes token, - const unsigned char *value, int length, - unsigned char **p, unsigned char *end) -{ - const unsigned char *name; -#ifdef LWS_WITH_HTTP2 - if (lwsi_role_h2(wsi) || lwsi_role_h2_ENCAPSULATION(wsi)) - return lws_add_http2_header_by_token(wsi, token, value, - length, p, end); -#endif - name = lws_token_to_string(token); - if (!name) - return 1; - - return lws_add_http_header_by_name(wsi, name, value, length, p, end); -} - -int lws_add_http_header_content_length(struct lws *wsi, - lws_filepos_t content_length, - unsigned char **p, unsigned char *end) -{ - char b[24]; - int n; - - n = sprintf(b, "%llu", (unsigned long long)content_length); - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH, - (unsigned char *)b, n, p, end)) - return 1; - wsi->http.tx_content_length = content_length; - wsi->http.tx_content_remain = content_length; - - lwsl_info("%s: wsi %p: tx_content_length/remain %llu\n", __func__, - wsi, (unsigned long long)content_length); - - return 0; -} - -int -lws_add_http_common_headers(struct lws *wsi, unsigned int code, - const char *content_type, lws_filepos_t content_len, - unsigned char **p, unsigned char *end) -{ - if (lws_add_http_header_status(wsi, code, p, end)) - return 1; - - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, - (unsigned char *)content_type, - (int)strlen(content_type), p, end)) - return 1; - - if (content_len != LWS_ILLEGAL_HTTP_CONTENT_LEN) { - if (lws_add_http_header_content_length(wsi, content_len, p, end)) - return 1; - } else { - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_CONNECTION, - (unsigned char *)"close", 5, - p, end)) - return 1; - - wsi->http.connection_type = HTTP_CONNECTION_CLOSE; - } - - return 0; -} - -STORE_IN_ROM static const char * const err400[] = { - "Bad Request", - "Unauthorized", - "Payment Required", - "Forbidden", - "Not Found", - "Method Not Allowed", - "Not Acceptable", - "Proxy Auth Required", - "Request Timeout", - "Conflict", - "Gone", - "Length Required", - "Precondition Failed", - "Request Entity Too Large", - "Request URI too Long", - "Unsupported Media Type", - "Requested Range Not Satisfiable", - "Expectation Failed" -}; - -STORE_IN_ROM static const char * const err500[] = { - "Internal Server Error", - "Not Implemented", - "Bad Gateway", - "Service Unavailable", - "Gateway Timeout", - "HTTP Version Not Supported" -}; - -int -lws_add_http_header_status(struct lws *wsi, unsigned int _code, - unsigned char **p, unsigned char *end) -{ - STORE_IN_ROM static const char * const hver[] = { - "HTTP/1.0", "HTTP/1.1", "HTTP/2" - }; - const struct lws_protocol_vhost_options *headers; - unsigned int code = _code & LWSAHH_CODE_MASK; - const char *description = "", *p1; - unsigned char code_and_desc[60]; - int n; - -#ifdef LWS_WITH_ACCESS_LOG - wsi->http.access_log.response = code; -#endif - -#ifdef LWS_WITH_HTTP2 - if (lwsi_role_h2(wsi) || lwsi_role_h2_ENCAPSULATION(wsi)) { - n = lws_add_http2_header_status(wsi, code, p, end); - if (n) - return n; - } else -#endif - { - if (code >= 400 && code < (400 + LWS_ARRAY_SIZE(err400))) - description = err400[code - 400]; - if (code >= 500 && code < (500 + LWS_ARRAY_SIZE(err500))) - description = err500[code - 500]; - - if (code == 100) - description = "Continue"; - if (code == 200) - description = "OK"; - if (code == 304) - description = "Not Modified"; - else - if (code >= 300 && code < 400) - description = "Redirect"; - - if (wsi->http.request_version < LWS_ARRAY_SIZE(hver)) - p1 = hver[wsi->http.request_version]; - else - p1 = hver[0]; - - n = sprintf((char *)code_and_desc, "%s %u %s", p1, code, - description); - - if (lws_add_http_header_by_name(wsi, NULL, code_and_desc, n, p, - end)) - return 1; - } - headers = wsi->vhost->headers; - while (headers) { - if (lws_add_http_header_by_name(wsi, - (const unsigned char *)headers->name, - (unsigned char *)headers->value, - (int)strlen(headers->value), p, end)) - return 1; - - headers = headers->next; - } - - if (wsi->context->server_string && - !(_code & LWSAHH_FLAG_NO_SERVER_NAME)) - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_SERVER, - (unsigned char *)wsi->context->server_string, - wsi->context->server_string_len, p, end)) - return 1; - - if (wsi->vhost->options & LWS_SERVER_OPTION_STS) - if (lws_add_http_header_by_name(wsi, (unsigned char *) - "Strict-Transport-Security:", - (unsigned char *)"max-age=15768000 ; " - "includeSubDomains", 36, p, end)) - return 1; - - return 0; -} - -LWS_VISIBLE int -lws_return_http_status(struct lws *wsi, unsigned int code, - const char *html_body) -{ - struct lws_context *context = lws_get_context(wsi); - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - unsigned char *p = pt->serv_buf + LWS_PRE; - unsigned char *start = p; - unsigned char *end = p + context->pt_serv_buf_size - LWS_PRE; - int n = 0, m = 0, len; - char slen[20]; - - if (!wsi->vhost) { - lwsl_err("%s: wsi not bound to vhost\n", __func__); - - return 1; - } -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - if (!wsi->handling_404 && - wsi->vhost->http.error_document_404 && - code == HTTP_STATUS_NOT_FOUND) - /* we should do a redirect, and do the 404 there */ - if (lws_http_redirect(wsi, HTTP_STATUS_FOUND, - (uint8_t *)wsi->vhost->http.error_document_404, - (int)strlen(wsi->vhost->http.error_document_404), - &p, end) > 0) - return 0; -#endif - - /* if the redirect failed, just do a simple status */ - p = start; - - if (!html_body) - html_body = ""; - - if (lws_add_http_header_status(wsi, code, &p, end)) - return 1; - - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, - (unsigned char *)"text/html", 9, - &p, end)) - return 1; - - len = 35 + (int)strlen(html_body) + sprintf(slen, "%d", code); - n = sprintf(slen, "%d", len); - - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH, - (unsigned char *)slen, n, &p, end)) - return 1; - - if (lws_finalize_http_header(wsi, &p, end)) - return 1; - -#if defined(LWS_WITH_HTTP2) - if (wsi->http2_substream) { - unsigned char *body = p + 512; - - /* - * for HTTP/2, the headers must be sent separately, since they - * go out in their own frame. That puts us in a bind that - * we won't always be able to get away with two lws_write()s in - * sequence, since the first may use up the writability due to - * the pipe being choked or SSL_WANT_. - * - * However we do need to send the human-readable body, and the - * END_STREAM. - * - * Solve it by writing the headers now... - */ - m = lws_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS); - if (m != lws_ptr_diff(p, start)) - return 1; - - /* - * ... but stash the body and send it as a priority next - * handle_POLLOUT - */ - - len = sprintf((char *)body, - "<html><body><h1>%u</h1>%s</body></html>", - code, html_body); - wsi->http.tx_content_length = len; - wsi->http.tx_content_remain = len; - - wsi->h2.pending_status_body = lws_malloc(len + LWS_PRE + 1, - "pending status body"); - if (!wsi->h2.pending_status_body) - return -1; - - strcpy(wsi->h2.pending_status_body + LWS_PRE, - (const char *)body); - lws_callback_on_writable(wsi); - - return 0; - } else -#endif - { - /* - * for http/1, we can just append the body after the finalized - * headers and send it all in one go. - */ - p += lws_snprintf((char *)p, end - p - 1, - "<html><body><h1>%u</h1>%s</body></html>", - code, html_body); - - n = lws_ptr_diff(p, start); - m = lws_write(wsi, start, n, LWS_WRITE_HTTP); - if (m != n) - return 1; - } - - return m != n; -} - -LWS_VISIBLE int -lws_http_redirect(struct lws *wsi, int code, const unsigned char *loc, int len, - unsigned char **p, unsigned char *end) -{ - unsigned char *start = *p; - - if (lws_add_http_header_status(wsi, code, p, end)) - return -1; - - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_LOCATION, loc, len, - p, end)) - return -1; - /* - * if we're going with http/1.1 and keepalive, we have to give fake - * content metadata so the client knows we completed the transaction and - * it can do the redirect... - */ - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, - (unsigned char *)"text/html", 9, p, - end)) - return -1; - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH, - (unsigned char *)"0", 1, p, end)) - return -1; - - if (lws_finalize_http_header(wsi, p, end)) - return -1; - - return lws_write(wsi, start, *p - start, LWS_WRITE_HTTP_HEADERS | - LWS_WRITE_H2_STREAM_END); -} diff --git a/thirdparty/libwebsockets/roles/http/lextable-strings.h b/thirdparty/libwebsockets/roles/http/lextable-strings.h deleted file mode 100644 index 631f5cb600..0000000000 --- a/thirdparty/libwebsockets/roles/http/lextable-strings.h +++ /dev/null @@ -1,108 +0,0 @@ -/* set of parsable strings -- ALL LOWER CASE */ - -#if !defined(STORE_IN_ROM) -#define STORE_IN_ROM -#endif - -STORE_IN_ROM static const char * const set[] = { - "get ", - "post ", - "options ", - "host:", - "connection:", - "upgrade:", - "origin:", - "sec-websocket-draft:", - "\x0d\x0a", - - "sec-websocket-extensions:", - "sec-websocket-key1:", - "sec-websocket-key2:", - "sec-websocket-protocol:", - - "sec-websocket-accept:", - "sec-websocket-nonce:", - "http/1.1 ", - "http2-settings:", - - "accept:", - "access-control-request-headers:", - "if-modified-since:", - "if-none-match:", - "accept-encoding:", - "accept-language:", - "pragma:", - "cache-control:", - "authorization:", - "cookie:", - "content-length:", - "content-type:", - "date:", - "range:", - "referer:", - "sec-websocket-key:", - "sec-websocket-version:", - "sec-websocket-origin:", - - ":authority", - ":method", - ":path", - ":scheme", - ":status", - - "accept-charset:", - "accept-ranges:", - "access-control-allow-origin:", - "age:", - "allow:", - "content-disposition:", - "content-encoding:", - "content-language:", - "content-location:", - "content-range:", - "etag:", - "expect:", - "expires:", - "from:", - "if-match:", - "if-range:", - "if-unmodified-since:", - "last-modified:", - "link:", - "location:", - "max-forwards:", - "proxy-authenticate:", - "proxy-authorization:", - "refresh:", - "retry-after:", - "server:", - "set-cookie:", - "strict-transport-security:", - "transfer-encoding:", - "user-agent:", - "vary:", - "via:", - "www-authenticate:", - - "patch", - "put", - "delete", - - "uri-args", /* fake header used for uri-only storage */ - - "proxy ", - "x-real-ip:", - "http/1.0 ", - - "x-forwarded-for", - "connect ", - "head ", - "te:", /* http/2 wants it to reject it */ - "replay-nonce:", /* ACME */ - ":protocol", /* defined in mcmanus-httpbis-h2-ws-02 */ - - "x-auth-token:", - - "", /* not matchable */ - -}; diff --git a/thirdparty/libwebsockets/roles/http/lextable.h b/thirdparty/libwebsockets/roles/http/lextable.h deleted file mode 100644 index 9a8063b157..0000000000 --- a/thirdparty/libwebsockets/roles/http/lextable.h +++ /dev/null @@ -1,838 +0,0 @@ -/* pos 0000: 0 */ 0x67 /* 'g' */, 0x40, 0x00 /* (to 0x0040 state 1) */, - 0x70 /* 'p' */, 0x42, 0x00 /* (to 0x0045 state 5) */, - 0x6F /* 'o' */, 0x51, 0x00 /* (to 0x0057 state 10) */, - 0x68 /* 'h' */, 0x5D, 0x00 /* (to 0x0066 state 18) */, - 0x63 /* 'c' */, 0x69, 0x00 /* (to 0x0075 state 23) */, - 0x75 /* 'u' */, 0x8A, 0x00 /* (to 0x0099 state 34) */, - 0x73 /* 's' */, 0xA0, 0x00 /* (to 0x00B2 state 48) */, - 0x0D /* '.' */, 0xD9, 0x00 /* (to 0x00EE state 68) */, - 0x61 /* 'a' */, 0x31, 0x01 /* (to 0x0149 state 129) */, - 0x69 /* 'i' */, 0x70, 0x01 /* (to 0x018B state 163) */, - 0x64 /* 'd' */, 0x19, 0x02 /* (to 0x0237 state 265) */, - 0x72 /* 'r' */, 0x22, 0x02 /* (to 0x0243 state 270) */, - 0x3A /* ':' */, 0x56, 0x02 /* (to 0x027A state 299) */, - 0x65 /* 'e' */, 0xE8, 0x02 /* (to 0x030F state 409) */, - 0x66 /* 'f' */, 0x04, 0x03 /* (to 0x032E state 425) */, - 0x6C /* 'l' */, 0x26, 0x03 /* (to 0x0353 state 458) */, - 0x6D /* 'm' */, 0x49, 0x03 /* (to 0x0379 state 484) */, - 0x74 /* 't' */, 0xB8, 0x03 /* (to 0x03EB state 578) */, - 0x76 /* 'v' */, 0xD9, 0x03 /* (to 0x040F state 606) */, - 0x77 /* 'w' */, 0xE6, 0x03 /* (to 0x041F state 614) */, - 0x78 /* 'x' */, 0x0D, 0x04 /* (to 0x0449 state 650) */, - 0x08, /* fail */ -/* pos 0040: 1 */ 0xE5 /* 'e' -> */, -/* pos 0041: 2 */ 0xF4 /* 't' -> */, -/* pos 0042: 3 */ 0xA0 /* ' ' -> */, -/* pos 0043: 4 */ 0x00, 0x00 /* - terminal marker 0 - */, -/* pos 0045: 5 */ 0x6F /* 'o' */, 0x0D, 0x00 /* (to 0x0052 state 6) */, - 0x72 /* 'r' */, 0x95, 0x01 /* (to 0x01DD state 211) */, - 0x61 /* 'a' */, 0xE6, 0x03 /* (to 0x0431 state 631) */, - 0x75 /* 'u' */, 0xE8, 0x03 /* (to 0x0436 state 635) */, - 0x08, /* fail */ -/* pos 0052: 6 */ 0xF3 /* 's' -> */, -/* pos 0053: 7 */ 0xF4 /* 't' -> */, -/* pos 0054: 8 */ 0xA0 /* ' ' -> */, -/* pos 0055: 9 */ 0x00, 0x01 /* - terminal marker 1 - */, -/* pos 0057: 10 */ 0x70 /* 'p' */, 0x07, 0x00 /* (to 0x005E state 11) */, - 0x72 /* 'r' */, 0x51, 0x00 /* (to 0x00AB state 42) */, - 0x08, /* fail */ -/* pos 005e: 11 */ 0xF4 /* 't' -> */, -/* pos 005f: 12 */ 0xE9 /* 'i' -> */, -/* pos 0060: 13 */ 0xEF /* 'o' -> */, -/* pos 0061: 14 */ 0xEE /* 'n' -> */, -/* pos 0062: 15 */ 0xF3 /* 's' -> */, -/* pos 0063: 16 */ 0xA0 /* ' ' -> */, -/* pos 0064: 17 */ 0x00, 0x02 /* - terminal marker 2 - */, -/* pos 0066: 18 */ 0x6F /* 'o' */, 0x0A, 0x00 /* (to 0x0070 state 19) */, - 0x74 /* 't' */, 0xBF, 0x00 /* (to 0x0128 state 110) */, - 0x65 /* 'e' */, 0x04, 0x04 /* (to 0x0470 state 676) */, - 0x08, /* fail */ -/* pos 0070: 19 */ 0xF3 /* 's' -> */, -/* pos 0071: 20 */ 0xF4 /* 't' -> */, -/* pos 0072: 21 */ 0xBA /* ':' -> */, -/* pos 0073: 22 */ 0x00, 0x03 /* - terminal marker 3 - */, -/* pos 0075: 23 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x007C state 24) */, - 0x61 /* 'a' */, 0x72, 0x01 /* (to 0x01EA state 217) */, - 0x08, /* fail */ -/* pos 007c: 24 */ 0x6E /* 'n' */, 0x07, 0x00 /* (to 0x0083 state 25) */, - 0x6F /* 'o' */, 0x87, 0x01 /* (to 0x0206 state 243) */, - 0x08, /* fail */ -/* pos 0083: 25 */ 0x6E /* 'n' */, 0x07, 0x00 /* (to 0x008A state 26) */, - 0x74 /* 't' */, 0x86, 0x01 /* (to 0x020C state 248) */, - 0x08, /* fail */ -/* pos 008a: 26 */ 0xE5 /* 'e' -> */, -/* pos 008b: 27 */ 0xE3 /* 'c' -> */, -/* pos 008c: 28 */ 0xF4 /* 't' -> */, -/* pos 008d: 29 */ 0x69 /* 'i' */, 0x07, 0x00 /* (to 0x0094 state 30) */, - 0x20 /* ' ' */, 0xDE, 0x03 /* (to 0x046E state 675) */, - 0x08, /* fail */ -/* pos 0094: 30 */ 0xEF /* 'o' -> */, -/* pos 0095: 31 */ 0xEE /* 'n' -> */, -/* pos 0096: 32 */ 0xBA /* ':' -> */, -/* pos 0097: 33 */ 0x00, 0x04 /* - terminal marker 4 - */, -/* pos 0099: 34 */ 0x70 /* 'p' */, 0x0A, 0x00 /* (to 0x00A3 state 35) */, - 0x73 /* 's' */, 0x68, 0x03 /* (to 0x0404 state 596) */, - 0x72 /* 'r' */, 0xA0, 0x03 /* (to 0x043F state 642) */, - 0x08, /* fail */ -/* pos 00a3: 35 */ 0xE7 /* 'g' -> */, -/* pos 00a4: 36 */ 0xF2 /* 'r' -> */, -/* pos 00a5: 37 */ 0xE1 /* 'a' -> */, -/* pos 00a6: 38 */ 0xE4 /* 'd' -> */, -/* pos 00a7: 39 */ 0xE5 /* 'e' -> */, -/* pos 00a8: 40 */ 0xBA /* ':' -> */, -/* pos 00a9: 41 */ 0x00, 0x05 /* - terminal marker 5 - */, -/* pos 00ab: 42 */ 0xE9 /* 'i' -> */, -/* pos 00ac: 43 */ 0xE7 /* 'g' -> */, -/* pos 00ad: 44 */ 0xE9 /* 'i' -> */, -/* pos 00ae: 45 */ 0xEE /* 'n' -> */, -/* pos 00af: 46 */ 0xBA /* ':' -> */, -/* pos 00b0: 47 */ 0x00, 0x06 /* - terminal marker 6 - */, -/* pos 00b2: 48 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x00B9 state 49) */, - 0x74 /* 't' */, 0x1C, 0x03 /* (to 0x03D1 state 553) */, - 0x08, /* fail */ -/* pos 00b9: 49 */ 0x63 /* 'c' */, 0x0A, 0x00 /* (to 0x00C3 state 50) */, - 0x72 /* 'r' */, 0x05, 0x03 /* (to 0x03C1 state 539) */, - 0x74 /* 't' */, 0x08, 0x03 /* (to 0x03C7 state 544) */, - 0x08, /* fail */ -/* pos 00c3: 50 */ 0xAD /* '-' -> */, -/* pos 00c4: 51 */ 0xF7 /* 'w' -> */, -/* pos 00c5: 52 */ 0xE5 /* 'e' -> */, -/* pos 00c6: 53 */ 0xE2 /* 'b' -> */, -/* pos 00c7: 54 */ 0xF3 /* 's' -> */, -/* pos 00c8: 55 */ 0xEF /* 'o' -> */, -/* pos 00c9: 56 */ 0xE3 /* 'c' -> */, -/* pos 00ca: 57 */ 0xEB /* 'k' -> */, -/* pos 00cb: 58 */ 0xE5 /* 'e' -> */, -/* pos 00cc: 59 */ 0xF4 /* 't' -> */, -/* pos 00cd: 60 */ 0xAD /* '-' -> */, -/* pos 00ce: 61 */ 0x64 /* 'd' */, 0x19, 0x00 /* (to 0x00E7 state 62) */, - 0x65 /* 'e' */, 0x20, 0x00 /* (to 0x00F1 state 70) */, - 0x6B /* 'k' */, 0x29, 0x00 /* (to 0x00FD state 81) */, - 0x70 /* 'p' */, 0x38, 0x00 /* (to 0x010F state 88) */, - 0x61 /* 'a' */, 0x3F, 0x00 /* (to 0x0119 state 97) */, - 0x6E /* 'n' */, 0x44, 0x00 /* (to 0x0121 state 104) */, - 0x76 /* 'v' */, 0x89, 0x01 /* (to 0x0269 state 284) */, - 0x6F /* 'o' */, 0x8F, 0x01 /* (to 0x0272 state 292) */, - 0x08, /* fail */ -/* pos 00e7: 62 */ 0xF2 /* 'r' -> */, -/* pos 00e8: 63 */ 0xE1 /* 'a' -> */, -/* pos 00e9: 64 */ 0xE6 /* 'f' -> */, -/* pos 00ea: 65 */ 0xF4 /* 't' -> */, -/* pos 00eb: 66 */ 0xBA /* ':' -> */, -/* pos 00ec: 67 */ 0x00, 0x07 /* - terminal marker 7 - */, -/* pos 00ee: 68 */ 0x8A /* '.' -> */, -/* pos 00ef: 69 */ 0x00, 0x08 /* - terminal marker 8 - */, -/* pos 00f1: 70 */ 0xF8 /* 'x' -> */, -/* pos 00f2: 71 */ 0xF4 /* 't' -> */, -/* pos 00f3: 72 */ 0xE5 /* 'e' -> */, -/* pos 00f4: 73 */ 0xEE /* 'n' -> */, -/* pos 00f5: 74 */ 0xF3 /* 's' -> */, -/* pos 00f6: 75 */ 0xE9 /* 'i' -> */, -/* pos 00f7: 76 */ 0xEF /* 'o' -> */, -/* pos 00f8: 77 */ 0xEE /* 'n' -> */, -/* pos 00f9: 78 */ 0xF3 /* 's' -> */, -/* pos 00fa: 79 */ 0xBA /* ':' -> */, -/* pos 00fb: 80 */ 0x00, 0x09 /* - terminal marker 9 - */, -/* pos 00fd: 81 */ 0xE5 /* 'e' -> */, -/* pos 00fe: 82 */ 0xF9 /* 'y' -> */, -/* pos 00ff: 83 */ 0x31 /* '1' */, 0x0A, 0x00 /* (to 0x0109 state 84) */, - 0x32 /* '2' */, 0x0A, 0x00 /* (to 0x010C state 86) */, - 0x3A /* ':' */, 0x62, 0x01 /* (to 0x0267 state 283) */, - 0x08, /* fail */ -/* pos 0109: 84 */ 0xBA /* ':' -> */, -/* pos 010a: 85 */ 0x00, 0x0A /* - terminal marker 10 - */, -/* pos 010c: 86 */ 0xBA /* ':' -> */, -/* pos 010d: 87 */ 0x00, 0x0B /* - terminal marker 11 - */, -/* pos 010f: 88 */ 0xF2 /* 'r' -> */, -/* pos 0110: 89 */ 0xEF /* 'o' -> */, -/* pos 0111: 90 */ 0xF4 /* 't' -> */, -/* pos 0112: 91 */ 0xEF /* 'o' -> */, -/* pos 0113: 92 */ 0xE3 /* 'c' -> */, -/* pos 0114: 93 */ 0xEF /* 'o' -> */, -/* pos 0115: 94 */ 0xEC /* 'l' -> */, -/* pos 0116: 95 */ 0xBA /* ':' -> */, -/* pos 0117: 96 */ 0x00, 0x0C /* - terminal marker 12 - */, -/* pos 0119: 97 */ 0xE3 /* 'c' -> */, -/* pos 011a: 98 */ 0xE3 /* 'c' -> */, -/* pos 011b: 99 */ 0xE5 /* 'e' -> */, -/* pos 011c: 100 */ 0xF0 /* 'p' -> */, -/* pos 011d: 101 */ 0xF4 /* 't' -> */, -/* pos 011e: 102 */ 0xBA /* ':' -> */, -/* pos 011f: 103 */ 0x00, 0x0D /* - terminal marker 13 - */, -/* pos 0121: 104 */ 0xEF /* 'o' -> */, -/* pos 0122: 105 */ 0xEE /* 'n' -> */, -/* pos 0123: 106 */ 0xE3 /* 'c' -> */, -/* pos 0124: 107 */ 0xE5 /* 'e' -> */, -/* pos 0125: 108 */ 0xBA /* ':' -> */, -/* pos 0126: 109 */ 0x00, 0x0E /* - terminal marker 14 - */, -/* pos 0128: 110 */ 0xF4 /* 't' -> */, -/* pos 0129: 111 */ 0xF0 /* 'p' -> */, -/* pos 012a: 112 */ 0x2F /* '/' */, 0x07, 0x00 /* (to 0x0131 state 113) */, - 0x32 /* '2' */, 0x10, 0x00 /* (to 0x013D state 118) */, - 0x08, /* fail */ -/* pos 0131: 113 */ 0xB1 /* '1' -> */, -/* pos 0132: 114 */ 0xAE /* '.' -> */, -/* pos 0133: 115 */ 0x31 /* '1' */, 0x07, 0x00 /* (to 0x013A state 116) */, - 0x30 /* '0' */, 0x27, 0x03 /* (to 0x045D state 660) */, - 0x08, /* fail */ -/* pos 013a: 116 */ 0xA0 /* ' ' -> */, -/* pos 013b: 117 */ 0x00, 0x0F /* - terminal marker 15 - */, -/* pos 013d: 118 */ 0xAD /* '-' -> */, -/* pos 013e: 119 */ 0xF3 /* 's' -> */, -/* pos 013f: 120 */ 0xE5 /* 'e' -> */, -/* pos 0140: 121 */ 0xF4 /* 't' -> */, -/* pos 0141: 122 */ 0xF4 /* 't' -> */, -/* pos 0142: 123 */ 0xE9 /* 'i' -> */, -/* pos 0143: 124 */ 0xEE /* 'n' -> */, -/* pos 0144: 125 */ 0xE7 /* 'g' -> */, -/* pos 0145: 126 */ 0xF3 /* 's' -> */, -/* pos 0146: 127 */ 0xBA /* ':' -> */, -/* pos 0147: 128 */ 0x00, 0x10 /* - terminal marker 16 - */, -/* pos 0149: 129 */ 0x63 /* 'c' */, 0x0D, 0x00 /* (to 0x0156 state 130) */, - 0x75 /* 'u' */, 0xAC, 0x00 /* (to 0x01F8 state 230) */, - 0x67 /* 'g' */, 0x86, 0x01 /* (to 0x02D5 state 358) */, - 0x6C /* 'l' */, 0x87, 0x01 /* (to 0x02D9 state 361) */, - 0x08, /* fail */ -/* pos 0156: 130 */ 0xE3 /* 'c' -> */, -/* pos 0157: 131 */ 0xE5 /* 'e' -> */, -/* pos 0158: 132 */ 0x70 /* 'p' */, 0x07, 0x00 /* (to 0x015F state 133) */, - 0x73 /* 's' */, 0x0E, 0x00 /* (to 0x0169 state 136) */, - 0x08, /* fail */ -/* pos 015f: 133 */ 0xF4 /* 't' -> */, -/* pos 0160: 134 */ 0x3A /* ':' */, 0x07, 0x00 /* (to 0x0167 state 135) */, - 0x2D /* '-' */, 0x59, 0x00 /* (to 0x01BC state 192) */, - 0x08, /* fail */ -/* pos 0167: 135 */ 0x00, 0x11 /* - terminal marker 17 - */, -/* pos 0169: 136 */ 0xF3 /* 's' -> */, -/* pos 016a: 137 */ 0xAD /* '-' -> */, -/* pos 016b: 138 */ 0xE3 /* 'c' -> */, -/* pos 016c: 139 */ 0xEF /* 'o' -> */, -/* pos 016d: 140 */ 0xEE /* 'n' -> */, -/* pos 016e: 141 */ 0xF4 /* 't' -> */, -/* pos 016f: 142 */ 0xF2 /* 'r' -> */, -/* pos 0170: 143 */ 0xEF /* 'o' -> */, -/* pos 0171: 144 */ 0xEC /* 'l' -> */, -/* pos 0172: 145 */ 0xAD /* '-' -> */, -/* pos 0173: 146 */ 0x72 /* 'r' */, 0x07, 0x00 /* (to 0x017A state 147) */, - 0x61 /* 'a' */, 0x51, 0x01 /* (to 0x02C7 state 345) */, - 0x08, /* fail */ -/* pos 017a: 147 */ 0xE5 /* 'e' -> */, -/* pos 017b: 148 */ 0xF1 /* 'q' -> */, -/* pos 017c: 149 */ 0xF5 /* 'u' -> */, -/* pos 017d: 150 */ 0xE5 /* 'e' -> */, -/* pos 017e: 151 */ 0xF3 /* 's' -> */, -/* pos 017f: 152 */ 0xF4 /* 't' -> */, -/* pos 0180: 153 */ 0xAD /* '-' -> */, -/* pos 0181: 154 */ 0xE8 /* 'h' -> */, -/* pos 0182: 155 */ 0xE5 /* 'e' -> */, -/* pos 0183: 156 */ 0xE1 /* 'a' -> */, -/* pos 0184: 157 */ 0xE4 /* 'd' -> */, -/* pos 0185: 158 */ 0xE5 /* 'e' -> */, -/* pos 0186: 159 */ 0xF2 /* 'r' -> */, -/* pos 0187: 160 */ 0xF3 /* 's' -> */, -/* pos 0188: 161 */ 0xBA /* ':' -> */, -/* pos 0189: 162 */ 0x00, 0x12 /* - terminal marker 18 - */, -/* pos 018b: 163 */ 0xE6 /* 'f' -> */, -/* pos 018c: 164 */ 0xAD /* '-' -> */, -/* pos 018d: 165 */ 0x6D /* 'm' */, 0x0D, 0x00 /* (to 0x019A state 166) */, - 0x6E /* 'n' */, 0x20, 0x00 /* (to 0x01B0 state 181) */, - 0x72 /* 'r' */, 0xA7, 0x01 /* (to 0x033A state 435) */, - 0x75 /* 'u' */, 0xAB, 0x01 /* (to 0x0341 state 441) */, - 0x08, /* fail */ -/* pos 019a: 166 */ 0x6F /* 'o' */, 0x07, 0x00 /* (to 0x01A1 state 167) */, - 0x61 /* 'a' */, 0x97, 0x01 /* (to 0x0334 state 430) */, - 0x08, /* fail */ -/* pos 01a1: 167 */ 0xE4 /* 'd' -> */, -/* pos 01a2: 168 */ 0xE9 /* 'i' -> */, -/* pos 01a3: 169 */ 0xE6 /* 'f' -> */, -/* pos 01a4: 170 */ 0xE9 /* 'i' -> */, -/* pos 01a5: 171 */ 0xE5 /* 'e' -> */, -/* pos 01a6: 172 */ 0xE4 /* 'd' -> */, -/* pos 01a7: 173 */ 0xAD /* '-' -> */, -/* pos 01a8: 174 */ 0xF3 /* 's' -> */, -/* pos 01a9: 175 */ 0xE9 /* 'i' -> */, -/* pos 01aa: 176 */ 0xEE /* 'n' -> */, -/* pos 01ab: 177 */ 0xE3 /* 'c' -> */, -/* pos 01ac: 178 */ 0xE5 /* 'e' -> */, -/* pos 01ad: 179 */ 0xBA /* ':' -> */, -/* pos 01ae: 180 */ 0x00, 0x13 /* - terminal marker 19 - */, -/* pos 01b0: 181 */ 0xEF /* 'o' -> */, -/* pos 01b1: 182 */ 0xEE /* 'n' -> */, -/* pos 01b2: 183 */ 0xE5 /* 'e' -> */, -/* pos 01b3: 184 */ 0xAD /* '-' -> */, -/* pos 01b4: 185 */ 0xED /* 'm' -> */, -/* pos 01b5: 186 */ 0xE1 /* 'a' -> */, -/* pos 01b6: 187 */ 0xF4 /* 't' -> */, -/* pos 01b7: 188 */ 0xE3 /* 'c' -> */, -/* pos 01b8: 189 */ 0xE8 /* 'h' -> */, -/* pos 01b9: 190 */ 0xBA /* ':' -> */, -/* pos 01ba: 191 */ 0x00, 0x14 /* - terminal marker 20 - */, -/* pos 01bc: 192 */ 0x65 /* 'e' */, 0x0D, 0x00 /* (to 0x01C9 state 193) */, - 0x6C /* 'l' */, 0x14, 0x00 /* (to 0x01D3 state 202) */, - 0x63 /* 'c' */, 0xF4, 0x00 /* (to 0x02B6 state 330) */, - 0x72 /* 'r' */, 0xFA, 0x00 /* (to 0x02BF state 338) */, - 0x08, /* fail */ -/* pos 01c9: 193 */ 0xEE /* 'n' -> */, -/* pos 01ca: 194 */ 0xE3 /* 'c' -> */, -/* pos 01cb: 195 */ 0xEF /* 'o' -> */, -/* pos 01cc: 196 */ 0xE4 /* 'd' -> */, -/* pos 01cd: 197 */ 0xE9 /* 'i' -> */, -/* pos 01ce: 198 */ 0xEE /* 'n' -> */, -/* pos 01cf: 199 */ 0xE7 /* 'g' -> */, -/* pos 01d0: 200 */ 0xBA /* ':' -> */, -/* pos 01d1: 201 */ 0x00, 0x15 /* - terminal marker 21 - */, -/* pos 01d3: 202 */ 0xE1 /* 'a' -> */, -/* pos 01d4: 203 */ 0xEE /* 'n' -> */, -/* pos 01d5: 204 */ 0xE7 /* 'g' -> */, -/* pos 01d6: 205 */ 0xF5 /* 'u' -> */, -/* pos 01d7: 206 */ 0xE1 /* 'a' -> */, -/* pos 01d8: 207 */ 0xE7 /* 'g' -> */, -/* pos 01d9: 208 */ 0xE5 /* 'e' -> */, -/* pos 01da: 209 */ 0xBA /* ':' -> */, -/* pos 01db: 210 */ 0x00, 0x16 /* - terminal marker 22 - */, -/* pos 01dd: 211 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x01E4 state 212) */, - 0x6F /* 'o' */, 0xA7, 0x01 /* (to 0x0387 state 497) */, - 0x08, /* fail */ -/* pos 01e4: 212 */ 0xE7 /* 'g' -> */, -/* pos 01e5: 213 */ 0xED /* 'm' -> */, -/* pos 01e6: 214 */ 0xE1 /* 'a' -> */, -/* pos 01e7: 215 */ 0xBA /* ':' -> */, -/* pos 01e8: 216 */ 0x00, 0x17 /* - terminal marker 23 - */, -/* pos 01ea: 217 */ 0xE3 /* 'c' -> */, -/* pos 01eb: 218 */ 0xE8 /* 'h' -> */, -/* pos 01ec: 219 */ 0xE5 /* 'e' -> */, -/* pos 01ed: 220 */ 0xAD /* '-' -> */, -/* pos 01ee: 221 */ 0xE3 /* 'c' -> */, -/* pos 01ef: 222 */ 0xEF /* 'o' -> */, -/* pos 01f0: 223 */ 0xEE /* 'n' -> */, -/* pos 01f1: 224 */ 0xF4 /* 't' -> */, -/* pos 01f2: 225 */ 0xF2 /* 'r' -> */, -/* pos 01f3: 226 */ 0xEF /* 'o' -> */, -/* pos 01f4: 227 */ 0xEC /* 'l' -> */, -/* pos 01f5: 228 */ 0xBA /* ':' -> */, -/* pos 01f6: 229 */ 0x00, 0x18 /* - terminal marker 24 - */, -/* pos 01f8: 230 */ 0xF4 /* 't' -> */, -/* pos 01f9: 231 */ 0xE8 /* 'h' -> */, -/* pos 01fa: 232 */ 0xEF /* 'o' -> */, -/* pos 01fb: 233 */ 0xF2 /* 'r' -> */, -/* pos 01fc: 234 */ 0xE9 /* 'i' -> */, -/* pos 01fd: 235 */ 0xFA /* 'z' -> */, -/* pos 01fe: 236 */ 0xE1 /* 'a' -> */, -/* pos 01ff: 237 */ 0xF4 /* 't' -> */, -/* pos 0200: 238 */ 0xE9 /* 'i' -> */, -/* pos 0201: 239 */ 0xEF /* 'o' -> */, -/* pos 0202: 240 */ 0xEE /* 'n' -> */, -/* pos 0203: 241 */ 0xBA /* ':' -> */, -/* pos 0204: 242 */ 0x00, 0x19 /* - terminal marker 25 - */, -/* pos 0206: 243 */ 0xEB /* 'k' -> */, -/* pos 0207: 244 */ 0xE9 /* 'i' -> */, -/* pos 0208: 245 */ 0xE5 /* 'e' -> */, -/* pos 0209: 246 */ 0xBA /* ':' -> */, -/* pos 020a: 247 */ 0x00, 0x1A /* - terminal marker 26 - */, -/* pos 020c: 248 */ 0xE5 /* 'e' -> */, -/* pos 020d: 249 */ 0xEE /* 'n' -> */, -/* pos 020e: 250 */ 0xF4 /* 't' -> */, -/* pos 020f: 251 */ 0xAD /* '-' -> */, -/* pos 0210: 252 */ 0x6C /* 'l' */, 0x10, 0x00 /* (to 0x0220 state 253) */, - 0x74 /* 't' */, 0x1E, 0x00 /* (to 0x0231 state 260) */, - 0x64 /* 'd' */, 0xC9, 0x00 /* (to 0x02DF state 366) */, - 0x65 /* 'e' */, 0xD3, 0x00 /* (to 0x02EC state 378) */, - 0x72 /* 'r' */, 0xEC, 0x00 /* (to 0x0308 state 403) */, - 0x08, /* fail */ -/* pos 0220: 253 */ 0x65 /* 'e' */, 0x0A, 0x00 /* (to 0x022A state 254) */, - 0x61 /* 'a' */, 0xD3, 0x00 /* (to 0x02F6 state 387) */, - 0x6F /* 'o' */, 0xD9, 0x00 /* (to 0x02FF state 395) */, - 0x08, /* fail */ -/* pos 022a: 254 */ 0xEE /* 'n' -> */, -/* pos 022b: 255 */ 0xE7 /* 'g' -> */, -/* pos 022c: 256 */ 0xF4 /* 't' -> */, -/* pos 022d: 257 */ 0xE8 /* 'h' -> */, -/* pos 022e: 258 */ 0xBA /* ':' -> */, -/* pos 022f: 259 */ 0x00, 0x1B /* - terminal marker 27 - */, -/* pos 0231: 260 */ 0xF9 /* 'y' -> */, -/* pos 0232: 261 */ 0xF0 /* 'p' -> */, -/* pos 0233: 262 */ 0xE5 /* 'e' -> */, -/* pos 0234: 263 */ 0xBA /* ':' -> */, -/* pos 0235: 264 */ 0x00, 0x1C /* - terminal marker 28 - */, -/* pos 0237: 265 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x023E state 266) */, - 0x65 /* 'e' */, 0xFF, 0x01 /* (to 0x0439 state 637) */, - 0x08, /* fail */ -/* pos 023e: 266 */ 0xF4 /* 't' -> */, -/* pos 023f: 267 */ 0xE5 /* 'e' -> */, -/* pos 0240: 268 */ 0xBA /* ':' -> */, -/* pos 0241: 269 */ 0x00, 0x1D /* - terminal marker 29 - */, -/* pos 0243: 270 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x024A state 271) */, - 0x65 /* 'e' */, 0x0A, 0x00 /* (to 0x0250 state 276) */, - 0x08, /* fail */ -/* pos 024a: 271 */ 0xEE /* 'n' -> */, -/* pos 024b: 272 */ 0xE7 /* 'g' -> */, -/* pos 024c: 273 */ 0xE5 /* 'e' -> */, -/* pos 024d: 274 */ 0xBA /* ':' -> */, -/* pos 024e: 275 */ 0x00, 0x1E /* - terminal marker 30 - */, -/* pos 0250: 276 */ 0x66 /* 'f' */, 0x0A, 0x00 /* (to 0x025A state 277) */, - 0x74 /* 't' */, 0x63, 0x01 /* (to 0x03B6 state 529) */, - 0x70 /* 'p' */, 0x22, 0x02 /* (to 0x0478 state 682) */, - 0x08, /* fail */ -/* pos 025a: 277 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x0261 state 278) */, - 0x72 /* 'r' */, 0x53, 0x01 /* (to 0x03B0 state 524) */, - 0x08, /* fail */ -/* pos 0261: 278 */ 0xF2 /* 'r' -> */, -/* pos 0262: 279 */ 0xE5 /* 'e' -> */, -/* pos 0263: 280 */ 0xF2 /* 'r' -> */, -/* pos 0264: 281 */ 0xBA /* ':' -> */, -/* pos 0265: 282 */ 0x00, 0x1F /* - terminal marker 31 - */, -/* pos 0267: 283 */ 0x00, 0x20 /* - terminal marker 32 - */, -/* pos 0269: 284 */ 0xE5 /* 'e' -> */, -/* pos 026a: 285 */ 0xF2 /* 'r' -> */, -/* pos 026b: 286 */ 0xF3 /* 's' -> */, -/* pos 026c: 287 */ 0xE9 /* 'i' -> */, -/* pos 026d: 288 */ 0xEF /* 'o' -> */, -/* pos 026e: 289 */ 0xEE /* 'n' -> */, -/* pos 026f: 290 */ 0xBA /* ':' -> */, -/* pos 0270: 291 */ 0x00, 0x21 /* - terminal marker 33 - */, -/* pos 0272: 292 */ 0xF2 /* 'r' -> */, -/* pos 0273: 293 */ 0xE9 /* 'i' -> */, -/* pos 0274: 294 */ 0xE7 /* 'g' -> */, -/* pos 0275: 295 */ 0xE9 /* 'i' -> */, -/* pos 0276: 296 */ 0xEE /* 'n' -> */, -/* pos 0277: 297 */ 0xBA /* ':' -> */, -/* pos 0278: 298 */ 0x00, 0x22 /* - terminal marker 34 - */, -/* pos 027a: 299 */ 0x61 /* 'a' */, 0x0D, 0x00 /* (to 0x0287 state 300) */, - 0x6D /* 'm' */, 0x14, 0x00 /* (to 0x0291 state 309) */, - 0x70 /* 'p' */, 0x18, 0x00 /* (to 0x0298 state 315) */, - 0x73 /* 's' */, 0x20, 0x00 /* (to 0x02A3 state 319) */, - 0x08, /* fail */ -/* pos 0287: 300 */ 0xF5 /* 'u' -> */, -/* pos 0288: 301 */ 0xF4 /* 't' -> */, -/* pos 0289: 302 */ 0xE8 /* 'h' -> */, -/* pos 028a: 303 */ 0xEF /* 'o' -> */, -/* pos 028b: 304 */ 0xF2 /* 'r' -> */, -/* pos 028c: 305 */ 0xE9 /* 'i' -> */, -/* pos 028d: 306 */ 0xF4 /* 't' -> */, -/* pos 028e: 307 */ 0xF9 /* 'y' -> */, -/* pos 028f: 308 */ 0x00, 0x23 /* - terminal marker 35 - */, -/* pos 0291: 309 */ 0xE5 /* 'e' -> */, -/* pos 0292: 310 */ 0xF4 /* 't' -> */, -/* pos 0293: 311 */ 0xE8 /* 'h' -> */, -/* pos 0294: 312 */ 0xEF /* 'o' -> */, -/* pos 0295: 313 */ 0xE4 /* 'd' -> */, -/* pos 0296: 314 */ 0x00, 0x24 /* - terminal marker 36 - */, -/* pos 0298: 315 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x029F state 316) */, - 0x72 /* 'r' */, 0xE9, 0x01 /* (to 0x0484 state 693) */, - 0x08, /* fail */ -/* pos 029f: 316 */ 0xF4 /* 't' -> */, -/* pos 02a0: 317 */ 0xE8 /* 'h' -> */, -/* pos 02a1: 318 */ 0x00, 0x25 /* - terminal marker 37 - */, -/* pos 02a3: 319 */ 0x63 /* 'c' */, 0x07, 0x00 /* (to 0x02AA state 320) */, - 0x74 /* 't' */, 0x0A, 0x00 /* (to 0x02B0 state 325) */, - 0x08, /* fail */ -/* pos 02aa: 320 */ 0xE8 /* 'h' -> */, -/* pos 02ab: 321 */ 0xE5 /* 'e' -> */, -/* pos 02ac: 322 */ 0xED /* 'm' -> */, -/* pos 02ad: 323 */ 0xE5 /* 'e' -> */, -/* pos 02ae: 324 */ 0x00, 0x26 /* - terminal marker 38 - */, -/* pos 02b0: 325 */ 0xE1 /* 'a' -> */, -/* pos 02b1: 326 */ 0xF4 /* 't' -> */, -/* pos 02b2: 327 */ 0xF5 /* 'u' -> */, -/* pos 02b3: 328 */ 0xF3 /* 's' -> */, -/* pos 02b4: 329 */ 0x00, 0x27 /* - terminal marker 39 - */, -/* pos 02b6: 330 */ 0xE8 /* 'h' -> */, -/* pos 02b7: 331 */ 0xE1 /* 'a' -> */, -/* pos 02b8: 332 */ 0xF2 /* 'r' -> */, -/* pos 02b9: 333 */ 0xF3 /* 's' -> */, -/* pos 02ba: 334 */ 0xE5 /* 'e' -> */, -/* pos 02bb: 335 */ 0xF4 /* 't' -> */, -/* pos 02bc: 336 */ 0xBA /* ':' -> */, -/* pos 02bd: 337 */ 0x00, 0x28 /* - terminal marker 40 - */, -/* pos 02bf: 338 */ 0xE1 /* 'a' -> */, -/* pos 02c0: 339 */ 0xEE /* 'n' -> */, -/* pos 02c1: 340 */ 0xE7 /* 'g' -> */, -/* pos 02c2: 341 */ 0xE5 /* 'e' -> */, -/* pos 02c3: 342 */ 0xF3 /* 's' -> */, -/* pos 02c4: 343 */ 0xBA /* ':' -> */, -/* pos 02c5: 344 */ 0x00, 0x29 /* - terminal marker 41 - */, -/* pos 02c7: 345 */ 0xEC /* 'l' -> */, -/* pos 02c8: 346 */ 0xEC /* 'l' -> */, -/* pos 02c9: 347 */ 0xEF /* 'o' -> */, -/* pos 02ca: 348 */ 0xF7 /* 'w' -> */, -/* pos 02cb: 349 */ 0xAD /* '-' -> */, -/* pos 02cc: 350 */ 0xEF /* 'o' -> */, -/* pos 02cd: 351 */ 0xF2 /* 'r' -> */, -/* pos 02ce: 352 */ 0xE9 /* 'i' -> */, -/* pos 02cf: 353 */ 0xE7 /* 'g' -> */, -/* pos 02d0: 354 */ 0xE9 /* 'i' -> */, -/* pos 02d1: 355 */ 0xEE /* 'n' -> */, -/* pos 02d2: 356 */ 0xBA /* ':' -> */, -/* pos 02d3: 357 */ 0x00, 0x2A /* - terminal marker 42 - */, -/* pos 02d5: 358 */ 0xE5 /* 'e' -> */, -/* pos 02d6: 359 */ 0xBA /* ':' -> */, -/* pos 02d7: 360 */ 0x00, 0x2B /* - terminal marker 43 - */, -/* pos 02d9: 361 */ 0xEC /* 'l' -> */, -/* pos 02da: 362 */ 0xEF /* 'o' -> */, -/* pos 02db: 363 */ 0xF7 /* 'w' -> */, -/* pos 02dc: 364 */ 0xBA /* ':' -> */, -/* pos 02dd: 365 */ 0x00, 0x2C /* - terminal marker 44 - */, -/* pos 02df: 366 */ 0xE9 /* 'i' -> */, -/* pos 02e0: 367 */ 0xF3 /* 's' -> */, -/* pos 02e1: 368 */ 0xF0 /* 'p' -> */, -/* pos 02e2: 369 */ 0xEF /* 'o' -> */, -/* pos 02e3: 370 */ 0xF3 /* 's' -> */, -/* pos 02e4: 371 */ 0xE9 /* 'i' -> */, -/* pos 02e5: 372 */ 0xF4 /* 't' -> */, -/* pos 02e6: 373 */ 0xE9 /* 'i' -> */, -/* pos 02e7: 374 */ 0xEF /* 'o' -> */, -/* pos 02e8: 375 */ 0xEE /* 'n' -> */, -/* pos 02e9: 376 */ 0xBA /* ':' -> */, -/* pos 02ea: 377 */ 0x00, 0x2D /* - terminal marker 45 - */, -/* pos 02ec: 378 */ 0xEE /* 'n' -> */, -/* pos 02ed: 379 */ 0xE3 /* 'c' -> */, -/* pos 02ee: 380 */ 0xEF /* 'o' -> */, -/* pos 02ef: 381 */ 0xE4 /* 'd' -> */, -/* pos 02f0: 382 */ 0xE9 /* 'i' -> */, -/* pos 02f1: 383 */ 0xEE /* 'n' -> */, -/* pos 02f2: 384 */ 0xE7 /* 'g' -> */, -/* pos 02f3: 385 */ 0xBA /* ':' -> */, -/* pos 02f4: 386 */ 0x00, 0x2E /* - terminal marker 46 - */, -/* pos 02f6: 387 */ 0xEE /* 'n' -> */, -/* pos 02f7: 388 */ 0xE7 /* 'g' -> */, -/* pos 02f8: 389 */ 0xF5 /* 'u' -> */, -/* pos 02f9: 390 */ 0xE1 /* 'a' -> */, -/* pos 02fa: 391 */ 0xE7 /* 'g' -> */, -/* pos 02fb: 392 */ 0xE5 /* 'e' -> */, -/* pos 02fc: 393 */ 0xBA /* ':' -> */, -/* pos 02fd: 394 */ 0x00, 0x2F /* - terminal marker 47 - */, -/* pos 02ff: 395 */ 0xE3 /* 'c' -> */, -/* pos 0300: 396 */ 0xE1 /* 'a' -> */, -/* pos 0301: 397 */ 0xF4 /* 't' -> */, -/* pos 0302: 398 */ 0xE9 /* 'i' -> */, -/* pos 0303: 399 */ 0xEF /* 'o' -> */, -/* pos 0304: 400 */ 0xEE /* 'n' -> */, -/* pos 0305: 401 */ 0xBA /* ':' -> */, -/* pos 0306: 402 */ 0x00, 0x30 /* - terminal marker 48 - */, -/* pos 0308: 403 */ 0xE1 /* 'a' -> */, -/* pos 0309: 404 */ 0xEE /* 'n' -> */, -/* pos 030a: 405 */ 0xE7 /* 'g' -> */, -/* pos 030b: 406 */ 0xE5 /* 'e' -> */, -/* pos 030c: 407 */ 0xBA /* ':' -> */, -/* pos 030d: 408 */ 0x00, 0x31 /* - terminal marker 49 - */, -/* pos 030f: 409 */ 0x74 /* 't' */, 0x07, 0x00 /* (to 0x0316 state 410) */, - 0x78 /* 'x' */, 0x09, 0x00 /* (to 0x031B state 414) */, - 0x08, /* fail */ -/* pos 0316: 410 */ 0xE1 /* 'a' -> */, -/* pos 0317: 411 */ 0xE7 /* 'g' -> */, -/* pos 0318: 412 */ 0xBA /* ':' -> */, -/* pos 0319: 413 */ 0x00, 0x32 /* - terminal marker 50 - */, -/* pos 031b: 414 */ 0xF0 /* 'p' -> */, -/* pos 031c: 415 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x0323 state 416) */, - 0x69 /* 'i' */, 0x09, 0x00 /* (to 0x0328 state 420) */, - 0x08, /* fail */ -/* pos 0323: 416 */ 0xE3 /* 'c' -> */, -/* pos 0324: 417 */ 0xF4 /* 't' -> */, -/* pos 0325: 418 */ 0xBA /* ':' -> */, -/* pos 0326: 419 */ 0x00, 0x33 /* - terminal marker 51 - */, -/* pos 0328: 420 */ 0xF2 /* 'r' -> */, -/* pos 0329: 421 */ 0xE5 /* 'e' -> */, -/* pos 032a: 422 */ 0xF3 /* 's' -> */, -/* pos 032b: 423 */ 0xBA /* ':' -> */, -/* pos 032c: 424 */ 0x00, 0x34 /* - terminal marker 52 - */, -/* pos 032e: 425 */ 0xF2 /* 'r' -> */, -/* pos 032f: 426 */ 0xEF /* 'o' -> */, -/* pos 0330: 427 */ 0xED /* 'm' -> */, -/* pos 0331: 428 */ 0xBA /* ':' -> */, -/* pos 0332: 429 */ 0x00, 0x35 /* - terminal marker 53 - */, -/* pos 0334: 430 */ 0xF4 /* 't' -> */, -/* pos 0335: 431 */ 0xE3 /* 'c' -> */, -/* pos 0336: 432 */ 0xE8 /* 'h' -> */, -/* pos 0337: 433 */ 0xBA /* ':' -> */, -/* pos 0338: 434 */ 0x00, 0x36 /* - terminal marker 54 - */, -/* pos 033a: 435 */ 0xE1 /* 'a' -> */, -/* pos 033b: 436 */ 0xEE /* 'n' -> */, -/* pos 033c: 437 */ 0xE7 /* 'g' -> */, -/* pos 033d: 438 */ 0xE5 /* 'e' -> */, -/* pos 033e: 439 */ 0xBA /* ':' -> */, -/* pos 033f: 440 */ 0x00, 0x37 /* - terminal marker 55 - */, -/* pos 0341: 441 */ 0xEE /* 'n' -> */, -/* pos 0342: 442 */ 0xED /* 'm' -> */, -/* pos 0343: 443 */ 0xEF /* 'o' -> */, -/* pos 0344: 444 */ 0xE4 /* 'd' -> */, -/* pos 0345: 445 */ 0xE9 /* 'i' -> */, -/* pos 0346: 446 */ 0xE6 /* 'f' -> */, -/* pos 0347: 447 */ 0xE9 /* 'i' -> */, -/* pos 0348: 448 */ 0xE5 /* 'e' -> */, -/* pos 0349: 449 */ 0xE4 /* 'd' -> */, -/* pos 034a: 450 */ 0xAD /* '-' -> */, -/* pos 034b: 451 */ 0xF3 /* 's' -> */, -/* pos 034c: 452 */ 0xE9 /* 'i' -> */, -/* pos 034d: 453 */ 0xEE /* 'n' -> */, -/* pos 034e: 454 */ 0xE3 /* 'c' -> */, -/* pos 034f: 455 */ 0xE5 /* 'e' -> */, -/* pos 0350: 456 */ 0xBA /* ':' -> */, -/* pos 0351: 457 */ 0x00, 0x38 /* - terminal marker 56 - */, -/* pos 0353: 458 */ 0x61 /* 'a' */, 0x0A, 0x00 /* (to 0x035D state 459) */, - 0x69 /* 'i' */, 0x15, 0x00 /* (to 0x036B state 472) */, - 0x6F /* 'o' */, 0x17, 0x00 /* (to 0x0370 state 476) */, - 0x08, /* fail */ -/* pos 035d: 459 */ 0xF3 /* 's' -> */, -/* pos 035e: 460 */ 0xF4 /* 't' -> */, -/* pos 035f: 461 */ 0xAD /* '-' -> */, -/* pos 0360: 462 */ 0xED /* 'm' -> */, -/* pos 0361: 463 */ 0xEF /* 'o' -> */, -/* pos 0362: 464 */ 0xE4 /* 'd' -> */, -/* pos 0363: 465 */ 0xE9 /* 'i' -> */, -/* pos 0364: 466 */ 0xE6 /* 'f' -> */, -/* pos 0365: 467 */ 0xE9 /* 'i' -> */, -/* pos 0366: 468 */ 0xE5 /* 'e' -> */, -/* pos 0367: 469 */ 0xE4 /* 'd' -> */, -/* pos 0368: 470 */ 0xBA /* ':' -> */, -/* pos 0369: 471 */ 0x00, 0x39 /* - terminal marker 57 - */, -/* pos 036b: 472 */ 0xEE /* 'n' -> */, -/* pos 036c: 473 */ 0xEB /* 'k' -> */, -/* pos 036d: 474 */ 0xBA /* ':' -> */, -/* pos 036e: 475 */ 0x00, 0x3A /* - terminal marker 58 - */, -/* pos 0370: 476 */ 0xE3 /* 'c' -> */, -/* pos 0371: 477 */ 0xE1 /* 'a' -> */, -/* pos 0372: 478 */ 0xF4 /* 't' -> */, -/* pos 0373: 479 */ 0xE9 /* 'i' -> */, -/* pos 0374: 480 */ 0xEF /* 'o' -> */, -/* pos 0375: 481 */ 0xEE /* 'n' -> */, -/* pos 0376: 482 */ 0xBA /* ':' -> */, -/* pos 0377: 483 */ 0x00, 0x3B /* - terminal marker 59 - */, -/* pos 0379: 484 */ 0xE1 /* 'a' -> */, -/* pos 037a: 485 */ 0xF8 /* 'x' -> */, -/* pos 037b: 486 */ 0xAD /* '-' -> */, -/* pos 037c: 487 */ 0xE6 /* 'f' -> */, -/* pos 037d: 488 */ 0xEF /* 'o' -> */, -/* pos 037e: 489 */ 0xF2 /* 'r' -> */, -/* pos 037f: 490 */ 0xF7 /* 'w' -> */, -/* pos 0380: 491 */ 0xE1 /* 'a' -> */, -/* pos 0381: 492 */ 0xF2 /* 'r' -> */, -/* pos 0382: 493 */ 0xE4 /* 'd' -> */, -/* pos 0383: 494 */ 0xF3 /* 's' -> */, -/* pos 0384: 495 */ 0xBA /* ':' -> */, -/* pos 0385: 496 */ 0x00, 0x3C /* - terminal marker 60 - */, -/* pos 0387: 497 */ 0xF8 /* 'x' -> */, -/* pos 0388: 498 */ 0xF9 /* 'y' -> */, -/* pos 0389: 499 */ 0x2D /* '-' */, 0x07, 0x00 /* (to 0x0390 state 500) */, - 0x20 /* ' ' */, 0xBB, 0x00 /* (to 0x0447 state 649) */, - 0x08, /* fail */ -/* pos 0390: 500 */ 0xE1 /* 'a' -> */, -/* pos 0391: 501 */ 0xF5 /* 'u' -> */, -/* pos 0392: 502 */ 0xF4 /* 't' -> */, -/* pos 0393: 503 */ 0xE8 /* 'h' -> */, -/* pos 0394: 504 */ 0x65 /* 'e' */, 0x07, 0x00 /* (to 0x039B state 505) */, - 0x6F /* 'o' */, 0x0E, 0x00 /* (to 0x03A5 state 514) */, - 0x08, /* fail */ -/* pos 039b: 505 */ 0xEE /* 'n' -> */, -/* pos 039c: 506 */ 0xF4 /* 't' -> */, -/* pos 039d: 507 */ 0xE9 /* 'i' -> */, -/* pos 039e: 508 */ 0xE3 /* 'c' -> */, -/* pos 039f: 509 */ 0xE1 /* 'a' -> */, -/* pos 03a0: 510 */ 0xF4 /* 't' -> */, -/* pos 03a1: 511 */ 0xE5 /* 'e' -> */, -/* pos 03a2: 512 */ 0xBA /* ':' -> */, -/* pos 03a3: 513 */ 0x00, 0x3D /* - terminal marker 61 - */, -/* pos 03a5: 514 */ 0xF2 /* 'r' -> */, -/* pos 03a6: 515 */ 0xE9 /* 'i' -> */, -/* pos 03a7: 516 */ 0xFA /* 'z' -> */, -/* pos 03a8: 517 */ 0xE1 /* 'a' -> */, -/* pos 03a9: 518 */ 0xF4 /* 't' -> */, -/* pos 03aa: 519 */ 0xE9 /* 'i' -> */, -/* pos 03ab: 520 */ 0xEF /* 'o' -> */, -/* pos 03ac: 521 */ 0xEE /* 'n' -> */, -/* pos 03ad: 522 */ 0xBA /* ':' -> */, -/* pos 03ae: 523 */ 0x00, 0x3E /* - terminal marker 62 - */, -/* pos 03b0: 524 */ 0xE5 /* 'e' -> */, -/* pos 03b1: 525 */ 0xF3 /* 's' -> */, -/* pos 03b2: 526 */ 0xE8 /* 'h' -> */, -/* pos 03b3: 527 */ 0xBA /* ':' -> */, -/* pos 03b4: 528 */ 0x00, 0x3F /* - terminal marker 63 - */, -/* pos 03b6: 529 */ 0xF2 /* 'r' -> */, -/* pos 03b7: 530 */ 0xF9 /* 'y' -> */, -/* pos 03b8: 531 */ 0xAD /* '-' -> */, -/* pos 03b9: 532 */ 0xE1 /* 'a' -> */, -/* pos 03ba: 533 */ 0xE6 /* 'f' -> */, -/* pos 03bb: 534 */ 0xF4 /* 't' -> */, -/* pos 03bc: 535 */ 0xE5 /* 'e' -> */, -/* pos 03bd: 536 */ 0xF2 /* 'r' -> */, -/* pos 03be: 537 */ 0xBA /* ':' -> */, -/* pos 03bf: 538 */ 0x00, 0x40 /* - terminal marker 64 - */, -/* pos 03c1: 539 */ 0xF6 /* 'v' -> */, -/* pos 03c2: 540 */ 0xE5 /* 'e' -> */, -/* pos 03c3: 541 */ 0xF2 /* 'r' -> */, -/* pos 03c4: 542 */ 0xBA /* ':' -> */, -/* pos 03c5: 543 */ 0x00, 0x41 /* - terminal marker 65 - */, -/* pos 03c7: 544 */ 0xAD /* '-' -> */, -/* pos 03c8: 545 */ 0xE3 /* 'c' -> */, -/* pos 03c9: 546 */ 0xEF /* 'o' -> */, -/* pos 03ca: 547 */ 0xEF /* 'o' -> */, -/* pos 03cb: 548 */ 0xEB /* 'k' -> */, -/* pos 03cc: 549 */ 0xE9 /* 'i' -> */, -/* pos 03cd: 550 */ 0xE5 /* 'e' -> */, -/* pos 03ce: 551 */ 0xBA /* ':' -> */, -/* pos 03cf: 552 */ 0x00, 0x42 /* - terminal marker 66 - */, -/* pos 03d1: 553 */ 0xF2 /* 'r' -> */, -/* pos 03d2: 554 */ 0xE9 /* 'i' -> */, -/* pos 03d3: 555 */ 0xE3 /* 'c' -> */, -/* pos 03d4: 556 */ 0xF4 /* 't' -> */, -/* pos 03d5: 557 */ 0xAD /* '-' -> */, -/* pos 03d6: 558 */ 0xF4 /* 't' -> */, -/* pos 03d7: 559 */ 0xF2 /* 'r' -> */, -/* pos 03d8: 560 */ 0xE1 /* 'a' -> */, -/* pos 03d9: 561 */ 0xEE /* 'n' -> */, -/* pos 03da: 562 */ 0xF3 /* 's' -> */, -/* pos 03db: 563 */ 0xF0 /* 'p' -> */, -/* pos 03dc: 564 */ 0xEF /* 'o' -> */, -/* pos 03dd: 565 */ 0xF2 /* 'r' -> */, -/* pos 03de: 566 */ 0xF4 /* 't' -> */, -/* pos 03df: 567 */ 0xAD /* '-' -> */, -/* pos 03e0: 568 */ 0xF3 /* 's' -> */, -/* pos 03e1: 569 */ 0xE5 /* 'e' -> */, -/* pos 03e2: 570 */ 0xE3 /* 'c' -> */, -/* pos 03e3: 571 */ 0xF5 /* 'u' -> */, -/* pos 03e4: 572 */ 0xF2 /* 'r' -> */, -/* pos 03e5: 573 */ 0xE9 /* 'i' -> */, -/* pos 03e6: 574 */ 0xF4 /* 't' -> */, -/* pos 03e7: 575 */ 0xF9 /* 'y' -> */, -/* pos 03e8: 576 */ 0xBA /* ':' -> */, -/* pos 03e9: 577 */ 0x00, 0x43 /* - terminal marker 67 - */, -/* pos 03eb: 578 */ 0x72 /* 'r' */, 0x07, 0x00 /* (to 0x03F2 state 579) */, - 0x65 /* 'e' */, 0x87, 0x00 /* (to 0x0475 state 680) */, - 0x08, /* fail */ -/* pos 03f2: 579 */ 0xE1 /* 'a' -> */, -/* pos 03f3: 580 */ 0xEE /* 'n' -> */, -/* pos 03f4: 581 */ 0xF3 /* 's' -> */, -/* pos 03f5: 582 */ 0xE6 /* 'f' -> */, -/* pos 03f6: 583 */ 0xE5 /* 'e' -> */, -/* pos 03f7: 584 */ 0xF2 /* 'r' -> */, -/* pos 03f8: 585 */ 0xAD /* '-' -> */, -/* pos 03f9: 586 */ 0xE5 /* 'e' -> */, -/* pos 03fa: 587 */ 0xEE /* 'n' -> */, -/* pos 03fb: 588 */ 0xE3 /* 'c' -> */, -/* pos 03fc: 589 */ 0xEF /* 'o' -> */, -/* pos 03fd: 590 */ 0xE4 /* 'd' -> */, -/* pos 03fe: 591 */ 0xE9 /* 'i' -> */, -/* pos 03ff: 592 */ 0xEE /* 'n' -> */, -/* pos 0400: 593 */ 0xE7 /* 'g' -> */, -/* pos 0401: 594 */ 0xBA /* ':' -> */, -/* pos 0402: 595 */ 0x00, 0x44 /* - terminal marker 68 - */, -/* pos 0404: 596 */ 0xE5 /* 'e' -> */, -/* pos 0405: 597 */ 0xF2 /* 'r' -> */, -/* pos 0406: 598 */ 0xAD /* '-' -> */, -/* pos 0407: 599 */ 0xE1 /* 'a' -> */, -/* pos 0408: 600 */ 0xE7 /* 'g' -> */, -/* pos 0409: 601 */ 0xE5 /* 'e' -> */, -/* pos 040a: 602 */ 0xEE /* 'n' -> */, -/* pos 040b: 603 */ 0xF4 /* 't' -> */, -/* pos 040c: 604 */ 0xBA /* ':' -> */, -/* pos 040d: 605 */ 0x00, 0x45 /* - terminal marker 69 - */, -/* pos 040f: 606 */ 0x61 /* 'a' */, 0x07, 0x00 /* (to 0x0416 state 607) */, - 0x69 /* 'i' */, 0x09, 0x00 /* (to 0x041B state 611) */, - 0x08, /* fail */ -/* pos 0416: 607 */ 0xF2 /* 'r' -> */, -/* pos 0417: 608 */ 0xF9 /* 'y' -> */, -/* pos 0418: 609 */ 0xBA /* ':' -> */, -/* pos 0419: 610 */ 0x00, 0x46 /* - terminal marker 70 - */, -/* pos 041b: 611 */ 0xE1 /* 'a' -> */, -/* pos 041c: 612 */ 0xBA /* ':' -> */, -/* pos 041d: 613 */ 0x00, 0x47 /* - terminal marker 71 - */, -/* pos 041f: 614 */ 0xF7 /* 'w' -> */, -/* pos 0420: 615 */ 0xF7 /* 'w' -> */, -/* pos 0421: 616 */ 0xAD /* '-' -> */, -/* pos 0422: 617 */ 0xE1 /* 'a' -> */, -/* pos 0423: 618 */ 0xF5 /* 'u' -> */, -/* pos 0424: 619 */ 0xF4 /* 't' -> */, -/* pos 0425: 620 */ 0xE8 /* 'h' -> */, -/* pos 0426: 621 */ 0xE5 /* 'e' -> */, -/* pos 0427: 622 */ 0xEE /* 'n' -> */, -/* pos 0428: 623 */ 0xF4 /* 't' -> */, -/* pos 0429: 624 */ 0xE9 /* 'i' -> */, -/* pos 042a: 625 */ 0xE3 /* 'c' -> */, -/* pos 042b: 626 */ 0xE1 /* 'a' -> */, -/* pos 042c: 627 */ 0xF4 /* 't' -> */, -/* pos 042d: 628 */ 0xE5 /* 'e' -> */, -/* pos 042e: 629 */ 0xBA /* ':' -> */, -/* pos 042f: 630 */ 0x00, 0x48 /* - terminal marker 72 - */, -/* pos 0431: 631 */ 0xF4 /* 't' -> */, -/* pos 0432: 632 */ 0xE3 /* 'c' -> */, -/* pos 0433: 633 */ 0xE8 /* 'h' -> */, -/* pos 0434: 634 */ 0x00, 0x49 /* - terminal marker 73 - */, -/* pos 0436: 635 */ 0xF4 /* 't' -> */, -/* pos 0437: 636 */ 0x00, 0x4A /* - terminal marker 74 - */, -/* pos 0439: 637 */ 0xEC /* 'l' -> */, -/* pos 043a: 638 */ 0xE5 /* 'e' -> */, -/* pos 043b: 639 */ 0xF4 /* 't' -> */, -/* pos 043c: 640 */ 0xE5 /* 'e' -> */, -/* pos 043d: 641 */ 0x00, 0x4B /* - terminal marker 75 - */, -/* pos 043f: 642 */ 0xE9 /* 'i' -> */, -/* pos 0440: 643 */ 0xAD /* '-' -> */, -/* pos 0441: 644 */ 0xE1 /* 'a' -> */, -/* pos 0442: 645 */ 0xF2 /* 'r' -> */, -/* pos 0443: 646 */ 0xE7 /* 'g' -> */, -/* pos 0444: 647 */ 0xF3 /* 's' -> */, -/* pos 0445: 648 */ 0x00, 0x4C /* - terminal marker 76 - */, -/* pos 0447: 649 */ 0x00, 0x4D /* - terminal marker 77 - */, -/* pos 0449: 650 */ 0xAD /* '-' -> */, -/* pos 044a: 651 */ 0x72 /* 'r' */, 0x0A, 0x00 /* (to 0x0454 state 652) */, - 0x66 /* 'f' */, 0x13, 0x00 /* (to 0x0460 state 662) */, - 0x61 /* 'a' */, 0x3C, 0x00 /* (to 0x048C state 700) */, - 0x08, /* fail */ -/* pos 0454: 652 */ 0xE5 /* 'e' -> */, -/* pos 0455: 653 */ 0xE1 /* 'a' -> */, -/* pos 0456: 654 */ 0xEC /* 'l' -> */, -/* pos 0457: 655 */ 0xAD /* '-' -> */, -/* pos 0458: 656 */ 0xE9 /* 'i' -> */, -/* pos 0459: 657 */ 0xF0 /* 'p' -> */, -/* pos 045a: 658 */ 0xBA /* ':' -> */, -/* pos 045b: 659 */ 0x00, 0x4E /* - terminal marker 78 - */, -/* pos 045d: 660 */ 0xA0 /* ' ' -> */, -/* pos 045e: 661 */ 0x00, 0x4F /* - terminal marker 79 - */, -/* pos 0460: 662 */ 0xEF /* 'o' -> */, -/* pos 0461: 663 */ 0xF2 /* 'r' -> */, -/* pos 0462: 664 */ 0xF7 /* 'w' -> */, -/* pos 0463: 665 */ 0xE1 /* 'a' -> */, -/* pos 0464: 666 */ 0xF2 /* 'r' -> */, -/* pos 0465: 667 */ 0xE4 /* 'd' -> */, -/* pos 0466: 668 */ 0xE5 /* 'e' -> */, -/* pos 0467: 669 */ 0xE4 /* 'd' -> */, -/* pos 0468: 670 */ 0xAD /* '-' -> */, -/* pos 0469: 671 */ 0xE6 /* 'f' -> */, -/* pos 046a: 672 */ 0xEF /* 'o' -> */, -/* pos 046b: 673 */ 0xF2 /* 'r' -> */, -/* pos 046c: 674 */ 0x00, 0x50 /* - terminal marker 80 - */, -/* pos 046e: 675 */ 0x00, 0x51 /* - terminal marker 81 - */, -/* pos 0470: 676 */ 0xE1 /* 'a' -> */, -/* pos 0471: 677 */ 0xE4 /* 'd' -> */, -/* pos 0472: 678 */ 0xA0 /* ' ' -> */, -/* pos 0473: 679 */ 0x00, 0x52 /* - terminal marker 82 - */, -/* pos 0475: 680 */ 0xBA /* ':' -> */, -/* pos 0476: 681 */ 0x00, 0x53 /* - terminal marker 83 - */, -/* pos 0478: 682 */ 0xEC /* 'l' -> */, -/* pos 0479: 683 */ 0xE1 /* 'a' -> */, -/* pos 047a: 684 */ 0xF9 /* 'y' -> */, -/* pos 047b: 685 */ 0xAD /* '-' -> */, -/* pos 047c: 686 */ 0xEE /* 'n' -> */, -/* pos 047d: 687 */ 0xEF /* 'o' -> */, -/* pos 047e: 688 */ 0xEE /* 'n' -> */, -/* pos 047f: 689 */ 0xE3 /* 'c' -> */, -/* pos 0480: 690 */ 0xE5 /* 'e' -> */, -/* pos 0481: 691 */ 0xBA /* ':' -> */, -/* pos 0482: 692 */ 0x00, 0x54 /* - terminal marker 84 - */, -/* pos 0484: 693 */ 0xEF /* 'o' -> */, -/* pos 0485: 694 */ 0xF4 /* 't' -> */, -/* pos 0486: 695 */ 0xEF /* 'o' -> */, -/* pos 0487: 696 */ 0xE3 /* 'c' -> */, -/* pos 0488: 697 */ 0xEF /* 'o' -> */, -/* pos 0489: 698 */ 0xEC /* 'l' -> */, -/* pos 048a: 699 */ 0x00, 0x55 /* - terminal marker 85 - */, -/* pos 048c: 700 */ 0xF5 /* 'u' -> */, -/* pos 048d: 701 */ 0xF4 /* 't' -> */, -/* pos 048e: 702 */ 0xE8 /* 'h' -> */, -/* pos 048f: 703 */ 0xAD /* '-' -> */, -/* pos 0490: 704 */ 0xF4 /* 't' -> */, -/* pos 0491: 705 */ 0xEF /* 'o' -> */, -/* pos 0492: 706 */ 0xEB /* 'k' -> */, -/* pos 0493: 707 */ 0xE5 /* 'e' -> */, -/* pos 0494: 708 */ 0xEE /* 'n' -> */, -/* pos 0495: 709 */ 0xBA /* ':' -> */, -/* pos 0496: 710 */ 0x00, 0x56 /* - terminal marker 86 - */, -/* total size 1176 bytes */ diff --git a/thirdparty/libwebsockets/roles/http/private.h b/thirdparty/libwebsockets/roles/http/private.h deleted file mode 100644 index 5699914742..0000000000 --- a/thirdparty/libwebsockets/roles/http/private.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * This is included from core/private.h if either H1 or H2 roles are - * enabled - */ - -#if defined(LWS_WITH_HTTP_PROXY) - #include <hubbub/hubbub.h> - #include <hubbub/parser.h> - #endif - -#define lwsi_role_http(wsi) (lwsi_role_h1(wsi) || lwsi_role_h2(wsi)) - -enum http_version { - HTTP_VERSION_1_0, - HTTP_VERSION_1_1, - HTTP_VERSION_2 -}; - -enum http_connection_type { - HTTP_CONNECTION_CLOSE, - HTTP_CONNECTION_KEEP_ALIVE -}; - -/* - * This is totally opaque to code using the library. It's exported as a - * forward-reference pointer-only declaration; the user can use the pointer with - * other APIs to get information out of it. - */ - -#if defined(LWS_WITH_ESP32) -typedef uint16_t ah_data_idx_t; -#else -typedef uint32_t ah_data_idx_t; -#endif - -struct lws_fragments { - ah_data_idx_t offset; - uint16_t len; - uint8_t nfrag; /* which ah->frag[] continues this content, or 0 */ - uint8_t flags; /* only http2 cares */ -}; - -#if defined(LWS_WITH_RANGES) -enum range_states { - LWSRS_NO_ACTIVE_RANGE, - LWSRS_BYTES_EQ, - LWSRS_FIRST, - LWSRS_STARTING, - LWSRS_ENDING, - LWSRS_COMPLETED, - LWSRS_SYNTAX, -}; - -struct lws_range_parsing { - unsigned long long start, end, extent, agg, budget; - const char buf[128]; - int pos; - enum range_states state; - char start_valid, end_valid, ctr, count_ranges, did_try, inside, send_ctr; -}; - -int -lws_ranges_init(struct lws *wsi, struct lws_range_parsing *rp, - unsigned long long extent); -int -lws_ranges_next(struct lws_range_parsing *rp); -void -lws_ranges_reset(struct lws_range_parsing *rp); -#endif - -/* - * these are assigned from a pool held in the context. - * Both client and server mode uses them for http header analysis - */ - -struct allocated_headers { - struct allocated_headers *next; /* linked list */ - struct lws *wsi; /* owner */ - char *data; /* prepared by context init to point to dedicated storage */ - ah_data_idx_t data_length; - /* - * the randomly ordered fragments, indexed by frag_index and - * lws_fragments->nfrag for continuation. - */ - struct lws_fragments frags[WSI_TOKEN_COUNT]; - time_t assigned; - /* - * for each recognized token, frag_index says which frag[] his data - * starts in (0 means the token did not appear) - * the actual header data gets dumped as it comes in, into data[] - */ - uint8_t frag_index[WSI_TOKEN_COUNT]; - -#ifndef LWS_NO_CLIENT - char initial_handshake_hash_base64[30]; -#endif - - uint32_t pos; - uint32_t http_response; - uint32_t current_token_limit; - int hdr_token_idx; - - int16_t lextable_pos; - - uint8_t in_use; - uint8_t nfrag; - char /*enum uri_path_states */ ups; - char /*enum uri_esc_states */ ues; - - char esc_stash; - char post_literal_equal; - uint8_t /* enum lws_token_indexes */ parser_state; -}; - - - -#if defined(LWS_WITH_HTTP_PROXY) -struct lws_rewrite { - hubbub_parser *parser; - hubbub_parser_optparams params; - const char *from, *to; - int from_len, to_len; - unsigned char *p, *end; - struct lws *wsi; -}; -static LWS_INLINE int hstrcmp(hubbub_string *s, const char *p, int len) -{ - if ((int)s->len != len) - return 1; - - return strncmp((const char *)s->ptr, p, len); -} -typedef hubbub_error (*hubbub_callback_t)(const hubbub_token *token, void *pw); -LWS_EXTERN struct lws_rewrite * -lws_rewrite_create(struct lws *wsi, hubbub_callback_t cb, const char *from, const char *to); -LWS_EXTERN void -lws_rewrite_destroy(struct lws_rewrite *r); -LWS_EXTERN int -lws_rewrite_parse(struct lws_rewrite *r, const unsigned char *in, int in_len); -#endif - -struct lws_pt_role_http { - struct allocated_headers *ah_list; - struct lws *ah_wait_list; -#ifdef LWS_WITH_CGI - struct lws_cgi *cgi_list; -#endif - int ah_wait_list_length; - uint32_t ah_pool_length; - - int ah_count_in_use; -}; - -struct lws_peer_role_http { - uint32_t count_ah; - uint32_t total_ah; -}; - -struct lws_vhost_role_http { - char http_proxy_address[128]; - const struct lws_http_mount *mount_list; - const char *error_document_404; - unsigned int http_proxy_port; -}; - -#ifdef LWS_WITH_ACCESS_LOG -struct lws_access_log { - char *header_log; - char *user_agent; - char *referrer; - unsigned long sent; - int response; -}; -#endif - -struct _lws_http_mode_related { - struct lws *new_wsi_list; - -#if defined(LWS_WITH_HTTP_PROXY) - struct lws_rewrite *rw; -#endif - struct allocated_headers *ah; - struct lws *ah_wait_list; - - lws_filepos_t filepos; - lws_filepos_t filelen; - lws_fop_fd_t fop_fd; - -#if defined(LWS_WITH_RANGES) - struct lws_range_parsing range; - char multipart_content_type[64]; -#endif - -#ifdef LWS_WITH_ACCESS_LOG - struct lws_access_log access_log; -#endif -#ifdef LWS_WITH_CGI - struct lws_cgi *cgi; /* wsi being cgi master have one of these */ -#endif - - enum http_version request_version; - enum http_connection_type connection_type; - lws_filepos_t tx_content_length; - lws_filepos_t tx_content_remain; - lws_filepos_t rx_content_length; - lws_filepos_t rx_content_remain; - -#if defined(LWS_WITH_HTTP_PROXY) - unsigned int perform_rewrite:1; -#endif - unsigned int deferred_transaction_completed:1; -}; - - -#ifndef LWS_NO_CLIENT -enum lws_chunk_parser { - ELCP_HEX, - ELCP_CR, - ELCP_CONTENT, - ELCP_POST_CR, - ELCP_POST_LF, -}; -#endif - -enum lws_parse_urldecode_results { - LPUR_CONTINUE, - LPUR_SWALLOW, - LPUR_FORBID, - LPUR_EXCESSIVE, -}; - -int -lws_read_h1(struct lws *wsi, unsigned char *buf, lws_filepos_t len); - -void -_lws_header_table_reset(struct allocated_headers *ah); - -LWS_EXTERN int -_lws_destroy_ah(struct lws_context_per_thread *pt, struct allocated_headers *ah); diff --git a/thirdparty/libwebsockets/roles/http/server/access-log.c b/thirdparty/libwebsockets/roles/http/server/access-log.c deleted file mode 100644 index 0e75309d7a..0000000000 --- a/thirdparty/libwebsockets/roles/http/server/access-log.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * libwebsockets - server access log handling - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -/* - * Produce Apache-compatible log string for wsi, like this: - * - * 2.31.234.19 - - [27/Mar/2016:03:22:44 +0800] - * "GET /aep-screen.png HTTP/1.1" - * 200 152987 "https://libwebsockets.org/index.html" - * "Mozilla/5.0 (Macint... Chrome/49.0.2623.87 Safari/537.36" - * - */ - -extern const char * const method_names[]; - -static const char * const hver[] = { - "HTTP/1.0", "HTTP/1.1", "HTTP/2" -}; - -void -lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int meth) -{ -#ifdef LWS_WITH_IPV6 - char ads[INET6_ADDRSTRLEN]; -#else - char ads[INET_ADDRSTRLEN]; -#endif - char da[64]; - const char *pa, *me; - struct tm *tmp; - time_t t = time(NULL); - int l = 256, m; - - if (!wsi->vhost) - return; - - /* only worry about preparing it if we store it */ - if (wsi->vhost->log_fd == (int)LWS_INVALID_FILE) - return; - - if (wsi->access_log_pending) - lws_access_log(wsi); - - wsi->http.access_log.header_log = lws_malloc(l, "access log"); - if (wsi->http.access_log.header_log) { - - tmp = localtime(&t); - if (tmp) - strftime(da, sizeof(da), "%d/%b/%Y:%H:%M:%S %z", tmp); - else - strcpy(da, "01/Jan/1970:00:00:00 +0000"); - - pa = lws_get_peer_simple(wsi, ads, sizeof(ads)); - if (!pa) - pa = "(unknown)"; - - if (wsi->http2_substream) - me = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD); - else - me = method_names[meth]; - if (!me) - me = "(null)"; - - lws_snprintf(wsi->http.access_log.header_log, l, - "%s - - [%s] \"%s %s %s\"", - pa, da, me, uri_ptr, - hver[wsi->http.request_version]); - - l = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_USER_AGENT); - if (l) { - wsi->http.access_log.user_agent = lws_malloc(l + 2, "access log"); - if (!wsi->http.access_log.user_agent) { - lwsl_err("OOM getting user agent\n"); - lws_free_set_NULL(wsi->http.access_log.header_log); - return; - } - - lws_hdr_copy(wsi, wsi->http.access_log.user_agent, - l + 1, WSI_TOKEN_HTTP_USER_AGENT); - - for (m = 0; m < l; m++) - if (wsi->http.access_log.user_agent[m] == '\"') - wsi->http.access_log.user_agent[m] = '\''; - } - l = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_REFERER); - if (l) { - wsi->http.access_log.referrer = lws_malloc(l + 2, "referrer"); - if (!wsi->http.access_log.referrer) { - lwsl_err("OOM getting user agent\n"); - lws_free_set_NULL(wsi->http.access_log.user_agent); - lws_free_set_NULL(wsi->http.access_log.header_log); - return; - } - lws_hdr_copy(wsi, wsi->http.access_log.referrer, - l + 1, WSI_TOKEN_HTTP_REFERER); - - for (m = 0; m < l; m++) - if (wsi->http.access_log.referrer[m] == '\"') - wsi->http.access_log.referrer[m] = '\''; - } - wsi->access_log_pending = 1; - } -} - - -int -lws_access_log(struct lws *wsi) -{ - char *p = wsi->http.access_log.user_agent, ass[512], - *p1 = wsi->http.access_log.referrer; - int l; - - if (!wsi->vhost) - return 0; - - if (wsi->vhost->log_fd == (int)LWS_INVALID_FILE) - return 0; - - if (!wsi->access_log_pending) - return 0; - - if (!wsi->http.access_log.header_log) - return 0; - - if (!p) - p = ""; - - if (!p1) - p1 = ""; - - /* - * We do this in two parts to restrict an oversize referrer such that - * we will always have space left to append an empty useragent, while - * maintaining the structure of the log text - */ - l = lws_snprintf(ass, sizeof(ass) - 7, "%s %d %lu \"%s", - wsi->http.access_log.header_log, - wsi->http.access_log.response, wsi->http.access_log.sent, p1); - if (strlen(p) > sizeof(ass) - 6 - l) - p[sizeof(ass) - 6 - l] = '\0'; - l += lws_snprintf(ass + l, sizeof(ass) - 1 - l, "\" \"%s\"\n", p); - - if (write(wsi->vhost->log_fd, ass, l) != l) - lwsl_err("Failed to write log\n"); - - if (wsi->http.access_log.header_log) { - lws_free(wsi->http.access_log.header_log); - wsi->http.access_log.header_log = NULL; - } - if (wsi->http.access_log.user_agent) { - lws_free(wsi->http.access_log.user_agent); - wsi->http.access_log.user_agent = NULL; - } - if (wsi->http.access_log.referrer) { - lws_free(wsi->http.access_log.referrer); - wsi->http.access_log.referrer = NULL; - } - wsi->access_log_pending = 0; - - return 0; -} - diff --git a/thirdparty/libwebsockets/roles/http/server/fops-zip.c b/thirdparty/libwebsockets/roles/http/server/fops-zip.c deleted file mode 100644 index 4db83ce621..0000000000 --- a/thirdparty/libwebsockets/roles/http/server/fops-zip.c +++ /dev/null @@ -1,668 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Original code used in this source file: - * - * https://github.com/PerBothner/DomTerm.git @912add15f3d0aec - * - * ./lws-term/io.c - * ./lws-term/junzip.c - * - * Copyright (C) 2017 Per Bothner <per@bothner.com> - * - * MIT License - * - * 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. - * - * - * lws rewrite: - * - * Copyright (C) 2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -#include <zlib.h> - -/* - * This code works with zip format containers which may have files compressed - * with gzip deflate (type 8) or store uncompressed (type 0). - * - * Linux zip produces such zipfiles by default, eg - * - * $ zip ../myzip.zip file1 file2 file3 - */ - -#define ZIP_COMPRESSION_METHOD_STORE 0 -#define ZIP_COMPRESSION_METHOD_DEFLATE 8 - -typedef struct { - lws_filepos_t filename_start; - uint32_t crc32; - uint32_t comp_size; - uint32_t uncomp_size; - uint32_t offset; - uint32_t mod_time; - uint16_t filename_len; - uint16_t extra; - uint16_t method; - uint16_t file_com_len; -} lws_fops_zip_hdr_t; - -typedef struct { - struct lws_fop_fd fop_fd; /* MUST BE FIRST logical fop_fd into - * file inside zip: fops_zip fops */ - lws_fop_fd_t zip_fop_fd; /* logical fop fd on to zip file - * itself: using platform fops */ - lws_fops_zip_hdr_t hdr; - z_stream inflate; - lws_filepos_t content_start; - lws_filepos_t exp_uncomp_pos; - union { - uint8_t trailer8[8]; - uint32_t trailer32[2]; - } u; - uint8_t rbuf[128]; /* decompression chunk size */ - int entry_count; - - unsigned int decompress:1; /* 0 = direct from file */ - unsigned int add_gzip_container:1; -} *lws_fops_zip_t; - -struct lws_plat_file_ops fops_zip; -#define fop_fd_to_priv(FD) ((lws_fops_zip_t)(FD)) - -static const uint8_t hd[] = { 31, 139, 8, 0, 0, 0, 0, 0, 0, 3 }; - -enum { - ZC_SIGNATURE = 0, - ZC_VERSION_MADE_BY = 4, - ZC_VERSION_NEEDED_TO_EXTRACT = 6, - ZC_GENERAL_PURPOSE_BIT_FLAG = 8, - ZC_COMPRESSION_METHOD = 10, - ZC_LAST_MOD_FILE_TIME = 12, - ZC_LAST_MOD_FILE_DATE = 14, - ZC_CRC32 = 16, - ZC_COMPRESSED_SIZE = 20, - ZC_UNCOMPRESSED_SIZE = 24, - ZC_FILE_NAME_LENGTH = 28, - ZC_EXTRA_FIELD_LENGTH = 30, - - ZC_FILE_COMMENT_LENGTH = 32, - ZC_DISK_NUMBER_START = 34, - ZC_INTERNAL_FILE_ATTRIBUTES = 36, - ZC_EXTERNAL_FILE_ATTRIBUTES = 38, - ZC_REL_OFFSET_LOCAL_HEADER = 42, - ZC_DIRECTORY_LENGTH = 46, - - ZE_SIGNATURE_OFFSET = 0, - ZE_DESK_NUMBER = 4, - ZE_CENTRAL_DIRECTORY_DISK_NUMBER = 6, - ZE_NUM_ENTRIES_THIS_DISK = 8, - ZE_NUM_ENTRIES = 10, - ZE_CENTRAL_DIRECTORY_SIZE = 12, - ZE_CENTRAL_DIR_OFFSET = 16, - ZE_ZIP_COMMENT_LENGTH = 20, - ZE_DIRECTORY_LENGTH = 22, - - ZL_REL_OFFSET_CONTENT = 28, - ZL_HEADER_LENGTH = 30, - - LWS_FZ_ERR_SEEK_END_RECORD = 1, - LWS_FZ_ERR_READ_END_RECORD, - LWS_FZ_ERR_END_RECORD_MAGIC, - LWS_FZ_ERR_END_RECORD_SANITY, - LWS_FZ_ERR_CENTRAL_SEEK, - LWS_FZ_ERR_CENTRAL_READ, - LWS_FZ_ERR_CENTRAL_SANITY, - LWS_FZ_ERR_NAME_TOO_LONG, - LWS_FZ_ERR_NAME_SEEK, - LWS_FZ_ERR_NAME_READ, - LWS_FZ_ERR_CONTENT_SANITY, - LWS_FZ_ERR_CONTENT_SEEK, - LWS_FZ_ERR_SCAN_SEEK, - LWS_FZ_ERR_NOT_FOUND, - LWS_FZ_ERR_ZLIB_INIT, - LWS_FZ_ERR_READ_CONTENT, - LWS_FZ_ERR_SEEK_COMPRESSED, -}; - -static uint16_t -get_u16(void *p) -{ - const uint8_t *c = (const uint8_t *)p; - - return (uint16_t)((c[0] | (c[1] << 8))); -} - -static uint32_t -get_u32(void *p) -{ - const uint8_t *c = (const uint8_t *)p; - - return (uint32_t)((c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24))); -} - -int -lws_fops_zip_scan(lws_fops_zip_t priv, const char *name, int len) -{ - lws_filepos_t amount; - uint8_t buf[96]; - int i; - - if (lws_vfs_file_seek_end(priv->zip_fop_fd, -ZE_DIRECTORY_LENGTH) < 0) - return LWS_FZ_ERR_SEEK_END_RECORD; - - if (lws_vfs_file_read(priv->zip_fop_fd, &amount, buf, - ZE_DIRECTORY_LENGTH)) - return LWS_FZ_ERR_READ_END_RECORD; - - if (amount != ZE_DIRECTORY_LENGTH) - return LWS_FZ_ERR_READ_END_RECORD; - - /* - * We require the zip to have the last record right at the end - * Linux zip always does this if no zip comment. - */ - if (buf[0] != 'P' || buf[1] != 'K' || buf[2] != 5 || buf[3] != 6) - return LWS_FZ_ERR_END_RECORD_MAGIC; - - i = get_u16(buf + ZE_NUM_ENTRIES); - - if (get_u16(buf + ZE_DESK_NUMBER) || - get_u16(buf + ZE_CENTRAL_DIRECTORY_DISK_NUMBER) || - i != get_u16(buf + ZE_NUM_ENTRIES_THIS_DISK)) - return LWS_FZ_ERR_END_RECORD_SANITY; - - /* end record is OK... look for our file in the central dir */ - - if (lws_vfs_file_seek_set(priv->zip_fop_fd, - get_u32(buf + ZE_CENTRAL_DIR_OFFSET)) < 0) - return LWS_FZ_ERR_CENTRAL_SEEK; - - while (i--) { - priv->content_start = lws_vfs_tell(priv->zip_fop_fd); - - if (lws_vfs_file_read(priv->zip_fop_fd, &amount, buf, - ZC_DIRECTORY_LENGTH)) - return LWS_FZ_ERR_CENTRAL_READ; - - if (amount != ZC_DIRECTORY_LENGTH) - return LWS_FZ_ERR_CENTRAL_READ; - - if (get_u32(buf + ZC_SIGNATURE) != 0x02014B50) - return LWS_FZ_ERR_CENTRAL_SANITY; - - lwsl_debug("cstart 0x%lx\n", (unsigned long)priv->content_start); - - priv->hdr.filename_len = get_u16(buf + ZC_FILE_NAME_LENGTH); - priv->hdr.extra = get_u16(buf + ZC_EXTRA_FIELD_LENGTH); - priv->hdr.filename_start = lws_vfs_tell(priv->zip_fop_fd); - - priv->hdr.method = get_u16(buf + ZC_COMPRESSION_METHOD); - priv->hdr.crc32 = get_u32(buf + ZC_CRC32); - priv->hdr.comp_size = get_u32(buf + ZC_COMPRESSED_SIZE); - priv->hdr.uncomp_size = get_u32(buf + ZC_UNCOMPRESSED_SIZE); - priv->hdr.offset = get_u32(buf + ZC_REL_OFFSET_LOCAL_HEADER); - priv->hdr.mod_time = get_u32(buf + ZC_LAST_MOD_FILE_TIME); - priv->hdr.file_com_len = get_u16(buf + ZC_FILE_COMMENT_LENGTH); - - if (priv->hdr.filename_len != len) - goto next; - - if (len >= (int)sizeof(buf) - 1) - return LWS_FZ_ERR_NAME_TOO_LONG; - - if (priv->zip_fop_fd->fops->LWS_FOP_READ(priv->zip_fop_fd, - &amount, buf, len)) - return LWS_FZ_ERR_NAME_READ; - if ((int)amount != len) - return LWS_FZ_ERR_NAME_READ; - - buf[len] = '\0'; - lwsl_debug("check %s vs %s\n", buf, name); - - if (strcmp((const char *)buf, name)) - goto next; - - /* we found a match */ - if (lws_vfs_file_seek_set(priv->zip_fop_fd, priv->hdr.offset) < 0) - return LWS_FZ_ERR_NAME_SEEK; - if (priv->zip_fop_fd->fops->LWS_FOP_READ(priv->zip_fop_fd, - &amount, buf, - ZL_HEADER_LENGTH)) - return LWS_FZ_ERR_NAME_READ; - if (amount != ZL_HEADER_LENGTH) - return LWS_FZ_ERR_NAME_READ; - - priv->content_start = priv->hdr.offset + - ZL_HEADER_LENGTH + - priv->hdr.filename_len + - get_u16(buf + ZL_REL_OFFSET_CONTENT); - - lwsl_debug("content supposed to start at 0x%lx\n", - (unsigned long)priv->content_start); - - if (priv->content_start > priv->zip_fop_fd->len) - return LWS_FZ_ERR_CONTENT_SANITY; - - if (lws_vfs_file_seek_set(priv->zip_fop_fd, - priv->content_start) < 0) - return LWS_FZ_ERR_CONTENT_SEEK; - - /* we are aligned at the start of the content */ - - priv->exp_uncomp_pos = 0; - - return 0; - -next: - if (i && lws_vfs_file_seek_set(priv->zip_fop_fd, - priv->content_start + - ZC_DIRECTORY_LENGTH + - priv->hdr.filename_len + - priv->hdr.extra + - priv->hdr.file_com_len) < 0) - return LWS_FZ_ERR_SCAN_SEEK; - } - - return LWS_FZ_ERR_NOT_FOUND; -} - -static int -lws_fops_zip_reset_inflate(lws_fops_zip_t priv) -{ - if (priv->decompress) - inflateEnd(&priv->inflate); - - priv->inflate.zalloc = Z_NULL; - priv->inflate.zfree = Z_NULL; - priv->inflate.opaque = Z_NULL; - priv->inflate.avail_in = 0; - priv->inflate.next_in = Z_NULL; - - if (inflateInit2(&priv->inflate, -MAX_WBITS) != Z_OK) { - lwsl_err("inflate init failed\n"); - return LWS_FZ_ERR_ZLIB_INIT; - } - - if (lws_vfs_file_seek_set(priv->zip_fop_fd, priv->content_start) < 0) - return LWS_FZ_ERR_CONTENT_SEEK; - - priv->exp_uncomp_pos = 0; - - return 0; -} - -static lws_fop_fd_t -lws_fops_zip_open(const struct lws_plat_file_ops *fops, const char *vfs_path, - const char *vpath, lws_fop_flags_t *flags) -{ - lws_fop_flags_t local_flags = 0; - lws_fops_zip_t priv; - char rp[192]; - int m; - - /* - * vpath points at the / after the fops signature in vfs_path, eg - * with a vfs_path "/var/www/docs/manual.zip/index.html", vpath - * will come pointing at "/index.html" - */ - - priv = lws_zalloc(sizeof(*priv), "fops_zip priv"); - if (!priv) - return NULL; - - priv->fop_fd.fops = &fops_zip; - - m = sizeof(rp) - 1; - if ((vpath - vfs_path - 1) < m) - m = lws_ptr_diff(vpath, vfs_path) - 1; - lws_strncpy(rp, vfs_path, m + 1); - - /* open the zip file itself using the incoming fops, not fops_zip */ - - priv->zip_fop_fd = fops->LWS_FOP_OPEN(fops, rp, NULL, &local_flags); - if (!priv->zip_fop_fd) { - lwsl_err("unable to open zip %s\n", rp); - goto bail1; - } - - if (*vpath == '/') - vpath++; - - m = lws_fops_zip_scan(priv, vpath, (int)strlen(vpath)); - if (m) { - lwsl_err("unable to find record matching '%s' %d\n", vpath, m); - goto bail2; - } - - /* the directory metadata tells us modification time, so pass it on */ - priv->fop_fd.mod_time = priv->hdr.mod_time; - *flags |= LWS_FOP_FLAG_MOD_TIME_VALID | LWS_FOP_FLAG_VIRTUAL; - priv->fop_fd.flags = *flags; - - /* The zip fop_fd is left pointing at the start of the content. - * - * 1) Content could be uncompressed (STORE), and we can always serve - * that directly - * - * 2) Content could be compressed (GZIP), and the client can handle - * receiving GZIP... we can wrap it in a GZIP header and trailer - * and serve the content part directly. The flag indicating we - * are providing GZIP directly is set so lws will send the right - * headers. - * - * 3) Content could be compressed (GZIP) but the client can't handle - * receiving GZIP... we can decompress it and serve as it is - * inflated piecemeal. - * - * 4) Content may be compressed some unknown way... fail - * - */ - if (priv->hdr.method == ZIP_COMPRESSION_METHOD_STORE) { - /* - * it is stored uncompressed, leave it indicated as - * uncompressed, and just serve it from inside the - * zip with no gzip container; - */ - - lwsl_info("direct zip serving (stored)\n"); - - priv->fop_fd.len = priv->hdr.uncomp_size; - - return &priv->fop_fd; - } - - if ((*flags & LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP) && - priv->hdr.method == ZIP_COMPRESSION_METHOD_DEFLATE) { - - /* - * We can serve the gzipped file contents directly as gzip - * from inside the zip container; client says it is OK. - * - * To convert to standalone gzip, we have to add a 10-byte - * constant header and a variable 8-byte trailer around the - * content. - * - * The 8-byte trailer is prepared now and held in the priv. - */ - - lwsl_info("direct zip serving (gzipped)\n"); - - priv->fop_fd.len = sizeof(hd) + priv->hdr.comp_size + - sizeof(priv->u); - - if (lws_is_be()) { - uint8_t *p = priv->u.trailer8; - - *p++ = (uint8_t)priv->hdr.crc32; - *p++ = (uint8_t)(priv->hdr.crc32 >> 8); - *p++ = (uint8_t)(priv->hdr.crc32 >> 16); - *p++ = (uint8_t)(priv->hdr.crc32 >> 24); - *p++ = (uint8_t)priv->hdr.uncomp_size; - *p++ = (uint8_t)(priv->hdr.uncomp_size >> 8); - *p++ = (uint8_t)(priv->hdr.uncomp_size >> 16); - *p = (uint8_t)(priv->hdr.uncomp_size >> 24); - } else { - priv->u.trailer32[0] = priv->hdr.crc32; - priv->u.trailer32[1] = priv->hdr.uncomp_size; - } - - *flags |= LWS_FOP_FLAG_COMPR_IS_GZIP; - priv->fop_fd.flags = *flags; - priv->add_gzip_container = 1; - - return &priv->fop_fd; - } - - if (priv->hdr.method == ZIP_COMPRESSION_METHOD_DEFLATE) { - - /* we must decompress it to serve it */ - - lwsl_info("decompressed zip serving\n"); - - priv->fop_fd.len = priv->hdr.uncomp_size; - - if (lws_fops_zip_reset_inflate(priv)) { - lwsl_err("inflate init failed\n"); - goto bail2; - } - - priv->decompress = 1; - - return &priv->fop_fd; - } - - /* we can't handle it ... */ - - lwsl_err("zipped file %s compressed in unknown way (%d)\n", vfs_path, - priv->hdr.method); - -bail2: - lws_vfs_file_close(&priv->zip_fop_fd); -bail1: - free(priv); - - return NULL; -} - -/* ie, we are closing the fop_fd for the file inside the gzip */ - -static int -lws_fops_zip_close(lws_fop_fd_t *fd) -{ - lws_fops_zip_t priv = fop_fd_to_priv(*fd); - - if (priv->decompress) - inflateEnd(&priv->inflate); - - lws_vfs_file_close(&priv->zip_fop_fd); /* close the gzip fop_fd */ - - free(priv); - *fd = NULL; - - return 0; -} - -static lws_fileofs_t -lws_fops_zip_seek_cur(lws_fop_fd_t fd, lws_fileofs_t offset_from_cur_pos) -{ - fd->pos += offset_from_cur_pos; - - return fd->pos; -} - -static int -lws_fops_zip_read(lws_fop_fd_t fd, lws_filepos_t *amount, uint8_t *buf, - lws_filepos_t len) -{ - lws_fops_zip_t priv = fop_fd_to_priv(fd); - lws_filepos_t ramount, rlen, cur = lws_vfs_tell(fd); - int ret; - - if (priv->decompress) { - - if (priv->exp_uncomp_pos != fd->pos) { - /* - * there has been a seek in the uncompressed fop_fd - * we have to restart the decompression and loop eating - * the decompressed data up to the seek point - */ - lwsl_info("seek in decompressed\n"); - - lws_fops_zip_reset_inflate(priv); - - while (priv->exp_uncomp_pos != fd->pos) { - rlen = len; - if (rlen > fd->pos - priv->exp_uncomp_pos) - rlen = fd->pos - priv->exp_uncomp_pos; - if (lws_fops_zip_read(fd, amount, buf, rlen)) - return LWS_FZ_ERR_SEEK_COMPRESSED; - } - *amount = 0; - } - - priv->inflate.avail_out = (unsigned int)len; - priv->inflate.next_out = buf; - -spin: - if (!priv->inflate.avail_in) { - rlen = sizeof(priv->rbuf); - if (rlen > priv->hdr.comp_size - - (cur - priv->content_start)) - rlen = priv->hdr.comp_size - - (priv->hdr.comp_size - - priv->content_start); - - if (priv->zip_fop_fd->fops->LWS_FOP_READ( - priv->zip_fop_fd, &ramount, priv->rbuf, - rlen)) - return LWS_FZ_ERR_READ_CONTENT; - - cur += ramount; - - priv->inflate.avail_in = (unsigned int)ramount; - priv->inflate.next_in = priv->rbuf; - } - - ret = inflate(&priv->inflate, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR) - return ret; - - switch (ret) { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; - /* fallthru */ - case Z_DATA_ERROR: - case Z_MEM_ERROR: - - return ret; - } - - if (!priv->inflate.avail_in && priv->inflate.avail_out && - cur != priv->content_start + priv->hdr.comp_size) - goto spin; - - *amount = len - priv->inflate.avail_out; - - priv->exp_uncomp_pos += *amount; - fd->pos += *amount; - - return 0; - } - - if (priv->add_gzip_container) { - - lwsl_info("%s: gzip + container\n", __func__); - *amount = 0; - - /* place the canned header at the start */ - - if (len && fd->pos < sizeof(hd)) { - rlen = sizeof(hd) - fd->pos; - if (rlen > len) - rlen = len; - /* provide stuff from canned header */ - memcpy(buf, hd + fd->pos, (size_t)rlen); - fd->pos += rlen; - buf += rlen; - len -= rlen; - *amount += rlen; - } - - /* serve gzipped data direct from zipfile */ - - if (len && fd->pos >= sizeof(hd) && - fd->pos < priv->hdr.comp_size + sizeof(hd)) { - - rlen = priv->hdr.comp_size - (priv->zip_fop_fd->pos - - priv->content_start); - if (rlen > len) - rlen = len; - - if (rlen && - priv->zip_fop_fd->pos < (priv->hdr.comp_size + - priv->content_start)) { - if (lws_vfs_file_read(priv->zip_fop_fd, - &ramount, buf, rlen)) - return LWS_FZ_ERR_READ_CONTENT; - *amount += ramount; - fd->pos += ramount; // virtual pos - buf += ramount; - len -= ramount; - } - } - - /* place the prepared trailer at the end */ - - if (len && fd->pos >= priv->hdr.comp_size + sizeof(hd) && - fd->pos < priv->hdr.comp_size + sizeof(hd) + - sizeof(priv->u)) { - cur = fd->pos - priv->hdr.comp_size - sizeof(hd); - rlen = sizeof(priv->u) - cur; - if (rlen > len) - rlen = len; - - memcpy(buf, priv->u.trailer8 + cur, (size_t)rlen); - - *amount += rlen; - fd->pos += rlen; - } - - return 0; - } - - lwsl_info("%s: store\n", __func__); - - if (len > priv->hdr.uncomp_size - (cur - priv->content_start)) - len = priv->hdr.comp_size - (priv->hdr.comp_size - - priv->content_start); - - if (priv->zip_fop_fd->fops->LWS_FOP_READ(priv->zip_fop_fd, - amount, buf, len)) - return LWS_FZ_ERR_READ_CONTENT; - - return 0; -} - -struct lws_plat_file_ops fops_zip = { - lws_fops_zip_open, - lws_fops_zip_close, - lws_fops_zip_seek_cur, - lws_fops_zip_read, - NULL, - { { ".zip/", 5 }, { ".jar/", 5 }, { ".war/", 5 } }, - NULL, -}; diff --git a/thirdparty/libwebsockets/roles/http/server/lejp-conf.c b/thirdparty/libwebsockets/roles/http/server/lejp-conf.c deleted file mode 100644 index fbf10c288e..0000000000 --- a/thirdparty/libwebsockets/roles/http/server/lejp-conf.c +++ /dev/null @@ -1,993 +0,0 @@ -/* - * libwebsockets web server application - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -#ifndef _WIN32 -/* this is needed for Travis CI */ -#include <dirent.h> -#endif - -#define ESC_INSTALL_DATADIR "_lws_ddir_" - -static const char * const paths_global[] = { - "global.uid", - "global.gid", - "global.count-threads", - "global.init-ssl", - "global.server-string", - "global.plugin-dir", - "global.ws-pingpong-secs", - "global.timeout-secs", - "global.reject-service-keywords[].*", - "global.reject-service-keywords[]", - "global.default-alpn", -}; - -enum lejp_global_paths { - LEJPGP_UID, - LEJPGP_GID, - LEJPGP_COUNT_THREADS, - LWJPGP_INIT_SSL, - LEJPGP_SERVER_STRING, - LEJPGP_PLUGIN_DIR, - LWJPGP_PINGPONG_SECS, - LWJPGP_TIMEOUT_SECS, - LWJPGP_REJECT_SERVICE_KEYWORDS_NAME, - LWJPGP_REJECT_SERVICE_KEYWORDS, - LWJPGP_DEFAULT_ALPN, -}; - -static const char * const paths_vhosts[] = { - "vhosts[]", - "vhosts[].mounts[]", - "vhosts[].name", - "vhosts[].port", - "vhosts[].interface", - "vhosts[].unix-socket", - "vhosts[].sts", - "vhosts[].host-ssl-key", - "vhosts[].host-ssl-cert", - "vhosts[].host-ssl-ca", - "vhosts[].access-log", - "vhosts[].mounts[].mountpoint", - "vhosts[].mounts[].origin", - "vhosts[].mounts[].protocol", - "vhosts[].mounts[].default", - "vhosts[].mounts[].auth-mask", - "vhosts[].mounts[].cgi-timeout", - "vhosts[].mounts[].cgi-env[].*", - "vhosts[].mounts[].cache-max-age", - "vhosts[].mounts[].cache-reuse", - "vhosts[].mounts[].cache-revalidate", - "vhosts[].mounts[].basic-auth", - "vhosts[].mounts[].cache-intermediaries", - "vhosts[].mounts[].extra-mimetypes.*", - "vhosts[].mounts[].interpret.*", - "vhosts[].ws-protocols[].*.*", - "vhosts[].ws-protocols[].*", - "vhosts[].ws-protocols[]", - "vhosts[].keepalive_timeout", - "vhosts[].enable-client-ssl", - "vhosts[].ciphers", - "vhosts[].ecdh-curve", - "vhosts[].noipv6", - "vhosts[].ipv6only", - "vhosts[].ssl-option-set", - "vhosts[].ssl-option-clear", - "vhosts[].mounts[].pmo[].*", - "vhosts[].headers[].*", - "vhosts[].headers[]", - "vhosts[].client-ssl-key", - "vhosts[].client-ssl-cert", - "vhosts[].client-ssl-ca", - "vhosts[].client-ssl-ciphers", - "vhosts[].onlyraw", - "vhosts[].client-cert-required", - "vhosts[].ignore-missing-cert", - "vhosts[].error-document-404", - "vhosts[].alpn", -}; - -enum lejp_vhost_paths { - LEJPVP, - LEJPVP_MOUNTS, - LEJPVP_NAME, - LEJPVP_PORT, - LEJPVP_INTERFACE, - LEJPVP_UNIXSKT, - LEJPVP_STS, - LEJPVP_HOST_SSL_KEY, - LEJPVP_HOST_SSL_CERT, - LEJPVP_HOST_SSL_CA, - LEJPVP_ACCESS_LOG, - LEJPVP_MOUNTPOINT, - LEJPVP_ORIGIN, - LEJPVP_MOUNT_PROTOCOL, - LEJPVP_DEFAULT, - LEJPVP_DEFAULT_AUTH_MASK, - LEJPVP_CGI_TIMEOUT, - LEJPVP_CGI_ENV, - LEJPVP_MOUNT_CACHE_MAX_AGE, - LEJPVP_MOUNT_CACHE_REUSE, - LEJPVP_MOUNT_CACHE_REVALIDATE, - LEJPVP_MOUNT_BASIC_AUTH, - LEJPVP_MOUNT_CACHE_INTERMEDIARIES, - LEJPVP_MOUNT_EXTRA_MIMETYPES, - LEJPVP_MOUNT_INTERPRET, - LEJPVP_PROTOCOL_NAME_OPT, - LEJPVP_PROTOCOL_NAME, - LEJPVP_PROTOCOL, - LEJPVP_KEEPALIVE_TIMEOUT, - LEJPVP_ENABLE_CLIENT_SSL, - LEJPVP_CIPHERS, - LEJPVP_ECDH_CURVE, - LEJPVP_NOIPV6, - LEJPVP_IPV6ONLY, - LEJPVP_SSL_OPTION_SET, - LEJPVP_SSL_OPTION_CLEAR, - LEJPVP_PMO, - LEJPVP_HEADERS_NAME, - LEJPVP_HEADERS, - LEJPVP_CLIENT_SSL_KEY, - LEJPVP_CLIENT_SSL_CERT, - LEJPVP_CLIENT_SSL_CA, - LEJPVP_CLIENT_CIPHERS, - LEJPVP_FLAG_ONLYRAW, - LEJPVP_FLAG_CLIENT_CERT_REQUIRED, - LEJPVP_IGNORE_MISSING_CERT, - LEJPVP_ERROR_DOCUMENT_404, - LEJPVP_ALPN, -}; - -static const char * const parser_errs[] = { - "", - "", - "No opening '{'", - "Expected closing '}'", - "Expected '\"'", - "String underrun", - "Illegal unescaped control char", - "Illegal escape format", - "Illegal hex number", - "Expected ':'", - "Illegal value start", - "Digit required after decimal point", - "Bad number format", - "Bad exponent format", - "Unknown token", - "Too many ']'", - "Mismatched ']'", - "Expected ']'", - "JSON nesting limit exceeded", - "Nesting tracking used up", - "Number too long", - "Comma or block end expected", - "Unknown", - "Parser callback errored (see earlier error)", -}; - -#define MAX_PLUGIN_DIRS 10 - -struct jpargs { - struct lws_context_creation_info *info; - struct lws_context *context; - const struct lws_protocols *protocols; - const struct lws_extension *extensions; - char *p, *end, valid; - struct lws_http_mount *head, *last; - - struct lws_protocol_vhost_options *pvo; - struct lws_protocol_vhost_options *pvo_em; - struct lws_protocol_vhost_options *pvo_int; - struct lws_http_mount m; - const char **plugin_dirs; - int count_plugin_dirs; - - unsigned int enable_client_ssl:1; - unsigned int fresh_mount:1; - unsigned int any_vhosts:1; - unsigned int chunk:1; -}; - -static void * -lwsws_align(struct jpargs *a) -{ - if ((lws_intptr_t)(a->p) & 15) - a->p += 16 - ((lws_intptr_t)(a->p) & 15); - - a->chunk = 0; - - return a->p; -} - -static int -arg_to_bool(const char *s) -{ - static const char * const on[] = { "on", "yes", "true" }; - int n = atoi(s); - - if (n) - return 1; - - for (n = 0; n < (int)LWS_ARRAY_SIZE(on); n++) - if (!strcasecmp(s, on[n])) - return 1; - - return 0; -} - -static signed char -lejp_globals_cb(struct lejp_ctx *ctx, char reason) -{ - struct jpargs *a = (struct jpargs *)ctx->user; - struct lws_protocol_vhost_options *rej; - int n; - - /* we only match on the prepared path strings */ - if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match) - return 0; - - /* this catches, eg, vhosts[].headers[].xxx */ - if (reason == LEJPCB_VAL_STR_END && - ctx->path_match == LWJPGP_REJECT_SERVICE_KEYWORDS_NAME + 1) { - rej = lwsws_align(a); - a->p += sizeof(*rej); - - n = lejp_get_wildcard(ctx, 0, a->p, a->end - a->p); - rej->next = a->info->reject_service_keywords; - a->info->reject_service_keywords = rej; - rej->name = a->p; - lwsl_notice(" adding rej %s=%s\n", a->p, ctx->buf); - a->p += n - 1; - *(a->p++) = '\0'; - rej->value = a->p; - rej->options = NULL; - goto dostring; - } - - switch (ctx->path_match - 1) { - case LEJPGP_UID: - a->info->uid = atoi(ctx->buf); - return 0; - case LEJPGP_GID: - a->info->gid = atoi(ctx->buf); - return 0; - case LEJPGP_COUNT_THREADS: - a->info->count_threads = atoi(ctx->buf); - return 0; - case LWJPGP_INIT_SSL: - if (arg_to_bool(ctx->buf)) - a->info->options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - return 0; - case LEJPGP_SERVER_STRING: - a->info->server_string = a->p; - break; - case LEJPGP_PLUGIN_DIR: - if (a->count_plugin_dirs == MAX_PLUGIN_DIRS - 1) { - lwsl_err("Too many plugin dirs\n"); - return -1; - } - a->plugin_dirs[a->count_plugin_dirs++] = a->p; - break; - - case LWJPGP_PINGPONG_SECS: - a->info->ws_ping_pong_interval = atoi(ctx->buf); - return 0; - - case LWJPGP_TIMEOUT_SECS: - a->info->timeout_secs = atoi(ctx->buf); - return 0; - - case LWJPGP_DEFAULT_ALPN: - a->info->alpn = a->p; - break; - - default: - return 0; - } - -dostring: - a->p += lws_snprintf(a->p, a->end - a->p, "%s", ctx->buf); - *(a->p)++ = '\0'; - - return 0; -} - -static signed char -lejp_vhosts_cb(struct lejp_ctx *ctx, char reason) -{ - struct jpargs *a = (struct jpargs *)ctx->user; - struct lws_protocol_vhost_options *pvo, *mp_cgienv, *headers; - struct lws_http_mount *m; - char *p, *p1; - int n; - -#if 0 - lwsl_notice(" %d: %s (%d)\n", reason, ctx->path, ctx->path_match); - for (n = 0; n < ctx->wildcount; n++) - lwsl_notice(" %d\n", ctx->wild[n]); -#endif - - if (reason == LEJPCB_OBJECT_START && ctx->path_match == LEJPVP + 1) { - uint32_t i[4]; - const char *ss; - - /* set the defaults for this vhost */ - a->valid = 1; - a->head = NULL; - a->last = NULL; - - i[0] = a->info->count_threads; - i[1] = a->info->options & ( - LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME | - LWS_SERVER_OPTION_LIBUV | - LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT | - LWS_SERVER_OPTION_EXPLICIT_VHOSTS | - LWS_SERVER_OPTION_UV_NO_SIGSEGV_SIGFPE_SPIN | - LWS_SERVER_OPTION_LIBEVENT | - LWS_SERVER_OPTION_LIBEV - ); - ss = a->info->server_string; - i[2] = a->info->ws_ping_pong_interval; - i[3] = a->info->timeout_secs; - - memset(a->info, 0, sizeof(*a->info)); - - a->info->count_threads = i[0]; - a->info->options = i[1]; - a->info->server_string = ss; - a->info->ws_ping_pong_interval = i[2]; - a->info->timeout_secs = i[3]; - - a->info->protocols = a->protocols; - a->info->extensions = a->extensions; -#if defined(LWS_WITH_TLS) - a->info->client_ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:" - "ECDHE-RSA-AES256-GCM-SHA384:" - "DHE-RSA-AES256-GCM-SHA384:" - "ECDHE-RSA-AES256-SHA384:" - "HIGH:!aNULL:!eNULL:!EXPORT:" - "!DES:!MD5:!PSK:!RC4:!HMAC_SHA1:" - "!SHA1:!DHE-RSA-AES128-GCM-SHA256:" - "!DHE-RSA-AES128-SHA256:" - "!AES128-GCM-SHA256:" - "!AES128-SHA256:" - "!DHE-RSA-AES256-SHA256:" - "!AES256-GCM-SHA384:" - "!AES256-SHA256"; -#endif - a->info->ssl_cipher_list = "ECDHE-ECDSA-AES256-GCM-SHA384:" - "ECDHE-RSA-AES256-GCM-SHA384:" - "DHE-RSA-AES256-GCM-SHA384:" - "ECDHE-RSA-AES256-SHA384:" - "HIGH:!aNULL:!eNULL:!EXPORT:" - "!DES:!MD5:!PSK:!RC4:!HMAC_SHA1:" - "!SHA1:!DHE-RSA-AES128-GCM-SHA256:" - "!DHE-RSA-AES128-SHA256:" - "!AES128-GCM-SHA256:" - "!AES128-SHA256:" - "!DHE-RSA-AES256-SHA256:" - "!AES256-GCM-SHA384:" - "!AES256-SHA256"; - a->info->keepalive_timeout = 5; - } - - if (reason == LEJPCB_OBJECT_START && - ctx->path_match == LEJPVP_MOUNTS + 1) { - a->fresh_mount = 1; - memset(&a->m, 0, sizeof(a->m)); - } - - /* this catches, eg, vhosts[].ws-protocols[].xxx-protocol */ - if (reason == LEJPCB_OBJECT_START && - ctx->path_match == LEJPVP_PROTOCOL_NAME + 1) { - a->pvo = lwsws_align(a); - a->p += sizeof(*a->pvo); - - n = lejp_get_wildcard(ctx, 0, a->p, a->end - a->p); - /* ie, enable this protocol, no options yet */ - a->pvo->next = a->info->pvo; - a->info->pvo = a->pvo; - a->pvo->name = a->p; - lwsl_info(" adding protocol %s\n", a->p); - a->p += n; - a->pvo->value = a->p; - a->pvo->options = NULL; - goto dostring; - } - - /* this catches, eg, vhosts[].headers[].xxx */ - if ((reason == LEJPCB_VAL_STR_END || reason == LEJPCB_VAL_STR_CHUNK) && - ctx->path_match == LEJPVP_HEADERS_NAME + 1) { - if (!a->chunk) { - headers = lwsws_align(a); - a->p += sizeof(*headers); - - n = lejp_get_wildcard(ctx, 0, a->p, - lws_ptr_diff(a->end, a->p)); - /* ie, add this header */ - headers->next = a->info->headers; - a->info->headers = headers; - headers->name = a->p; - - lwsl_notice(" adding header %s=%s\n", a->p, ctx->buf); - a->p += n - 1; - *(a->p++) = ':'; - if (a->p < a->end) - *(a->p++) = '\0'; - else - *(a->p - 1) = '\0'; - headers->value = a->p; - headers->options = NULL; - } - a->chunk = reason == LEJPCB_VAL_STR_CHUNK; - goto dostring; - } - - if (reason == LEJPCB_OBJECT_END && - (ctx->path_match == LEJPVP + 1 || !ctx->path[0]) && - a->valid) { - - struct lws_vhost *vhost; - - //lwsl_notice("%s\n", ctx->path); - if (!a->info->port) { - lwsl_err("Port required (eg, 443)"); - return 1; - } - a->valid = 0; - a->info->mounts = a->head; - - vhost = lws_create_vhost(a->context, a->info); - if (!vhost) { - lwsl_err("Failed to create vhost %s\n", - a->info->vhost_name); - return 1; - } - a->any_vhosts = 1; - -#if defined(LWS_WITH_TLS) - if (a->enable_client_ssl) { - const char *cert_filepath = a->info->client_ssl_cert_filepath; - const char *private_key_filepath = a->info->client_ssl_private_key_filepath; - const char *ca_filepath = a->info->client_ssl_ca_filepath; - const char *cipher_list = a->info->client_ssl_cipher_list; - memset(a->info, 0, sizeof(*a->info)); - a->info->client_ssl_cert_filepath = cert_filepath; - a->info->client_ssl_private_key_filepath = private_key_filepath; - a->info->client_ssl_ca_filepath = ca_filepath; - a->info->client_ssl_cipher_list = cipher_list; - a->info->options = LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; - lws_init_vhost_client_ssl(a->info, vhost); - } -#endif - - return 0; - } - - if (reason == LEJPCB_OBJECT_END && - ctx->path_match == LEJPVP_MOUNTS + 1) { - static const char * const mount_protocols[] = { - "http://", - "https://", - "file://", - "cgi://", - ">http://", - ">https://", - "callback://", - "gzip://", - }; - - if (!a->fresh_mount) - return 0; - - if (!a->m.mountpoint || !a->m.origin) { - lwsl_err("mountpoint and origin required\n"); - return 1; - } - lwsl_debug("adding mount %s\n", a->m.mountpoint); - m = lwsws_align(a); - memcpy(m, &a->m, sizeof(*m)); - if (a->last) - a->last->mount_next = m; - - for (n = 0; n < (int)LWS_ARRAY_SIZE(mount_protocols); n++) - if (!strncmp(a->m.origin, mount_protocols[n], - strlen(mount_protocols[n]))) { - lwsl_info("----%s\n", a->m.origin); - m->origin_protocol = n; - m->origin = a->m.origin + - strlen(mount_protocols[n]); - break; - } - - if (n == (int)LWS_ARRAY_SIZE(mount_protocols)) { - lwsl_err("unsupported protocol:// %s\n", a->m.origin); - return 1; - } - - a->p += sizeof(*m); - if (!a->head) - a->head = m; - - a->last = m; - a->fresh_mount = 0; - } - - /* we only match on the prepared path strings */ - if (!(reason & LEJP_FLAG_CB_IS_VALUE) || !ctx->path_match) - return 0; - - switch (ctx->path_match - 1) { - case LEJPVP_NAME: - a->info->vhost_name = a->p; - break; - case LEJPVP_PORT: - a->info->port = atoi(ctx->buf); - return 0; - case LEJPVP_INTERFACE: - a->info->iface = a->p; - break; - case LEJPVP_UNIXSKT: - if (arg_to_bool(ctx->buf)) - a->info->options |= LWS_SERVER_OPTION_UNIX_SOCK; - else - a->info->options &= ~(LWS_SERVER_OPTION_UNIX_SOCK); - return 0; - case LEJPVP_STS: - if (arg_to_bool(ctx->buf)) - a->info->options |= LWS_SERVER_OPTION_STS; - else - a->info->options &= ~(LWS_SERVER_OPTION_STS); - return 0; - case LEJPVP_HOST_SSL_KEY: - a->info->ssl_private_key_filepath = a->p; - break; - case LEJPVP_HOST_SSL_CERT: - a->info->ssl_cert_filepath = a->p; - break; - case LEJPVP_HOST_SSL_CA: - a->info->ssl_ca_filepath = a->p; - break; - case LEJPVP_ACCESS_LOG: - a->info->log_filepath = a->p; - break; - case LEJPVP_MOUNTPOINT: - a->m.mountpoint = a->p; - a->m.mountpoint_len = (unsigned char)strlen(ctx->buf); - break; - case LEJPVP_ORIGIN: - if (!strncmp(ctx->buf, "callback://", 11)) - a->m.protocol = a->p + 11; - - if (!a->m.origin) - a->m.origin = a->p; - break; - case LEJPVP_DEFAULT: - a->m.def = a->p; - break; - case LEJPVP_DEFAULT_AUTH_MASK: - a->m.auth_mask = atoi(ctx->buf); - return 0; - case LEJPVP_MOUNT_CACHE_MAX_AGE: - a->m.cache_max_age = atoi(ctx->buf); - return 0; - case LEJPVP_MOUNT_CACHE_REUSE: - a->m.cache_reusable = arg_to_bool(ctx->buf); - return 0; - case LEJPVP_MOUNT_CACHE_REVALIDATE: - a->m.cache_revalidate = arg_to_bool(ctx->buf); - return 0; - case LEJPVP_MOUNT_CACHE_INTERMEDIARIES: - a->m.cache_intermediaries = arg_to_bool(ctx->buf);; - return 0; - case LEJPVP_MOUNT_BASIC_AUTH: - a->m.basic_auth_login_file = a->p; - break; - case LEJPVP_CGI_TIMEOUT: - a->m.cgi_timeout = atoi(ctx->buf); - return 0; - case LEJPVP_KEEPALIVE_TIMEOUT: - a->info->keepalive_timeout = atoi(ctx->buf); - return 0; -#if defined(LWS_WITH_TLS) - case LEJPVP_CLIENT_CIPHERS: - a->info->client_ssl_cipher_list = a->p; - break; -#endif - case LEJPVP_CIPHERS: - a->info->ssl_cipher_list = a->p; - break; - case LEJPVP_ECDH_CURVE: - a->info->ecdh_curve = a->p; - break; - case LEJPVP_PMO: - case LEJPVP_CGI_ENV: - mp_cgienv = lwsws_align(a); - a->p += sizeof(*a->m.cgienv); - - mp_cgienv->next = a->m.cgienv; - a->m.cgienv = mp_cgienv; - - n = lejp_get_wildcard(ctx, 0, a->p, a->end - a->p); - mp_cgienv->name = a->p; - a->p += n; - mp_cgienv->value = a->p; - mp_cgienv->options = NULL; - //lwsl_notice(" adding pmo / cgi-env '%s' = '%s'\n", mp_cgienv->name, - // mp_cgienv->value); - goto dostring; - - case LEJPVP_PROTOCOL_NAME_OPT: - /* this catches, eg, - * vhosts[].ws-protocols[].xxx-protocol.yyy-option - * ie, these are options attached to a protocol with { } - */ - pvo = lwsws_align(a); - a->p += sizeof(*a->pvo); - - n = lejp_get_wildcard(ctx, 1, a->p, a->end - a->p); - /* ie, enable this protocol, no options yet */ - pvo->next = a->pvo->options; - a->pvo->options = pvo; - pvo->name = a->p; - a->p += n; - pvo->value = a->p; - pvo->options = NULL; - break; - - case LEJPVP_MOUNT_EXTRA_MIMETYPES: - a->pvo_em = lwsws_align(a); - a->p += sizeof(*a->pvo_em); - - n = lejp_get_wildcard(ctx, 0, a->p, a->end - a->p); - /* ie, enable this protocol, no options yet */ - a->pvo_em->next = a->m.extra_mimetypes; - a->m.extra_mimetypes = a->pvo_em; - a->pvo_em->name = a->p; - lwsl_notice(" adding extra-mimetypes %s -> %s\n", a->p, ctx->buf); - a->p += n; - a->pvo_em->value = a->p; - a->pvo_em->options = NULL; - break; - - case LEJPVP_MOUNT_INTERPRET: - a->pvo_int = lwsws_align(a); - a->p += sizeof(*a->pvo_int); - - n = lejp_get_wildcard(ctx, 0, a->p, a->end - a->p); - /* ie, enable this protocol, no options yet */ - a->pvo_int->next = a->m.interpret; - a->m.interpret = a->pvo_int; - a->pvo_int->name = a->p; - lwsl_notice(" adding interpret %s -> %s\n", a->p, - ctx->buf); - a->p += n; - a->pvo_int->value = a->p; - a->pvo_int->options = NULL; - break; - - case LEJPVP_ENABLE_CLIENT_SSL: - a->enable_client_ssl = arg_to_bool(ctx->buf); - return 0; -#if defined(LWS_WITH_TLS) - case LEJPVP_CLIENT_SSL_KEY: - a->info->client_ssl_private_key_filepath = a->p; - break; - case LEJPVP_CLIENT_SSL_CERT: - a->info->client_ssl_cert_filepath = a->p; - break; - case LEJPVP_CLIENT_SSL_CA: - a->info->client_ssl_ca_filepath = a->p; - break; -#endif - - case LEJPVP_NOIPV6: - if (arg_to_bool(ctx->buf)) - a->info->options |= LWS_SERVER_OPTION_DISABLE_IPV6; - else - a->info->options &= ~(LWS_SERVER_OPTION_DISABLE_IPV6); - return 0; - - case LEJPVP_FLAG_ONLYRAW: - if (arg_to_bool(ctx->buf)) - a->info->options |= LWS_SERVER_OPTION_ONLY_RAW; - else - a->info->options &= ~(LWS_SERVER_OPTION_ONLY_RAW); - return 0; - - case LEJPVP_IPV6ONLY: - a->info->options |= LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY; - if (arg_to_bool(ctx->buf)) - a->info->options |= LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE; - else - a->info->options &= ~(LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE); - return 0; - - case LEJPVP_FLAG_CLIENT_CERT_REQUIRED: - if (arg_to_bool(ctx->buf)) - a->info->options |= - LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT; - return 0; - - case LEJPVP_IGNORE_MISSING_CERT: - if (arg_to_bool(ctx->buf)) - a->info->options |= LWS_SERVER_OPTION_IGNORE_MISSING_CERT; - else - a->info->options &= ~(LWS_SERVER_OPTION_IGNORE_MISSING_CERT); - - return 0; - - case LEJPVP_ERROR_DOCUMENT_404: - a->info->error_document_404 = a->p; - break; - - case LEJPVP_SSL_OPTION_SET: - a->info->ssl_options_set |= atol(ctx->buf); - return 0; - case LEJPVP_SSL_OPTION_CLEAR: - a->info->ssl_options_clear |= atol(ctx->buf); - return 0; - - case LEJPVP_ALPN: - a->info->alpn = a->p; - break; - - default: - return 0; - } - -dostring: - p = ctx->buf; - p[LEJP_STRING_CHUNK] = '\0'; - p1 = strstr(p, ESC_INSTALL_DATADIR); - if (p1) { - n = p1 - p; - if (n > a->end - a->p) - n = a->end - a->p; - lws_strncpy(a->p, p, n + 1); - a->p += n; - a->p += lws_snprintf(a->p, a->end - a->p, "%s", LWS_INSTALL_DATADIR); - p += n + strlen(ESC_INSTALL_DATADIR); - } - - a->p += lws_snprintf(a->p, a->end - a->p, "%s", p); - if (reason == LEJPCB_VAL_STR_END) - *(a->p)++ = '\0'; - - return 0; -} - -/* - * returns 0 = OK, 1 = can't open, 2 = parsing error - */ - -static int -lwsws_get_config(void *user, const char *f, const char * const *paths, - int count_paths, lejp_callback cb) -{ - unsigned char buf[128]; - struct lejp_ctx ctx; - int n, m, fd; - - fd = lws_open(f, O_RDONLY); - if (fd < 0) { - lwsl_err("Cannot open %s\n", f); - return 2; - } - lwsl_info("%s: %s\n", __func__, f); - lejp_construct(&ctx, cb, user, paths, count_paths); - - do { - n = read(fd, buf, sizeof(buf)); - if (!n) - break; - - m = (int)(signed char)lejp_parse(&ctx, buf, n); - } while (m == LEJP_CONTINUE); - - close(fd); - n = ctx.line; - lejp_destruct(&ctx); - - if (m < 0) { - lwsl_err("%s(%u): parsing error %d: %s\n", f, n, m, - parser_errs[-m]); - return 2; - } - - return 0; -} - -#if defined(LWS_WITH_LIBUV) && UV_VERSION_MAJOR > 0 - -static int -lwsws_get_config_d(void *user, const char *d, const char * const *paths, - int count_paths, lejp_callback cb) -{ - uv_dirent_t dent; - uv_fs_t req; - char path[256]; - int ret = 0, ir; - uv_loop_t loop; - - ir = uv_loop_init(&loop); - if (ir) { - lwsl_err("%s: loop init failed %d\n", __func__, ir); - } - - if (!uv_fs_scandir(&loop, &req, d, 0, NULL)) { - lwsl_err("Scandir on %s failed\n", d); - return 2; - } - - while (uv_fs_scandir_next(&req, &dent) != UV_EOF) { - lws_snprintf(path, sizeof(path) - 1, "%s/%s", d, dent.name); - ret = lwsws_get_config(user, path, paths, count_paths, cb); - if (ret) - goto bail; - } - -bail: - uv_fs_req_cleanup(&req); - while (uv_loop_close(&loop)) - ; - - return ret; -} - -#else - -#ifndef _WIN32 -static int filter(const struct dirent *ent) -{ - if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) - return 0; - - return 1; -} -#endif - -static int -lwsws_get_config_d(void *user, const char *d, const char * const *paths, - int count_paths, lejp_callback cb) -{ -#ifndef _WIN32 - struct dirent **namelist; - char path[256]; - int n, i, ret = 0; - - n = scandir(d, &namelist, filter, alphasort); - if (n < 0) { - lwsl_err("Scandir on %s failed\n", d); - return 1; - } - - for (i = 0; i < n; i++) { - if (strchr(namelist[i]->d_name, '~')) - goto skip; - lws_snprintf(path, sizeof(path) - 1, "%s/%s", d, - namelist[i]->d_name); - ret = lwsws_get_config(user, path, paths, count_paths, cb); - if (ret) { - while (i++ < n) - free(namelist[i]); - goto bail; - } -skip: - free(namelist[i]); - } - -bail: - free(namelist); - - return ret; -#else - return 0; -#endif -} - -#endif - -int -lwsws_get_config_globals(struct lws_context_creation_info *info, const char *d, - char **cs, int *len) -{ - struct jpargs a; - const char * const *old = info->plugin_dirs; - char dd[128]; - - memset(&a, 0, sizeof(a)); - - a.info = info; - a.p = *cs; - a.end = (a.p + *len) - 1; - a.valid = 0; - - lwsws_align(&a); - info->plugin_dirs = (void *)a.p; - a.plugin_dirs = (void *)a.p; /* writeable version */ - a.p += MAX_PLUGIN_DIRS * sizeof(void *); - - /* copy any default paths */ - - while (old && *old) { - a.plugin_dirs[a.count_plugin_dirs++] = *old; - old++; - } - - lws_snprintf(dd, sizeof(dd) - 1, "%s/conf", d); - if (lwsws_get_config(&a, dd, paths_global, - LWS_ARRAY_SIZE(paths_global), lejp_globals_cb) > 1) - return 1; - lws_snprintf(dd, sizeof(dd) - 1, "%s/conf.d", d); - if (lwsws_get_config_d(&a, dd, paths_global, - LWS_ARRAY_SIZE(paths_global), lejp_globals_cb) > 1) - return 1; - - a.plugin_dirs[a.count_plugin_dirs] = NULL; - - *cs = a.p; - *len = a.end - a.p; - - return 0; -} - -int -lwsws_get_config_vhosts(struct lws_context *context, - struct lws_context_creation_info *info, const char *d, - char **cs, int *len) -{ - struct jpargs a; - char dd[128]; - - memset(&a, 0, sizeof(a)); - - a.info = info; - a.p = *cs; - a.end = a.p + *len; - a.valid = 0; - a.context = context; - a.protocols = info->protocols; - a.extensions = info->extensions; - - lws_snprintf(dd, sizeof(dd) - 1, "%s/conf", d); - if (lwsws_get_config(&a, dd, paths_vhosts, - LWS_ARRAY_SIZE(paths_vhosts), lejp_vhosts_cb) > 1) - return 1; - lws_snprintf(dd, sizeof(dd) - 1, "%s/conf.d", d); - if (lwsws_get_config_d(&a, dd, paths_vhosts, - LWS_ARRAY_SIZE(paths_vhosts), lejp_vhosts_cb) > 1) - return 1; - - *cs = a.p; - *len = a.end - a.p; - - if (!a.any_vhosts) { - lwsl_err("Need at least one vhost\n"); - return 1; - } - -// lws_finalize_startup(context); - - return 0; -} diff --git a/thirdparty/libwebsockets/roles/http/server/parsers.c b/thirdparty/libwebsockets/roles/http/server/parsers.c deleted file mode 100644 index 482bdc676a..0000000000 --- a/thirdparty/libwebsockets/roles/http/server/parsers.c +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -static const unsigned char lextable[] = { - #include "../lextable.h" -}; - -#define FAIL_CHAR 0x08 - -static struct allocated_headers * -_lws_create_ah(struct lws_context_per_thread *pt, ah_data_idx_t data_size) -{ - struct allocated_headers *ah = lws_zalloc(sizeof(*ah), "ah struct"); - - if (!ah) - return NULL; - - ah->data = lws_malloc(data_size, "ah data"); - if (!ah->data) { - lws_free(ah); - - return NULL; - } - ah->next = pt->http.ah_list; - pt->http.ah_list = ah; - ah->data_length = data_size; - pt->http.ah_pool_length++; - - lwsl_info("%s: created ah %p (size %d): pool length %d\n", __func__, - ah, (int)data_size, pt->http.ah_pool_length); - - return ah; -} - -int -_lws_destroy_ah(struct lws_context_per_thread *pt, struct allocated_headers *ah) -{ - lws_start_foreach_llp(struct allocated_headers **, a, pt->http.ah_list) { - if ((*a) == ah) { - *a = ah->next; - pt->http.ah_pool_length--; - lwsl_info("%s: freed ah %p : pool length %d\n", - __func__, ah, pt->http.ah_pool_length); - if (ah->data) - lws_free(ah->data); - lws_free(ah); - - return 0; - } - } lws_end_foreach_llp(a, next); - - return 1; -} - -void -_lws_header_table_reset(struct allocated_headers *ah) -{ - /* init the ah to reflect no headers or data have appeared yet */ - memset(ah->frag_index, 0, sizeof(ah->frag_index)); - memset(ah->frags, 0, sizeof(ah->frags)); - ah->nfrag = 0; - ah->pos = 0; - ah->http_response = 0; - ah->parser_state = WSI_TOKEN_NAME_PART; - ah->lextable_pos = 0; -} - -// doesn't scrub the ah rxbuffer by default, parent must do if needed - -void -__lws_header_table_reset(struct lws *wsi, int autoservice) -{ - struct allocated_headers *ah = wsi->http.ah; - struct lws_context_per_thread *pt; - struct lws_pollfd *pfd; - - /* if we have the idea we're resetting 'our' ah, must be bound to one */ - assert(ah); - /* ah also concurs with ownership */ - assert(ah->wsi == wsi); - - _lws_header_table_reset(ah); - - /* since we will restart the ah, our new headers are not completed */ - wsi->hdr_parsing_completed = 0; - - /* while we hold the ah, keep a timeout on the wsi */ - __lws_set_timeout(wsi, PENDING_TIMEOUT_HOLDING_AH, - wsi->vhost->timeout_secs_ah_idle); - - time(&ah->assigned); - - if (wsi->position_in_fds_table != LWS_NO_FDS_POS && - lws_buflist_next_segment_len(&wsi->buflist, NULL) && - autoservice) { - lwsl_debug("%s: service on readbuf ah\n", __func__); - - pt = &wsi->context->pt[(int)wsi->tsi]; - /* - * Unlike a normal connect, we have the headers already - * (or the first part of them anyway) - */ - pfd = &pt->fds[wsi->position_in_fds_table]; - pfd->revents |= LWS_POLLIN; - lwsl_err("%s: calling service\n", __func__); - lws_service_fd_tsi(wsi->context, pfd, wsi->tsi); - } -} - -void -lws_header_table_reset(struct lws *wsi, int autoservice) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - - lws_pt_lock(pt, __func__); - - __lws_header_table_reset(wsi, autoservice); - - lws_pt_unlock(pt); -} - -static void -_lws_header_ensure_we_are_on_waiting_list(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - struct lws_pollargs pa; - struct lws **pwsi = &pt->http.ah_wait_list; - - while (*pwsi) { - if (*pwsi == wsi) - return; - pwsi = &(*pwsi)->http.ah_wait_list; - } - - lwsl_info("%s: wsi: %p\n", __func__, wsi); - wsi->http.ah_wait_list = pt->http.ah_wait_list; - pt->http.ah_wait_list = wsi; - pt->http.ah_wait_list_length++; - - /* we cannot accept input then */ - - _lws_change_pollfd(wsi, LWS_POLLIN, 0, &pa); -} - -static int -__lws_remove_from_ah_waiting_list(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - struct lws **pwsi =&pt->http.ah_wait_list; - - while (*pwsi) { - if (*pwsi == wsi) { - lwsl_info("%s: wsi %p\n", __func__, wsi); - /* point prev guy to our next */ - *pwsi = wsi->http.ah_wait_list; - /* we shouldn't point anywhere now */ - wsi->http.ah_wait_list = NULL; - pt->http.ah_wait_list_length--; - - return 1; - } - pwsi = &(*pwsi)->http.ah_wait_list; - } - - return 0; -} - -int LWS_WARN_UNUSED_RESULT -lws_header_table_attach(struct lws *wsi, int autoservice) -{ - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - struct lws_pollargs pa; - int n; - - lwsl_info("%s: wsi %p: ah %p (tsi %d, count = %d) in\n", __func__, - (void *)wsi, (void *)wsi->http.ah, wsi->tsi, - pt->http.ah_count_in_use); - - lws_pt_lock(pt, __func__); - - /* if we are already bound to one, just clear it down */ - if (wsi->http.ah) { - lwsl_info("%s: cleardown\n", __func__); - goto reset; - } - - n = pt->http.ah_count_in_use == context->max_http_header_pool; -#if defined(LWS_WITH_PEER_LIMITS) - if (!n) { - n = lws_peer_confirm_ah_attach_ok(context, wsi->peer); - if (n) - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_C_PEER_LIMIT_AH_DENIED, 1); - } -#endif - if (n) { - /* - * Pool is either all busy, or we don't want to give this - * particular guy an ah right now... - * - * Make sure we are on the waiting list, and return that we - * weren't able to provide the ah - */ - _lws_header_ensure_we_are_on_waiting_list(wsi); - - goto bail; - } - - __lws_remove_from_ah_waiting_list(wsi); - - wsi->http.ah = _lws_create_ah(pt, context->max_http_header_data); - if (!wsi->http.ah) { /* we could not create an ah */ - _lws_header_ensure_we_are_on_waiting_list(wsi); - - goto bail; - } - - wsi->http.ah->in_use = 1; - wsi->http.ah->wsi = wsi; /* mark our owner */ - pt->http.ah_count_in_use++; - -#if defined(LWS_WITH_PEER_LIMITS) && (defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)) - lws_context_lock(context); /* <====================================== */ - if (wsi->peer) - wsi->peer->http.count_ah++; - lws_context_unlock(context); /* ====================================> */ -#endif - - _lws_change_pollfd(wsi, 0, LWS_POLLIN, &pa); - - lwsl_info("%s: did attach wsi %p: ah %p: count %d (on exit)\n", __func__, - (void *)wsi, (void *)wsi->http.ah, pt->http.ah_count_in_use); - -reset: - __lws_header_table_reset(wsi, autoservice); - - lws_pt_unlock(pt); - -#ifndef LWS_NO_CLIENT - if (lwsi_role_client(wsi) && lwsi_state(wsi) == LRS_UNCONNECTED) - if (!lws_client_connect_via_info2(wsi)) - /* our client connect has failed, the wsi - * has been closed - */ - return -1; -#endif - - return 0; - -bail: - lws_pt_unlock(pt); - - return 1; -} - -int __lws_header_table_detach(struct lws *wsi, int autoservice) -{ - struct lws_context *context = wsi->context; - struct allocated_headers *ah = wsi->http.ah; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - struct lws_pollargs pa; - struct lws **pwsi, **pwsi_eligible; - time_t now; - - __lws_remove_from_ah_waiting_list(wsi); - - if (!ah) - return 0; - - lwsl_info("%s: wsi %p: ah %p (tsi=%d, count = %d)\n", __func__, - (void *)wsi, (void *)ah, wsi->tsi, - pt->http.ah_count_in_use); - - /* we did have an ah attached */ - time(&now); - if (ah->assigned && now - ah->assigned > 3) { - /* - * we're detaching the ah, but it was held an - * unreasonably long time - */ - lwsl_debug("%s: wsi %p: ah held %ds, role/state 0x%x 0x%x," - "\n", __func__, wsi, (int)(now - ah->assigned), - lwsi_role(wsi), lwsi_state(wsi)); - } - - ah->assigned = 0; - - /* if we think we're detaching one, there should be one in use */ - assert(pt->http.ah_count_in_use > 0); - /* and this specific one should have been in use */ - assert(ah->in_use); - memset(&wsi->http.ah, 0, sizeof(wsi->http.ah)); - -#if defined(LWS_WITH_PEER_LIMITS) - if (ah->wsi) - lws_peer_track_ah_detach(context, wsi->peer); -#endif - ah->wsi = NULL; /* no owner */ - - pwsi = &pt->http.ah_wait_list; - - /* oh there is nobody on the waiting list... leave the ah unattached */ - if (!*pwsi) - goto nobody_usable_waiting; - - /* - * at least one wsi on the same tsi is waiting, give it to oldest guy - * who is allowed to take it (if any) - */ - lwsl_info("pt wait list %p\n", *pwsi); - wsi = NULL; - pwsi_eligible = NULL; - - while (*pwsi) { -#if defined(LWS_WITH_PEER_LIMITS) - /* are we willing to give this guy an ah? */ - if (!lws_peer_confirm_ah_attach_ok(context, (*pwsi)->peer)) -#endif - { - wsi = *pwsi; - pwsi_eligible = pwsi; - } -#if defined(LWS_WITH_PEER_LIMITS) - else - if (!(*pwsi)->http.ah_wait_list) - lws_stats_atomic_bump(context, pt, - LWSSTATS_C_PEER_LIMIT_AH_DENIED, 1); -#endif - pwsi = &(*pwsi)->http.ah_wait_list; - } - - if (!wsi) /* everybody waiting already has too many ah... */ - goto nobody_usable_waiting; - - lwsl_info("%s: transferring ah to last eligible wsi in wait list %p (wsistate 0x%x)\n", __func__, wsi, wsi->wsistate); - - wsi->http.ah = ah; - ah->wsi = wsi; /* new owner */ - - __lws_header_table_reset(wsi, autoservice); -#if defined(LWS_WITH_PEER_LIMITS) && (defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)) - lws_context_lock(context); /* <====================================== */ - if (wsi->peer) - wsi->peer->http.count_ah++; - lws_context_unlock(context); /* ====================================> */ -#endif - - /* clients acquire the ah and then insert themselves in fds table... */ - if (wsi->position_in_fds_table != LWS_NO_FDS_POS) { - lwsl_info("%s: Enabling %p POLLIN\n", __func__, wsi); - - /* he has been stuck waiting for an ah, but now his wait is - * over, let him progress */ - - _lws_change_pollfd(wsi, 0, LWS_POLLIN, &pa); - } - - /* point prev guy to next guy in list instead */ - *pwsi_eligible = wsi->http.ah_wait_list; - /* the guy who got one is out of the list */ - wsi->http.ah_wait_list = NULL; - pt->http.ah_wait_list_length--; - -#ifndef LWS_NO_CLIENT - if (lwsi_role_client(wsi) && lwsi_state(wsi) == LRS_UNCONNECTED) { - lws_pt_unlock(pt); - - if (!lws_client_connect_via_info2(wsi)) { - /* our client connect has failed, the wsi - * has been closed - */ - - return -1; - } - return 0; - } -#endif - - assert(!!pt->http.ah_wait_list_length == !!(lws_intptr_t)pt->http.ah_wait_list); -bail: - lwsl_info("%s: wsi %p: ah %p (tsi=%d, count = %d)\n", __func__, - (void *)wsi, (void *)ah, pt->tid, pt->http.ah_count_in_use); - - return 0; - -nobody_usable_waiting: - lwsl_info("%s: nobody usable waiting\n", __func__); - _lws_destroy_ah(pt, ah); - pt->http.ah_count_in_use--; - - goto bail; -} - -int lws_header_table_detach(struct lws *wsi, int autoservice) -{ - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - int n; - - lws_pt_lock(pt, __func__); - n = __lws_header_table_detach(wsi, autoservice); - lws_pt_unlock(pt); - - return n; -} - -LWS_VISIBLE int -lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx) -{ - int n; - - if (!wsi->http.ah) - return 0; - - n = wsi->http.ah->frag_index[h]; - if (!n) - return 0; - do { - if (!frag_idx) - return wsi->http.ah->frags[n].len; - n = wsi->http.ah->frags[n].nfrag; - } while (frag_idx-- && n); - - return 0; -} - -LWS_VISIBLE int lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h) -{ - int n; - int len = 0; - - if (!wsi->http.ah) - return 0; - - n = wsi->http.ah->frag_index[h]; - if (!n) - return 0; - do { - len += wsi->http.ah->frags[n].len; - n = wsi->http.ah->frags[n].nfrag; - } while (n); - - return len; -} - -LWS_VISIBLE int lws_hdr_copy_fragment(struct lws *wsi, char *dst, int len, - enum lws_token_indexes h, int frag_idx) -{ - int n = 0; - int f; - - if (!wsi->http.ah) - return -1; - - f = wsi->http.ah->frag_index[h]; - - if (!f) - return -1; - - while (n < frag_idx) { - f = wsi->http.ah->frags[f].nfrag; - if (!f) - return -1; - n++; - } - - if (wsi->http.ah->frags[f].len >= len) - return -1; - - memcpy(dst, wsi->http.ah->data + wsi->http.ah->frags[f].offset, - wsi->http.ah->frags[f].len); - dst[wsi->http.ah->frags[f].len] = '\0'; - - return wsi->http.ah->frags[f].len; -} - -LWS_VISIBLE int lws_hdr_copy(struct lws *wsi, char *dst, int len, - enum lws_token_indexes h) -{ - int toklen = lws_hdr_total_length(wsi, h); - int n; - - if (toklen >= len) - return -1; - - if (!wsi->http.ah) - return -1; - - n = wsi->http.ah->frag_index[h]; - if (!n) - return 0; - - do { - if (wsi->http.ah->frags[n].len >= len) - return -1; - strncpy(dst, &wsi->http.ah->data[wsi->http.ah->frags[n].offset], - wsi->http.ah->frags[n].len); - dst += wsi->http.ah->frags[n].len; - len -= wsi->http.ah->frags[n].len; - n = wsi->http.ah->frags[n].nfrag; - } while (n); - *dst = '\0'; - - return toklen; -} - -char *lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h) -{ - int n; - - n = wsi->http.ah->frag_index[h]; - if (!n) - return NULL; - - return wsi->http.ah->data + wsi->http.ah->frags[n].offset; -} - -static int LWS_WARN_UNUSED_RESULT -lws_pos_in_bounds(struct lws *wsi) -{ - if (wsi->http.ah->pos < - (unsigned int)wsi->context->max_http_header_data) - return 0; - - if ((int)wsi->http.ah->pos == wsi->context->max_http_header_data) { - lwsl_err("Ran out of header data space\n"); - return 1; - } - - /* - * with these tests everywhere, it should never be able to exceed - * the limit, only meet it - */ - lwsl_err("%s: pos %d, limit %d\n", __func__, wsi->http.ah->pos, - wsi->context->max_http_header_data); - assert(0); - - return 1; -} - -int LWS_WARN_UNUSED_RESULT -lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s) -{ - wsi->http.ah->nfrag++; - if (wsi->http.ah->nfrag == LWS_ARRAY_SIZE(wsi->http.ah->frags)) { - lwsl_warn("More hdr frags than we can deal with, dropping\n"); - return -1; - } - - wsi->http.ah->frag_index[h] = wsi->http.ah->nfrag; - - wsi->http.ah->frags[wsi->http.ah->nfrag].offset = wsi->http.ah->pos; - wsi->http.ah->frags[wsi->http.ah->nfrag].len = 0; - wsi->http.ah->frags[wsi->http.ah->nfrag].nfrag = 0; - - do { - if (lws_pos_in_bounds(wsi)) - return -1; - - wsi->http.ah->data[wsi->http.ah->pos++] = *s; - if (*s) - wsi->http.ah->frags[wsi->http.ah->nfrag].len++; - } while (*s++); - - return 0; -} - -static int LWS_WARN_UNUSED_RESULT -issue_char(struct lws *wsi, unsigned char c) -{ - unsigned short frag_len; - - if (lws_pos_in_bounds(wsi)) - return -1; - - frag_len = wsi->http.ah->frags[wsi->http.ah->nfrag].len; - /* - * If we haven't hit the token limit, just copy the character into - * the header - */ - if (frag_len < wsi->http.ah->current_token_limit) { - wsi->http.ah->data[wsi->http.ah->pos++] = c; - if (c) - wsi->http.ah->frags[wsi->http.ah->nfrag].len++; - return 0; - } - - /* Insert a null character when we *hit* the limit: */ - if (frag_len == wsi->http.ah->current_token_limit) { - if (lws_pos_in_bounds(wsi)) - return -1; - - wsi->http.ah->data[wsi->http.ah->pos++] = '\0'; - lwsl_warn("header %i exceeds limit %d\n", - wsi->http.ah->parser_state, - wsi->http.ah->current_token_limit); - } - - return 1; -} - -int -lws_parse_urldecode(struct lws *wsi, uint8_t *_c) -{ - struct allocated_headers *ah = wsi->http.ah; - unsigned int enc = 0; - uint8_t c = *_c; - - // lwsl_notice("ah->ups %d\n", ah->ups); - - /* - * PRIORITY 1 - * special URI processing... convert %xx - */ - switch (ah->ues) { - case URIES_IDLE: - if (c == '%') { - ah->ues = URIES_SEEN_PERCENT; - goto swallow; - } - break; - case URIES_SEEN_PERCENT: - if (char_to_hex(c) < 0) - /* illegal post-% char */ - goto forbid; - - ah->esc_stash = c; - ah->ues = URIES_SEEN_PERCENT_H1; - goto swallow; - - case URIES_SEEN_PERCENT_H1: - if (char_to_hex(c) < 0) - /* illegal post-% char */ - goto forbid; - - *_c = (char_to_hex(ah->esc_stash) << 4) | - char_to_hex(c); - c = *_c; - enc = 1; - ah->ues = URIES_IDLE; - break; - } - - /* - * PRIORITY 2 - * special URI processing... - * convert /.. or /... or /../ etc to / - * convert /./ to / - * convert // or /// etc to / - * leave /.dir or whatever alone - */ - - switch (ah->ups) { - case URIPS_IDLE: - if (!c) - return -1; - /* genuine delimiter */ - if ((c == '&' || c == ';') && !enc) { - if (issue_char(wsi, '\0') < 0) - return -1; - /* link to next fragment */ - ah->frags[ah->nfrag].nfrag = ah->nfrag + 1; - ah->nfrag++; - if (ah->nfrag >= LWS_ARRAY_SIZE(ah->frags)) - goto excessive; - /* start next fragment after the & */ - ah->post_literal_equal = 0; - ah->frags[ah->nfrag].offset = ++ah->pos; - ah->frags[ah->nfrag].len = 0; - ah->frags[ah->nfrag].nfrag = 0; - goto swallow; - } - /* uriencoded = in the name part, disallow */ - if (c == '=' && enc && - ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] && - !ah->post_literal_equal) { - c = '_'; - *_c =c; - } - - /* after the real =, we don't care how many = */ - if (c == '=' && !enc) - ah->post_literal_equal = 1; - - /* + to space */ - if (c == '+' && !enc) { - c = ' '; - *_c = c; - } - /* issue the first / always */ - if (c == '/' && !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS]) - ah->ups = URIPS_SEEN_SLASH; - break; - case URIPS_SEEN_SLASH: - /* swallow subsequent slashes */ - if (c == '/') - goto swallow; - /* track and swallow the first . after / */ - if (c == '.') { - ah->ups = URIPS_SEEN_SLASH_DOT; - goto swallow; - } - ah->ups = URIPS_IDLE; - break; - case URIPS_SEEN_SLASH_DOT: - /* swallow second . */ - if (c == '.') { - ah->ups = URIPS_SEEN_SLASH_DOT_DOT; - goto swallow; - } - /* change /./ to / */ - if (c == '/') { - ah->ups = URIPS_SEEN_SLASH; - goto swallow; - } - /* it was like /.dir ... regurgitate the . */ - ah->ups = URIPS_IDLE; - if (issue_char(wsi, '.') < 0) - return -1; - break; - - case URIPS_SEEN_SLASH_DOT_DOT: - - /* /../ or /..[End of URI] --> backup to last / */ - if (c == '/' || c == '?') { - /* - * back up one dir level if possible - * safe against header fragmentation because - * the method URI can only be in 1 fragment - */ - if (ah->frags[ah->nfrag].len > 2) { - ah->pos--; - ah->frags[ah->nfrag].len--; - do { - ah->pos--; - ah->frags[ah->nfrag].len--; - } while (ah->frags[ah->nfrag].len > 1 && - ah->data[ah->pos] != '/'); - } - ah->ups = URIPS_SEEN_SLASH; - if (ah->frags[ah->nfrag].len > 1) - break; - goto swallow; - } - - /* /..[^/] ... regurgitate and allow */ - - if (issue_char(wsi, '.') < 0) - return -1; - if (issue_char(wsi, '.') < 0) - return -1; - ah->ups = URIPS_IDLE; - break; - } - - if (c == '?' && !enc && - !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS]) { /* start of URI args */ - if (ah->ues != URIES_IDLE) - goto forbid; - - /* seal off uri header */ - if (issue_char(wsi, '\0') < 0) - return -1; - - /* move to using WSI_TOKEN_HTTP_URI_ARGS */ - ah->nfrag++; - if (ah->nfrag >= LWS_ARRAY_SIZE(ah->frags)) - goto excessive; - ah->frags[ah->nfrag].offset = ++ah->pos; - ah->frags[ah->nfrag].len = 0; - ah->frags[ah->nfrag].nfrag = 0; - - ah->post_literal_equal = 0; - ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] = ah->nfrag; - ah->ups = URIPS_IDLE; - goto swallow; - } - - return LPUR_CONTINUE; - -swallow: - return LPUR_SWALLOW; - -forbid: - return LPUR_FORBID; - -excessive: - return LPUR_EXCESSIVE; -} - -static const unsigned char methods[] = { - WSI_TOKEN_GET_URI, - WSI_TOKEN_POST_URI, - WSI_TOKEN_OPTIONS_URI, - WSI_TOKEN_PUT_URI, - WSI_TOKEN_PATCH_URI, - WSI_TOKEN_DELETE_URI, - WSI_TOKEN_CONNECT, - WSI_TOKEN_HEAD_URI, -}; - -/* - * possible returns:, -1 fail, 0 ok or 2, transition to raw - */ - -int LWS_WARN_UNUSED_RESULT -lws_parse(struct lws *wsi, unsigned char *buf, int *len) -{ - struct allocated_headers *ah = wsi->http.ah; - struct lws_context *context = wsi->context; - unsigned int n, m; - unsigned char c; - int r, pos; - - assert(wsi->http.ah); - - do { - (*len)--; - c = *buf++; - - switch (ah->parser_state) { - default: - - lwsl_parser("WSI_TOK_(%d) '%c'\n", ah->parser_state, c); - - /* collect into malloc'd buffers */ - /* optional initial space swallow */ - if (!ah->frags[ah->frag_index[ah->parser_state]].len && - c == ' ') - break; - - for (m = 0; m < LWS_ARRAY_SIZE(methods); m++) - if (ah->parser_state == methods[m]) - break; - if (m == LWS_ARRAY_SIZE(methods)) - /* it was not any of the methods */ - goto check_eol; - - /* special URI processing... end at space */ - - if (c == ' ') { - /* enforce starting with / */ - if (!ah->frags[ah->nfrag].len) - if (issue_char(wsi, '/') < 0) - return -1; - - if (ah->ups == URIPS_SEEN_SLASH_DOT_DOT) { - /* - * back up one dir level if possible - * safe against header fragmentation because - * the method URI can only be in 1 fragment - */ - if (ah->frags[ah->nfrag].len > 2) { - ah->pos--; - ah->frags[ah->nfrag].len--; - do { - ah->pos--; - ah->frags[ah->nfrag].len--; - } while (ah->frags[ah->nfrag].len > 1 && - ah->data[ah->pos] != '/'); - } - } - - /* begin parsing HTTP version: */ - if (issue_char(wsi, '\0') < 0) - return -1; - ah->parser_state = WSI_TOKEN_HTTP; - goto start_fragment; - } - - r = lws_parse_urldecode(wsi, &c); - switch (r) { - case LPUR_CONTINUE: - break; - case LPUR_SWALLOW: - goto swallow; - case LPUR_FORBID: - goto forbid; - case LPUR_EXCESSIVE: - goto excessive; - default: - return -1; - } -check_eol: - /* bail at EOL */ - if (ah->parser_state != WSI_TOKEN_CHALLENGE && - c == '\x0d') { - if (ah->ues != URIES_IDLE) - goto forbid; - - c = '\0'; - ah->parser_state = WSI_TOKEN_SKIPPING_SAW_CR; - lwsl_parser("*\n"); - } - - n = issue_char(wsi, c); - if ((int)n < 0) - return -1; - if (n > 0) - ah->parser_state = WSI_TOKEN_SKIPPING; - -swallow: - /* per-protocol end of headers management */ - - if (ah->parser_state == WSI_TOKEN_CHALLENGE) - goto set_parsing_complete; - break; - - /* collecting and checking a name part */ - case WSI_TOKEN_NAME_PART: - lwsl_parser("WSI_TOKEN_NAME_PART '%c' 0x%02X (role=0x%x) " - "wsi->lextable_pos=%d\n", c, c, lwsi_role(wsi), - ah->lextable_pos); - - if (c >= 'A' && c <= 'Z') - c += 'a' - 'A'; - - pos = ah->lextable_pos; - - while (1) { - if (lextable[pos] & (1 << 7)) { /* 1-byte, fail on mismatch */ - if ((lextable[pos] & 0x7f) != c) { -nope: - ah->lextable_pos = -1; - break; - } - /* fall thru */ - pos++; - if (lextable[pos] == FAIL_CHAR) - goto nope; - - ah->lextable_pos = pos; - break; - } - - if (lextable[pos] == FAIL_CHAR) - goto nope; - - /* b7 = 0, end or 3-byte */ - if (lextable[pos] < FAIL_CHAR) { /* terminal marker */ - ah->lextable_pos = pos; - break; - } - - if (lextable[pos] == c) { /* goto */ - ah->lextable_pos = pos + (lextable[pos + 1]) + - (lextable[pos + 2] << 8); - break; - } - - /* fall thru goto */ - pos += 3; - /* continue */ - } - - /* - * If it's h1, server needs to look out for unknown - * methods... - */ - if (ah->lextable_pos < 0 && lwsi_role_h1(wsi) && - lwsi_role_server(wsi)) { - /* this is not a header we know about */ - for (m = 0; m < LWS_ARRAY_SIZE(methods); m++) - if (ah->frag_index[methods[m]]) { - /* - * already had the method, no idea what - * this crap from the client is, ignore - */ - ah->parser_state = WSI_TOKEN_SKIPPING; - break; - } - /* - * hm it's an unknown http method from a client in fact, - * it cannot be valid http - */ - if (m == LWS_ARRAY_SIZE(methods)) { - /* - * are we set up to accept raw in these cases? - */ - if (lws_check_opt(wsi->vhost->options, - LWS_SERVER_OPTION_FALLBACK_TO_RAW)) - return 2; /* transition to raw */ - - lwsl_info("Unknown method - dropping\n"); - goto forbid; - } - break; - } - /* - * ...otherwise for a client, let him ignore unknown headers - * coming from the server - */ - if (ah->lextable_pos < 0) { - ah->parser_state = WSI_TOKEN_SKIPPING; - break; - } - - if (lextable[ah->lextable_pos] < FAIL_CHAR) { - /* terminal state */ - - n = ((unsigned int)lextable[ah->lextable_pos] << 8) | - lextable[ah->lextable_pos + 1]; - - lwsl_parser("known hdr %d\n", n); - for (m = 0; m < LWS_ARRAY_SIZE(methods); m++) - if (n == methods[m] && - ah->frag_index[methods[m]]) { - lwsl_warn("Duplicated method\n"); - return -1; - } - - /* - * WSORIGIN is protocol equiv to ORIGIN, - * JWebSocket likes to send it, map to ORIGIN - */ - if (n == WSI_TOKEN_SWORIGIN) - n = WSI_TOKEN_ORIGIN; - - ah->parser_state = (enum lws_token_indexes) - (WSI_TOKEN_GET_URI + n); - ah->ups = URIPS_IDLE; - - if (context->token_limits) - ah->current_token_limit = context-> - token_limits->token_limit[ - ah->parser_state]; - else - ah->current_token_limit = - wsi->context->max_http_header_data; - - if (ah->parser_state == WSI_TOKEN_CHALLENGE) - goto set_parsing_complete; - - goto start_fragment; - } - break; - -start_fragment: - ah->nfrag++; -excessive: - if (ah->nfrag == LWS_ARRAY_SIZE(ah->frags)) { - lwsl_warn("More hdr frags than we can deal with\n"); - return -1; - } - - ah->frags[ah->nfrag].offset = ah->pos; - ah->frags[ah->nfrag].len = 0; - ah->frags[ah->nfrag].nfrag = 0; - ah->frags[ah->nfrag].flags = 2; - - n = ah->frag_index[ah->parser_state]; - if (!n) { /* first fragment */ - ah->frag_index[ah->parser_state] = ah->nfrag; - ah->hdr_token_idx = ah->parser_state; - break; - } - /* continuation */ - while (ah->frags[n].nfrag) - n = ah->frags[n].nfrag; - ah->frags[n].nfrag = ah->nfrag; - - if (issue_char(wsi, ' ') < 0) - return -1; - break; - - /* skipping arg part of a name we didn't recognize */ - case WSI_TOKEN_SKIPPING: - lwsl_parser("WSI_TOKEN_SKIPPING '%c'\n", c); - - if (c == '\x0d') - ah->parser_state = WSI_TOKEN_SKIPPING_SAW_CR; - break; - - case WSI_TOKEN_SKIPPING_SAW_CR: - lwsl_parser("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c); - if (ah->ues != URIES_IDLE) - goto forbid; - if (c == '\x0a') { - ah->parser_state = WSI_TOKEN_NAME_PART; - ah->lextable_pos = 0; - } else - ah->parser_state = WSI_TOKEN_SKIPPING; - break; - /* we're done, ignore anything else */ - - case WSI_PARSING_COMPLETE: - lwsl_parser("WSI_PARSING_COMPLETE '%c'\n", c); - break; - } - - } while (*len); - - return 0; - -set_parsing_complete: - if (ah->ues != URIES_IDLE) - goto forbid; - if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) { - if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION)) - wsi->rx_frame_type = /* temp for ws version index */ - atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION)); - - lwsl_parser("v%02d hdrs done\n", wsi->rx_frame_type); - } - ah->parser_state = WSI_PARSING_COMPLETE; - wsi->hdr_parsing_completed = 1; - - return 0; - -forbid: - lwsl_notice(" forbidding on uri sanitation\n"); - lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL); - - return -1; -} - diff --git a/thirdparty/libwebsockets/roles/http/server/server.c b/thirdparty/libwebsockets/roles/http/server/server.c deleted file mode 100644 index abd86dc9b5..0000000000 --- a/thirdparty/libwebsockets/roles/http/server/server.c +++ /dev/null @@ -1,2765 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -const char * const method_names[] = { - "GET", "POST", "OPTIONS", "PUT", "PATCH", "DELETE", "CONNECT", "HEAD", -#ifdef LWS_WITH_HTTP2 - ":path", -#endif - }; - -/* - * return 0: all done - * 1: nonfatal error - * <0: fatal error - * - * REQUIRES CONTEXT LOCK HELD - */ - -int -_lws_vhost_init_server(const struct lws_context_creation_info *info, - struct lws_vhost *vhost) -{ - int n, opt = 1, limit = 1; - lws_sockfd_type sockfd; - struct lws_vhost *vh; - struct lws *wsi; - int m = 0, is; - - (void)method_names; - (void)opt; - - if (info) { - vhost->iface = info->iface; - vhost->listen_port = info->port; - } - - /* set up our external listening socket we serve on */ - - if (vhost->listen_port == CONTEXT_PORT_NO_LISTEN || - vhost->listen_port == CONTEXT_PORT_NO_LISTEN_SERVER) - return 0; - - vh = vhost->context->vhost_list; - while (vh) { - if (vh->listen_port == vhost->listen_port) { - if (((!vhost->iface && !vh->iface) || - (vhost->iface && vh->iface && - !strcmp(vhost->iface, vh->iface))) && - vh->lserv_wsi - ) { - lwsl_notice(" using listen skt from vhost %s\n", - vh->name); - return 0; - } - } - vh = vh->vhost_next; - } - - if (vhost->iface) { - /* - * let's check before we do anything else about the disposition - * of the interface he wants to bind to... - */ - is = lws_socket_bind(vhost, LWS_SOCK_INVALID, vhost->listen_port, vhost->iface); - lwsl_debug("initial if check says %d\n", is); -deal: - - lws_start_foreach_llp(struct lws_vhost **, pv, - vhost->context->no_listener_vhost_list) { - if (is >= LWS_ITOSA_USABLE && *pv == vhost) { - /* on the list and shouldn't be: remove it */ - lwsl_debug("deferred iface: removing vh %s\n", (*pv)->name); - *pv = vhost->no_listener_vhost_list; - vhost->no_listener_vhost_list = NULL; - goto done_list; - } - if (is < LWS_ITOSA_USABLE && *pv == vhost) - goto done_list; - } lws_end_foreach_llp(pv, no_listener_vhost_list); - - /* not on the list... */ - - if (is < LWS_ITOSA_USABLE) { - - /* ... but needs to be: so add it */ - - lwsl_debug("deferred iface: adding vh %s\n", vhost->name); - vhost->no_listener_vhost_list = vhost->context->no_listener_vhost_list; - vhost->context->no_listener_vhost_list = vhost; - } - -done_list: - - switch (is) { - default: - break; - case LWS_ITOSA_NOT_EXIST: - /* can't add it */ - if (info) /* first time */ - lwsl_err("VH %s: iface %s port %d DOESN'T EXIST\n", - vhost->name, vhost->iface, vhost->listen_port); - return 1; - case LWS_ITOSA_NOT_USABLE: - /* can't add it */ - if (info) /* first time */ - lwsl_err("VH %s: iface %s port %d NOT USABLE\n", - vhost->name, vhost->iface, vhost->listen_port); - return 1; - } - } - - (void)n; -#if defined(__linux__) -#ifdef LWS_WITH_UNIX_SOCK - /* - * A Unix domain sockets cannot be bound for several times, even if we set - * the SO_REUSE* options on. - * However, fortunately, each thread is able to independently listen when - * running on a reasonably new Linux kernel. So we can safely assume - * creating just one listening socket for a multi-threaded environment won't - * fail in most cases. - */ - if (!LWS_UNIX_SOCK_ENABLED(vhost)) -#endif - limit = vhost->context->count_threads; -#endif - - for (m = 0; m < limit; m++) { -#ifdef LWS_WITH_UNIX_SOCK - if (LWS_UNIX_SOCK_ENABLED(vhost)) - sockfd = socket(AF_UNIX, SOCK_STREAM, 0); - else -#endif -#ifdef LWS_WITH_IPV6 - if (LWS_IPV6_ENABLED(vhost)) - sockfd = socket(AF_INET6, SOCK_STREAM, 0); - else -#endif - sockfd = socket(AF_INET, SOCK_STREAM, 0); - - if (sockfd == LWS_SOCK_INVALID) { - lwsl_err("ERROR opening socket\n"); - return 1; - } -#if !defined(LWS_WITH_ESP32) -#if (defined(WIN32) || defined(_WIN32)) && defined(SO_EXCLUSIVEADDRUSE) - /* - * only accept that we are the only listener on the port - * https://msdn.microsoft.com/zh-tw/library/ - * windows/desktop/ms740621(v=vs.85).aspx - * - * for lws, to match Linux, we default to exclusive listen - */ - if (!lws_check_opt(vhost->options, - LWS_SERVER_OPTION_ALLOW_LISTEN_SHARE)) { - if (setsockopt(sockfd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, - (const void *)&opt, sizeof(opt)) < 0) { - lwsl_err("reuseaddr failed\n"); - compatible_close(sockfd); - return -1; - } - } else -#endif - - /* - * allow us to restart even if old sockets in TIME_WAIT - */ - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, - (const void *)&opt, sizeof(opt)) < 0) { - lwsl_err("reuseaddr failed\n"); - compatible_close(sockfd); - return -1; - } - -#if defined(LWS_WITH_IPV6) && defined(IPV6_V6ONLY) - if (LWS_IPV6_ENABLED(vhost) && - vhost->options & LWS_SERVER_OPTION_IPV6_V6ONLY_MODIFY) { - int value = (vhost->options & - LWS_SERVER_OPTION_IPV6_V6ONLY_VALUE) ? 1 : 0; - if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, - (const void*)&value, sizeof(value)) < 0) { - compatible_close(sockfd); - return -1; - } - } -#endif - -#if defined(__linux__) && defined(SO_REUSEPORT) - /* keep coverity happy */ -#if LWS_MAX_SMP > 1 - n = 1; -#else - n = lws_check_opt(vhost->options, - LWS_SERVER_OPTION_ALLOW_LISTEN_SHARE); -#endif - if (n && vhost->context->count_threads > 1) - if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, - (const void *)&opt, sizeof(opt)) < 0) { - compatible_close(sockfd); - return -1; - } -#endif -#endif - lws_plat_set_socket_options(vhost, sockfd); - - is = lws_socket_bind(vhost, sockfd, vhost->listen_port, vhost->iface); - /* - * There is a race where the network device may come up and then - * go away and fail here. So correctly handle unexpected failure - * here despite we earlier confirmed it. - */ - if (is < 0) { - lwsl_info("%s: lws_socket_bind says %d\n", __func__, is); - compatible_close(sockfd); - goto deal; - } - vhost->listen_port = is; - - lwsl_debug("%s: lws_socket_bind says %d\n", __func__, is); - - wsi = lws_zalloc(sizeof(struct lws), "listen wsi"); - if (wsi == NULL) { - lwsl_err("Out of mem\n"); - goto bail; - } - wsi->context = vhost->context; - wsi->desc.sockfd = sockfd; - lws_role_transition(wsi, 0, LRS_UNCONNECTED, &role_ops_listen); - wsi->protocol = vhost->protocols; - wsi->tsi = m; - wsi->vhost = vhost; - wsi->listener = 1; - - if (wsi->context->event_loop_ops->init_vhost_listen_wsi) - wsi->context->event_loop_ops->init_vhost_listen_wsi(wsi); - - if (__insert_wsi_socket_into_fds(vhost->context, wsi)) { - lwsl_notice("inserting wsi socket into fds failed\n"); - goto bail; - } - - vhost->context->count_wsi_allocated++; - vhost->lserv_wsi = wsi; - - n = listen(wsi->desc.sockfd, LWS_SOMAXCONN); - if (n < 0) { - lwsl_err("listen failed with error %d\n", LWS_ERRNO); - vhost->lserv_wsi = NULL; - vhost->context->count_wsi_allocated--; - __remove_wsi_socket_from_fds(wsi); - goto bail; - } - } /* for each thread able to independently listen */ - - if (!lws_check_opt(vhost->context->options, LWS_SERVER_OPTION_EXPLICIT_VHOSTS)) { -#ifdef LWS_WITH_UNIX_SOCK - if (LWS_UNIX_SOCK_ENABLED(vhost)) - lwsl_info(" Listening on \"%s\"\n", vhost->iface); - else -#endif - lwsl_info(" Listening on port %d\n", vhost->listen_port); - } - - // info->port = vhost->listen_port; - - return 0; - -bail: - compatible_close(sockfd); - - return -1; -} - -struct lws_vhost * -lws_select_vhost(struct lws_context *context, int port, const char *servername) -{ - struct lws_vhost *vhost = context->vhost_list; - const char *p; - int n, m, colon; - - n = (int)strlen(servername); - colon = n; - p = strchr(servername, ':'); - if (p) - colon = lws_ptr_diff(p, servername); - - /* Priotity 1: first try exact matches */ - - while (vhost) { - if (port == vhost->listen_port && - !strncmp(vhost->name, servername, colon)) { - lwsl_info("SNI: Found: %s\n", servername); - return vhost; - } - vhost = vhost->vhost_next; - } - - /* - * Priority 2: if no exact matches, try matching *.vhost-name - * unintentional matches are possible but resolve to x.com for *.x.com - * which is reasonable. If exact match exists we already chose it and - * never reach here. SSL will still fail it if the cert doesn't allow - * *.x.com. - */ - vhost = context->vhost_list; - while (vhost) { - m = (int)strlen(vhost->name); - if (port == vhost->listen_port && - m <= (colon - 2) && - servername[colon - m - 1] == '.' && - !strncmp(vhost->name, servername + colon - m, m)) { - lwsl_info("SNI: Found %s on wildcard: %s\n", - servername, vhost->name); - return vhost; - } - vhost = vhost->vhost_next; - } - - /* Priority 3: match the first vhost on our port */ - - vhost = context->vhost_list; - while (vhost) { - if (port == vhost->listen_port) { - lwsl_info("%s: vhost match to %s based on port %d\n", - __func__, vhost->name, port); - return vhost; - } - vhost = vhost->vhost_next; - } - - /* no match */ - - return NULL; -} - -LWS_VISIBLE LWS_EXTERN const char * -lws_get_mimetype(const char *file, const struct lws_http_mount *m) -{ - int n = (int)strlen(file); - const struct lws_protocol_vhost_options *pvo = NULL; - - if (m) - pvo = m->extra_mimetypes; - - if (n < 5) - return NULL; - - if (!strcmp(&file[n - 4], ".ico")) - return "image/x-icon"; - - if (!strcmp(&file[n - 4], ".gif")) - return "image/gif"; - - if (!strcmp(&file[n - 3], ".js")) - return "text/javascript"; - - if (!strcmp(&file[n - 4], ".png")) - return "image/png"; - - if (!strcmp(&file[n - 4], ".jpg")) - return "image/jpeg"; - - if (!strcmp(&file[n - 3], ".gz")) - return "application/gzip"; - - if (!strcmp(&file[n - 4], ".JPG")) - return "image/jpeg"; - - if (!strcmp(&file[n - 5], ".html")) - return "text/html"; - - if (!strcmp(&file[n - 4], ".css")) - return "text/css"; - - if (!strcmp(&file[n - 4], ".txt")) - return "text/plain"; - - if (!strcmp(&file[n - 4], ".svg")) - return "image/svg+xml"; - - if (!strcmp(&file[n - 4], ".ttf")) - return "application/x-font-ttf"; - - if (!strcmp(&file[n - 4], ".otf")) - return "application/font-woff"; - - if (!strcmp(&file[n - 5], ".woff")) - return "application/font-woff"; - - if (!strcmp(&file[n - 4], ".xml")) - return "application/xml"; - - while (pvo) { - if (pvo->name[0] == '*') /* ie, match anything */ - return pvo->value; - - if (!strcmp(&file[n - strlen(pvo->name)], pvo->name)) - return pvo->value; - - pvo = pvo->next; - } - - return NULL; -} -static lws_fop_flags_t -lws_vfs_prepare_flags(struct lws *wsi) -{ - lws_fop_flags_t f = 0; - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_ACCEPT_ENCODING)) - return f; - - if (strstr(lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_ACCEPT_ENCODING), - "gzip")) { - lwsl_info("client indicates GZIP is acceptable\n"); - f |= LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP; - } - - return f; -} - -static int -lws_http_serve(struct lws *wsi, char *uri, const char *origin, - const struct lws_http_mount *m) -{ - const struct lws_protocol_vhost_options *pvo = m->interpret; - struct lws_process_html_args args; - const char *mimetype; -#if !defined(_WIN32_WCE) - const struct lws_plat_file_ops *fops; - const char *vpath; - lws_fop_flags_t fflags = LWS_O_RDONLY; -#if defined(WIN32) && defined(LWS_HAVE__STAT32I64) - struct _stat32i64 st; -#else - struct stat st; -#endif - int spin = 0; -#endif - char path[256], sym[512]; - unsigned char *p = (unsigned char *)sym + 32 + LWS_PRE, *start = p; - unsigned char *end = p + sizeof(sym) - 32 - LWS_PRE; -#if !defined(WIN32) && !defined(LWS_WITH_ESP32) - size_t len; -#endif - int n; - - wsi->handling_404 = 0; - if (!wsi->vhost) - return -1; - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - if (wsi->vhost->http.error_document_404 && - !strcmp(uri, wsi->vhost->http.error_document_404)) - wsi->handling_404 = 1; -#endif - - lws_snprintf(path, sizeof(path) - 1, "%s/%s", origin, uri); - -#if !defined(_WIN32_WCE) - - fflags |= lws_vfs_prepare_flags(wsi); - - do { - spin++; - fops = lws_vfs_select_fops(wsi->context->fops, path, &vpath); - - if (wsi->http.fop_fd) - lws_vfs_file_close(&wsi->http.fop_fd); - - wsi->http.fop_fd = fops->LWS_FOP_OPEN(wsi->context->fops, - path, vpath, &fflags); - if (!wsi->http.fop_fd) { - lwsl_info("%s: Unable to open '%s': errno %d\n", - __func__, path, errno); - - return -1; - } - - /* if it can't be statted, don't try */ - if (fflags & LWS_FOP_FLAG_VIRTUAL) - break; -#if defined(LWS_WITH_ESP32) - break; -#endif -#if !defined(WIN32) - if (fstat(wsi->http.fop_fd->fd, &st)) { - lwsl_info("unable to stat %s\n", path); - goto bail; - } -#else -#if defined(LWS_HAVE__STAT32I64) - if (_stat32i64(path, &st)) { - lwsl_info("unable to stat %s\n", path); - goto bail; - } -#else - if (stat(path, &st)) { - lwsl_info("unable to stat %s\n", path); - goto bail; - } -#endif -#endif - - wsi->http.fop_fd->mod_time = (uint32_t)st.st_mtime; - fflags |= LWS_FOP_FLAG_MOD_TIME_VALID; - -#if !defined(WIN32) && !defined(LWS_WITH_ESP32) - if ((S_IFMT & st.st_mode) == S_IFLNK) { - len = readlink(path, sym, sizeof(sym) - 1); - if (len) { - lwsl_err("Failed to read link %s\n", path); - goto bail; - } - sym[len] = '\0'; - lwsl_debug("symlink %s -> %s\n", path, sym); - lws_snprintf(path, sizeof(path) - 1, "%s", sym); - } -#endif - if ((S_IFMT & st.st_mode) == S_IFDIR) { - lwsl_debug("default filename append to dir\n"); - lws_snprintf(path, sizeof(path) - 1, "%s/%s/index.html", - origin, uri); - } - - } while ((S_IFMT & st.st_mode) != S_IFREG && spin < 5); - - if (spin == 5) - lwsl_err("symlink loop %s \n", path); - - n = sprintf(sym, "%08llX%08lX", - (unsigned long long)lws_vfs_get_length(wsi->http.fop_fd), - (unsigned long)lws_vfs_get_mod_time(wsi->http.fop_fd)); - - /* disable ranges if IF_RANGE token invalid */ - - if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_RANGE)) - if (strcmp(sym, lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_IF_RANGE))) - /* differs - defeat Range: */ - wsi->http.ah->frag_index[WSI_TOKEN_HTTP_RANGE] = 0; - - if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_NONE_MATCH)) { - /* - * he thinks he has some version of it already, - * check if the tag matches - */ - if (!strcmp(sym, lws_hdr_simple_ptr(wsi, - WSI_TOKEN_HTTP_IF_NONE_MATCH))) { - - lwsl_debug("%s: ETAG match %s %s\n", __func__, - uri, origin); - - /* we don't need to send the payload */ - if (lws_add_http_header_status(wsi, - HTTP_STATUS_NOT_MODIFIED, &p, end)) - return -1; - - if (lws_add_http_header_by_token(wsi, - WSI_TOKEN_HTTP_ETAG, - (unsigned char *)sym, n, &p, end)) - return -1; - - if (lws_finalize_http_header(wsi, &p, end)) - return -1; - - n = lws_write(wsi, start, p - start, - LWS_WRITE_HTTP_HEADERS | - LWS_WRITE_H2_STREAM_END); - if (n != (p - start)) { - lwsl_err("_write returned %d from %ld\n", n, - (long)(p - start)); - return -1; - } - - lws_vfs_file_close(&wsi->http.fop_fd); - - return lws_http_transaction_completed(wsi); - } - } - - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_ETAG, - (unsigned char *)sym, n, &p, end)) - return -1; -#endif - - mimetype = lws_get_mimetype(path, m); - if (!mimetype) { - lwsl_err("unknown mimetype for %s\n", path); - goto bail; - } - if (!mimetype[0]) - lwsl_debug("sending no mimetype for %s\n", path); - - wsi->sending_chunked = 0; - - /* - * check if this is in the list of file suffixes to be interpreted by - * a protocol - */ - while (pvo) { - n = (int)strlen(path); - if (n > (int)strlen(pvo->name) && - !strcmp(&path[n - strlen(pvo->name)], pvo->name)) { - wsi->interpreting = 1; - if (!wsi->http2_substream) - wsi->sending_chunked = 1; - wsi->protocol_interpret_idx = - (char)(lws_intptr_t)pvo->value; - lwsl_info("want %s interpreted by %s\n", path, - wsi->vhost->protocols[ - (int)(lws_intptr_t)(pvo->value)].name); - wsi->protocol = &wsi->vhost->protocols[ - (int)(lws_intptr_t)(pvo->value)]; - if (lws_ensure_user_space(wsi)) - return -1; - break; - } - pvo = pvo->next; - } - - if (m->protocol) { - const struct lws_protocols *pp = lws_vhost_name_to_protocol( - wsi->vhost, m->protocol); - - if (lws_bind_protocol(wsi, pp)) - return 1; - args.p = (char *)p; - args.max_len = lws_ptr_diff(end, p); - if (pp->callback(wsi, LWS_CALLBACK_ADD_HEADERS, - wsi->user_space, &args, 0)) - return -1; - p = (unsigned char *)args.p; - } - - n = lws_serve_http_file(wsi, path, mimetype, (char *)start, - lws_ptr_diff(p, start)); - - if (n < 0 || ((n > 0) && lws_http_transaction_completed(wsi))) - return -1; /* error or can't reuse connection: close the socket */ - - return 0; -bail: - - return -1; -} - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) -const struct lws_http_mount * -lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len) -{ - const struct lws_http_mount *hm, *hit = NULL; - int best = 0; - - hm = wsi->vhost->http.mount_list; - while (hm) { - if (uri_len >= hm->mountpoint_len && - !strncmp(uri_ptr, hm->mountpoint, hm->mountpoint_len) && - (uri_ptr[hm->mountpoint_len] == '\0' || - uri_ptr[hm->mountpoint_len] == '/' || - hm->mountpoint_len == 1) - ) { - if (hm->origin_protocol == LWSMPRO_CALLBACK || - ((hm->origin_protocol == LWSMPRO_CGI || - lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) || - (wsi->http2_substream && - lws_hdr_total_length(wsi, - WSI_TOKEN_HTTP_COLON_PATH)) || - hm->protocol) && - hm->mountpoint_len > best)) { - best = hm->mountpoint_len; - hit = hm; - } - } - hm = hm->mount_next; - } - - return hit; -} -#endif - -#if !defined(LWS_WITH_ESP32) -static int -lws_find_string_in_file(const char *filename, const char *string, int stringlen) -{ - char buf[128]; - int fd, match = 0, pos = 0, n = 0, hit = 0; - - fd = lws_open(filename, O_RDONLY); - if (fd < 0) { - lwsl_err("can't open auth file: %s\n", filename); - return 0; - } - - while (1) { - if (pos == n) { - n = read(fd, buf, sizeof(buf)); - if (n <= 0) { - if (match == stringlen) - hit = 1; - break; - } - pos = 0; - } - - if (match == stringlen) { - if (buf[pos] == '\r' || buf[pos] == '\n') { - hit = 1; - break; - } - match = 0; - } - - if (buf[pos] == string[match]) - match++; - else - match = 0; - - pos++; - } - - close(fd); - - return hit; -} -#endif - -static int -lws_unauthorised_basic_auth(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - unsigned char *start = pt->serv_buf + LWS_PRE, - *p = start, *end = p + 512; - char buf[64]; - int n; - - /* no auth... tell him it is required */ - - if (lws_add_http_header_status(wsi, HTTP_STATUS_UNAUTHORIZED, &p, end)) - return -1; - - n = lws_snprintf(buf, sizeof(buf), "Basic realm=\"lwsws\""); - if (lws_add_http_header_by_token(wsi, - WSI_TOKEN_HTTP_WWW_AUTHENTICATE, - (unsigned char *)buf, n, &p, end)) - return -1; - - if (lws_finalize_http_header(wsi, &p, end)) - return -1; - - n = lws_write(wsi, start, p - start, LWS_WRITE_HTTP_HEADERS | - LWS_WRITE_H2_STREAM_END); - if (n < 0) - return -1; - - return lws_http_transaction_completed(wsi); - -} - -int lws_clean_url(char *p) -{ - if (p[0] == 'h' && p[1] == 't' && p[2] == 't' && p[3] == 'p') { - p += 4; - if (*p == 's') - p++; - if (*p == ':') { - p++; - if (*p == '/') - p++; - } - } - - while (*p) { - if (p[0] == '/' && p[1] == '/') { - char *p1 = p; - while (*p1) { - *p1 = p1[1]; - p1++; - } - continue; - } - p++; - } - - return 0; -} - -static const unsigned char methods[] = { - WSI_TOKEN_GET_URI, - WSI_TOKEN_POST_URI, - WSI_TOKEN_OPTIONS_URI, - WSI_TOKEN_PUT_URI, - WSI_TOKEN_PATCH_URI, - WSI_TOKEN_DELETE_URI, - WSI_TOKEN_CONNECT, - WSI_TOKEN_HEAD_URI, -#ifdef LWS_WITH_HTTP2 - WSI_TOKEN_HTTP_COLON_PATH, -#endif -}; - -static int -lws_http_get_uri_and_method(struct lws *wsi, char **puri_ptr, int *puri_len) -{ - int n, count = 0; - - for (n = 0; n < (int)LWS_ARRAY_SIZE(methods); n++) - if (lws_hdr_total_length(wsi, methods[n])) - count++; - if (!count) { - lwsl_warn("Missing URI in HTTP request\n"); - return -1; - } - - if (count != 1 && - !(wsi->http2_substream && - lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH))) { - lwsl_warn("multiple methods?\n"); - return -1; - } - - for (n = 0; n < (int)LWS_ARRAY_SIZE(methods); n++) - if (lws_hdr_total_length(wsi, methods[n])) { - *puri_ptr = lws_hdr_simple_ptr(wsi, methods[n]); - *puri_len = lws_hdr_total_length(wsi, methods[n]); - return n; - } - - return -1; -} - -int -lws_http_action(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - enum http_connection_type connection_type; - enum http_version request_version; - char content_length_str[32]; - struct lws_process_html_args args; - const struct lws_http_mount *hit = NULL; - unsigned int n; - char http_version_str[10]; - char http_conn_str[20]; - int http_version_len; - char *uri_ptr = NULL, *s; - int uri_len = 0, meth; - static const char * const oprot[] = { - "http://", "https://" - }; - - meth = lws_http_get_uri_and_method(wsi, &uri_ptr, &uri_len); - if (meth < 0 || meth >= (int)LWS_ARRAY_SIZE(method_names)) - goto bail_nuke_ah; - - /* we insist on absolute paths */ - - if (!uri_ptr || uri_ptr[0] != '/') { - lws_return_http_status(wsi, HTTP_STATUS_FORBIDDEN, NULL); - - goto bail_nuke_ah; - } - - lwsl_info("Method: '%s' (%d), request for '%s'\n", method_names[meth], - meth, uri_ptr); - - if (wsi->role_ops && wsi->role_ops->check_upgrades) - switch (wsi->role_ops->check_upgrades(wsi)) { - case LWS_UPG_RET_DONE: - return 0; - case LWS_UPG_RET_CONTINUE: - break; - case LWS_UPG_RET_BAIL: - goto bail_nuke_ah; - } - - if (lws_ensure_user_space(wsi)) - goto bail_nuke_ah; - - /* HTTP header had a content length? */ - - wsi->http.rx_content_length = 0; - if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) || - lws_hdr_total_length(wsi, WSI_TOKEN_PATCH_URI) || - lws_hdr_total_length(wsi, WSI_TOKEN_PUT_URI)) - wsi->http.rx_content_length = 100 * 1024 * 1024; - - if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) { - lws_hdr_copy(wsi, content_length_str, - sizeof(content_length_str) - 1, - WSI_TOKEN_HTTP_CONTENT_LENGTH); - wsi->http.rx_content_length = atoll(content_length_str); - } - - if (wsi->http2_substream) { - wsi->http.request_version = HTTP_VERSION_2; - } else { - /* http_version? Default to 1.0, override with token: */ - request_version = HTTP_VERSION_1_0; - - /* Works for single digit HTTP versions. : */ - http_version_len = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP); - if (http_version_len > 7) { - lws_hdr_copy(wsi, http_version_str, - sizeof(http_version_str) - 1, - WSI_TOKEN_HTTP); - if (http_version_str[5] == '1' && - http_version_str[7] == '1') - request_version = HTTP_VERSION_1_1; - } - wsi->http.request_version = request_version; - - /* HTTP/1.1 defaults to "keep-alive", 1.0 to "close" */ - if (request_version == HTTP_VERSION_1_1) - connection_type = HTTP_CONNECTION_KEEP_ALIVE; - else - connection_type = HTTP_CONNECTION_CLOSE; - - /* Override default if http "Connection:" header: */ - if (lws_hdr_total_length(wsi, WSI_TOKEN_CONNECTION)) { - lws_hdr_copy(wsi, http_conn_str, - sizeof(http_conn_str) - 1, - WSI_TOKEN_CONNECTION); - http_conn_str[sizeof(http_conn_str) - 1] = '\0'; - if (!strcasecmp(http_conn_str, "keep-alive")) - connection_type = HTTP_CONNECTION_KEEP_ALIVE; - else - if (!strcasecmp(http_conn_str, "close")) - connection_type = HTTP_CONNECTION_CLOSE; - } - wsi->http.connection_type = connection_type; - } - - n = wsi->protocol->callback(wsi, LWS_CALLBACK_FILTER_HTTP_CONNECTION, - wsi->user_space, uri_ptr, uri_len); - if (n) { - lwsl_info("LWS_CALLBACK_HTTP closing\n"); - - return 1; - } - /* - * if there is content supposed to be coming, - * put a timeout on it having arrived - */ - lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, - wsi->context->timeout_secs); -#ifdef LWS_WITH_TLS - if (wsi->tls.redirect_to_https) { - /* - * we accepted http:// only so we could redirect to - * https://, so issue the redirect. Create the redirection - * URI from the host: header and ignore the path part - */ - unsigned char *start = pt->serv_buf + LWS_PRE, *p = start, - *end = p + 512; - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST)) - goto bail_nuke_ah; - - n = sprintf((char *)end, "https://%s/", - lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST)); - - n = lws_http_redirect(wsi, HTTP_STATUS_MOVED_PERMANENTLY, - end, n, &p, end); - if ((int)n < 0) - goto bail_nuke_ah; - - return lws_http_transaction_completed(wsi); - } -#endif - -#ifdef LWS_WITH_ACCESS_LOG - lws_prepare_access_log_info(wsi, uri_ptr, meth); -#endif - - /* can we serve it from the mount list? */ - - hit = lws_find_mount(wsi, uri_ptr, uri_len); - if (!hit) { - /* deferred cleanup and reset to protocols[0] */ - - lwsl_info("no hit\n"); - - if (lws_bind_protocol(wsi, &wsi->vhost->protocols[0])) - return 1; - - lwsi_set_state(wsi, LRS_DOING_TRANSACTION); - - n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP, - wsi->user_space, uri_ptr, uri_len); - - goto after; - } - - s = uri_ptr + hit->mountpoint_len; - - /* - * if we have a mountpoint like https://xxx.com/yyy - * there is an implied / at the end for our purposes since - * we can only mount on a "directory". - * - * But if we just go with that, the browser cannot understand - * that he is actually looking down one "directory level", so - * even though we give him /yyy/abc.html he acts like the - * current directory level is /. So relative urls like "x.png" - * wrongly look outside the mountpoint. - * - * Therefore if we didn't come in on a url with an explicit - * / at the end, we must redirect to add it so the browser - * understands he is one "directory level" down. - */ - if ((hit->mountpoint_len > 1 || - (hit->origin_protocol == LWSMPRO_REDIR_HTTP || - hit->origin_protocol == LWSMPRO_REDIR_HTTPS)) && - (*s != '/' || - (hit->origin_protocol == LWSMPRO_REDIR_HTTP || - hit->origin_protocol == LWSMPRO_REDIR_HTTPS)) && - (hit->origin_protocol != LWSMPRO_CGI && - hit->origin_protocol != LWSMPRO_CALLBACK)) { - unsigned char *start = pt->serv_buf + LWS_PRE, - *p = start, *end = p + 512; - - lwsl_debug("Doing 301 '%s' org %s\n", s, hit->origin); - - /* > at start indicates deal with by redirect */ - if (hit->origin_protocol == LWSMPRO_REDIR_HTTP || - hit->origin_protocol == LWSMPRO_REDIR_HTTPS) - n = lws_snprintf((char *)end, 256, "%s%s", - oprot[hit->origin_protocol & 1], - hit->origin); - else { - if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST)) { - if (!lws_hdr_total_length(wsi, - WSI_TOKEN_HTTP_COLON_AUTHORITY)) - goto bail_nuke_ah; - n = lws_snprintf((char *)end, 256, - "%s%s%s/", oprot[!!lws_is_ssl(wsi)], - lws_hdr_simple_ptr(wsi, - WSI_TOKEN_HTTP_COLON_AUTHORITY), - uri_ptr); - } else - n = lws_snprintf((char *)end, 256, - "%s%s%s/", oprot[!!lws_is_ssl(wsi)], - lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST), - uri_ptr); - } - - lws_clean_url((char *)end); - n = lws_http_redirect(wsi, HTTP_STATUS_MOVED_PERMANENTLY, - end, n, &p, end); - if ((int)n < 0) - goto bail_nuke_ah; - - return lws_http_transaction_completed(wsi); - } - - /* basic auth? */ - - if (hit->basic_auth_login_file) { - char b64[160], plain[(sizeof(b64) * 3) / 4]; - int m; - - /* Did he send auth? */ - if (!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_AUTHORIZATION)) - return lws_unauthorised_basic_auth(wsi); - - n = HTTP_STATUS_FORBIDDEN; - - m = lws_hdr_copy(wsi, b64, sizeof(b64), - WSI_TOKEN_HTTP_AUTHORIZATION); - if (m < 7) { - lwsl_err("b64 auth too long\n"); - goto transaction_result_n; - } - - b64[5] = '\0'; - if (strcasecmp(b64, "Basic")) { - lwsl_err("auth missing basic: %s\n", b64); - goto transaction_result_n; - } - - /* It'll be like Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l */ - - m = lws_b64_decode_string(b64 + 6, plain, sizeof(plain)); - if (m < 0) { - lwsl_err("plain auth too long\n"); - goto transaction_result_n; - } - - if (!lws_find_string_in_file(hit->basic_auth_login_file, - plain, m)) { - lwsl_err("basic auth lookup failed\n"); - return lws_unauthorised_basic_auth(wsi); - } - - lwsl_info("basic auth accepted\n"); - - /* accept the auth */ - } - -#if defined(LWS_WITH_HTTP_PROXY) - /* - * The mount is a reverse proxy? - */ - - if (hit->origin_protocol == LWSMPRO_HTTPS || - hit->origin_protocol == LWSMPRO_HTTP) { - struct lws_client_connect_info i; - char ads[96], rpath[256], *pcolon, *pslash, *p; - int n, na; - - memset(&i, 0, sizeof(i)); - i.context = lws_get_context(wsi); - - pcolon = strchr(hit->origin, ':'); - pslash = strchr(hit->origin, '/'); - if (!pslash) { - lwsl_err("Proxy mount origin '%s' must have /\n", - hit->origin); - return -1; - } - if (pcolon > pslash) - pcolon = NULL; - - if (pcolon) - n = pcolon - hit->origin; - else - n = pslash - hit->origin; - - if (n >= (int)sizeof(ads) - 2) - n = sizeof(ads) - 2; - - memcpy(ads, hit->origin, n); - ads[n] = '\0'; - - i.address = ads; - i.port = 80; - if (hit->origin_protocol == LWSMPRO_HTTPS) { - i.port = 443; - i.ssl_connection = 1; - } - if (pcolon) - i.port = atoi(pcolon + 1); - - lws_snprintf(rpath, sizeof(rpath) - 1, "/%s/%s", pslash + 1, - uri_ptr + hit->mountpoint_len); - lws_clean_url(rpath); - na = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_URI_ARGS); - if (na) { - p = rpath + strlen(rpath); - *p++ = '?'; - lws_hdr_copy(wsi, p, &rpath[sizeof(rpath) - 1] - p, - WSI_TOKEN_HTTP_URI_ARGS); - while (--na) { - if (*p == '\0') - *p = '&'; - p++; - } - } - - - i.path = rpath; - i.host = i.address; - i.origin = NULL; - i.method = "GET"; - i.parent_wsi = wsi; - i.uri_replace_from = hit->origin; - i.uri_replace_to = hit->mountpoint; - - lwsl_notice("proxying to %s port %d url %s, ssl %d, " - "from %s, to %s\n", - i.address, i.port, i.path, i.ssl_connection, - i.uri_replace_from, i.uri_replace_to); - - if (!lws_client_connect_via_info(&i)) { - lwsl_err("proxy connect fail\n"); - return 1; - } - - return 0; - } -#endif - - /* - * A particular protocol callback is mounted here? - * - * For the duration of this http transaction, bind us to the - * associated protocol - */ - if (hit->origin_protocol == LWSMPRO_CALLBACK || hit->protocol) { - const struct lws_protocols *pp; - const char *name = hit->origin; - if (hit->protocol) - name = hit->protocol; - - pp = lws_vhost_name_to_protocol(wsi->vhost, name); - if (!pp) { - n = -1; - lwsl_err("Unable to find plugin '%s'\n", - hit->origin); - return 1; - } - - if (lws_bind_protocol(wsi, pp)) - return 1; - - args.p = uri_ptr; - args.len = uri_len; - args.max_len = hit->auth_mask; - args.final = 0; /* used to signal callback dealt with it */ - args.chunked = 0; - - n = wsi->protocol->callback(wsi, - LWS_CALLBACK_CHECK_ACCESS_RIGHTS, - wsi->user_space, &args, 0); - if (n) { - lws_return_http_status(wsi, HTTP_STATUS_UNAUTHORIZED, - NULL); - goto bail_nuke_ah; - } - if (args.final) /* callback completely handled it well */ - return 0; - - if (hit->cgienv && wsi->protocol->callback(wsi, - LWS_CALLBACK_HTTP_PMO, - wsi->user_space, (void *)hit->cgienv, 0)) - return 1; - - if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) { - n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP, - wsi->user_space, - uri_ptr + hit->mountpoint_len, - uri_len - hit->mountpoint_len); - goto after; - } - } - -#ifdef LWS_WITH_CGI - /* did we hit something with a cgi:// origin? */ - if (hit->origin_protocol == LWSMPRO_CGI) { - const char *cmd[] = { - NULL, /* replace with cgi path */ - NULL - }; - - lwsl_debug("%s: cgi\n", __func__); - cmd[0] = hit->origin; - - n = 5; - if (hit->cgi_timeout) - n = hit->cgi_timeout; - - n = lws_cgi(wsi, cmd, hit->mountpoint_len, n, - hit->cgienv); - if (n) { - lwsl_err("%s: cgi failed\n", __func__); - return -1; - } - - goto deal_body; - } -#endif - - n = (int)strlen(s); - if (s[0] == '\0' || (n == 1 && s[n - 1] == '/')) - s = (char *)hit->def; - if (!s) - s = "index.html"; - - wsi->cache_secs = hit->cache_max_age; - wsi->cache_reuse = hit->cache_reusable; - wsi->cache_revalidate = hit->cache_revalidate; - wsi->cache_intermediaries = hit->cache_intermediaries; - - n = 1; - if (hit->origin_protocol == LWSMPRO_FILE) - n = lws_http_serve(wsi, s, hit->origin, hit); - if (n) { - /* - * lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL); - */ - if (hit->protocol) { - const struct lws_protocols *pp = - lws_vhost_name_to_protocol( - wsi->vhost, hit->protocol); - - if (lws_bind_protocol(wsi, pp)) - return 1; - - n = pp->callback(wsi, LWS_CALLBACK_HTTP, - wsi->user_space, - uri_ptr + hit->mountpoint_len, - uri_len - hit->mountpoint_len); - } else - n = wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP, - wsi->user_space, uri_ptr, uri_len); - } - -after: - if (n) { - lwsl_info("LWS_CALLBACK_HTTP closing\n"); - - return 1; - } - -#ifdef LWS_WITH_CGI -deal_body: -#endif - /* - * If we're not issuing a file, check for content_length or - * HTTP keep-alive. No keep-alive header allocation for - * ISSUING_FILE, as this uses HTTP/1.0. - * - * In any case, return 0 and let lws_read decide how to - * proceed based on state - */ - if (lwsi_state(wsi) != LRS_ISSUING_FILE) { - /* Prepare to read body if we have a content length: */ - lwsl_debug("wsi->http.rx_content_length %lld %d %d\n", - (long long)wsi->http.rx_content_length, - wsi->upgraded_to_http2, wsi->http2_substream); - if (wsi->http.rx_content_length > 0) { - struct lws_tokens ebuf; - int m; - - lwsi_set_state(wsi, LRS_BODY); - lwsl_info("%s: %p: LRS_BODY state set (0x%x)\n", - __func__, wsi, wsi->wsistate); - wsi->http.rx_content_remain = - wsi->http.rx_content_length; - - /* - * At this point we have transitioned from deferred - * action to expecting BODY on the stream wsi, if it's - * in a bundle like h2. So if the stream wsi has its - * own buflist, we need to deal with that first. - */ - - while (1) { - ebuf.len = (int)lws_buflist_next_segment_len( - &wsi->buflist, (uint8_t **)&ebuf.token); - if (!ebuf.len) - break; - lwsl_notice("%s: consuming %d\n", __func__, (int)ebuf.len); - m = lws_read_h1(wsi, (uint8_t *)ebuf.token, ebuf.len); - if (m < 0) - return -1; - - if (lws_buflist_aware_consume(wsi, &ebuf, m, 1)) - return -1; - } - } - } - - return 0; - -bail_nuke_ah: - lws_header_table_detach(wsi, 1); - - return 1; - -transaction_result_n: - lws_return_http_status(wsi, n, NULL); - - return lws_http_transaction_completed(wsi); -} - -int -lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len) -{ - struct lws_context *context = lws_get_context(wsi); - unsigned char *obuf = *buf; -#if defined(LWS_WITH_HTTP2) - char tbuf[128], *p; -#endif - size_t olen = len; - int n = 0, m, i; - - if (len >= 10000000) { - lwsl_err("%s: assert: len %ld\n", __func__, (long)len); - assert(0); - } - - if (!wsi->http.ah) { - lwsl_err("%s: assert: NULL ah\n", __func__); - assert(0); - } - - while (len) { - if (!lwsi_role_server(wsi) || !lwsi_role_http(wsi)) { - lwsl_err("%s: bad wsi role 0x%x\n", __func__, - lwsi_role(wsi)); - goto bail_nuke_ah; - } - - i = (int)len; - m = lws_parse(wsi, *buf, &i); - lwsl_info("%s: parsed count %d\n", __func__, (int)len - i); - (*buf) += (int)len - i; - len = i; - if (m) { - if (m == 2) { - /* - * we are transitioning from http with - * an AH, to raw. Drop the ah and set - * the mode. - */ -raw_transition: - lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - lws_bind_protocol(wsi, &wsi->vhost->protocols[ - wsi->vhost-> - raw_protocol_index]); - lwsl_info("transition to raw vh %s prot %d\n", - wsi->vhost->name, - wsi->vhost->raw_protocol_index); - if ((wsi->protocol->callback)(wsi, - LWS_CALLBACK_RAW_ADOPT, - wsi->user_space, NULL, 0)) - goto bail_nuke_ah; - - lws_role_transition(wsi, 0, LRS_ESTABLISHED, - &role_ops_raw_skt); - lws_header_table_detach(wsi, 1); - - if (m == 2 && (wsi->protocol->callback)(wsi, - LWS_CALLBACK_RAW_RX, - wsi->user_space, obuf, olen)) - return 1; - - return 0; - } - lwsl_info("lws_parse failed\n"); - goto bail_nuke_ah; - } - - if (wsi->http.ah->parser_state != WSI_PARSING_COMPLETE) - continue; - - lwsl_parser("%s: lws_parse sees parsing complete\n", __func__); - - /* select vhost */ - - if (lws_hdr_total_length(wsi, WSI_TOKEN_HOST)) { - struct lws_vhost *vhost = lws_select_vhost( - context, wsi->vhost->listen_port, - lws_hdr_simple_ptr(wsi, WSI_TOKEN_HOST)); - - if (vhost) - wsi->vhost = vhost; - } else - lwsl_info("no host\n"); - - if (!lwsi_role_h2(wsi) || !lwsi_role_server(wsi)) { - wsi->vhost->conn_stats.h1_trans++; - if (!wsi->conn_stat_done) { - wsi->vhost->conn_stats.h1_conn++; - wsi->conn_stat_done = 1; - } - } - - /* check for unwelcome guests */ - - if (wsi->context->reject_service_keywords) { - const struct lws_protocol_vhost_options *rej = - wsi->context->reject_service_keywords; - char ua[384], *msg = NULL; - - if (lws_hdr_copy(wsi, ua, sizeof(ua) - 1, - WSI_TOKEN_HTTP_USER_AGENT) > 0) { -#ifdef LWS_WITH_ACCESS_LOG - char *uri_ptr = NULL; - int meth, uri_len; -#endif - ua[sizeof(ua) - 1] = '\0'; - while (rej) { - if (!strstr(ua, rej->name)) { - rej = rej->next; - continue; - } - - msg = strchr(rej->value, ' '); - if (msg) - msg++; - lws_return_http_status(wsi, - atoi(rej->value), msg); -#ifdef LWS_WITH_ACCESS_LOG - meth = lws_http_get_uri_and_method(wsi, - &uri_ptr, &uri_len); - if (meth >= 0) - lws_prepare_access_log_info(wsi, - uri_ptr, meth); - - /* wsi close will do the log */ -#endif - wsi->vhost->conn_stats.rejected++; - /* - * We don't want anything from - * this rejected guy. Follow - * the close flow, not the - * transaction complete flow. - */ - goto bail_nuke_ah; - } - } - } - - - if (lws_hdr_total_length(wsi, WSI_TOKEN_CONNECT)) { - lwsl_info("Changing to RAW mode\n"); - m = 0; - goto raw_transition; - } - - lwsi_set_state(wsi, LRS_PRE_WS_SERVING_ACCEPT); - lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - - /* is this websocket protocol or normal http 1.0? */ - - if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) { - if (!strcasecmp(lws_hdr_simple_ptr(wsi, - WSI_TOKEN_UPGRADE), - "websocket")) { -#if defined(LWS_ROLE_WS) - wsi->vhost->conn_stats.ws_upg++; - lwsl_info("Upgrade to ws\n"); - goto upgrade_ws; -#endif - } -#if defined(LWS_WITH_HTTP2) - if (!strcasecmp(lws_hdr_simple_ptr(wsi, - WSI_TOKEN_UPGRADE), - "h2c")) { - wsi->vhost->conn_stats.h2_upg++; - lwsl_info("Upgrade to h2c\n"); - goto upgrade_h2c; - } -#endif - lwsl_info("Unknown upgrade\n"); - /* dunno what he wanted to upgrade to */ - goto bail_nuke_ah; - } - - /* no upgrade ack... he remained as HTTP */ - - lwsl_info("%s: %p: No upgrade\n", __func__, wsi); - - lwsi_set_state(wsi, LRS_ESTABLISHED); - wsi->http.fop_fd = NULL; - - lwsl_debug("%s: wsi %p: ah %p\n", __func__, (void *)wsi, - (void *)wsi->http.ah); - - n = lws_http_action(wsi); - - return n; - -#if defined(LWS_WITH_HTTP2) -upgrade_h2c: - if (!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP2_SETTINGS)) { - lwsl_info("missing http2_settings\n"); - goto bail_nuke_ah; - } - - lwsl_info("h2c upgrade...\n"); - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP2_SETTINGS); - /* convert the peer's HTTP-Settings */ - n = lws_b64_decode_string(p, tbuf, sizeof(tbuf)); - if (n < 0) { - lwsl_parser("HTTP2_SETTINGS too long\n"); - return 1; - } - - /* adopt the header info */ - - if (!wsi->h2.h2n) { - wsi->h2.h2n = lws_zalloc(sizeof(*wsi->h2.h2n), - "h2n"); - if (!wsi->h2.h2n) - return 1; - } - - lws_h2_init(wsi); - - /* HTTP2 union */ - - lws_h2_settings(wsi, &wsi->h2.h2n->set, (unsigned char *)tbuf, n); - - lws_hpack_dynamic_size(wsi, wsi->h2.h2n->set.s[ - H2SET_HEADER_TABLE_SIZE]); - - strcpy(tbuf, "HTTP/1.1 101 Switching Protocols\x0d\x0a" - "Connection: Upgrade\x0d\x0a" - "Upgrade: h2c\x0d\x0a\x0d\x0a"); - m = (int)strlen(tbuf); - n = lws_issue_raw(wsi, (unsigned char *)tbuf, m); - if (n != m) { - lwsl_debug("http2 switch: ERROR writing to socket\n"); - return 1; - } - - lwsi_set_state(wsi, LRS_H2_AWAIT_PREFACE); - wsi->upgraded_to_http2 = 1; - - return 0; -#endif -#if defined(LWS_ROLE_WS) -upgrade_ws: - if (lws_process_ws_upgrade(wsi)) - goto bail_nuke_ah; - - return 0; -#endif - } /* while all chars are handled */ - - return 0; - -bail_nuke_ah: - /* drop the header info */ - lws_header_table_detach(wsi, 1); - - return 1; -} - - -static int -lws_get_idlest_tsi(struct lws_context *context) -{ - unsigned int lowest = ~0; - int n = 0, hit = -1; - - for (; n < context->count_threads; n++) { - if ((unsigned int)context->pt[n].fds_count != - context->fd_limit_per_thread - 1 && - (unsigned int)context->pt[n].fds_count < lowest) { - lowest = context->pt[n].fds_count; - hit = n; - } - } - - return hit; -} - -struct lws * -lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi) -{ - struct lws *new_wsi; - int n = fixed_tsi; - - if (n < 0) - n = lws_get_idlest_tsi(vhost->context); - - if (n < 0) { - lwsl_err("no space for new conn\n"); - return NULL; - } - - new_wsi = lws_zalloc(sizeof(struct lws), "new server wsi"); - if (new_wsi == NULL) { - lwsl_err("Out of memory for new connection\n"); - return NULL; - } - - new_wsi->tsi = n; - lwsl_debug("new wsi %p joining vhost %s, tsi %d\n", new_wsi, - vhost->name, new_wsi->tsi); - - new_wsi->vhost = vhost; - new_wsi->context = vhost->context; - new_wsi->pending_timeout = NO_PENDING_TIMEOUT; - new_wsi->rxflow_change_to = LWS_RXFLOW_ALLOW; - - /* initialize the instance struct */ - - lwsi_set_state(new_wsi, LRS_UNCONNECTED); - new_wsi->hdr_parsing_completed = 0; - -#ifdef LWS_WITH_TLS - new_wsi->tls.use_ssl = LWS_SSL_ENABLED(vhost); -#endif - - /* - * these can only be set once the protocol is known - * we set an un-established connection's protocol pointer - * to the start of the supported list, so it can look - * for matching ones during the handshake - */ - new_wsi->protocol = vhost->protocols; - new_wsi->user_space = NULL; - new_wsi->desc.sockfd = LWS_SOCK_INVALID; - new_wsi->position_in_fds_table = LWS_NO_FDS_POS; - - vhost->context->count_wsi_allocated++; - - /* - * outermost create notification for wsi - * no user_space because no protocol selection - */ - vhost->protocols[0].callback(new_wsi, LWS_CALLBACK_WSI_CREATE, - NULL, NULL, 0); - - return new_wsi; -} - -LWS_VISIBLE int LWS_WARN_UNUSED_RESULT -lws_http_transaction_completed(struct lws *wsi) -{ - int n = NO_PENDING_TIMEOUT; - - if (wsi->trunc_len) { - /* - * ...so he tried to send something large as the http reply, - * it went as a partial, but he immediately said the - * transaction was completed. - * - * Defer the transaction completed until the last part of the - * partial is sent. - */ - lwsl_notice("%s: deferring due to partial\n", __func__); - wsi->http.deferred_transaction_completed = 1; - - return 0; - } - - lwsl_info("%s: wsi %p\n", __func__, wsi); - - lws_access_log(wsi); - - if (!wsi->hdr_parsing_completed) { - char peer[64]; - lws_get_peer_simple(wsi, peer, sizeof(peer) - 1); - peer[sizeof(peer) - 1] = '\0'; - lwsl_notice("%s: (from %s) ignoring, ah parsing incomplete\n", - __func__, peer); - return 0; - } - - /* if we can't go back to accept new headers, drop the connection */ - if (wsi->http2_substream) - return 0; - - if (wsi->seen_zero_length_recv) - return 1; - - if (wsi->http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) { - lwsl_notice("%s: %p: close connection\n", __func__, wsi); - return 1; - } - - if (lws_bind_protocol(wsi, &wsi->vhost->protocols[0])) - return 1; - - /* - * otherwise set ourselves up ready to go again, but because we have no - * idea about the wsi writability, we make put it in a holding state - * until we can verify POLLOUT. The part of this that confirms POLLOUT - * with no partials is in lws_server_socket_service() below. - */ - lwsl_debug("%s: %p: setting DEF_ACT from 0x%x\n", __func__, - wsi, wsi->wsistate); - lwsi_set_state(wsi, LRS_DEFERRING_ACTION); - wsi->http.tx_content_length = 0; - wsi->http.tx_content_remain = 0; - wsi->hdr_parsing_completed = 0; -#ifdef LWS_WITH_ACCESS_LOG - wsi->http.access_log.sent = 0; -#endif - - if (wsi->vhost->keepalive_timeout) - n = PENDING_TIMEOUT_HTTP_KEEPALIVE_IDLE; - lws_set_timeout(wsi, n, wsi->vhost->keepalive_timeout); - - /* - * We already know we are on http1.1 / keepalive and the next thing - * coming will be another header set. - * - * If there is no pending rx and we still have the ah, drop it and - * reacquire a new ah when the new headers start to arrive. (Otherwise - * we needlessly hog an ah indefinitely.) - * - * However if there is pending rx and we know from the keepalive state - * that is already at least the start of another header set, simply - * reset the existing header table and keep it. - */ - if (wsi->http.ah) { - // lws_buflist_describe(&wsi->buflist, wsi); - if (!lws_buflist_next_segment_len(&wsi->buflist, NULL)) { - lwsl_info("%s: %p: nothing in buflist so detaching ah\n", - __func__, wsi); - lws_header_table_detach(wsi, 1); -#ifdef LWS_WITH_TLS - /* - * additionally... if we are hogging an SSL instance - * with no pending pipelined headers (or ah now), and - * SSL is scarce, drop this connection without waiting - */ - - if (wsi->vhost->tls.use_ssl && - wsi->context->simultaneous_ssl_restriction && - wsi->context->simultaneous_ssl == - wsi->context->simultaneous_ssl_restriction) { - lwsl_info("%s: simultaneous_ssl_restriction\n", - __func__); - return 1; - } -#endif - } else { - lwsl_info("%s: %p: resetting and keeping ah as pipeline\n", - __func__, wsi); - lws_header_table_reset(wsi, 0); - /* - * If we kept the ah, we should restrict the amount - * of time we are willing to keep it. Otherwise it - * will be bound the whole time the connection remains - * open. - */ - lws_set_timeout(wsi, PENDING_TIMEOUT_HOLDING_AH, - wsi->vhost->keepalive_timeout); - } - /* If we're (re)starting on headers, need other implied init */ - if (wsi->http.ah) - wsi->http.ah->ues = URIES_IDLE; - - //lwsi_set_state(wsi, LRS_ESTABLISHED); - } else - if (lws_buflist_next_segment_len(&wsi->buflist, NULL)) - if (lws_header_table_attach(wsi, 0)) - lwsl_debug("acquired ah\n"); - - lwsl_info("%s: %p: keep-alive await new transaction\n", __func__, wsi); - lws_callback_on_writable(wsi); - - return 0; -} - -/* if not a socket, it's a raw, non-ssl file descriptor */ - -LWS_VISIBLE struct lws * -lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type, - lws_sock_file_fd_type fd, const char *vh_prot_name, - struct lws *parent) -{ - struct lws_context *context = vh->context; - struct lws *new_wsi; - struct lws_context_per_thread *pt; - int n, ssl = 0; - -#if defined(LWS_WITH_PEER_LIMITS) - struct lws_peer *peer = NULL; - - if (type & LWS_ADOPT_SOCKET && !(type & LWS_ADOPT_WS_PARENTIO)) { - peer = lws_get_or_create_peer(vh, fd.sockfd); - - if (peer && context->ip_limit_wsi && - peer->count_wsi >= context->ip_limit_wsi) { - lwsl_notice("Peer reached wsi limit %d\n", - context->ip_limit_wsi); - lws_stats_atomic_bump(context, &context->pt[0], - LWSSTATS_C_PEER_LIMIT_WSI_DENIED, 1); - return NULL; - } - } -#endif - - n = -1; - if (parent) - n = parent->tsi; - new_wsi = lws_create_new_server_wsi(vh, n); - if (!new_wsi) { - if (type & LWS_ADOPT_SOCKET && !(type & LWS_ADOPT_WS_PARENTIO)) - compatible_close(fd.sockfd); - return NULL; - } -#if defined(LWS_WITH_PEER_LIMITS) - if (peer) - lws_peer_add_wsi(context, peer, new_wsi); -#endif - pt = &context->pt[(int)new_wsi->tsi]; - lws_stats_atomic_bump(context, pt, LWSSTATS_C_CONNECTIONS, 1); - - if (parent) { - new_wsi->parent = parent; - new_wsi->sibling_list = parent->child_list; - parent->child_list = new_wsi; - - if (type & LWS_ADOPT_WS_PARENTIO) - new_wsi->parent_carries_io = 1; - } - - new_wsi->desc = fd; - - if (vh_prot_name) { - new_wsi->protocol = lws_vhost_name_to_protocol(new_wsi->vhost, - vh_prot_name); - if (!new_wsi->protocol) { - lwsl_err("Protocol %s not enabled on vhost %s\n", - vh_prot_name, new_wsi->vhost->name); - goto bail; - } - if (lws_ensure_user_space(new_wsi)) { - lwsl_notice("OOM trying to get user_space\n"); - goto bail; - } -#if defined(LWS_ROLE_WS) - if (type & LWS_ADOPT_WS_PARENTIO) { - new_wsi->desc.sockfd = LWS_SOCK_INVALID; - lwsl_debug("binding to %s\n", new_wsi->protocol->name); - lws_bind_protocol(new_wsi, new_wsi->protocol); - lws_role_transition(new_wsi, LWSIFR_SERVER, - LRS_ESTABLISHED, &role_ops_ws); - /* allocate the ws struct for the wsi */ - new_wsi->ws = lws_zalloc(sizeof(*new_wsi->ws), "ws struct"); - if (!new_wsi->ws) { - lwsl_notice("OOM\n"); - goto bail; - } - lws_server_init_wsi_for_ws(new_wsi); - - return new_wsi; - } -#endif - } else -#if defined(LWS_ROLE_H1) - if (type & LWS_ADOPT_HTTP) {/* he will transition later */ - new_wsi->protocol = - &vh->protocols[vh->default_protocol_index]; - new_wsi->role_ops = &role_ops_h1; - } - else -#endif - { /* this is the only time he will transition */ - lws_bind_protocol(new_wsi, - &vh->protocols[vh->raw_protocol_index]); - lws_role_transition(new_wsi, 0, LRS_ESTABLISHED, - &role_ops_raw_skt); - } - - if (type & LWS_ADOPT_SOCKET) { /* socket desc */ - lwsl_debug("%s: new wsi %p, sockfd %d\n", __func__, new_wsi, - (int)(lws_intptr_t)fd.sockfd); -#if !defined(LWS_WITH_ESP32) - if (type & LWS_ADOPT_FLAG_UDP) - /* - * these can be >128 bytes, so just alloc for UDP - */ - new_wsi->udp = lws_malloc(sizeof(*new_wsi->udp), - "udp struct"); -#endif - - if (type & LWS_ADOPT_HTTP) - /* the transport is accepted... - * give him time to negotiate */ - lws_set_timeout(new_wsi, - PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, - context->timeout_secs); - - } else /* file desc */ - lwsl_debug("%s: new wsi %p, filefd %d\n", __func__, new_wsi, - (int)(lws_intptr_t)fd.filefd); - - /* - * A new connection was accepted. Give the user a chance to - * set properties of the newly created wsi. There's no protocol - * selected yet so we issue this to the vhosts's default protocol, - * itself by default protocols[0] - */ - n = LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED; - if (!(type & LWS_ADOPT_HTTP)) { - if (!(type & LWS_ADOPT_SOCKET)) - n = LWS_CALLBACK_RAW_ADOPT_FILE; - else - n = LWS_CALLBACK_RAW_ADOPT; - } - - if (!LWS_SSL_ENABLED(new_wsi->vhost) || !(type & LWS_ADOPT_ALLOW_SSL) || - !(type & LWS_ADOPT_SOCKET)) { - /* non-SSL */ - if (!(type & LWS_ADOPT_HTTP)) { - if (!(type & LWS_ADOPT_SOCKET)) - lws_role_transition(new_wsi, 0, LRS_ESTABLISHED, - &role_ops_raw_file); - else - lws_role_transition(new_wsi, 0, LRS_ESTABLISHED, - &role_ops_raw_skt); - } -#if defined(LWS_ROLE_H1) - else - lws_role_transition(new_wsi, LWSIFR_SERVER, - LRS_HEADERS, &role_ops_h1); -#endif - } else { - /* SSL */ - if (!(type & LWS_ADOPT_HTTP)) - lws_role_transition(new_wsi, 0, LRS_SSL_INIT, - &role_ops_raw_skt); -#if defined(LWS_ROLE_H1) - else - lws_role_transition(new_wsi, LWSIFR_SERVER, - LRS_SSL_INIT, &role_ops_h1); -#endif - ssl = 1; - } - - lwsl_debug("new wsi wsistate 0x%x\n", new_wsi->wsistate); - - if (context->event_loop_ops->accept) - context->event_loop_ops->accept(new_wsi); - - if (!ssl) { - lws_pt_lock(pt, __func__); - if (__insert_wsi_socket_into_fds(context, new_wsi)) { - lws_pt_unlock(pt); - lwsl_err("%s: fail inserting socket\n", __func__); - goto fail; - } - lws_pt_unlock(pt); - } else - if (lws_server_socket_service_ssl(new_wsi, fd.sockfd)) { - lwsl_info("%s: fail ssl negotiation\n", __func__); - goto fail; - } - - /* - * by deferring callback to this point, after insertion to fds, - * lws_callback_on_writable() can work from the callback - */ - if ((new_wsi->protocol->callback)( - new_wsi, n, new_wsi->user_space, NULL, 0)) - goto fail; - - if (type & LWS_ADOPT_HTTP) { - if (!lws_header_table_attach(new_wsi, 0)) - lwsl_debug("Attached ah immediately\n"); - else - lwsl_info("%s: waiting for ah\n", __func__); - } - - lws_cancel_service_pt(new_wsi); - - return new_wsi; - -fail: - if (type & LWS_ADOPT_SOCKET) - lws_close_free_wsi(new_wsi, LWS_CLOSE_STATUS_NOSTATUS, "adopt skt fail"); - - return NULL; - -bail: - lwsl_notice("%s: exiting on bail\n", __func__); - if (parent) - parent->child_list = new_wsi->sibling_list; - if (new_wsi->user_space) - lws_free(new_wsi->user_space); - lws_free(new_wsi); - compatible_close(fd.sockfd); - - return NULL; -} - -LWS_VISIBLE struct lws * -lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd) -{ - lws_sock_file_fd_type fd; - - fd.sockfd = accept_fd; - return lws_adopt_descriptor_vhost(vh, LWS_ADOPT_SOCKET | - LWS_ADOPT_HTTP | LWS_ADOPT_ALLOW_SSL, fd, NULL, NULL); -} - -LWS_VISIBLE struct lws * -lws_adopt_socket(struct lws_context *context, lws_sockfd_type accept_fd) -{ - return lws_adopt_socket_vhost(context->vhost_list, accept_fd); -} - -/* Common read-buffer adoption for lws_adopt_*_readbuf */ -static struct lws* -adopt_socket_readbuf(struct lws *wsi, const char *readbuf, size_t len) -{ - struct lws_context_per_thread *pt; - struct lws_pollfd *pfd; - int n; - - if (!wsi) - return NULL; - - if (!readbuf || len == 0) - return wsi; - - if (wsi->position_in_fds_table == LWS_NO_FDS_POS) - return wsi; - - pt = &wsi->context->pt[(int)wsi->tsi]; - - n = lws_buflist_append_segment(&wsi->buflist, (const uint8_t *)readbuf, len); - if (n < 0) - goto bail; - if (n) - lws_dll_lws_add_front(&wsi->dll_buflist, &pt->dll_head_buflist); - - /* - * we can't process the initial read data until we can attach an ah. - * - * if one is available, get it and place the data in his ah rxbuf... - * wsi with ah that have pending rxbuf get auto-POLLIN service. - * - * no autoservice because we didn't get a chance to attach the - * readbuf data to wsi or ah yet, and we will do it next if we get - * the ah. - */ - if (wsi->http.ah || !lws_header_table_attach(wsi, 0)) { - - lwsl_notice("%s: calling service on readbuf ah\n", __func__); - - /* unlike a normal connect, we have the headers already - * (or the first part of them anyway). - * libuv won't come back and service us without a network - * event, so we need to do the header service right here. - */ - pfd = &pt->fds[wsi->position_in_fds_table]; - pfd->revents |= LWS_POLLIN; - lwsl_err("%s: calling service\n", __func__); - if (lws_service_fd_tsi(wsi->context, pfd, wsi->tsi)) - /* service closed us */ - return NULL; - - return wsi; - } - lwsl_err("%s: deferring handling ah\n", __func__); - - return wsi; - -bail: - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "adopt skt readbuf fail"); - - return NULL; -} - -LWS_VISIBLE struct lws * -lws_adopt_socket_readbuf(struct lws_context *context, lws_sockfd_type accept_fd, - const char *readbuf, size_t len) -{ - return adopt_socket_readbuf(lws_adopt_socket(context, accept_fd), - readbuf, len); -} - -LWS_VISIBLE struct lws * -lws_adopt_socket_vhost_readbuf(struct lws_vhost *vhost, - lws_sockfd_type accept_fd, - const char *readbuf, size_t len) -{ - return adopt_socket_readbuf(lws_adopt_socket_vhost(vhost, accept_fd), - readbuf, len); -} - -LWS_VISIBLE int -lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, - const char *other_headers, int other_headers_len) -{ - static const char * const intermediates[] = { "private", "public" }; - struct lws_context *context = lws_get_context(wsi); - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; -#if defined(LWS_WITH_RANGES) - struct lws_range_parsing *rp = &wsi->http.range; -#endif - char cache_control[50], *cc = "no-store"; - unsigned char *response = pt->serv_buf + LWS_PRE; - unsigned char *p = response; - unsigned char *end = p + context->pt_serv_buf_size - LWS_PRE; - lws_filepos_t total_content_length; - int ret = 0, cclen = 8, n = HTTP_STATUS_OK; - lws_fop_flags_t fflags = LWS_O_RDONLY; -#if defined(LWS_WITH_RANGES) - int ranges; -#endif - const struct lws_plat_file_ops *fops; - const char *vpath; - - if (wsi->handling_404) - n = HTTP_STATUS_NOT_FOUND; - - /* - * We either call the platform fops .open with first arg platform fops, - * or we call fops_zip .open with first arg platform fops, and fops_zip - * open will decide whether to switch to fops_zip or stay with fops_def. - * - * If wsi->http.fop_fd is already set, the caller already opened it - */ - if (!wsi->http.fop_fd) { - fops = lws_vfs_select_fops(wsi->context->fops, file, &vpath); - fflags |= lws_vfs_prepare_flags(wsi); - wsi->http.fop_fd = fops->LWS_FOP_OPEN(wsi->context->fops, - file, vpath, &fflags); - if (!wsi->http.fop_fd) { - lwsl_info("%s: Unable to open: '%s': errno %d\n", - __func__, file, errno); - if (lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND, NULL)) - return -1; - return !wsi->http2_substream; - } - } - wsi->http.filelen = lws_vfs_get_length(wsi->http.fop_fd); - total_content_length = wsi->http.filelen; - -#if defined(LWS_WITH_RANGES) - ranges = lws_ranges_init(wsi, rp, wsi->http.filelen); - - lwsl_debug("Range count %d\n", ranges); - /* - * no ranges -> 200; - * 1 range -> 206 + Content-Type: normal; Content-Range; - * more -> 206 + Content-Type: multipart/byteranges - * Repeat the true Content-Type in each multipart header - * along with Content-Range - */ - if (ranges < 0) { - /* it means he expressed a range in Range:, but it was illegal */ - lws_return_http_status(wsi, HTTP_STATUS_REQ_RANGE_NOT_SATISFIABLE, - NULL); - if (lws_http_transaction_completed(wsi)) - return -1; /* <0 means just hang up */ - - lws_vfs_file_close(&wsi->http.fop_fd); - - return 0; /* == 0 means we dealt with the transaction complete */ - } - if (ranges) - n = HTTP_STATUS_PARTIAL_CONTENT; -#endif - - if (lws_add_http_header_status(wsi, n, &p, end)) - return -1; - - if ((wsi->http.fop_fd->flags & (LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP | - LWS_FOP_FLAG_COMPR_IS_GZIP)) == - (LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP | LWS_FOP_FLAG_COMPR_IS_GZIP)) { - if (lws_add_http_header_by_token(wsi, - WSI_TOKEN_HTTP_CONTENT_ENCODING, - (unsigned char *)"gzip", 4, &p, end)) - return -1; - lwsl_info("file is being provided in gzip\n"); - } - - if ( -#if defined(LWS_WITH_RANGES) - ranges < 2 && -#endif - content_type && content_type[0]) - if (lws_add_http_header_by_token(wsi, - WSI_TOKEN_HTTP_CONTENT_TYPE, - (unsigned char *)content_type, - (int)strlen(content_type), - &p, end)) - return -1; - -#if defined(LWS_WITH_RANGES) - if (ranges >= 2) { /* multipart byteranges */ - lws_strncpy(wsi->http.multipart_content_type, content_type, - sizeof(wsi->http.multipart_content_type)); - - if (lws_add_http_header_by_token(wsi, - WSI_TOKEN_HTTP_CONTENT_TYPE, - (unsigned char *) - "multipart/byteranges; " - "boundary=_lws", - 20, &p, end)) - return -1; - - /* - * our overall content length has to include - * - * - (n + 1) x "_lws\r\n" - * - n x Content-Type: xxx/xxx\r\n - * - n x Content-Range: bytes xxx-yyy/zzz\r\n - * - n x /r/n - * - the actual payloads (aggregated in rp->agg) - * - * Precompute it for the main response header - */ - - total_content_length = (lws_filepos_t)rp->agg + - 6 /* final _lws\r\n */; - - lws_ranges_reset(rp); - while (lws_ranges_next(rp)) { - n = lws_snprintf(cache_control, sizeof(cache_control), - "bytes %llu-%llu/%llu", - rp->start, rp->end, rp->extent); - - total_content_length += - 6 /* header _lws\r\n */ + - /* Content-Type: xxx/xxx\r\n */ - 14 + strlen(content_type) + 2 + - /* Content-Range: xxxx\r\n */ - 15 + n + 2 + - 2; /* /r/n */ - } - - lws_ranges_reset(rp); - lws_ranges_next(rp); - } - - if (ranges == 1) { - total_content_length = (lws_filepos_t)rp->agg; - n = lws_snprintf(cache_control, sizeof(cache_control), - "bytes %llu-%llu/%llu", - rp->start, rp->end, rp->extent); - - if (lws_add_http_header_by_token(wsi, - WSI_TOKEN_HTTP_CONTENT_RANGE, - (unsigned char *)cache_control, - n, &p, end)) - return -1; - } - - wsi->http.range.inside = 0; - - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_ACCEPT_RANGES, - (unsigned char *)"bytes", 5, &p, end)) - return -1; -#endif - - if (!wsi->http2_substream) { - if (!wsi->sending_chunked) { - if (lws_add_http_header_content_length(wsi, - total_content_length, - &p, end)) - return -1; - } else { - if (lws_add_http_header_by_token(wsi, - WSI_TOKEN_HTTP_TRANSFER_ENCODING, - (unsigned char *)"chunked", - 7, &p, end)) - return -1; - } - } - - if (wsi->cache_secs && wsi->cache_reuse) { - if (wsi->cache_revalidate) { - cc = cache_control; - cclen = sprintf(cache_control, "%s max-age: %u", - intermediates[wsi->cache_intermediaries], - wsi->cache_secs); - } else { - cc = "no-cache"; - cclen = 8; - } - } - - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CACHE_CONTROL, - (unsigned char *)cc, cclen, &p, end)) - return -1; - - if (wsi->http.connection_type == HTTP_CONNECTION_KEEP_ALIVE) - if (lws_add_http_header_by_token(wsi, WSI_TOKEN_CONNECTION, - (unsigned char *)"keep-alive", 10, &p, end)) - return -1; - - if (other_headers) { - if ((end - p) < other_headers_len) - return -1; - memcpy(p, other_headers, other_headers_len); - p += other_headers_len; - } - - if (lws_finalize_http_header(wsi, &p, end)) - return -1; - - ret = lws_write(wsi, response, p - response, LWS_WRITE_HTTP_HEADERS); - if (ret != (p - response)) { - lwsl_err("_write returned %d from %ld\n", ret, - (long)(p - response)); - return -1; - } - - wsi->http.filepos = 0; - lwsi_set_state(wsi, LRS_ISSUING_FILE); - - lws_callback_on_writable(wsi); - - return 0; -} - -LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) -{ - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - struct lws_process_html_args args; - lws_filepos_t amount, poss; - unsigned char *p, *pstart; -#if defined(LWS_WITH_RANGES) - unsigned char finished = 0; -#endif - int n, m; - - lwsl_debug("wsi->http2_substream %d\n", wsi->http2_substream); - - do { - - if (wsi->trunc_len) { - if (lws_issue_raw(wsi, wsi->trunc_alloc + - wsi->trunc_offset, - wsi->trunc_len) < 0) { - lwsl_info("%s: closing\n", __func__); - goto file_had_it; - } - break; - } - - if (wsi->http.filepos == wsi->http.filelen) - goto all_sent; - - n = 0; - - pstart = pt->serv_buf + LWS_H2_FRAME_HEADER_LENGTH; - - p = pstart; - -#if defined(LWS_WITH_RANGES) - if (wsi->http.range.count_ranges && !wsi->http.range.inside) { - - lwsl_notice("%s: doing range start %llu\n", __func__, - wsi->http.range.start); - - if ((long long)lws_vfs_file_seek_cur(wsi->http.fop_fd, - wsi->http.range.start - - wsi->http.filepos) < 0) - goto file_had_it; - - wsi->http.filepos = wsi->http.range.start; - - if (wsi->http.range.count_ranges > 1) { - n = lws_snprintf((char *)p, - context->pt_serv_buf_size - - LWS_H2_FRAME_HEADER_LENGTH, - "_lws\x0d\x0a" - "Content-Type: %s\x0d\x0a" - "Content-Range: bytes %llu-%llu/%llu\x0d\x0a" - "\x0d\x0a", - wsi->http.multipart_content_type, - wsi->http.range.start, - wsi->http.range.end, - wsi->http.range.extent); - p += n; - } - - wsi->http.range.budget = wsi->http.range.end - - wsi->http.range.start + 1; - wsi->http.range.inside = 1; - } -#endif - - poss = context->pt_serv_buf_size - n - LWS_H2_FRAME_HEADER_LENGTH; - - if (wsi->http.tx_content_length) - if (poss > wsi->http.tx_content_remain) - poss = wsi->http.tx_content_remain; - - /* - * if there is a hint about how much we will do well to send at - * one time, restrict ourselves to only trying to send that. - */ - if (wsi->protocol->tx_packet_size && - poss > wsi->protocol->tx_packet_size) - poss = wsi->protocol->tx_packet_size; - - if (wsi->role_ops->tx_credit) { - lws_filepos_t txc = wsi->role_ops->tx_credit(wsi); - - if (!txc) { - lwsl_info("%s: came here with no tx credit\n", - __func__); - return 0; - } - if (txc < poss) - poss = txc; - - /* - * consumption of the actual payload amount sent will be - * handled when the role data frame is sent - */ - } - -#if defined(LWS_WITH_RANGES) - if (wsi->http.range.count_ranges) { - if (wsi->http.range.count_ranges > 1) - poss -= 7; /* allow for final boundary */ - if (poss > wsi->http.range.budget) - poss = wsi->http.range.budget; - } -#endif - if (wsi->sending_chunked) { - /* we need to drop the chunk size in here */ - p += 10; - /* allow for the chunk to grow by 128 in translation */ - poss -= 10 + 128; - } - - if (lws_vfs_file_read(wsi->http.fop_fd, &amount, p, poss) < 0) - goto file_had_it; /* caller will close */ - - if (wsi->sending_chunked) - n = (int)amount; - else - n = lws_ptr_diff(p, pstart) + (int)amount; - - lwsl_debug("%s: sending %d\n", __func__, n); - - if (n) { - lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, - context->timeout_secs); - - if (wsi->interpreting) { - args.p = (char *)p; - args.len = n; - args.max_len = (unsigned int)poss + 128; - args.final = wsi->http.filepos + n == - wsi->http.filelen; - args.chunked = wsi->sending_chunked; - if (user_callback_handle_rxflow( - wsi->vhost->protocols[ - (int)wsi->protocol_interpret_idx].callback, - wsi, LWS_CALLBACK_PROCESS_HTML, - wsi->user_space, &args, 0) < 0) - goto file_had_it; - n = args.len; - p = (unsigned char *)args.p; - } else - p = pstart; - -#if defined(LWS_WITH_RANGES) - if (wsi->http.range.send_ctr + 1 == - wsi->http.range.count_ranges && // last range - wsi->http.range.count_ranges > 1 && // was 2+ ranges (ie, multipart) - wsi->http.range.budget - amount == 0) {// final part - n += lws_snprintf((char *)pstart + n, 6, - "_lws\x0d\x0a"); // append trailing boundary - lwsl_debug("added trailing boundary\n"); - } -#endif - m = lws_write(wsi, p, n, - wsi->http.filepos + amount == wsi->http.filelen ? - LWS_WRITE_HTTP_FINAL : - LWS_WRITE_HTTP - ); - if (m < 0) - goto file_had_it; - - wsi->http.filepos += amount; - -#if defined(LWS_WITH_RANGES) - if (wsi->http.range.count_ranges >= 1) { - wsi->http.range.budget -= amount; - if (wsi->http.range.budget == 0) { - lwsl_notice("range budget exhausted\n"); - wsi->http.range.inside = 0; - wsi->http.range.send_ctr++; - - if (lws_ranges_next(&wsi->http.range) < 1) { - finished = 1; - goto all_sent; - } - } - } -#endif - - if (m != n) { - /* adjust for what was not sent */ - if (lws_vfs_file_seek_cur(wsi->http.fop_fd, - m - n) == - (lws_fileofs_t)-1) - goto file_had_it; - } - } - -all_sent: - if ((!wsi->trunc_len && wsi->http.filepos >= wsi->http.filelen) -#if defined(LWS_WITH_RANGES) - || finished) -#else - ) -#endif - { - lwsi_set_state(wsi, LRS_ESTABLISHED); - /* we might be in keepalive, so close it off here */ - lws_vfs_file_close(&wsi->http.fop_fd); - - lwsl_debug("file completed\n"); - - if (wsi->protocol->callback && - user_callback_handle_rxflow(wsi->protocol->callback, - wsi, LWS_CALLBACK_HTTP_FILE_COMPLETION, - wsi->user_space, NULL, - 0) < 0) { - /* - * For http/1.x, the choices from - * transaction_completed are either - * 0 to use the connection for pipelined - * or nonzero to hang it up. - * - * However for http/2. while we are - * still interested in hanging up the - * nwsi if there was a network-level - * fatal error, simply completing the - * transaction is a matter of the stream - * state, not the root connection at the - * network level - */ - if (wsi->http2_substream) - return 1; - else - return -1; - } - - return 1; /* >0 indicates completed */ - } - } while (0); // while (!lws_send_pipe_choked(wsi)) - - lws_callback_on_writable(wsi); - - return 0; /* indicates further processing must be done */ - -file_had_it: - lws_vfs_file_close(&wsi->http.fop_fd); - - return -1; -} - - -LWS_VISIBLE void -lws_server_get_canonical_hostname(struct lws_context *context, - const struct lws_context_creation_info *info) -{ - if (lws_check_opt(info->options, - LWS_SERVER_OPTION_SKIP_SERVER_CANONICAL_NAME)) - return; -#if !defined(LWS_WITH_ESP32) - /* find canonical hostname */ - gethostname((char *)context->canonical_hostname, - sizeof(context->canonical_hostname) - 1); - - lwsl_info(" canonical_hostname = %s\n", context->canonical_hostname); -#else - (void)context; -#endif -} - - -LWS_VISIBLE LWS_EXTERN int -lws_chunked_html_process(struct lws_process_html_args *args, - struct lws_process_html_state *s) -{ - char *sp, buffer[32]; - const char *pc; - int old_len, n; - - /* do replacements */ - sp = args->p; - old_len = args->len; - args->len = 0; - s->start = sp; - while (sp < args->p + old_len) { - - if (args->len + 7 >= args->max_len) { - lwsl_err("Used up interpret padding\n"); - return -1; - } - - if ((!s->pos && *sp == '$') || s->pos) { - int hits = 0, hit = 0; - - if (!s->pos) - s->start = sp; - s->swallow[s->pos++] = *sp; - if (s->pos == sizeof(s->swallow) - 1) - goto skip; - for (n = 0; n < s->count_vars; n++) - if (!strncmp(s->swallow, s->vars[n], s->pos)) { - hits++; - hit = n; - } - if (!hits) { -skip: - s->swallow[s->pos] = '\0'; - memcpy(s->start, s->swallow, s->pos); - args->len++; - s->pos = 0; - sp = s->start + 1; - continue; - } - if (hits == 1 && s->pos == (int)strlen(s->vars[hit])) { - pc = s->replace(s->data, hit); - if (!pc) - pc = "NULL"; - n = (int)strlen(pc); - s->swallow[s->pos] = '\0'; - if (n != s->pos) { - memmove(s->start + n, - s->start + s->pos, - old_len - (sp - args->p)); - old_len += (n - s->pos) + 1; - } - memcpy(s->start, pc, n); - args->len++; - sp = s->start + 1; - - s->pos = 0; - } - sp++; - continue; - } - - args->len++; - sp++; - } - - if (args->chunked) { - /* no space left for final chunk trailer */ - if (args->final && args->len + 7 >= args->max_len) - return -1; - - n = sprintf(buffer, "%X\x0d\x0a", args->len); - - args->p -= n; - memcpy(args->p, buffer, n); - args->len += n; - - if (args->final) { - sp = args->p + args->len; - *sp++ = '\x0d'; - *sp++ = '\x0a'; - *sp++ = '0'; - *sp++ = '\x0d'; - *sp++ = '\x0a'; - *sp++ = '\x0d'; - *sp++ = '\x0a'; - args->len += 7; - } else { - sp = args->p + args->len; - *sp++ = '\x0d'; - *sp++ = '\x0a'; - args->len += 2; - } - } - - return 0; -} diff --git a/thirdparty/libwebsockets/roles/listen/ops-listen.c b/thirdparty/libwebsockets/roles/listen/ops-listen.c deleted file mode 100644 index dbeb9753a2..0000000000 --- a/thirdparty/libwebsockets/roles/listen/ops-listen.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include <core/private.h> - -static int -rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi, - struct lws_pollfd *pollfd) -{ - struct lws_context *context = wsi->context; - lws_sockfd_type accept_fd = LWS_SOCK_INVALID; - lws_sock_file_fd_type fd; - int opts = LWS_ADOPT_SOCKET | LWS_ADOPT_ALLOW_SSL; - struct sockaddr_storage cli_addr; - socklen_t clilen; - - /* pollin means a client has connected to us then - * - * pollout is a hack on esp32 for background accepts signalling - * they completed - */ - - do { - struct lws *cwsi; - - if (!(pollfd->revents & (LWS_POLLIN | LWS_POLLOUT)) || - !(pollfd->events & LWS_POLLIN)) - break; - -#if defined(LWS_WITH_TLS) - /* - * can we really accept it, with regards to SSL limit? - * another vhost may also have had POLLIN on his - * listener this round and used it up already - */ - if (wsi->vhost->tls.use_ssl && - context->simultaneous_ssl_restriction && - context->simultaneous_ssl == - context->simultaneous_ssl_restriction) - /* - * no... ignore it, he won't come again until - * we are below the simultaneous_ssl_restriction - * limit and POLLIN is enabled on him again - */ - break; -#endif - /* listen socket got an unencrypted connection... */ - - clilen = sizeof(cli_addr); - lws_latency_pre(context, wsi); - - /* - * We cannot identify the peer who is in the listen - * socket connect queue before we accept it; even if - * we could, not accepting it due to PEER_LIMITS would - * block the connect queue for other legit peers. - */ - - accept_fd = accept((int)pollfd->fd, - (struct sockaddr *)&cli_addr, &clilen); - lws_latency(context, wsi, "listener accept", - (int)accept_fd, accept_fd != LWS_SOCK_INVALID); - if (accept_fd == LWS_SOCK_INVALID) { - if (LWS_ERRNO == LWS_EAGAIN || - LWS_ERRNO == LWS_EWOULDBLOCK) { - break; - } - lwsl_err("ERROR on accept: %s\n", - strerror(LWS_ERRNO)); - break; - } - - lws_plat_set_socket_options(wsi->vhost, accept_fd); - -#if defined(LWS_WITH_IPV6) - lwsl_debug("accepted new conn port %u on fd=%d\n", - ((cli_addr.ss_family == AF_INET6) ? - ntohs(((struct sockaddr_in6 *) &cli_addr)->sin6_port) : - ntohs(((struct sockaddr_in *) &cli_addr)->sin_port)), - accept_fd); -#else - lwsl_debug("accepted new conn port %u on fd=%d\n", - ntohs(((struct sockaddr_in *) &cli_addr)->sin_port), - accept_fd); -#endif - - /* - * look at who we connected to and give user code a - * chance to reject based on client IP. There's no - * protocol selected yet so we issue this to - * protocols[0] - */ - if ((wsi->vhost->protocols[0].callback)(wsi, - LWS_CALLBACK_FILTER_NETWORK_CONNECTION, - NULL, - (void *)(lws_intptr_t)accept_fd, 0)) { - lwsl_debug("Callback denied net connection\n"); - compatible_close(accept_fd); - break; - } - - if (!(wsi->vhost->options & LWS_SERVER_OPTION_ONLY_RAW)) - opts |= LWS_ADOPT_HTTP; - else - opts = LWS_ADOPT_SOCKET; - - fd.sockfd = accept_fd; - cwsi = lws_adopt_descriptor_vhost(wsi->vhost, opts, fd, - NULL, NULL); - if (!cwsi) - /* already closed cleanly as necessary */ - return LWS_HPI_RET_WSI_ALREADY_DIED; - - if (lws_server_socket_service_ssl(cwsi, accept_fd)) { - lws_close_free_wsi(cwsi, LWS_CLOSE_STATUS_NOSTATUS, - "listen svc fail"); - return LWS_HPI_RET_WSI_ALREADY_DIED; - } - - lwsl_info("%s: new wsi %p: wsistate 0x%x, role_ops %s\n", - __func__, cwsi, cwsi->wsistate, cwsi->role_ops->name); - - } while (pt->fds_count < context->fd_limit_per_thread - 1 && - wsi->position_in_fds_table != LWS_NO_FDS_POS && - lws_poll_listen_fd(&pt->fds[wsi->position_in_fds_table]) > 0); - - return LWS_HPI_RET_HANDLED; -} - -int rops_handle_POLLOUT_listen(struct lws *wsi) -{ - return LWS_HP_RET_USER_SERVICE; -} - -struct lws_role_ops role_ops_listen = { - /* role name */ "listen", - /* alpn id */ NULL, - /* check_upgrades */ NULL, - /* init_context */ NULL, - /* init_vhost */ NULL, - /* destroy_vhost */ NULL, - /* periodic_checks */ NULL, - /* service_flag_pending */ NULL, - /* handle_POLLIN */ rops_handle_POLLIN_listen, - /* handle_POLLOUT */ rops_handle_POLLOUT_listen, - /* perform_user_POLLOUT */ NULL, - /* callback_on_writable */ NULL, - /* tx_credit */ NULL, - /* write_role_protocol */ NULL, - /* encapsulation_parent */ NULL, - /* alpn_negotiated */ NULL, - /* close_via_role_protocol */ NULL, - /* close_role */ NULL, - /* close_kill_connection */ NULL, - /* destroy_role */ NULL, - /* writeable cb clnt, srv */ { 0, 0 }, - /* close cb clnt, srv */ { 0, 0 }, - /* file_handle */ 0, -}; diff --git a/thirdparty/libwebsockets/roles/pipe/ops-pipe.c b/thirdparty/libwebsockets/roles/pipe/ops-pipe.c deleted file mode 100644 index b9348d58d7..0000000000 --- a/thirdparty/libwebsockets/roles/pipe/ops-pipe.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include <core/private.h> - -static int -rops_handle_POLLIN_pipe(struct lws_context_per_thread *pt, struct lws *wsi, - struct lws_pollfd *pollfd) -{ -#if !defined(WIN32) && !defined(_WIN32) - char s[100]; - int n; - - /* - * discard the byte(s) that signaled us - * We really don't care about the number of bytes, but coverity - * thinks we should. - */ - n = read(wsi->desc.sockfd, s, sizeof(s)); - (void)n; - if (n < 0) - return LWS_HPI_RET_PLEASE_CLOSE_ME; -#endif - /* - * the poll() wait, or the event loop for libuv etc is a - * process-wide resource that we interrupted. So let every - * protocol that may be interested in the pipe event know that - * it happened. - */ - if (lws_broadcast(wsi->context, LWS_CALLBACK_EVENT_WAIT_CANCELLED, - NULL, 0)) { - lwsl_info("closed in event cancel\n"); - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } - - return LWS_HPI_RET_HANDLED; -} - -struct lws_role_ops role_ops_pipe = { - /* role name */ "pipe", - /* alpn id */ NULL, - /* check_upgrades */ NULL, - /* init_context */ NULL, - /* init_vhost */ NULL, - /* destroy_vhost */ NULL, - /* periodic_checks */ NULL, - /* service_flag_pending */ NULL, - /* handle_POLLIN */ rops_handle_POLLIN_pipe, - /* handle_POLLOUT */ NULL, - /* perform_user_POLLOUT */ NULL, - /* callback_on_writable */ NULL, - /* tx_credit */ NULL, - /* write_role_protocol */ NULL, - /* encapsulation_parent */ NULL, - /* alpn_negotiated */ NULL, - /* close_via_role_protocol */ NULL, - /* close_role */ NULL, - /* close_kill_connection */ NULL, - /* destroy_role */ NULL, - /* writeable cb clnt, srv */ { 0, 0 }, - /* close cb clnt, srv */ { 0, 0 }, - /* file_handle */ 1, -}; diff --git a/thirdparty/libwebsockets/roles/private.h b/thirdparty/libwebsockets/roles/private.h deleted file mode 100644 index ae4278b5d3..0000000000 --- a/thirdparty/libwebsockets/roles/private.h +++ /dev/null @@ -1,282 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * This is included from core/private.h - */ - -typedef uint32_t lws_wsi_state_t; - -/* - * The wsi->role_ops pointer decides almost everything about what role the wsi - * will play, h2, raw, ws, etc. - * - * However there are a few additional flags needed that vary, such as if the - * role is a client or server side, if it has that concept. And the connection - * fulfilling the role, has a separate dynamic state. - * - * 31 16 15 0 - * [ role flags ] [ state ] - * - * The role flags part is generally invariant for the lifetime of the wsi, - * although it can change if the connection role itself does, eg, if the - * connection upgrades from H1 -> WS1 the role flags may be changed at that - * point. - * - * The state part reflects the dynamic connection state, and the states are - * reused between roles. - * - * None of the internal role or state representations are made available outside - * of lws internals. Even for lws internals, if you add stuff here, please keep - * the constants inside this header only by adding necessary helpers here and - * use the helpers in the actual code. This is to ease any future refactors. - * - * Notice LWSIFR_ENCAP means we have a parent wsi that actually carries our - * data as a stream inside a different protocol. - */ - -#define _RS 16 - -#define LWSIFR_CLIENT (0x1000 << _RS) /* client side */ -#define LWSIFR_SERVER (0x2000 << _RS) /* server side */ - -#define LWSIFR_P_ENCAP_H2 (0x0100 << _RS) /* we are encapsulated by h2 */ - -enum lwsi_role { - LWSI_ROLE_MASK = (0xffff << _RS), - LWSI_ROLE_ENCAP_MASK = (0x0f00 << _RS), -}; - -#define lwsi_role(wsi) (wsi->wsistate & LWSI_ROLE_MASK) -#if !defined (_DEBUG) -#define lwsi_set_role(wsi, role) wsi->wsistate = \ - (wsi->wsistate & (~LWSI_ROLE_MASK)) | role -#else -void lwsi_set_role(struct lws *wsi, lws_wsi_state_t role); -#endif - -#define lwsi_role_client(wsi) (!!(wsi->wsistate & LWSIFR_CLIENT)) -#define lwsi_role_server(wsi) (!!(wsi->wsistate & LWSIFR_SERVER)) -#define lwsi_role_h2_ENCAPSULATION(wsi) \ - ((wsi->wsistate & LWSI_ROLE_ENCAP_MASK) == LWSIFR_P_ENCAP_H2) - -/* Pollout wants a callback in this state */ -#define LWSIFS_POCB (0x100) -/* Before any protocol connection was established */ -#define LWSIFS_NOT_EST (0x200) - -enum lwsi_state { - - /* Phase 1: pre-transport */ - - LRS_UNCONNECTED = LWSIFS_NOT_EST | 0, - LRS_WAITING_CONNECT = LWSIFS_NOT_EST | 1, - - /* Phase 2: establishing intermediaries on top of transport */ - - LRS_WAITING_PROXY_REPLY = LWSIFS_NOT_EST | 2, - LRS_WAITING_SSL = LWSIFS_NOT_EST | 3, - LRS_WAITING_SOCKS_GREETING_REPLY = LWSIFS_NOT_EST | 4, - LRS_WAITING_SOCKS_CONNECT_REPLY = LWSIFS_NOT_EST | 5, - LRS_WAITING_SOCKS_AUTH_REPLY = LWSIFS_NOT_EST | 6, - - /* Phase 3: establishing tls tunnel */ - - LRS_SSL_INIT = LWSIFS_NOT_EST | 7, - LRS_SSL_ACK_PENDING = LWSIFS_NOT_EST | 8, - LRS_PRE_WS_SERVING_ACCEPT = LWSIFS_NOT_EST | 9, - - /* Phase 4: connected */ - - LRS_WAITING_SERVER_REPLY = LWSIFS_NOT_EST | 10, - LRS_H2_AWAIT_PREFACE = LWSIFS_NOT_EST | 11, - LRS_H2_AWAIT_SETTINGS = LWSIFS_NOT_EST | - LWSIFS_POCB | 12, - - /* Phase 5: protocol logically established */ - - LRS_H2_CLIENT_SEND_SETTINGS = LWSIFS_POCB | 13, - LRS_H2_WAITING_TO_SEND_HEADERS = LWSIFS_POCB | 14, - LRS_DEFERRING_ACTION = LWSIFS_POCB | 15, - LRS_IDLING = 16, - LRS_H1C_ISSUE_HANDSHAKE = 17, - LRS_H1C_ISSUE_HANDSHAKE2 = 18, - LRS_ISSUE_HTTP_BODY = 19, - LRS_ISSUING_FILE = 20, - LRS_HEADERS = 21, - LRS_BODY = 22, - LRS_ESTABLISHED = LWSIFS_POCB | 23, - /* we are established, but we have embarked on serving a single - * transaction. Other transaction input may be pending, but we will - * not service it while we are busy dealing with the current - * transaction. - * - * When we complete the current transaction, we would reset our state - * back to ESTABLISHED and start to process the next transaction. - */ - LRS_DOING_TRANSACTION = LWSIFS_POCB | 24, - - /* Phase 6: finishing */ - - LRS_WAITING_TO_SEND_CLOSE = LWSIFS_POCB | 25, - LRS_RETURNED_CLOSE = LWSIFS_POCB | 26, - LRS_AWAITING_CLOSE_ACK = LWSIFS_POCB | 27, - LRS_FLUSHING_BEFORE_CLOSE = LWSIFS_POCB | 28, - LRS_SHUTDOWN = 29, - - /* Phase 7: dead */ - - LRS_DEAD_SOCKET = 30, - - LRS_MASK = 0xffff -}; - -#define lwsi_state(wsi) ((enum lwsi_state)(wsi->wsistate & LRS_MASK)) -#define lwsi_state_PRE_CLOSE(wsi) ((enum lwsi_state)(wsi->wsistate_pre_close & LRS_MASK)) -#define lwsi_state_est(wsi) (!(wsi->wsistate & LWSIFS_NOT_EST)) -#define lwsi_state_est_PRE_CLOSE(wsi) (!(wsi->wsistate_pre_close & LWSIFS_NOT_EST)) -#define lwsi_state_can_handle_POLLOUT(wsi) (wsi->wsistate & LWSIFS_POCB) -#if !defined (_DEBUG) -#define lwsi_set_state(wsi, lrs) wsi->wsistate = \ - (wsi->wsistate & (~LRS_MASK)) | lrs -#else -void lwsi_set_state(struct lws *wsi, lws_wsi_state_t lrs); -#endif - -/* - * internal role-specific ops - */ -struct lws_context_per_thread; -struct lws_role_ops { - const char *name; - const char *alpn; - /* - * After http headers have parsed, this is the last chance for a role - * to upgrade the connection to something else using the headers. - * ws-over-h2 is upgraded from h2 like this. - */ - int (*check_upgrades)(struct lws *wsi); - /* role-specific context init during context creation */ - int (*init_context)(struct lws_context *context, - const struct lws_context_creation_info *info); - /* role-specific per-vhost init during vhost creation */ - int (*init_vhost)(struct lws_vhost *vh, - const struct lws_context_creation_info *info); - /* role-specific per-vhost destructor during vhost destroy */ - int (*destroy_vhost)(struct lws_vhost *vh); - /* generic 1Hz callback for the role itself */ - int (*periodic_checks)(struct lws_context *context, int tsi, - time_t now); - /* chance for the role to force POLLIN without network activity */ - int (*service_flag_pending)(struct lws_context *context, int tsi); - /* an fd using this role has POLLIN signalled */ - int (*handle_POLLIN)(struct lws_context_per_thread *pt, struct lws *wsi, - struct lws_pollfd *pollfd); - /* an fd using the role wanted a POLLOUT callback and now has it */ - int (*handle_POLLOUT)(struct lws *wsi); - /* perform user pollout */ - int (*perform_user_POLLOUT)(struct lws *wsi); - /* do effective callback on writeable */ - int (*callback_on_writable)(struct lws *wsi); - /* connection-specific tx credit in bytes */ - lws_fileofs_t (*tx_credit)(struct lws *wsi); - /* role-specific write formatting */ - int (*write_role_protocol)(struct lws *wsi, unsigned char *buf, - size_t len, enum lws_write_protocol *wp); - - /* get encapsulation parent */ - struct lws * (*encapsulation_parent)(struct lws *wsi); - - /* role-specific destructor */ - int (*alpn_negotiated)(struct lws *wsi, const char *alpn); - - /* chance for the role to handle close in the protocol */ - int (*close_via_role_protocol)(struct lws *wsi, - enum lws_close_status reason); - /* role-specific close processing */ - int (*close_role)(struct lws_context_per_thread *pt, struct lws *wsi); - /* role-specific connection close processing */ - int (*close_kill_connection)(struct lws *wsi, - enum lws_close_status reason); - /* role-specific destructor */ - int (*destroy_role)(struct lws *wsi); - - /* - * the callback reasons for WRITEABLE for client, server - * (just client applies if no concept of client or server) - */ - uint16_t writeable_cb[2]; - /* - * the callback reasons for CLOSE for client, server - * (just client applies if no concept of client or server) - */ - uint16_t close_cb[2]; - - unsigned int file_handle:1; /* role operates on files not sockets */ -}; - -/* core roles */ -extern struct lws_role_ops role_ops_raw_skt, role_ops_raw_file, role_ops_listen, - role_ops_pipe; - -/* bring in role private declarations */ - -#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) - #include "roles/http/private.h" -#else - #define lwsi_role_http(wsi) (0) -#endif - -#if defined(LWS_ROLE_H1) - #include "roles/h1/private.h" -#else - #define lwsi_role_h1(wsi) (0) -#endif - -#if defined(LWS_ROLE_H2) - #include "roles/h2/private.h" -#else - #define lwsi_role_h2(wsi) (0) -#endif - -#if defined(LWS_ROLE_WS) - #include "roles/ws/private.h" -#else - #define lwsi_role_ws(wsi) (0) -#endif - -#if defined(LWS_ROLE_CGI) - #include "roles/cgi/private.h" -#else - #define lwsi_role_cgi(wsi) (0) -#endif - -enum { - LWS_HP_RET_BAIL_OK, - LWS_HP_RET_BAIL_DIE, - LWS_HP_RET_USER_SERVICE, - - LWS_HPI_RET_WSI_ALREADY_DIED, /* we closed it */ - LWS_HPI_RET_HANDLED, /* no probs */ - LWS_HPI_RET_PLEASE_CLOSE_ME, /* close it for us */ - - LWS_UPG_RET_DONE, - LWS_UPG_RET_CONTINUE, - LWS_UPG_RET_BAIL -}; diff --git a/thirdparty/libwebsockets/roles/raw/ops-raw.c b/thirdparty/libwebsockets/roles/raw/ops-raw.c deleted file mode 100644 index 68b52bded6..0000000000 --- a/thirdparty/libwebsockets/roles/raw/ops-raw.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include <core/private.h> - -static int -rops_handle_POLLIN_raw_skt(struct lws_context_per_thread *pt, struct lws *wsi, - struct lws_pollfd *pollfd) -{ - struct lws_tokens ebuf; - int n, buffered; - - /* pending truncated sends have uber priority */ - - if (wsi->trunc_len) { - if (!(pollfd->revents & LWS_POLLOUT)) - return LWS_HPI_RET_HANDLED; - - if (lws_issue_raw(wsi, wsi->trunc_alloc + wsi->trunc_offset, - wsi->trunc_len) < 0) - goto fail; - /* - * we can't afford to allow input processing to send - * something new, so spin around he event loop until - * he doesn't have any partials - */ - return LWS_HPI_RET_HANDLED; - } - - if ((pollfd->revents & pollfd->events & LWS_POLLIN) && - /* any tunnel has to have been established... */ - lwsi_state(wsi) != LRS_SSL_ACK_PENDING && - !(wsi->favoured_pollin && - (pollfd->revents & pollfd->events & LWS_POLLOUT))) { - - buffered = lws_buflist_aware_read(pt, wsi, &ebuf); - switch (ebuf.len) { - case 0: - lwsl_info("%s: read 0 len\n", __func__); - wsi->seen_zero_length_recv = 1; - lws_change_pollfd(wsi, LWS_POLLIN, 0); - - /* - * we need to go to fail here, since it's the only - * chance we get to understand that the socket has - * closed - */ - // goto try_pollout; - goto fail; - - case LWS_SSL_CAPABLE_ERROR: - goto fail; - case LWS_SSL_CAPABLE_MORE_SERVICE: - goto try_pollout; - } - - n = user_callback_handle_rxflow(wsi->protocol->callback, - wsi, LWS_CALLBACK_RAW_RX, - wsi->user_space, ebuf.token, - ebuf.len); - if (n < 0) { - lwsl_info("LWS_CALLBACK_RAW_RX_fail\n"); - goto fail; - } - - if (lws_buflist_aware_consume(wsi, &ebuf, ebuf.len, buffered)) - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } else - if (wsi->favoured_pollin && - (pollfd->revents & pollfd->events & LWS_POLLOUT)) - /* we balanced the last favouring of pollin */ - wsi->favoured_pollin = 0; - -try_pollout: - - /* this handles POLLOUT for http serving fragments */ - - if (!(pollfd->revents & LWS_POLLOUT)) - return LWS_HPI_RET_HANDLED; - - /* one shot */ - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) { - lwsl_notice("%s a\n", __func__); - goto fail; - } - - /* clear back-to-back write detection */ - wsi->could_have_pending = 0; - - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_C_WRITEABLE_CB, 1); -#if defined(LWS_WITH_STATS) - if (wsi->active_writable_req_us) { - uint64_t ul = time_in_microseconds() - - wsi->active_writable_req_us; - - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_MS_WRITABLE_DELAY, ul); - lws_stats_atomic_max(wsi->context, pt, - LWSSTATS_MS_WORST_WRITABLE_DELAY, ul); - wsi->active_writable_req_us = 0; - } -#endif - n = user_callback_handle_rxflow(wsi->protocol->callback, - wsi, LWS_CALLBACK_RAW_WRITEABLE, - wsi->user_space, NULL, 0); - if (n < 0) { - lwsl_info("writeable_fail\n"); - goto fail; - } - - return LWS_HPI_RET_HANDLED; - -fail: - lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "raw svc fail"); - - return LWS_HPI_RET_WSI_ALREADY_DIED; -} - - -static int -rops_handle_POLLIN_raw_file(struct lws_context_per_thread *pt, struct lws *wsi, - struct lws_pollfd *pollfd) -{ - int n; - - if (pollfd->revents & LWS_POLLOUT) { - n = lws_callback_as_writeable(wsi); - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) { - lwsl_info("failed at set pollfd\n"); - return LWS_HPI_RET_WSI_ALREADY_DIED; - } - if (n) - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } - - if (pollfd->revents & LWS_POLLIN) { - if (user_callback_handle_rxflow(wsi->protocol->callback, - wsi, LWS_CALLBACK_RAW_RX_FILE, - wsi->user_space, NULL, 0)) { - lwsl_debug("raw rx callback closed it\n"); - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } - } - - if (pollfd->revents & LWS_POLLHUP) - return LWS_HPI_RET_PLEASE_CLOSE_ME; - - return LWS_HPI_RET_HANDLED; -} - - -struct lws_role_ops role_ops_raw_skt = { - /* role name */ "raw-skt", - /* alpn id */ NULL, - /* check_upgrades */ NULL, - /* init_context */ NULL, - /* init_vhost */ NULL, - /* destroy_vhost */ NULL, - /* periodic_checks */ NULL, - /* service_flag_pending */ NULL, - /* handle_POLLIN */ rops_handle_POLLIN_raw_skt, - /* handle_POLLOUT */ NULL, - /* perform_user_POLLOUT */ NULL, - /* callback_on_writable */ NULL, - /* tx_credit */ NULL, - /* write_role_protocol */ NULL, - /* encapsulation_parent */ NULL, - /* alpn_negotiated */ NULL, - /* close_via_role_protocol */ NULL, - /* close_role */ NULL, - /* close_kill_connection */ NULL, - /* destroy_role */ NULL, - /* writeable cb clnt, srv */ { LWS_CALLBACK_RAW_WRITEABLE, 0 }, - /* close cb clnt, srv */ { LWS_CALLBACK_RAW_CLOSE, 0 }, - /* file_handle */ 0, -}; - - - -struct lws_role_ops role_ops_raw_file = { - /* role name */ "raw-file", - /* alpn id */ NULL, - /* check_upgrades */ NULL, - /* init_context */ NULL, - /* init_vhost */ NULL, - /* destroy_vhost */ NULL, - /* periodic_checks */ NULL, - /* service_flag_pending */ NULL, - /* handle_POLLIN */ rops_handle_POLLIN_raw_file, - /* handle_POLLOUT */ NULL, - /* perform_user_POLLOUT */ NULL, - /* callback_on_writable */ NULL, - /* tx_credit */ NULL, - /* write_role_protocol */ NULL, - /* encapsulation_parent */ NULL, - /* alpn_negotiated */ NULL, - /* close_via_role_protocol */ NULL, - /* close_role */ NULL, - /* close_kill_connection */ NULL, - /* destroy_role */ NULL, - /* writeable cb clnt, srv */ { LWS_CALLBACK_RAW_WRITEABLE_FILE, 0 }, - /* close cb clnt, srv */ { LWS_CALLBACK_RAW_CLOSE_FILE, 0 }, - /* file_handle */ 1, -}; diff --git a/thirdparty/libwebsockets/roles/ws/client-parser-ws.c b/thirdparty/libwebsockets/roles/ws/client-parser-ws.c deleted file mode 100644 index 7287fb1590..0000000000 --- a/thirdparty/libwebsockets/roles/ws/client-parser-ws.c +++ /dev/null @@ -1,605 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -/* - * parsers.c: lws_ws_rx_sm() needs to be roughly kept in - * sync with changes here, esp related to ext draining - */ - -int lws_ws_client_rx_sm(struct lws *wsi, unsigned char c) -{ - int callback_action = LWS_CALLBACK_CLIENT_RECEIVE; - int handled, m; - unsigned short close_code; - struct lws_tokens ebuf; - unsigned char *pp; -#if !defined(LWS_WITHOUT_EXTENSIONS) - int rx_draining_ext = 0, n; -#endif - - ebuf.token = NULL; - ebuf.len = 0; - -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (wsi->ws->rx_draining_ext) { - assert(!c); - - lws_remove_wsi_from_draining_ext_list(wsi); - rx_draining_ext = 1; - lwsl_debug("%s: doing draining flow\n", __func__); - - goto drain_extension; - } -#endif - - if (wsi->socket_is_permanently_unusable) - return -1; - - switch (wsi->lws_rx_parse_state) { - case LWS_RXPS_NEW: - /* control frames (PING) may interrupt checkable sequences */ - wsi->ws->defeat_check_utf8 = 0; - - switch (wsi->ws->ietf_spec_revision) { - case 13: - wsi->ws->opcode = c & 0xf; - /* revisit if an extension wants them... */ - switch (wsi->ws->opcode) { - case LWSWSOPC_TEXT_FRAME: - wsi->ws->rsv_first_msg = (c & 0x70); - wsi->ws->continuation_possible = 1; - wsi->ws->check_utf8 = lws_check_opt( - wsi->context->options, - LWS_SERVER_OPTION_VALIDATE_UTF8); - wsi->ws->utf8 = 0; - wsi->ws->first_fragment = 1; - break; - case LWSWSOPC_BINARY_FRAME: - wsi->ws->rsv_first_msg = (c & 0x70); - wsi->ws->check_utf8 = 0; - wsi->ws->continuation_possible = 1; - wsi->ws->first_fragment = 1; - break; - case LWSWSOPC_CONTINUATION: - if (!wsi->ws->continuation_possible) { - lwsl_info("disordered continuation\n"); - return -1; - } - wsi->ws->first_fragment = 0; - break; - case LWSWSOPC_CLOSE: - wsi->ws->check_utf8 = 0; - wsi->ws->utf8 = 0; - break; - case 3: - case 4: - case 5: - case 6: - case 7: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - lwsl_info("illegal opcode\n"); - return -1; - default: - wsi->ws->defeat_check_utf8 = 1; - break; - } - wsi->ws->rsv = (c & 0x70); - /* revisit if an extension wants them... */ - if ( -#if !defined(LWS_WITHOUT_EXTENSIONS) - !wsi->ws->count_act_ext && -#endif - wsi->ws->rsv) { - lwsl_info("illegal rsv bits set\n"); - return -1; - } - wsi->ws->final = !!((c >> 7) & 1); - lwsl_ext("%s: This RX frame Final %d\n", __func__, - wsi->ws->final); - - if (wsi->ws->owed_a_fin && - (wsi->ws->opcode == LWSWSOPC_TEXT_FRAME || - wsi->ws->opcode == LWSWSOPC_BINARY_FRAME)) { - lwsl_info("hey you owed us a FIN\n"); - return -1; - } - if ((!(wsi->ws->opcode & 8)) && wsi->ws->final) { - wsi->ws->continuation_possible = 0; - wsi->ws->owed_a_fin = 0; - } - - if ((wsi->ws->opcode & 8) && !wsi->ws->final) { - lwsl_info("control msg can't be fragmented\n"); - return -1; - } - if (!wsi->ws->final) - wsi->ws->owed_a_fin = 1; - - switch (wsi->ws->opcode) { - case LWSWSOPC_TEXT_FRAME: - case LWSWSOPC_BINARY_FRAME: - wsi->ws->frame_is_binary = wsi->ws->opcode == - LWSWSOPC_BINARY_FRAME; - break; - } - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN; - break; - - default: - lwsl_err("unknown spec version %02d\n", - wsi->ws->ietf_spec_revision); - break; - } - break; - - case LWS_RXPS_04_FRAME_HDR_LEN: - - wsi->ws->this_frame_masked = !!(c & 0x80); - - switch (c & 0x7f) { - case 126: - /* control frames are not allowed to have big lengths */ - if (wsi->ws->opcode & 8) - goto illegal_ctl_length; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2; - break; - case 127: - /* control frames are not allowed to have big lengths */ - if (wsi->ws->opcode & 8) - goto illegal_ctl_length; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8; - break; - default: - wsi->ws->rx_packet_length = c & 0x7f; - if (wsi->ws->this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else { - if (wsi->ws->rx_packet_length) { - wsi->lws_rx_parse_state = - LWS_RXPS_WS_FRAME_PAYLOAD; - } else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - } - break; - } - break; - - case LWS_RXPS_04_FRAME_HDR_LEN16_2: - wsi->ws->rx_packet_length = c << 8; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN16_1: - wsi->ws->rx_packet_length |= c; - if (wsi->ws->this_frame_masked) - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else { - if (wsi->ws->rx_packet_length) - wsi->lws_rx_parse_state = - LWS_RXPS_WS_FRAME_PAYLOAD; - else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - } - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_8: - if (c & 0x80) { - lwsl_warn("b63 of length must be zero\n"); - /* kill the connection */ - return -1; - } -#if defined __LP64__ - wsi->ws->rx_packet_length = ((size_t)c) << 56; -#else - wsi->ws->rx_packet_length = 0; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_7: -#if defined __LP64__ - wsi->ws->rx_packet_length |= ((size_t)c) << 48; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_6: -#if defined __LP64__ - wsi->ws->rx_packet_length |= ((size_t)c) << 40; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_5: -#if defined __LP64__ - wsi->ws->rx_packet_length |= ((size_t)c) << 32; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_4: - wsi->ws->rx_packet_length |= ((size_t)c) << 24; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_3: - wsi->ws->rx_packet_length |= ((size_t)c) << 16; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_2: - wsi->ws->rx_packet_length |= ((size_t)c) << 8; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_1: - wsi->ws->rx_packet_length |= (size_t)c; - if (wsi->ws->this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else { - if (wsi->ws->rx_packet_length) - wsi->lws_rx_parse_state = - LWS_RXPS_WS_FRAME_PAYLOAD; - else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - } - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_1: - wsi->ws->mask[0] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_2: - wsi->ws->mask[1] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_3: - wsi->ws->mask[2] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_4: - wsi->ws->mask[3] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - - if (wsi->ws->rx_packet_length) - wsi->lws_rx_parse_state = - LWS_RXPS_WS_FRAME_PAYLOAD; - else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - break; - - case LWS_RXPS_WS_FRAME_PAYLOAD: - - assert(wsi->ws->rx_ubuf); -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (wsi->ws->rx_draining_ext) - goto drain_extension; -#endif - if (wsi->ws->this_frame_masked && !wsi->ws->all_zero_nonce) - c ^= wsi->ws->mask[(wsi->ws->mask_idx++) & 3]; - - wsi->ws->rx_ubuf[LWS_PRE + (wsi->ws->rx_ubuf_head++)] = c; - - if (--wsi->ws->rx_packet_length == 0) { - /* spill because we have the whole frame */ - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - - /* - * if there's no protocol max frame size given, we are - * supposed to default to context->pt_serv_buf_size - */ - if (!wsi->protocol->rx_buffer_size && - wsi->ws->rx_ubuf_head != wsi->context->pt_serv_buf_size) - break; - - if (wsi->protocol->rx_buffer_size && - wsi->ws->rx_ubuf_head != wsi->protocol->rx_buffer_size) - break; - - /* spill because we filled our rx buffer */ -spill: - - handled = 0; - - /* - * is this frame a control packet we should take care of at this - * layer? If so service it and hide it from the user callback - */ - - switch (wsi->ws->opcode) { - case LWSWSOPC_CLOSE: - pp = (unsigned char *)&wsi->ws->rx_ubuf[LWS_PRE]; - if (lws_check_opt(wsi->context->options, - LWS_SERVER_OPTION_VALIDATE_UTF8) && - wsi->ws->rx_ubuf_head > 2 && - lws_check_utf8(&wsi->ws->utf8, pp + 2, - wsi->ws->rx_ubuf_head - 2)) - goto utf8_fail; - - /* is this an acknowledgment of our close? */ - if (lwsi_state(wsi) == LRS_AWAITING_CLOSE_ACK) { - /* - * fine he has told us he is closing too, let's - * finish our close - */ - lwsl_parser("seen server's close ack\n"); - return -1; - } - - lwsl_parser("client sees server close len = %d\n", - wsi->ws->rx_ubuf_head); - if (wsi->ws->rx_ubuf_head >= 2) { - close_code = (pp[0] << 8) | pp[1]; - if (close_code < 1000 || - close_code == 1004 || - close_code == 1005 || - close_code == 1006 || - close_code == 1012 || - close_code == 1013 || - close_code == 1014 || - close_code == 1015 || - (close_code >= 1016 && close_code < 3000) - ) { - pp[0] = (LWS_CLOSE_STATUS_PROTOCOL_ERR >> 8) & 0xff; - pp[1] = LWS_CLOSE_STATUS_PROTOCOL_ERR & 0xff; - } - } - if (user_callback_handle_rxflow( - wsi->protocol->callback, wsi, - LWS_CALLBACK_WS_PEER_INITIATED_CLOSE, - wsi->user_space, pp, - wsi->ws->rx_ubuf_head)) - return -1; - - memcpy(wsi->ws->ping_payload_buf + LWS_PRE, pp, - wsi->ws->rx_ubuf_head); - wsi->ws->close_in_ping_buffer_len = wsi->ws->rx_ubuf_head; - - lwsl_info("%s: scheduling return close as ack\n", __func__); - __lws_change_pollfd(wsi, LWS_POLLIN, 0); - lws_set_timeout(wsi, PENDING_TIMEOUT_CLOSE_SEND, 3); - wsi->waiting_to_send_close_frame = 1; - wsi->close_needs_ack = 0; - lwsi_set_state(wsi, LRS_WAITING_TO_SEND_CLOSE); - lws_callback_on_writable(wsi); - handled = 1; - break; - - case LWSWSOPC_PING: - lwsl_info("received %d byte ping, sending pong\n", - wsi->ws->rx_ubuf_head); - - /* he set a close reason on this guy, ignore PING */ - if (wsi->ws->close_in_ping_buffer_len) - goto ping_drop; - - if (wsi->ws->ping_pending_flag) { - /* - * there is already a pending ping payload - * we should just log and drop - */ - lwsl_parser("DROP PING since one pending\n"); - goto ping_drop; - } - - /* control packets can only be < 128 bytes long */ - if (wsi->ws->rx_ubuf_head > 128 - 3) { - lwsl_parser("DROP PING payload too large\n"); - goto ping_drop; - } - - /* stash the pong payload */ - memcpy(wsi->ws->ping_payload_buf + LWS_PRE, - &wsi->ws->rx_ubuf[LWS_PRE], - wsi->ws->rx_ubuf_head); - - wsi->ws->ping_payload_len = wsi->ws->rx_ubuf_head; - wsi->ws->ping_pending_flag = 1; - - /* get it sent as soon as possible */ - lws_callback_on_writable(wsi); -ping_drop: - wsi->ws->rx_ubuf_head = 0; - handled = 1; - break; - - case LWSWSOPC_PONG: - lwsl_info("client received pong\n"); - lwsl_hexdump(&wsi->ws->rx_ubuf[LWS_PRE], - wsi->ws->rx_ubuf_head); - - if (wsi->pending_timeout == - PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG) { - lwsl_info("%p: received expected PONG\n", wsi); - lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - } - - /* issue it */ - callback_action = LWS_CALLBACK_CLIENT_RECEIVE_PONG; - break; - - case LWSWSOPC_CONTINUATION: - case LWSWSOPC_TEXT_FRAME: - case LWSWSOPC_BINARY_FRAME: - break; - - default: - /* not handled or failed */ - lwsl_ext("Unhandled ext opc 0x%x\n", wsi->ws->opcode); - wsi->ws->rx_ubuf_head = 0; - - return -1; - } - - /* - * No it's real payload, pass it up to the user callback. - * It's nicely buffered with the pre-padding taken care of - * so it can be sent straight out again using lws_write - */ - if (handled) - goto already_done; - - ebuf.token = &wsi->ws->rx_ubuf[LWS_PRE]; - ebuf.len = wsi->ws->rx_ubuf_head; - -#if !defined(LWS_WITHOUT_EXTENSIONS) -drain_extension: - lwsl_ext("%s: passing %d to ext\n", __func__, ebuf.len); - - n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &ebuf, 0); - lwsl_ext("Ext RX returned %d\n", n); - if (n < 0) { - wsi->socket_is_permanently_unusable = 1; - return -1; - } -#endif - lwsl_debug("post inflate ebuf len %d\n", ebuf.len); - -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (rx_draining_ext && !ebuf.len) { - lwsl_debug(" --- ending drain on 0 read result\n"); - goto already_done; - } -#endif - - if (wsi->ws->check_utf8 && !wsi->ws->defeat_check_utf8) { - if (lws_check_utf8(&wsi->ws->utf8, - (unsigned char *)ebuf.token, - ebuf.len)) { - lws_close_reason(wsi, - LWS_CLOSE_STATUS_INVALID_PAYLOAD, - (uint8_t *)"bad utf8", 8); - goto utf8_fail; - } - - /* we are ending partway through utf-8 character? */ - if (!wsi->ws->rx_packet_length && wsi->ws->final && - wsi->ws->utf8 -#if !defined(LWS_WITHOUT_EXTENSIONS) - && !n -#endif - ) { - lwsl_info("FINAL utf8 error\n"); - lws_close_reason(wsi, - LWS_CLOSE_STATUS_INVALID_PAYLOAD, - (uint8_t *)"partial utf8", 12); -utf8_fail: - lwsl_info("utf8 error\n"); - lwsl_hexdump_info(ebuf.token, ebuf.len); - - return -1; - } - } - - if (ebuf.len < 0 && - callback_action != LWS_CALLBACK_CLIENT_RECEIVE_PONG) - goto already_done; - - if (!ebuf.token) - goto already_done; - - ebuf.token[ebuf.len] = '\0'; - - if (!wsi->protocol->callback) - goto already_done; - - if (callback_action == LWS_CALLBACK_CLIENT_RECEIVE_PONG) - lwsl_info("Client doing pong callback\n"); - - if ( - /* coverity says dead code otherwise */ -#if !defined(LWS_WITHOUT_EXTENSIONS) - n && -#endif - ebuf.len) - /* extension had more... main loop will come back - * we want callback to be done with this set, if so, - * because lws_is_final() hides it was final until the - * last chunk - */ - lws_add_wsi_to_draining_ext_list(wsi); - else - lws_remove_wsi_from_draining_ext_list(wsi); - - if (lwsi_state(wsi) == LRS_RETURNED_CLOSE || - lwsi_state(wsi) == LRS_WAITING_TO_SEND_CLOSE || - lwsi_state(wsi) == LRS_AWAITING_CLOSE_ACK) - goto already_done; - - m = wsi->protocol->callback(wsi, - (enum lws_callback_reasons)callback_action, - wsi->user_space, ebuf.token, ebuf.len); - - wsi->ws->first_fragment = 0; - - // lwsl_notice("%s: bulk ws rx: input used %d, output %d\n", - // __func__, wsi->ws->rx_ubuf_head, ebuf.len); - - /* if user code wants to close, let caller know */ - if (m) - return 1; - -already_done: - wsi->ws->rx_ubuf_head = 0; - break; - default: - lwsl_err("client rx illegal state\n"); - return 1; - } - - return 0; - -illegal_ctl_length: - lwsl_warn("Control frame asking for extended length is illegal\n"); - - /* kill the connection */ - return -1; -} - - diff --git a/thirdparty/libwebsockets/roles/ws/client-ws.c b/thirdparty/libwebsockets/roles/ws/client-ws.c deleted file mode 100644 index fd6cf42551..0000000000 --- a/thirdparty/libwebsockets/roles/ws/client-ws.c +++ /dev/null @@ -1,629 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include <core/private.h> - -/* - * In-place str to lower case - */ - -static void -strtolower(char *s) -{ - while (*s) { -#ifdef LWS_PLAT_OPTEE - int tolower_optee(int c); - *s = tolower_optee((int)*s); -#else - *s = tolower((int)*s); -#endif - s++; - } -} - -int -lws_create_client_ws_object(struct lws_client_connect_info *i, struct lws *wsi) -{ - int v = SPEC_LATEST_SUPPORTED; - - /* allocate the ws struct for the wsi */ - wsi->ws = lws_zalloc(sizeof(*wsi->ws), "client ws struct"); - if (!wsi->ws) { - lwsl_notice("OOM\n"); - return 1; - } - - /* -1 means just use latest supported */ - if (i->ietf_version_or_minus_one != -1 && - i->ietf_version_or_minus_one) - v = i->ietf_version_or_minus_one; - - wsi->ws->ietf_spec_revision = v; - - return 0; -} - -#if !defined(LWS_NO_CLIENT) -int -lws_ws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len) -{ - if ((lwsi_state(wsi) != LRS_WAITING_PROXY_REPLY) && - (lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE) && - (lwsi_state(wsi) != LRS_WAITING_SERVER_REPLY) && - !lwsi_role_client(wsi)) - return 0; - - // lwsl_notice("%s: hs client gets %d in\n", __func__, (int)len); - - while (len) { - /* - * we were accepting input but now we stopped doing so - */ - if (lws_is_flowcontrolled(wsi)) { - //lwsl_notice("%s: caching %ld\n", __func__, (long)len); - lws_rxflow_cache(wsi, *buf, 0, (int)len); - *buf += len; - return 0; - } -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (wsi->ws->rx_draining_ext) { - int m; - - //lwsl_notice("%s: draining ext\n", __func__); - if (lwsi_role_client(wsi)) - m = lws_ws_client_rx_sm(wsi, 0); - else - m = lws_ws_rx_sm(wsi, 0, 0); - if (m < 0) - return -1; - continue; - } -#endif - /* caller will account for buflist usage */ - - if (lws_ws_client_rx_sm(wsi, *(*buf)++)) { - lwsl_notice("%s: client_rx_sm exited, DROPPING %d\n", - __func__, (int)len); - return -1; - } - len--; - } - // lwsl_notice("%s: finished with %ld\n", __func__, (long)len); - - return 0; -} -#endif - -char * -lws_generate_client_ws_handshake(struct lws *wsi, char *p) -{ - char buf[128], hash[20], key_b64[40]; - int n; -#if !defined(LWS_WITHOUT_EXTENSIONS) - const struct lws_extension *ext; - int ext_count = 0; -#endif - - /* - * create the random key - */ - n = lws_get_random(wsi->context, hash, 16); - if (n != 16) { - lwsl_err("Unable to read from random dev %s\n", - SYSTEM_RANDOM_FILEPATH); - return NULL; - } - - lws_b64_encode_string(hash, 16, key_b64, sizeof(key_b64)); - - p += sprintf(p, "Upgrade: websocket\x0d\x0a" - "Connection: Upgrade\x0d\x0a" - "Sec-WebSocket-Key: "); - strcpy(p, key_b64); - p += strlen(key_b64); - p += sprintf(p, "\x0d\x0a"); - if (lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS)) - p += sprintf(p, "Sec-WebSocket-Protocol: %s\x0d\x0a", - lws_hdr_simple_ptr(wsi, - _WSI_TOKEN_CLIENT_SENT_PROTOCOLS)); - - /* tell the server what extensions we could support */ - -#if !defined(LWS_WITHOUT_EXTENSIONS) - ext = wsi->vhost->ws.extensions; - while (ext && ext->callback) { - - n = wsi->vhost->protocols[0].callback(wsi, - LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED, - wsi->user_space, (char *)ext->name, 0); - - /* - * zero return from callback means go ahead and allow - * the extension, it's what we get if the callback is - * unhandled - */ - - if (n) { - ext++; - continue; - } - - /* apply it */ - - if (ext_count) - *p++ = ','; - else - p += sprintf(p, "Sec-WebSocket-Extensions: "); - p += sprintf(p, "%s", ext->client_offer); - ext_count++; - - ext++; - } - if (ext_count) - p += sprintf(p, "\x0d\x0a"); -#endif - - if (wsi->ws->ietf_spec_revision) - p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a", - wsi->ws->ietf_spec_revision); - - /* prepare the expected server accept response */ - - key_b64[39] = '\0'; /* enforce composed length below buf sizeof */ - n = sprintf(buf, "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", - key_b64); - - lws_SHA1((unsigned char *)buf, n, (unsigned char *)hash); - - lws_b64_encode_string(hash, 20, - wsi->http.ah->initial_handshake_hash_base64, - sizeof(wsi->http.ah->initial_handshake_hash_base64)); - - return p; -} - -int -lws_client_ws_upgrade(struct lws *wsi, const char **cce) -{ - int n, len, okay = 0; - struct lws_context *context = wsi->context; - const char *pc; - char *p; -#if !defined(LWS_WITHOUT_EXTENSIONS) - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - char *sb = (char *)&pt->serv_buf[0]; - const struct lws_ext_options *opts; - const struct lws_extension *ext; - char ext_name[128]; - const char *c, *a; - char ignore; - int more = 1; -#endif - - if (wsi->client_h2_substream) {/* !!! client ws-over-h2 not there yet */ - lwsl_warn("%s: client ws-over-h2 upgrade not supported yet\n", - __func__); - *cce = "HS: h2 / ws upgrade unsupported"; - goto bail3; - } - - if (wsi->http.ah->http_response == 401) { - lwsl_warn( - "lws_client_handshake: got bad HTTP response '%d'\n", - wsi->http.ah->http_response); - *cce = "HS: ws upgrade unauthorized"; - goto bail3; - } - - if (wsi->http.ah->http_response != 101) { - lwsl_warn( - "lws_client_handshake: got bad HTTP response '%d'\n", - wsi->http.ah->http_response); - *cce = "HS: ws upgrade response not 101"; - goto bail3; - } - - if (lws_hdr_total_length(wsi, WSI_TOKEN_ACCEPT) == 0) { - lwsl_info("no ACCEPT\n"); - *cce = "HS: ACCEPT missing"; - goto bail3; - } - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_UPGRADE); - if (!p) { - lwsl_info("no UPGRADE\n"); - *cce = "HS: UPGRADE missing"; - goto bail3; - } - strtolower(p); - if (strcmp(p, "websocket")) { - lwsl_warn( - "lws_client_handshake: got bad Upgrade header '%s'\n", p); - *cce = "HS: Upgrade to something other than websocket"; - goto bail3; - } - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_CONNECTION); - if (!p) { - lwsl_info("no Connection hdr\n"); - *cce = "HS: CONNECTION missing"; - goto bail3; - } - strtolower(p); - if (strcmp(p, "upgrade")) { - lwsl_warn("lws_client_int_s_hs: bad header %s\n", p); - *cce = "HS: UPGRADE malformed"; - goto bail3; - } - - pc = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS); - if (!pc) { - lwsl_parser("lws_client_int_s_hs: no protocol list\n"); - } else - lwsl_parser("lws_client_int_s_hs: protocol list '%s'\n", pc); - - /* - * confirm the protocol the server wants to talk was in the list - * of protocols we offered - */ - - len = lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL); - if (!len) { - lwsl_info("%s: WSI_TOKEN_PROTOCOL is null\n", __func__); - /* - * no protocol name to work from, - * default to first protocol - */ - n = 0; - wsi->protocol = &wsi->vhost->protocols[0]; - goto check_extensions; - } - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL); - len = (int)strlen(p); - - while (pc && *pc && !okay) { - if (!strncmp(pc, p, len) && - (pc[len] == ',' || pc[len] == '\0')) { - okay = 1; - continue; - } - while (*pc && *pc++ != ',') - ; - while (*pc && *pc == ' ') - pc++; - } - - if (!okay) { - lwsl_info("%s: got bad protocol %s\n", __func__, p); - *cce = "HS: PROTOCOL malformed"; - goto bail2; - } - - /* - * identify the selected protocol struct and set it - */ - n = 0; - /* keep client connection pre-bound protocol */ - if (!lwsi_role_client(wsi)) - wsi->protocol = NULL; - - while (wsi->vhost->protocols[n].callback) { - if (!wsi->protocol && - strcmp(p, wsi->vhost->protocols[n].name) == 0) { - wsi->protocol = &wsi->vhost->protocols[n]; - break; - } - n++; - } - - if (!wsi->vhost->protocols[n].callback) { /* no match */ - /* if server, that's already fatal */ - if (!lwsi_role_client(wsi)) { - lwsl_info("%s: fail protocol %s\n", __func__, p); - *cce = "HS: Cannot match protocol"; - goto bail2; - } - - /* for client, find the index of our pre-bound protocol */ - - n = 0; - while (wsi->vhost->protocols[n].callback) { - if (wsi->protocol && strcmp(wsi->protocol->name, - wsi->vhost->protocols[n].name) == 0) { - wsi->protocol = &wsi->vhost->protocols[n]; - break; - } - n++; - } - - if (!wsi->vhost->protocols[n].callback) { - if (wsi->protocol) - lwsl_err("Failed to match protocol %s\n", - wsi->protocol->name); - else - lwsl_err("No protocol on client\n"); - goto bail2; - } - } - - lwsl_debug("Selected protocol %s\n", wsi->protocol->name); - -check_extensions: - /* - * stitch protocol choice into the vh protocol linked list - * We always insert ourselves at the start of the list - * - * X <-> B - * X <-> pAn <-> pB - */ - - lws_vhost_lock(wsi->vhost); - - wsi->same_vh_protocol_prev = /* guy who points to us */ - &wsi->vhost->same_vh_protocol_list[n]; - wsi->same_vh_protocol_next = /* old first guy is our next */ - wsi->vhost->same_vh_protocol_list[n]; - /* we become the new first guy */ - wsi->vhost->same_vh_protocol_list[n] = wsi; - - if (wsi->same_vh_protocol_next) - /* old first guy points back to us now */ - wsi->same_vh_protocol_next->same_vh_protocol_prev = - &wsi->same_vh_protocol_next; - wsi->on_same_vh_list = 1; - - lws_vhost_unlock(wsi->vhost); - -#if !defined(LWS_WITHOUT_EXTENSIONS) - /* instantiate the accepted extensions */ - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS)) { - lwsl_ext("no client extensions allowed by server\n"); - goto check_accept; - } - - /* - * break down the list of server accepted extensions - * and go through matching them or identifying bogons - */ - - if (lws_hdr_copy(wsi, sb, context->pt_serv_buf_size, - WSI_TOKEN_EXTENSIONS) < 0) { - lwsl_warn("ext list from server failed to copy\n"); - *cce = "HS: EXT: list too big"; - goto bail2; - } - - c = sb; - n = 0; - ignore = 0; - a = NULL; - while (more) { - - if (*c && (*c != ',' && *c != '\t')) { - if (*c == ';') { - ignore = 1; - if (!a) - a = c + 1; - } - if (ignore || *c == ' ') { - c++; - continue; - } - - ext_name[n] = *c++; - if (n < (int)sizeof(ext_name) - 1) - n++; - continue; - } - ext_name[n] = '\0'; - ignore = 0; - if (!*c) - more = 0; - else { - c++; - if (!n) - continue; - } - - /* check we actually support it */ - - lwsl_notice("checking client ext %s\n", ext_name); - - n = 0; - ext = wsi->vhost->ws.extensions; - while (ext && ext->callback) { - if (strcmp(ext_name, ext->name)) { - ext++; - continue; - } - - n = 1; - lwsl_notice("instantiating client ext %s\n", ext_name); - - /* instantiate the extension on this conn */ - - wsi->ws->active_extensions[wsi->ws->count_act_ext] = ext; - - /* allow him to construct his ext instance */ - - if (ext->callback(lws_get_context(wsi), ext, wsi, - LWS_EXT_CB_CLIENT_CONSTRUCT, - (void *)&wsi->ws->act_ext_user[wsi->ws->count_act_ext], - (void *)&opts, 0)) { - lwsl_info(" ext %s failed construction\n", - ext_name); - ext++; - continue; - } - - /* - * allow the user code to override ext defaults if it - * wants to - */ - ext_name[0] = '\0'; - if (user_callback_handle_rxflow(wsi->protocol->callback, - wsi, LWS_CALLBACK_WS_EXT_DEFAULTS, - (char *)ext->name, ext_name, - sizeof(ext_name))) { - *cce = "HS: EXT: failed setting defaults"; - goto bail2; - } - - if (ext_name[0] && - lws_ext_parse_options(ext, wsi, wsi->ws->act_ext_user[ - wsi->ws->count_act_ext], opts, ext_name, - (int)strlen(ext_name))) { - lwsl_err("%s: unable to parse user defaults '%s'", - __func__, ext_name); - *cce = "HS: EXT: failed parsing defaults"; - goto bail2; - } - - /* - * give the extension the server options - */ - if (a && lws_ext_parse_options(ext, wsi, - wsi->ws->act_ext_user[wsi->ws->count_act_ext], - opts, a, lws_ptr_diff(c, a))) { - lwsl_err("%s: unable to parse remote def '%s'", - __func__, a); - *cce = "HS: EXT: failed parsing options"; - goto bail2; - } - - if (ext->callback(lws_get_context(wsi), ext, wsi, - LWS_EXT_CB_OPTION_CONFIRM, - wsi->ws->act_ext_user[wsi->ws->count_act_ext], - NULL, 0)) { - lwsl_err("%s: ext %s rejects server options %s", - __func__, ext->name, a); - *cce = "HS: EXT: Rejects server options"; - goto bail2; - } - - wsi->ws->count_act_ext++; - - ext++; - } - - if (n == 0) { - lwsl_warn("Unknown ext '%s'!\n", ext_name); - *cce = "HS: EXT: unknown ext"; - goto bail2; - } - - a = NULL; - n = 0; - } - -check_accept: -#endif - - /* - * Confirm his accept token is the one we precomputed - */ - - p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_ACCEPT); - if (strcmp(p, wsi->http.ah->initial_handshake_hash_base64)) { - lwsl_warn("lws_client_int_s_hs: accept '%s' wrong vs '%s'\n", p, - wsi->http.ah->initial_handshake_hash_base64); - *cce = "HS: Accept hash wrong"; - goto bail2; - } - - /* allocate the per-connection user memory (if any) */ - if (lws_ensure_user_space(wsi)) { - lwsl_err("Problem allocating wsi user mem\n"); - *cce = "HS: OOM"; - goto bail2; - } - - /* - * we seem to be good to go, give client last chance to check - * headers and OK it - */ - if (wsi->protocol->callback(wsi, - LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH, - wsi->user_space, NULL, 0)) { - *cce = "HS: Rejected by filter cb"; - goto bail2; - } - - /* clear his proxy connection timeout */ - lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - - /* free up his parsing allocations */ - lws_header_table_detach(wsi, 0); - - lws_role_transition(wsi, LWSIFR_CLIENT, LRS_ESTABLISHED, - &role_ops_ws); - lws_restart_ws_ping_pong_timer(wsi); - - wsi->rxflow_change_to = LWS_RXFLOW_ALLOW; - - /* - * create the frame buffer for this connection according to the - * size mentioned in the protocol definition. If 0 there, then - * use a big default for compatibility - */ - n = (int)wsi->protocol->rx_buffer_size; - if (!n) - n = context->pt_serv_buf_size; - n += LWS_PRE; - wsi->ws->rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */, - "client frame buffer"); - if (!wsi->ws->rx_ubuf) { - lwsl_err("Out of Mem allocating rx buffer %d\n", n); - *cce = "HS: OOM"; - goto bail2; - } - wsi->ws->rx_ubuf_alloc = n; - lwsl_info("Allocating client RX buffer %d\n", n); - -#if !defined(LWS_WITH_ESP32) - if (setsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_SNDBUF, - (const char *)&n, sizeof n)) { - lwsl_warn("Failed to set SNDBUF to %d", n); - *cce = "HS: SO_SNDBUF failed"; - goto bail3; - } -#endif - - lwsl_debug("handshake OK for protocol %s\n", wsi->protocol->name); - - /* call him back to inform him he is up */ - - if (wsi->protocol->callback(wsi, LWS_CALLBACK_CLIENT_ESTABLISHED, - wsi->user_space, NULL, 0)) { - *cce = "HS: Rejected at CLIENT_ESTABLISHED"; - goto bail3; - } - - return 0; - -bail3: - return 3; - -bail2: - return 2; -} diff --git a/thirdparty/libwebsockets/roles/ws/ops-ws.c b/thirdparty/libwebsockets/roles/ws/ops-ws.c deleted file mode 100644 index 665b2c9b74..0000000000 --- a/thirdparty/libwebsockets/roles/ws/ops-ws.c +++ /dev/null @@ -1,1994 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include <core/private.h> - -#define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); } - -/* - * client-parser.c: lws_ws_client_rx_sm() needs to be roughly kept in - * sync with changes here, esp related to ext draining - */ - -int -lws_ws_rx_sm(struct lws *wsi, char already_processed, unsigned char c) -{ - int callback_action = LWS_CALLBACK_RECEIVE; - int ret = 0; - unsigned short close_code; - struct lws_tokens ebuf; - unsigned char *pp; - int n = 0; -#if !defined(LWS_WITHOUT_EXTENSIONS) - int rx_draining_ext = 0; - int lin; -#endif - - ebuf.token = NULL; - ebuf.len = 0; - if (wsi->socket_is_permanently_unusable) - return -1; - - switch (wsi->lws_rx_parse_state) { - case LWS_RXPS_NEW: -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (wsi->ws->rx_draining_ext) { - ebuf.token = NULL; - ebuf.len = 0; - lws_remove_wsi_from_draining_ext_list(wsi); - rx_draining_ext = 1; - lwsl_debug("%s: doing draining flow\n", __func__); - - goto drain_extension; - } -#endif - switch (wsi->ws->ietf_spec_revision) { - case 13: - /* - * no prepended frame key any more - */ - wsi->ws->all_zero_nonce = 1; - goto handle_first; - - default: - lwsl_warn("lws_ws_rx_sm: unknown spec version %d\n", - wsi->ws->ietf_spec_revision); - break; - } - break; - case LWS_RXPS_04_mask_1: - wsi->ws->mask[1] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_04_mask_2; - break; - case LWS_RXPS_04_mask_2: - wsi->ws->mask[2] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_04_mask_3; - break; - case LWS_RXPS_04_mask_3: - wsi->ws->mask[3] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - - /* - * start from the zero'th byte in the XOR key buffer since - * this is the start of a frame with a new key - */ - - wsi->ws->mask_idx = 0; - - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1; - break; - - /* - * 04 logical framing from the spec (all this is masked when incoming - * and has to be unmasked) - * - * We ignore the possibility of extension data because we don't - * negotiate any extensions at the moment. - * - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-------+-+-------------+-------------------------------+ - * |F|R|R|R| opcode|R| Payload len | Extended payload length | - * |I|S|S|S| (4) |S| (7) | (16/63) | - * |N|V|V|V| |V| | (if payload len==126/127) | - * | |1|2|3| |4| | | - * +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - + - * | Extended payload length continued, if payload len == 127 | - * + - - - - - - - - - - - - - - - +-------------------------------+ - * | | Extension data | - * +-------------------------------+ - - - - - - - - - - - - - - - + - * : : - * +---------------------------------------------------------------+ - * : Application data : - * +---------------------------------------------------------------+ - * - * We pass payload through to userland as soon as we get it, ignoring - * FIN. It's up to userland to buffer it up if it wants to see a - * whole unfragmented block of the original size (which may be up to - * 2^63 long!) - */ - - case LWS_RXPS_04_FRAME_HDR_1: -handle_first: - - wsi->ws->opcode = c & 0xf; - wsi->ws->rsv = c & 0x70; - wsi->ws->final = !!((c >> 7) & 1); - wsi->ws->defeat_check_utf8 = 0; - - if (((wsi->ws->opcode) & 8) && !wsi->ws->final) { - lws_close_reason(wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, - (uint8_t *)"frag ctl", 8); - return -1; - } - - switch (wsi->ws->opcode) { - case LWSWSOPC_TEXT_FRAME: - wsi->ws->check_utf8 = lws_check_opt( - wsi->context->options, - LWS_SERVER_OPTION_VALIDATE_UTF8); - /* fallthru */ - case LWSWSOPC_BINARY_FRAME: - if (wsi->ws->opcode == LWSWSOPC_BINARY_FRAME) - wsi->ws->check_utf8 = 0; - if (wsi->ws->continuation_possible) { - lws_close_reason(wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, (uint8_t *)"bad cont", 8); - return -1; - } - wsi->ws->rsv_first_msg = (c & 0x70); - wsi->ws->frame_is_binary = - wsi->ws->opcode == LWSWSOPC_BINARY_FRAME; - wsi->ws->first_fragment = 1; - wsi->ws->continuation_possible = !wsi->ws->final; - break; - case LWSWSOPC_CONTINUATION: - if (!wsi->ws->continuation_possible) { - lws_close_reason(wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, (uint8_t *)"bad cont", 8); - return -1; - } - break; - case LWSWSOPC_CLOSE: - wsi->ws->check_utf8 = 0; - wsi->ws->utf8 = 0; - break; - case 3: - case 4: - case 5: - case 6: - case 7: - case 0xb: - case 0xc: - case 0xd: - case 0xe: - case 0xf: - lws_close_reason(wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, (uint8_t *)"bad opc", 7); - lwsl_info("illegal opcode\n"); - return -1; - } - - if (wsi->ws->owed_a_fin && - (wsi->ws->opcode == LWSWSOPC_TEXT_FRAME || - wsi->ws->opcode == LWSWSOPC_BINARY_FRAME)) { - lwsl_info("hey you owed us a FIN\n"); - lws_close_reason(wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, (uint8_t *)"bad fin", 7); - return -1; - } - if ((!(wsi->ws->opcode & 8)) && wsi->ws->final) { - wsi->ws->continuation_possible = 0; - wsi->ws->owed_a_fin = 0; - } - - if (!wsi->ws->final) - wsi->ws->owed_a_fin = 1; - - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN; - if (wsi->ws->rsv && - ( -#if !defined(LWS_WITHOUT_EXTENSIONS) - !wsi->ws->count_act_ext || -#endif - (wsi->ws->rsv & ~0x40))) { - lws_close_reason(wsi, LWS_CLOSE_STATUS_PROTOCOL_ERR, - (uint8_t *)"rsv bits", 8); - return -1; - } - break; - - case LWS_RXPS_04_FRAME_HDR_LEN: - - wsi->ws->this_frame_masked = !!(c & 0x80); - - switch (c & 0x7f) { - case 126: - /* control frames are not allowed to have big lengths */ - if (wsi->ws->opcode & 8) - goto illegal_ctl_length; - - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2; - break; - case 127: - /* control frames are not allowed to have big lengths */ - if (wsi->ws->opcode & 8) - goto illegal_ctl_length; - - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8; - break; - default: - wsi->ws->rx_packet_length = c & 0x7f; - - - if (wsi->ws->this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else - if (wsi->ws->rx_packet_length) { - wsi->lws_rx_parse_state = - LWS_RXPS_WS_FRAME_PAYLOAD; - } else { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - break; - } - break; - - case LWS_RXPS_04_FRAME_HDR_LEN16_2: - wsi->ws->rx_packet_length = c << 8; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN16_1: - wsi->ws->rx_packet_length |= c; - if (wsi->ws->this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else { - wsi->lws_rx_parse_state = - LWS_RXPS_WS_FRAME_PAYLOAD; - } - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_8: - if (c & 0x80) { - lwsl_warn("b63 of length must be zero\n"); - /* kill the connection */ - return -1; - } -#if defined __LP64__ - wsi->ws->rx_packet_length = ((size_t)c) << 56; -#else - wsi->ws->rx_packet_length = 0; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_7: -#if defined __LP64__ - wsi->ws->rx_packet_length |= ((size_t)c) << 48; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_6: -#if defined __LP64__ - wsi->ws->rx_packet_length |= ((size_t)c) << 40; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_5: -#if defined __LP64__ - wsi->ws->rx_packet_length |= ((size_t)c) << 32; -#endif - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_4: - wsi->ws->rx_packet_length |= ((size_t)c) << 24; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_3: - wsi->ws->rx_packet_length |= ((size_t)c) << 16; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_2: - wsi->ws->rx_packet_length |= ((size_t)c) << 8; - wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1; - break; - - case LWS_RXPS_04_FRAME_HDR_LEN64_1: - wsi->ws->rx_packet_length |= ((size_t)c); - if (wsi->ws->this_frame_masked) - wsi->lws_rx_parse_state = - LWS_RXPS_07_COLLECT_FRAME_KEY_1; - else - wsi->lws_rx_parse_state = LWS_RXPS_WS_FRAME_PAYLOAD; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_1: - wsi->ws->mask[0] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_2: - wsi->ws->mask[1] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_3: - wsi->ws->mask[2] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4; - break; - - case LWS_RXPS_07_COLLECT_FRAME_KEY_4: - wsi->ws->mask[3] = c; - if (c) - wsi->ws->all_zero_nonce = 0; - wsi->lws_rx_parse_state = LWS_RXPS_WS_FRAME_PAYLOAD; - wsi->ws->mask_idx = 0; - if (wsi->ws->rx_packet_length == 0) { - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } - break; - - - case LWS_RXPS_WS_FRAME_PAYLOAD: - assert(wsi->ws->rx_ubuf); - - if (wsi->ws->rx_ubuf_head + LWS_PRE >= wsi->ws->rx_ubuf_alloc) { - lwsl_err("Attempted overflow \n"); - return -1; - } - if (!(already_processed & ALREADY_PROCESSED_IGNORE_CHAR)) { - if (wsi->ws->all_zero_nonce) - wsi->ws->rx_ubuf[LWS_PRE + (wsi->ws->rx_ubuf_head++)] = - c; - else - wsi->ws->rx_ubuf[LWS_PRE + (wsi->ws->rx_ubuf_head++)] = - c ^ wsi->ws->mask[(wsi->ws->mask_idx++) & 3]; - - --wsi->ws->rx_packet_length; - } - - if (!wsi->ws->rx_packet_length) { - lwsl_debug("%s: ws fragment length exhausted\n", __func__); - /* spill because we have the whole frame */ - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - goto spill; - } -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (wsi->ws->rx_draining_ext) { - lwsl_debug("%s: UNTIL_EXHAUSTED draining\n", __func__); - goto drain_extension; - } -#endif - /* - * if there's no protocol max frame size given, we are - * supposed to default to context->pt_serv_buf_size - */ - if (!wsi->protocol->rx_buffer_size && - wsi->ws->rx_ubuf_head != wsi->context->pt_serv_buf_size) - break; - - if (wsi->protocol->rx_buffer_size && - wsi->ws->rx_ubuf_head != wsi->protocol->rx_buffer_size) - break; - - /* spill because we filled our rx buffer */ -spill: - /* - * is this frame a control packet we should take care of at this - * layer? If so service it and hide it from the user callback - */ - - lwsl_parser("spill on %s\n", wsi->protocol->name); - - switch (wsi->ws->opcode) { - case LWSWSOPC_CLOSE: - - if (wsi->ws->peer_has_sent_close) - break; - - wsi->ws->peer_has_sent_close = 1; - - pp = (unsigned char *)&wsi->ws->rx_ubuf[LWS_PRE]; - if (lws_check_opt(wsi->context->options, - LWS_SERVER_OPTION_VALIDATE_UTF8) && - wsi->ws->rx_ubuf_head > 2 && - lws_check_utf8(&wsi->ws->utf8, pp + 2, - wsi->ws->rx_ubuf_head - 2)) - goto utf8_fail; - - /* is this an acknowledgment of our close? */ - if (lwsi_state(wsi) == LRS_AWAITING_CLOSE_ACK) { - /* - * fine he has told us he is closing too, let's - * finish our close - */ - lwsl_parser("seen client close ack\n"); - return -1; - } - if (lwsi_state(wsi) == LRS_RETURNED_CLOSE) - /* if he sends us 2 CLOSE, kill him */ - return -1; - - if (lws_partial_buffered(wsi)) { - /* - * if we're in the middle of something, - * we can't do a normal close response and - * have to just close our end. - */ - wsi->socket_is_permanently_unusable = 1; - lwsl_parser("Closing on peer close due to Pending tx\n"); - return -1; - } - - if (wsi->ws->rx_ubuf_head >= 2) { - close_code = (pp[0] << 8) | pp[1]; - if (close_code < 1000 || - close_code == 1004 || - close_code == 1005 || - close_code == 1006 || - close_code == 1012 || - close_code == 1013 || - close_code == 1014 || - close_code == 1015 || - (close_code >= 1016 && close_code < 3000) - ) { - pp[0] = (LWS_CLOSE_STATUS_PROTOCOL_ERR >> 8) & 0xff; - pp[1] = LWS_CLOSE_STATUS_PROTOCOL_ERR & 0xff; - } - } - - if (user_callback_handle_rxflow( - wsi->protocol->callback, wsi, - LWS_CALLBACK_WS_PEER_INITIATED_CLOSE, - wsi->user_space, - &wsi->ws->rx_ubuf[LWS_PRE], - wsi->ws->rx_ubuf_head)) - return -1; - - lwsl_parser("server sees client close packet\n"); - lwsi_set_state(wsi, LRS_RETURNED_CLOSE); - /* deal with the close packet contents as a PONG */ - wsi->ws->payload_is_close = 1; - goto process_as_ping; - - case LWSWSOPC_PING: - lwsl_info("received %d byte ping, sending pong\n", - wsi->ws->rx_ubuf_head); - - if (wsi->ws->ping_pending_flag) { - /* - * there is already a pending ping payload - * we should just log and drop - */ - lwsl_parser("DROP PING since one pending\n"); - goto ping_drop; - } -process_as_ping: - /* control packets can only be < 128 bytes long */ - if (wsi->ws->rx_ubuf_head > 128 - 3) { - lwsl_parser("DROP PING payload too large\n"); - goto ping_drop; - } - - /* stash the pong payload */ - memcpy(wsi->ws->ping_payload_buf + LWS_PRE, - &wsi->ws->rx_ubuf[LWS_PRE], - wsi->ws->rx_ubuf_head); - - wsi->ws->ping_payload_len = wsi->ws->rx_ubuf_head; - wsi->ws->ping_pending_flag = 1; - - /* get it sent as soon as possible */ - lws_callback_on_writable(wsi); -ping_drop: - wsi->ws->rx_ubuf_head = 0; - return 0; - - case LWSWSOPC_PONG: - lwsl_info("received pong\n"); - lwsl_hexdump(&wsi->ws->rx_ubuf[LWS_PRE], - wsi->ws->rx_ubuf_head); - - if (wsi->pending_timeout == - PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG) { - lwsl_info("received expected PONG on wsi %p\n", - wsi); - lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); - } - - /* issue it */ - callback_action = LWS_CALLBACK_RECEIVE_PONG; - break; - - case LWSWSOPC_TEXT_FRAME: - case LWSWSOPC_BINARY_FRAME: - case LWSWSOPC_CONTINUATION: - break; - - default: - lwsl_parser("unknown opc %x\n", wsi->ws->opcode); - - return -1; - } - - /* - * No it's real payload, pass it up to the user callback. - * It's nicely buffered with the pre-padding taken care of - * so it can be sent straight out again using lws_write - */ - - ebuf.token = &wsi->ws->rx_ubuf[LWS_PRE]; - ebuf.len = wsi->ws->rx_ubuf_head; - - if (wsi->ws->opcode == LWSWSOPC_PONG && !ebuf.len) - goto already_done; -#if !defined(LWS_WITHOUT_EXTENSIONS) -drain_extension: -#endif - // lwsl_notice("%s: passing %d to ext\n", __func__, ebuf.len); - - if (lwsi_state(wsi) == LRS_RETURNED_CLOSE || - lwsi_state(wsi) == LRS_AWAITING_CLOSE_ACK) - goto already_done; -#if !defined(LWS_WITHOUT_EXTENSIONS) - lin = ebuf.len; - //if (lin) - // lwsl_hexdump_notice(ebuf.token, ebuf.len); - n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &ebuf, 0); - lwsl_debug("%s: ext says %d / ebuf.len %d\n", __func__, n, ebuf.len); - if (wsi->ws->rx_draining_ext) - already_processed &= ~ALREADY_PROCESSED_NO_CB; -#endif - /* - * ebuf may be pointing somewhere completely different now, - * it's the output - */ -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (n < 0) { - /* - * we may rely on this to get RX, just drop connection - */ - wsi->socket_is_permanently_unusable = 1; - return -1; - } -#endif - if ( -#if !defined(LWS_WITHOUT_EXTENSIONS) - rx_draining_ext && -#endif - ebuf.len == 0) - goto already_done; - - if ( -#if !defined(LWS_WITHOUT_EXTENSIONS) - n && -#endif - ebuf.len) - /* extension had more... main loop will come back */ - lws_add_wsi_to_draining_ext_list(wsi); - else - lws_remove_wsi_from_draining_ext_list(wsi); - - if (wsi->ws->check_utf8 && !wsi->ws->defeat_check_utf8) { - if (lws_check_utf8(&wsi->ws->utf8, - (unsigned char *)ebuf.token, - ebuf.len)) { - lws_close_reason(wsi, - LWS_CLOSE_STATUS_INVALID_PAYLOAD, - (uint8_t *)"bad utf8", 8); - goto utf8_fail; - } - - /* we are ending partway through utf-8 character? */ - if (!wsi->ws->rx_packet_length && wsi->ws->final && - wsi->ws->utf8 && !n) { - lwsl_info("FINAL utf8 error\n"); - lws_close_reason(wsi, - LWS_CLOSE_STATUS_INVALID_PAYLOAD, - (uint8_t *)"partial utf8", 12); -utf8_fail: - lwsl_notice("utf8 error\n"); - lwsl_hexdump_notice(ebuf.token, ebuf.len); - - return -1; - } - } - - if (!wsi->wsistate_pre_close && (ebuf.len >= 0 || - callback_action == LWS_CALLBACK_RECEIVE_PONG)) { - if (ebuf.len) - ebuf.token[ebuf.len] = '\0'; - - if (wsi->protocol->callback && - !(already_processed & ALREADY_PROCESSED_NO_CB)) { - if (callback_action == LWS_CALLBACK_RECEIVE_PONG) - lwsl_info("Doing pong callback\n"); - - ret = user_callback_handle_rxflow( - wsi->protocol->callback, - wsi, (enum lws_callback_reasons) - callback_action, - wsi->user_space, - ebuf.token, - ebuf.len); - } - wsi->ws->first_fragment = 0; - } - -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (!lin) - break; -#endif - -already_done: - wsi->ws->rx_ubuf_head = 0; - break; - } - - return ret; - -illegal_ctl_length: - - lwsl_warn("Control frame with xtended length is illegal\n"); - /* kill the connection */ - return -1; -} - - -LWS_VISIBLE size_t -lws_remaining_packet_payload(struct lws *wsi) -{ - return wsi->ws->rx_packet_length; -} - -LWS_VISIBLE int lws_frame_is_binary(struct lws *wsi) -{ - return wsi->ws->frame_is_binary; -} - -void -lws_add_wsi_to_draining_ext_list(struct lws *wsi) -{ -#if !defined(LWS_WITHOUT_EXTENSIONS) - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - - if (wsi->ws->rx_draining_ext) - return; - - lwsl_debug("%s: RX EXT DRAINING: Adding to list\n", __func__); - - wsi->ws->rx_draining_ext = 1; - wsi->ws->rx_draining_ext_list = pt->ws.rx_draining_ext_list; - pt->ws.rx_draining_ext_list = wsi; -#endif -} - -void -lws_remove_wsi_from_draining_ext_list(struct lws *wsi) -{ -#if !defined(LWS_WITHOUT_EXTENSIONS) - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - struct lws **w = &pt->ws.rx_draining_ext_list; - - if (!wsi->ws->rx_draining_ext) - return; - - lwsl_debug("%s: RX EXT DRAINING: Removing from list\n", __func__); - - wsi->ws->rx_draining_ext = 0; - - /* remove us from context draining ext list */ - while (*w) { - if (*w == wsi) { - /* if us, point it instead to who we were pointing to */ - *w = wsi->ws->rx_draining_ext_list; - break; - } - w = &((*w)->ws->rx_draining_ext_list); - } - wsi->ws->rx_draining_ext_list = NULL; -#endif -} - -LWS_EXTERN void -lws_restart_ws_ping_pong_timer(struct lws *wsi) -{ - if (!wsi->context->ws_ping_pong_interval || - !lwsi_role_ws(wsi)) - return; - - wsi->ws->time_next_ping_check = (time_t)lws_now_secs(); -} - -static int -lws_0405_frame_mask_generate(struct lws *wsi) -{ - int n; - /* fetch the per-frame nonce */ - - n = lws_get_random(lws_get_context(wsi), wsi->ws->mask, 4); - if (n != 4) { - lwsl_parser("Unable to read from random device %s %d\n", - SYSTEM_RANDOM_FILEPATH, n); - return 1; - } - - /* start masking from first byte of masking key buffer */ - wsi->ws->mask_idx = 0; - - return 0; -} - -int -lws_server_init_wsi_for_ws(struct lws *wsi) -{ - int n; - - lwsi_set_state(wsi, LRS_ESTABLISHED); - lws_restart_ws_ping_pong_timer(wsi); - - /* - * create the frame buffer for this connection according to the - * size mentioned in the protocol definition. If 0 there, use - * a big default for compatibility - */ - - n = (int)wsi->protocol->rx_buffer_size; - if (!n) - n = wsi->context->pt_serv_buf_size; - n += LWS_PRE; - wsi->ws->rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */, "rx_ubuf"); - if (!wsi->ws->rx_ubuf) { - lwsl_err("Out of Mem allocating rx buffer %d\n", n); - return 1; - } - wsi->ws->rx_ubuf_alloc = n; - lwsl_debug("Allocating RX buffer %d\n", n); - -#if !defined(LWS_WITH_ESP32) - if (!wsi->parent_carries_io && - !wsi->h2_stream_carries_ws) - if (setsockopt(wsi->desc.sockfd, SOL_SOCKET, SO_SNDBUF, - (const char *)&n, sizeof n)) { - lwsl_warn("Failed to set SNDBUF to %d", n); - return 1; - } -#endif - - /* notify user code that we're ready to roll */ - - if (wsi->protocol->callback) - if (wsi->protocol->callback(wsi, LWS_CALLBACK_ESTABLISHED, - wsi->user_space, -#ifdef LWS_WITH_TLS - wsi->tls.ssl, -#else - NULL, -#endif - wsi->h2_stream_carries_ws)) - return 1; - - lwsl_debug("ws established\n"); - - return 0; -} - - - -LWS_VISIBLE int -lws_is_final_fragment(struct lws *wsi) -{ -#if !defined(LWS_WITHOUT_EXTENSIONS) - lwsl_debug("%s: final %d, rx pk length %ld, draining %ld\n", __func__, - wsi->ws->final, (long)wsi->ws->rx_packet_length, - (long)wsi->ws->rx_draining_ext); - return wsi->ws->final && !wsi->ws->rx_packet_length && - !wsi->ws->rx_draining_ext; -#else - return wsi->ws->final && !wsi->ws->rx_packet_length; -#endif -} - -LWS_VISIBLE int -lws_is_first_fragment(struct lws *wsi) -{ - return wsi->ws->first_fragment; -} - -LWS_VISIBLE unsigned char -lws_get_reserved_bits(struct lws *wsi) -{ - return wsi->ws->rsv; -} - -LWS_VISIBLE LWS_EXTERN int -lws_get_close_length(struct lws *wsi) -{ - return wsi->ws->close_in_ping_buffer_len; -} - -LWS_VISIBLE LWS_EXTERN unsigned char * -lws_get_close_payload(struct lws *wsi) -{ - return &wsi->ws->ping_payload_buf[LWS_PRE]; -} - -LWS_VISIBLE LWS_EXTERN void -lws_close_reason(struct lws *wsi, enum lws_close_status status, - unsigned char *buf, size_t len) -{ - unsigned char *p, *start; - int budget = sizeof(wsi->ws->ping_payload_buf) - LWS_PRE; - - assert(lwsi_role_ws(wsi)); - - start = p = &wsi->ws->ping_payload_buf[LWS_PRE]; - - *p++ = (((int)status) >> 8) & 0xff; - *p++ = ((int)status) & 0xff; - - if (buf) - while (len-- && p < start + budget) - *p++ = *buf++; - - wsi->ws->close_in_ping_buffer_len = lws_ptr_diff(p, start); -} - -static int -lws_is_ws_with_ext(struct lws *wsi) -{ -#if defined(LWS_WITHOUT_EXTENSIONS) - return 0; -#else - return lwsi_role_ws(wsi) && !!wsi->ws->count_act_ext; -#endif -} - -static int -rops_handle_POLLIN_ws(struct lws_context_per_thread *pt, struct lws *wsi, - struct lws_pollfd *pollfd) -{ - struct lws_tokens ebuf; - unsigned int pending = 0; - char buffered = 0; - int n = 0, m; -#if defined(LWS_WITH_HTTP2) - struct lws *wsi1; -#endif - - if (!wsi->ws) { - lwsl_err("ws role wsi with no ws\n"); - return 1; - } - - // lwsl_notice("%s: %s\n", __func__, wsi->protocol->name); - - //lwsl_info("%s: wsistate 0x%x, pollout %d\n", __func__, - // wsi->wsistate, pollfd->revents & LWS_POLLOUT); - - /* - * something went wrong with parsing the handshake, and - * we ended up back in the event loop without completing it - */ - if (lwsi_state(wsi) == LRS_PRE_WS_SERVING_ACCEPT) { - wsi->socket_is_permanently_unusable = 1; - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } - - ebuf.token = NULL; - ebuf.len = 0; - - if (lwsi_state(wsi) == LRS_WAITING_CONNECT) { -#if !defined(LWS_NO_CLIENT) - if ((pollfd->revents & LWS_POLLOUT) && - lws_handle_POLLOUT_event(wsi, pollfd)) { - lwsl_debug("POLLOUT event closed it\n"); - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } - - n = lws_client_socket_service(wsi, pollfd, NULL); - if (n) - return LWS_HPI_RET_WSI_ALREADY_DIED; -#endif - return LWS_HPI_RET_HANDLED; - } - - //lwsl_notice("%s: wsi->ws->tx_draining_ext %d revents 0x%x 0x%x %d\n", __func__, wsi->ws->tx_draining_ext, pollfd->revents, wsi->wsistate, lwsi_state_can_handle_POLLOUT(wsi)); - - /* 1: something requested a callback when it was OK to write */ - - if ((pollfd->revents & LWS_POLLOUT) && - lwsi_state_can_handle_POLLOUT(wsi) && - lws_handle_POLLOUT_event(wsi, pollfd)) { - if (lwsi_state(wsi) == LRS_RETURNED_CLOSE) - lwsi_set_state(wsi, LRS_FLUSHING_BEFORE_CLOSE); - - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } - - if (lwsi_state(wsi) == LRS_RETURNED_CLOSE || - lwsi_state(wsi) == LRS_WAITING_TO_SEND_CLOSE) { - /* - * we stopped caring about anything except control - * packets. Force flow control off, defeat tx - * draining. - */ - lws_rx_flow_control(wsi, 1); -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (wsi->ws) - wsi->ws->tx_draining_ext = 0; -#endif - } -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (wsi->ws->tx_draining_ext) - /* - * We cannot deal with new RX until the TX ext path has - * been drained. It's because new rx will, eg, crap on - * the wsi rx buf that may be needed to retain state. - * - * TX ext drain path MUST go through event loop to avoid - * blocking. - */ - return LWS_HPI_RET_HANDLED; -#endif - if (lws_is_flowcontrolled(wsi)) { - /* We cannot deal with any kind of new RX because we are - * RX-flowcontrolled. - */ - lwsl_info("flowcontrolled\n"); - return LWS_HPI_RET_HANDLED; - } - -#if defined(LWS_WITH_HTTP2) - if (wsi->http2_substream || wsi->upgraded_to_http2) { - wsi1 = lws_get_network_wsi(wsi); - if (wsi1 && wsi1->trunc_len) - /* We cannot deal with any kind of new RX - * because we are dealing with a partial send - * (new RX may trigger new http_action() that - * expect to be able to send) - */ - return LWS_HPI_RET_HANDLED; - } -#endif - -#if !defined(LWS_WITHOUT_EXTENSIONS) - /* 2: RX Extension needs to be drained - */ - - if (wsi->ws->rx_draining_ext) { - - lwsl_debug("%s: RX EXT DRAINING: Service\n", __func__); -#ifndef LWS_NO_CLIENT - if (lwsi_role_client(wsi)) { - n = lws_ws_client_rx_sm(wsi, 0); - if (n < 0) - /* we closed wsi */ - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } else -#endif - n = lws_ws_rx_sm(wsi, ALREADY_PROCESSED_IGNORE_CHAR, 0); - - return LWS_HPI_RET_HANDLED; - } - - if (wsi->ws->rx_draining_ext) - /* - * We have RX EXT content to drain, but can't do it - * right now. That means we cannot do anything lower - * priority either. - */ - return LWS_HPI_RET_HANDLED; -#endif - - /* 3: buflist needs to be drained - */ -read: - //lws_buflist_describe(&wsi->buflist, wsi); - ebuf.len = (int)lws_buflist_next_segment_len(&wsi->buflist, - (uint8_t **)&ebuf.token); - if (ebuf.len) { - lwsl_info("draining buflist (len %d)\n", ebuf.len); - buffered = 1; - goto drain; - } - - if (!(pollfd->revents & pollfd->events & LWS_POLLIN) && !wsi->http.ah) - return LWS_HPI_RET_HANDLED; - - if (lws_is_flowcontrolled(wsi)) { - lwsl_info("%s: %p should be rxflow (bm 0x%x)..\n", - __func__, wsi, wsi->rxflow_bitmap); - return LWS_HPI_RET_HANDLED; - } - - if (!(lwsi_role_client(wsi) && - (lwsi_state(wsi) != LRS_ESTABLISHED && - lwsi_state(wsi) != LRS_AWAITING_CLOSE_ACK && - lwsi_state(wsi) != LRS_H2_WAITING_TO_SEND_HEADERS))) { - /* - * In case we are going to react to this rx by scheduling - * writes, we need to restrict the amount of rx to the size - * the protocol reported for rx buffer. - * - * Otherwise we get a situation we have to absorb possibly a - * lot of reads before we get a chance to drain them by writing - * them, eg, with echo type tests in autobahn. - */ - - buffered = 0; - ebuf.token = (char *)pt->serv_buf; - if (lwsi_role_ws(wsi)) - ebuf.len = wsi->ws->rx_ubuf_alloc; - else - ebuf.len = wsi->context->pt_serv_buf_size; - - if ((unsigned int)ebuf.len > wsi->context->pt_serv_buf_size) - ebuf.len = wsi->context->pt_serv_buf_size; - - if ((int)pending > ebuf.len) - pending = ebuf.len; - - ebuf.len = lws_ssl_capable_read(wsi, (uint8_t *)ebuf.token, - pending ? (int)pending : - ebuf.len); - switch (ebuf.len) { - case 0: - lwsl_info("%s: zero length read\n", - __func__); - return LWS_HPI_RET_PLEASE_CLOSE_ME; - case LWS_SSL_CAPABLE_MORE_SERVICE: - lwsl_info("SSL Capable more service\n"); - return LWS_HPI_RET_HANDLED; - case LWS_SSL_CAPABLE_ERROR: - lwsl_info("%s: LWS_SSL_CAPABLE_ERROR\n", - __func__); - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } - // lwsl_notice("Actual RX %d\n", ebuf.len); - - lws_restart_ws_ping_pong_timer(wsi); - - /* - * coverity thinks ssl_capable_read() may read over - * 2GB. Dissuade it... - */ - ebuf.len &= 0x7fffffff; - } - -drain: - - /* - * give any active extensions a chance to munge the buffer - * before parse. We pass in a pointer to an lws_tokens struct - * prepared with the default buffer and content length that's in - * there. Rather than rewrite the default buffer, extensions - * that expect to grow the buffer can adapt .token to - * point to their own per-connection buffer in the extension - * user allocation. By default with no extensions or no - * extension callback handling, just the normal input buffer is - * used then so it is efficient. - */ - m = 0; - do { - - /* service incoming data */ - //lws_buflist_describe(&wsi->buflist, wsi); - if (ebuf.len) { -#if defined(LWS_ROLE_H2) - if (lwsi_role_h2(wsi) && lwsi_state(wsi) != LRS_BODY) - n = lws_read_h2(wsi, (unsigned char *)ebuf.token, - ebuf.len); - else -#endif - n = lws_read_h1(wsi, (unsigned char *)ebuf.token, - ebuf.len); - - if (n < 0) { - /* we closed wsi */ - n = 0; - return LWS_HPI_RET_WSI_ALREADY_DIED; - } - //lws_buflist_describe(&wsi->buflist, wsi); - //lwsl_notice("%s: consuming %d / %d\n", __func__, n, ebuf.len); - if (lws_buflist_aware_consume(wsi, &ebuf, n, buffered)) - return LWS_HPI_RET_PLEASE_CLOSE_ME; - } - - ebuf.token = NULL; - ebuf.len = 0; - } while (m); - - if (wsi->http.ah -#if !defined(LWS_NO_CLIENT) - && !wsi->client_h2_alpn -#endif - ) { - lwsl_info("%s: %p: detaching ah\n", __func__, wsi); - lws_header_table_detach(wsi, 0); - } - - pending = lws_ssl_pending(wsi); - if (pending) { - if (lws_is_ws_with_ext(wsi)) - pending = pending > wsi->ws->rx_ubuf_alloc ? - wsi->ws->rx_ubuf_alloc : pending; - else - pending = pending > wsi->context->pt_serv_buf_size ? - wsi->context->pt_serv_buf_size : pending; - goto read; - } - - if (buffered && /* were draining, now nothing left */ - !lws_buflist_next_segment_len(&wsi->buflist, NULL)) { - lwsl_info("%s: %p flow buf: drained\n", __func__, wsi); - /* having drained the rxflow buffer, can rearm POLLIN */ -#ifdef LWS_NO_SERVER - n = -#endif - __lws_rx_flow_control(wsi); - /* n ignored, needed for NO_SERVER case */ - } - - /* n = 0 */ - return LWS_HPI_RET_HANDLED; -} - - -int rops_handle_POLLOUT_ws(struct lws *wsi) -{ - int write_type = LWS_WRITE_PONG; -#if !defined(LWS_WITHOUT_EXTENSIONS) - struct lws_tokens ebuf; - int ret, m; -#endif - int n; - -#if !defined(LWS_WITHOUT_EXTENSIONS) - lwsl_debug("%s: %s: wsi->ws->tx_draining_ext %d\n", __func__, - wsi->protocol->name, wsi->ws->tx_draining_ext); -#endif - - /* Priority 3: pending control packets (pong or close) - * - * 3a: close notification packet requested from close api - */ - - if (lwsi_state(wsi) == LRS_WAITING_TO_SEND_CLOSE) { - lwsl_debug("sending close packet\n"); - lwsl_hexdump_debug(&wsi->ws->ping_payload_buf[LWS_PRE], - wsi->ws->close_in_ping_buffer_len); - wsi->waiting_to_send_close_frame = 0; - n = lws_write(wsi, &wsi->ws->ping_payload_buf[LWS_PRE], - wsi->ws->close_in_ping_buffer_len, - LWS_WRITE_CLOSE); - if (n >= 0) { - if (wsi->close_needs_ack) { - lwsi_set_state(wsi, LRS_AWAITING_CLOSE_ACK); - lws_set_timeout(wsi, PENDING_TIMEOUT_CLOSE_ACK, 5); - lwsl_debug("sent close indication, awaiting ack\n"); - - return LWS_HP_RET_BAIL_OK; - } - wsi->close_needs_ack = 0; - lwsi_set_state(wsi, LRS_RETURNED_CLOSE); - } - - return LWS_HP_RET_BAIL_DIE; - } - - /* else, the send failed and we should just hang up */ - - if ((lwsi_role_ws(wsi) && wsi->ws->ping_pending_flag) || - (lwsi_state(wsi) == LRS_RETURNED_CLOSE && - wsi->ws->payload_is_close)) { - - if (wsi->ws->payload_is_close) - write_type = LWS_WRITE_CLOSE; - else { - if (wsi->wsistate_pre_close) { - /* we started close flow, forget pong */ - wsi->ws->ping_pending_flag = 0; - return LWS_HP_RET_BAIL_OK; - } - lwsl_info("issuing pong %d on wsi %p\n", wsi->ws->ping_payload_len, wsi); - } - - n = lws_write(wsi, &wsi->ws->ping_payload_buf[LWS_PRE], - wsi->ws->ping_payload_len, write_type); - if (n < 0) - return LWS_HP_RET_BAIL_DIE; - - /* well he is sent, mark him done */ - wsi->ws->ping_pending_flag = 0; - if (wsi->ws->payload_is_close) { - // assert(0); - /* oh... a close frame was it... then we are done */ - return LWS_HP_RET_BAIL_DIE; - } - - /* otherwise for PING, leave POLLOUT active either way */ - return LWS_HP_RET_BAIL_OK; - } - - if (!wsi->socket_is_permanently_unusable && wsi->ws->send_check_ping) { - - lwsl_info("issuing ping on wsi %p\n", wsi); - wsi->ws->send_check_ping = 0; - n = lws_write(wsi, &wsi->ws->ping_payload_buf[LWS_PRE], - 0, LWS_WRITE_PING); - if (n < 0) - return LWS_HP_RET_BAIL_DIE; - - /* - * we apparently were able to send the PING in a reasonable time - * now reset the clock on our peer to be able to send the - * PONG in a reasonable time. - */ - - lws_set_timeout(wsi, PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG, - wsi->context->timeout_secs); - - return LWS_HP_RET_BAIL_OK; - } - - /* Priority 4: if we are closing, not allowed to send more data frags - * which means user callback or tx ext flush banned now - */ - if (lwsi_state(wsi) == LRS_RETURNED_CLOSE) - return LWS_HP_RET_USER_SERVICE; - -#if !defined(LWS_WITHOUT_EXTENSIONS) - /* Priority 5: Tx path extension with more to send - * - * These are handled as new fragments each time around - * So while we must block new writeable callback to enforce - * payload ordering, but since they are always complete - * fragments control packets can interleave OK. - */ - if (wsi->ws->tx_draining_ext) { - lwsl_ext("SERVICING TX EXT DRAINING\n"); - if (lws_write(wsi, NULL, 0, LWS_WRITE_CONTINUATION) < 0) - return LWS_HP_RET_BAIL_DIE; - /* leave POLLOUT active */ - return LWS_HP_RET_BAIL_OK; - } - - /* Priority 6: extensions - */ - if (!wsi->ws->extension_data_pending && !wsi->ws->tx_draining_ext) { - lwsl_ext("%s: !wsi->ws->extension_data_pending\n", __func__); - return LWS_HP_RET_USER_SERVICE; - } - - /* - * check in on the active extensions, see if they - * had pending stuff to spill... they need to get the - * first look-in otherwise sequence will be disordered - * - * NULL, zero-length ebuf means just spill pending - */ - - ret = 1; - if (wsi->role_ops == &role_ops_raw_skt || - wsi->role_ops == &role_ops_raw_file) - ret = 0; - - while (ret == 1) { - - /* default to nobody has more to spill */ - - ret = 0; - ebuf.token = NULL; - ebuf.len = 0; - - /* give every extension a chance to spill */ - - m = lws_ext_cb_active(wsi, LWS_EXT_CB_PACKET_TX_PRESEND, - &ebuf, 0); - if (m < 0) { - lwsl_err("ext reports fatal error\n"); - return LWS_HP_RET_BAIL_DIE; - } - if (m) - /* - * at least one extension told us he has more - * to spill, so we will go around again after - */ - ret = 1; - - /* assuming they gave us something to send, send it */ - - if (ebuf.len) { - n = lws_issue_raw(wsi, (unsigned char *)ebuf.token, - ebuf.len); - if (n < 0) { - lwsl_info("closing from POLLOUT spill\n"); - return LWS_HP_RET_BAIL_DIE; - } - /* - * Keep amount spilled small to minimize chance of this - */ - if (n != ebuf.len) { - lwsl_err("Unable to spill ext %d vs %d\n", - ebuf.len, n); - return LWS_HP_RET_BAIL_DIE; - } - } else - continue; - - /* no extension has more to spill */ - - if (!ret) - continue; - - /* - * There's more to spill from an extension, but we just sent - * something... did that leave the pipe choked? - */ - - if (!lws_send_pipe_choked(wsi)) - /* no we could add more */ - continue; - - lwsl_info("choked in POLLOUT service\n"); - - /* - * Yes, he's choked. Leave the POLLOUT masked on so we will - * come back here when he is unchoked. Don't call the user - * callback to enforce ordering of spilling, he'll get called - * when we come back here and there's nothing more to spill. - */ - - return LWS_HP_RET_BAIL_OK; - } - - wsi->ws->extension_data_pending = 0; -#endif - - return LWS_HP_RET_USER_SERVICE; -} - -static int -rops_periodic_checks_ws(struct lws_context *context, int tsi, time_t now) -{ - struct lws_vhost *vh; - - if (!context->ws_ping_pong_interval || - context->last_ws_ping_pong_check_s >= now + 10) - return 0; - - vh = context->vhost_list; - context->last_ws_ping_pong_check_s = now; - - while (vh) { - int n; - - lws_vhost_lock(vh); - - for (n = 0; n < vh->count_protocols; n++) { - struct lws *wsi = vh->same_vh_protocol_list[n]; - - while (wsi) { - if (lwsi_role_ws(wsi) && - !wsi->socket_is_permanently_unusable && - !wsi->ws->send_check_ping && - wsi->ws->time_next_ping_check && - lws_compare_time_t(context, now, - wsi->ws->time_next_ping_check) > - context->ws_ping_pong_interval) { - - lwsl_info("req pp on wsi %p\n", wsi); - wsi->ws->send_check_ping = 1; - lws_set_timeout(wsi, - PENDING_TIMEOUT_WS_PONG_CHECK_SEND_PING, - context->timeout_secs); - lws_callback_on_writable(wsi); - wsi->ws->time_next_ping_check = now; - } - wsi = wsi->same_vh_protocol_next; - } - } - - lws_vhost_unlock(vh); - vh = vh->vhost_next; - } - - return 0; -} - -static int -rops_service_flag_pending_ws(struct lws_context *context, int tsi) -{ -#if !defined(LWS_WITHOUT_EXTENSIONS) - struct lws_context_per_thread *pt = &context->pt[tsi]; - struct lws *wsi; - int forced = 0; - - /* POLLIN faking (the pt lock is taken by the parent) */ - - /* - * 1) For all guys with already-available ext data to drain, if they are - * not flowcontrolled, fake their POLLIN status - */ - wsi = pt->ws.rx_draining_ext_list; - while (wsi && wsi->position_in_fds_table != LWS_NO_FDS_POS) { - pt->fds[wsi->position_in_fds_table].revents |= - pt->fds[wsi->position_in_fds_table].events & LWS_POLLIN; - if (pt->fds[wsi->position_in_fds_table].revents & LWS_POLLIN) - forced = 1; - - wsi = wsi->ws->rx_draining_ext_list; - } - - return forced; -#else - return 0; -#endif -} - -static int -rops_close_via_role_protocol_ws(struct lws *wsi, enum lws_close_status reason) -{ - if (!wsi->ws) - return 0; - - if (!wsi->ws->close_in_ping_buffer_len && /* already a reason */ - (reason == LWS_CLOSE_STATUS_NOSTATUS || - reason == LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY)) - return 0; - - lwsl_debug("%s: sending close indication...\n", __func__); - - /* if no prepared close reason, use 1000 and no aux data */ - - if (!wsi->ws->close_in_ping_buffer_len) { - wsi->ws->close_in_ping_buffer_len = 2; - wsi->ws->ping_payload_buf[LWS_PRE] = (reason >> 8) & 0xff; - wsi->ws->ping_payload_buf[LWS_PRE + 1] = reason & 0xff; - } - - wsi->waiting_to_send_close_frame = 1; - wsi->close_needs_ack = 1; - lwsi_set_state(wsi, LRS_WAITING_TO_SEND_CLOSE); - __lws_set_timeout(wsi, PENDING_TIMEOUT_CLOSE_SEND, 5); - - lws_callback_on_writable(wsi); - - return 1; -} - -static int -rops_close_role_ws(struct lws_context_per_thread *pt, struct lws *wsi) -{ -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (wsi->ws->rx_draining_ext) { - struct lws **w = &pt->ws.rx_draining_ext_list; - - wsi->ws->rx_draining_ext = 0; - /* remove us from context draining ext list */ - while (*w) { - if (*w == wsi) { - *w = wsi->ws->rx_draining_ext_list; - break; - } - w = &((*w)->ws->rx_draining_ext_list); - } - wsi->ws->rx_draining_ext_list = NULL; - } - - if (wsi->ws->tx_draining_ext) { - struct lws **w = &pt->ws.tx_draining_ext_list; - lwsl_ext("%s: CLEARING tx_draining_ext\n", __func__); - wsi->ws->tx_draining_ext = 0; - /* remove us from context draining ext list */ - while (*w) { - if (*w == wsi) { - *w = wsi->ws->tx_draining_ext_list; - break; - } - w = &((*w)->ws->tx_draining_ext_list); - } - wsi->ws->tx_draining_ext_list = NULL; - } -#endif - lws_free_set_NULL(wsi->ws->rx_ubuf); - - if (wsi->trunc_alloc) - /* not going to be completed... nuke it */ - lws_free_set_NULL(wsi->trunc_alloc); - - wsi->ws->ping_payload_len = 0; - wsi->ws->ping_pending_flag = 0; - - /* deallocate any active extension contexts */ - - if (lws_ext_cb_active(wsi, LWS_EXT_CB_DESTROY, NULL, 0) < 0) - lwsl_warn("extension destruction failed\n"); - - return 0; -} - -static int -rops_write_role_protocol_ws(struct lws *wsi, unsigned char *buf, size_t len, - enum lws_write_protocol *wp) -{ -#if !defined(LWS_WITHOUT_EXTENSIONS) - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - enum lws_write_protocol wpt; -#endif - int masked7 = lwsi_role_client(wsi); - unsigned char is_masked_bit = 0; - unsigned char *dropmask = NULL; - struct lws_tokens ebuf; - size_t orig_len = len; - int pre = 0, n = 0; - - // lwsl_err("%s: wp 0x%x len %d\n", __func__, *wp, (int)len); -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (wsi->ws->tx_draining_ext) { - /* remove us from the list */ - struct lws **w = &pt->ws.tx_draining_ext_list; - - lwsl_ext("%s: CLEARING tx_draining_ext\n", __func__); - wsi->ws->tx_draining_ext = 0; - /* remove us from context draining ext list */ - while (*w) { - if (*w == wsi) { - *w = wsi->ws->tx_draining_ext_list; - break; - } - w = &((*w)->ws->tx_draining_ext_list); - } - wsi->ws->tx_draining_ext_list = NULL; - - wpt = *wp; - *wp = (wsi->ws->tx_draining_stashed_wp & 0xc0)| - LWS_WRITE_CONTINUATION; - - /* - * When we are just flushing (len == 0), we can trust the - * stashed wp info completely. Otherwise adjust it to the - * FIN status of the incoming packet. - */ - - if (!(wpt & LWS_WRITE_NO_FIN) && len) - *wp &= ~LWS_WRITE_NO_FIN; - - lwsl_ext("FORCED draining wp to 0x%02X (stashed 0x%02X, incoming 0x%02X)\n", *wp, - wsi->ws->tx_draining_stashed_wp, wpt); - // assert(0); - } -#endif - lws_restart_ws_ping_pong_timer(wsi); - - if (((*wp) & 0x1f) == LWS_WRITE_HTTP || - ((*wp) & 0x1f) == LWS_WRITE_HTTP_FINAL || - ((*wp) & 0x1f) == LWS_WRITE_HTTP_HEADERS_CONTINUATION || - ((*wp) & 0x1f) == LWS_WRITE_HTTP_HEADERS) - goto send_raw; - - - - /* if we are continuing a frame that already had its header done */ - - if (wsi->ws->inside_frame) { - lwsl_debug("INSIDE FRAME\n"); - goto do_more_inside_frame; - } - - wsi->ws->clean_buffer = 1; - - /* - * give a chance to the extensions to modify payload - * the extension may decide to produce unlimited payload erratically - * (eg, compression extension), so we require only that if he produces - * something, it will be a complete fragment of the length known at - * the time (just the fragment length known), and if he has - * more we will come back next time he is writeable and allow him to - * produce more fragments until he's drained. - * - * This allows what is sent each time it is writeable to be limited to - * a size that can be sent without partial sends or blocking, allows - * interleaving of control frames and other connection service. - */ - ebuf.token = (char *)buf; - ebuf.len = (int)len; - - switch ((int)*wp) { - case LWS_WRITE_PING: - case LWS_WRITE_PONG: - case LWS_WRITE_CLOSE: - break; - default: -#if !defined(LWS_WITHOUT_EXTENSIONS) - // lwsl_notice("LWS_EXT_CB_PAYLOAD_TX\n"); - // m = (int)ebuf.len; - /* returns 0 if no more tx pending, 1 if more pending */ - n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_TX, &ebuf, *wp); - if (n < 0) - return -1; - // lwsl_notice("ext processed %d plaintext into %d compressed (wp 0x%x)\n", m, (int)ebuf.len, *wp); - - if (n && ebuf.len) { - lwsl_ext("write drain len %d (wp 0x%x) SETTING tx_draining_ext\n", (int)ebuf.len, *wp); - /* extension requires further draining */ - wsi->ws->tx_draining_ext = 1; - wsi->ws->tx_draining_ext_list = pt->ws.tx_draining_ext_list; - pt->ws.tx_draining_ext_list = wsi; - /* we must come back to do more */ - lws_callback_on_writable(wsi); - /* - * keep a copy of the write type for the overall - * action that has provoked generation of these - * fragments, so the last guy can use its FIN state. - */ - wsi->ws->tx_draining_stashed_wp = *wp; - /* this is definitely not actually the last fragment - * because the extension asserted he has more coming - * So make sure this intermediate one doesn't go out - * with a FIN. - */ - *wp |= LWS_WRITE_NO_FIN; - } -#endif - if (ebuf.len && wsi->ws->stashed_write_pending) { - wsi->ws->stashed_write_pending = 0; - *wp = ((*wp) & 0xc0) | (int)wsi->ws->stashed_write_type; - } - } - - /* - * an extension did something we need to keep... for example, if - * compression extension, it has already updated its state according - * to this being issued - */ - if ((char *)buf != ebuf.token) { - /* - * ext might eat it, but not have anything to issue yet. - * In that case we have to follow his lead, but stash and - * replace the write type that was lost here the first time. - */ - if (len && !ebuf.len) { - if (!wsi->ws->stashed_write_pending) - wsi->ws->stashed_write_type = (char)(*wp) & 0x3f; - wsi->ws->stashed_write_pending = 1; - return (int)len; - } - /* - * extension recreated it: - * need to buffer this if not all sent - */ - wsi->ws->clean_buffer = 0; - } - - buf = (unsigned char *)ebuf.token; - len = ebuf.len; - - if (!buf) { - lwsl_err("null buf (%d)\n", (int)len); - return -1; - } - - switch (wsi->ws->ietf_spec_revision) { - case 13: - if (masked7) { - pre += 4; - dropmask = &buf[0 - pre]; - is_masked_bit = 0x80; - } - - switch ((*wp) & 0xf) { - case LWS_WRITE_TEXT: - n = LWSWSOPC_TEXT_FRAME; - break; - case LWS_WRITE_BINARY: - n = LWSWSOPC_BINARY_FRAME; - break; - case LWS_WRITE_CONTINUATION: - n = LWSWSOPC_CONTINUATION; - break; - - case LWS_WRITE_CLOSE: - n = LWSWSOPC_CLOSE; - break; - case LWS_WRITE_PING: - n = LWSWSOPC_PING; - break; - case LWS_WRITE_PONG: - n = LWSWSOPC_PONG; - break; - default: - lwsl_warn("lws_write: unknown write opc / wp\n"); - return -1; - } - - if (!((*wp) & LWS_WRITE_NO_FIN)) - n |= 1 << 7; - - if (len < 126) { - pre += 2; - buf[-pre] = n; - buf[-pre + 1] = (unsigned char)(len | is_masked_bit); - } else { - if (len < 65536) { - pre += 4; - buf[-pre] = n; - buf[-pre + 1] = 126 | is_masked_bit; - buf[-pre + 2] = (unsigned char)(len >> 8); - buf[-pre + 3] = (unsigned char)len; - } else { - pre += 10; - buf[-pre] = n; - buf[-pre + 1] = 127 | is_masked_bit; -#if defined __LP64__ - buf[-pre + 2] = (len >> 56) & 0x7f; - buf[-pre + 3] = len >> 48; - buf[-pre + 4] = len >> 40; - buf[-pre + 5] = len >> 32; -#else - buf[-pre + 2] = 0; - buf[-pre + 3] = 0; - buf[-pre + 4] = 0; - buf[-pre + 5] = 0; -#endif - buf[-pre + 6] = (unsigned char)(len >> 24); - buf[-pre + 7] = (unsigned char)(len >> 16); - buf[-pre + 8] = (unsigned char)(len >> 8); - buf[-pre + 9] = (unsigned char)len; - } - } - break; - } - -do_more_inside_frame: - - /* - * Deal with masking if we are in client -> server direction and - * the wp demands it - */ - - if (masked7) { - if (!wsi->ws->inside_frame) - if (lws_0405_frame_mask_generate(wsi)) { - lwsl_err("frame mask generation failed\n"); - return -1; - } - - /* - * in v7, just mask the payload - */ - if (dropmask) { /* never set if already inside frame */ - for (n = 4; n < (int)len + 4; n++) - dropmask[n] = dropmask[n] ^ wsi->ws->mask[ - (wsi->ws->mask_idx++) & 3]; - - /* copy the frame nonce into place */ - memcpy(dropmask, wsi->ws->mask, 4); - } - } - - if (lwsi_role_h2_ENCAPSULATION(wsi)) { - struct lws *encap = lws_get_network_wsi(wsi); - - assert(encap != wsi); - return encap->role_ops->write_role_protocol(wsi, buf - pre, - len + pre, wp); - } - - switch ((*wp) & 0x1f) { - case LWS_WRITE_TEXT: - case LWS_WRITE_BINARY: - case LWS_WRITE_CONTINUATION: - if (!wsi->h2_stream_carries_ws) { - - /* - * give any active extensions a chance to munge the - * buffer before send. We pass in a pointer to an - * lws_tokens struct prepared with the default buffer - * and content length that's in there. Rather than - * rewrite the default buffer, extensions that expect - * to grow the buffer can adapt .token to point to their - * own per-connection buffer in the extension user - * allocation. By default with no extensions or no - * extension callback handling, just the normal input - * buffer is used then so it is efficient. - * - * callback returns 1 in case it wants to spill more - * buffers - * - * This takes care of holding the buffer if send is - * incomplete, ie, if wsi->ws->clean_buffer is 0 - * (meaning an extension meddled with the buffer). If - * wsi->ws->clean_buffer is 1, it will instead return - * to the user code how much OF THE USER BUFFER was - * consumed. - */ - - n = lws_issue_raw_ext_access(wsi, buf - pre, len + pre); - wsi->ws->inside_frame = 1; - if (n <= 0) - return n; - - if (n == (int)len + pre) { - /* everything in the buffer was handled - * (or rebuffered...) */ - wsi->ws->inside_frame = 0; - return (int)orig_len; - } - - /* - * it is how many bytes of user buffer got sent... may - * be < orig_len in which case callback when writable - * has already been arranged and user code can call - * lws_write() again with the rest later. - */ - - return n - pre; - } - break; - default: - break; - } - -send_raw: - return lws_issue_raw(wsi, (unsigned char *)buf - pre, len + pre); -} - -static int -rops_close_kill_connection_ws(struct lws *wsi, enum lws_close_status reason) -{ - /* deal with ws encapsulation in h2 */ -#if defined(LWS_WITH_HTTP2) - if (wsi->http2_substream && wsi->h2_stream_carries_ws) - return role_ops_h2.close_kill_connection(wsi, reason); - - return 0; -#else - return 0; -#endif -} - -static int -rops_callback_on_writable_ws(struct lws *wsi) -{ -#if defined(LWS_WITH_HTTP2) - if (lwsi_role_h2_ENCAPSULATION(wsi)) { - /* we know then that it has an h2 parent */ - struct lws *enc = role_ops_h2.encapsulation_parent(wsi); - - assert(enc); - if (enc->role_ops->callback_on_writable(wsi)) - return 1; - } -#endif - return 0; -} - -static int -rops_init_vhost_ws(struct lws_vhost *vh, - const struct lws_context_creation_info *info) -{ -#if !defined(LWS_WITHOUT_EXTENSIONS) -#ifdef LWS_WITH_PLUGINS - struct lws_plugin *plugin = vh->context->plugin_list; - int m; - - if (vh->context->plugin_extension_count) { - - m = 0; - while (info->extensions && info->extensions[m].callback) - m++; - - /* - * give the vhost a unified list of extensions including the - * ones that came from plugins - */ - vh->ws.extensions = lws_zalloc(sizeof(struct lws_extension) * - (m + vh->context->plugin_extension_count + 1), - "extensions"); - if (!vh->ws.extensions) - return 1; - - memcpy((struct lws_extension *)vh->ws.extensions, info->extensions, - sizeof(struct lws_extension) * m); - plugin = vh->context->plugin_list; - while (plugin) { - memcpy((struct lws_extension *)&vh->ws.extensions[m], - plugin->caps.extensions, - sizeof(struct lws_extension) * - plugin->caps.count_extensions); - m += plugin->caps.count_extensions; - plugin = plugin->list; - } - } else -#endif - vh->ws.extensions = info->extensions; -#endif - - return 0; -} - -static int -rops_destroy_vhost_ws(struct lws_vhost *vh) -{ -#ifdef LWS_WITH_PLUGINS -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (vh->context->plugin_extension_count) - lws_free((void *)vh->ws.extensions); -#endif -#endif - - return 0; -} - -static int -rops_destroy_role_ws(struct lws *wsi) -{ - lws_free_set_NULL(wsi->ws); - - return 0; -} - -struct lws_role_ops role_ops_ws = { - /* role name */ "ws", - /* alpn id */ NULL, - /* check_upgrades */ NULL, - /* init_context */ NULL, - /* init_vhost */ rops_init_vhost_ws, - /* destroy_vhost */ rops_destroy_vhost_ws, - /* periodic_checks */ rops_periodic_checks_ws, - /* service_flag_pending */ rops_service_flag_pending_ws, - /* handle_POLLIN */ rops_handle_POLLIN_ws, - /* handle_POLLOUT */ rops_handle_POLLOUT_ws, - /* perform_user_POLLOUT */ NULL, - /* callback_on_writable */ rops_callback_on_writable_ws, - /* tx_credit */ NULL, - /* write_role_protocol */ rops_write_role_protocol_ws, - /* encapsulation_parent */ NULL, - /* alpn_negotiated */ NULL, - /* close_via_role_protocol */ rops_close_via_role_protocol_ws, - /* close_role */ rops_close_role_ws, - /* close_kill_connection */ rops_close_kill_connection_ws, - /* destroy_role */ rops_destroy_role_ws, - /* writeable cb clnt, srv */ { LWS_CALLBACK_CLIENT_WRITEABLE, - LWS_CALLBACK_SERVER_WRITEABLE }, - /* close cb clnt, srv */ { LWS_CALLBACK_CLIENT_CLOSED, - LWS_CALLBACK_CLOSED }, - /* file handles */ 0 -}; diff --git a/thirdparty/libwebsockets/roles/ws/private.h b/thirdparty/libwebsockets/roles/ws/private.h deleted file mode 100644 index 71ffcaea96..0000000000 --- a/thirdparty/libwebsockets/roles/ws/private.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * This is included from core/private.h if LWS_ROLE_WS - */ - -extern struct lws_role_ops role_ops_ws; - -#define lwsi_role_ws(wsi) (wsi->role_ops == &role_ops_ws) - -enum lws_rx_parse_state { - LWS_RXPS_NEW, - - LWS_RXPS_04_mask_1, - LWS_RXPS_04_mask_2, - LWS_RXPS_04_mask_3, - - LWS_RXPS_04_FRAME_HDR_1, - LWS_RXPS_04_FRAME_HDR_LEN, - LWS_RXPS_04_FRAME_HDR_LEN16_2, - LWS_RXPS_04_FRAME_HDR_LEN16_1, - LWS_RXPS_04_FRAME_HDR_LEN64_8, - LWS_RXPS_04_FRAME_HDR_LEN64_7, - LWS_RXPS_04_FRAME_HDR_LEN64_6, - LWS_RXPS_04_FRAME_HDR_LEN64_5, - LWS_RXPS_04_FRAME_HDR_LEN64_4, - LWS_RXPS_04_FRAME_HDR_LEN64_3, - LWS_RXPS_04_FRAME_HDR_LEN64_2, - LWS_RXPS_04_FRAME_HDR_LEN64_1, - - LWS_RXPS_07_COLLECT_FRAME_KEY_1, - LWS_RXPS_07_COLLECT_FRAME_KEY_2, - LWS_RXPS_07_COLLECT_FRAME_KEY_3, - LWS_RXPS_07_COLLECT_FRAME_KEY_4, - - LWS_RXPS_WS_FRAME_PAYLOAD -}; - -enum lws_websocket_opcodes_07 { - LWSWSOPC_CONTINUATION = 0, - LWSWSOPC_TEXT_FRAME = 1, - LWSWSOPC_BINARY_FRAME = 2, - - LWSWSOPC_NOSPEC__MUX = 7, - - /* control extensions 8+ */ - - LWSWSOPC_CLOSE = 8, - LWSWSOPC_PING = 9, - LWSWSOPC_PONG = 0xa, -}; - -/* this is not usable directly by user code any more, lws_close_reason() */ -#define LWS_WRITE_CLOSE 4 - -#define ALREADY_PROCESSED_IGNORE_CHAR 1 -#define ALREADY_PROCESSED_NO_CB 2 - -#if !defined(LWS_WITHOUT_EXTENSIONS) -struct lws_vhost_role_ws { - const struct lws_extension *extensions; -}; - -struct lws_pt_role_ws { - struct lws *rx_draining_ext_list; - struct lws *tx_draining_ext_list; -}; -#endif - -struct _lws_websocket_related { - char *rx_ubuf; -#if !defined(LWS_WITHOUT_EXTENSIONS) - const struct lws_extension *active_extensions[LWS_MAX_EXTENSIONS_ACTIVE]; - void *act_ext_user[LWS_MAX_EXTENSIONS_ACTIVE]; - struct lws *rx_draining_ext_list; - struct lws *tx_draining_ext_list; -#endif - /* Also used for close content... control opcode == < 128 */ - uint8_t ping_payload_buf[128 - 3 + LWS_PRE]; - uint8_t mask[4]; - - time_t time_next_ping_check; - size_t rx_packet_length; - uint32_t rx_ubuf_head; - uint32_t rx_ubuf_alloc; - - uint8_t ping_payload_len; - uint8_t mask_idx; - uint8_t opcode; - uint8_t rsv; - uint8_t rsv_first_msg; - /* zero if no info, or length including 2-byte close code */ - uint8_t close_in_ping_buffer_len; - uint8_t utf8; - uint8_t stashed_write_type; - uint8_t tx_draining_stashed_wp; - uint8_t ietf_spec_revision; - - unsigned int final:1; - unsigned int frame_is_binary:1; - unsigned int all_zero_nonce:1; - unsigned int this_frame_masked:1; - unsigned int inside_frame:1; /* next write will be more of frame */ - unsigned int clean_buffer:1; /* buffer not rewritten by extension */ - unsigned int payload_is_close:1; /* process as PONG, but it is close */ - unsigned int ping_pending_flag:1; - unsigned int continuation_possible:1; - unsigned int owed_a_fin:1; - unsigned int check_utf8:1; - unsigned int defeat_check_utf8:1; - unsigned int stashed_write_pending:1; - unsigned int send_check_ping:1; - unsigned int first_fragment:1; - unsigned int peer_has_sent_close:1; -#if !defined(LWS_WITHOUT_EXTENSIONS) - unsigned int extension_data_pending:1; - unsigned int rx_draining_ext:1; - unsigned int tx_draining_ext:1; - - uint8_t count_act_ext; -#endif -}; - -int -lws_ws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len); - -#if !defined(LWS_WITHOUT_EXTENSIONS) -LWS_VISIBLE void -lws_context_init_extensions(const struct lws_context_creation_info *info, - struct lws_context *context); -LWS_EXTERN int -lws_any_extension_handled(struct lws *wsi, enum lws_extension_callback_reasons r, - void *v, size_t len); - -LWS_EXTERN int -lws_ext_cb_active(struct lws *wsi, int reason, void *buf, int len); -LWS_EXTERN int -lws_ext_cb_all_exts(struct lws_context *context, struct lws *wsi, int reason, - void *arg, int len); -#endif - -int -handshake_0405(struct lws_context *context, struct lws *wsi); -int -lws_process_ws_upgrade(struct lws *wsi); -int -lws_server_init_wsi_for_ws(struct lws *wsi); diff --git a/thirdparty/libwebsockets/roles/ws/server-ws.c b/thirdparty/libwebsockets/roles/ws/server-ws.c deleted file mode 100644 index 62bcd8524f..0000000000 --- a/thirdparty/libwebsockets/roles/ws/server-ws.c +++ /dev/null @@ -1,836 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include <core/private.h> - -#define LWS_CPYAPP(ptr, str) { strcpy(ptr, str); ptr += strlen(str); } - -#if !defined(LWS_WITHOUT_EXTENSIONS) -static int -lws_extension_server_handshake(struct lws *wsi, char **p, int budget) -{ - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - char ext_name[64], *args, *end = (*p) + budget - 1; - const struct lws_ext_options *opts, *po; - const struct lws_extension *ext; - struct lws_ext_option_arg oa; - int n, m, more = 1; - int ext_count = 0; - char ignore; - char *c; - - /* - * Figure out which extensions the client has that we want to - * enable on this connection, and give him back the list - */ - if (!lws_hdr_total_length(wsi, WSI_TOKEN_EXTENSIONS)) - return 0; - - /* - * break down the list of client extensions - * and go through them - */ - - if (lws_hdr_copy(wsi, (char *)pt->serv_buf, context->pt_serv_buf_size, - WSI_TOKEN_EXTENSIONS) < 0) - return 1; - - c = (char *)pt->serv_buf; - lwsl_parser("WSI_TOKEN_EXTENSIONS = '%s'\n", c); - wsi->ws->count_act_ext = 0; - ignore = 0; - n = 0; - args = NULL; - - /* - * We may get a simple request - * - * Sec-WebSocket-Extensions: permessage-deflate - * - * or an elaborated one with requested options - * - * Sec-WebSocket-Extensions: permessage-deflate; \ - * server_no_context_takeover; \ - * client_no_context_takeover - */ - - while (more) { - - if (c >= (char *)pt->serv_buf + 255) - return -1; - - if (*c && (*c != ',' && *c != '\t')) { - if (*c == ';') { - ignore = 1; - if (!args) - args = c + 1; - } - if (ignore || *c == ' ') { - c++; - continue; - } - ext_name[n] = *c++; - if (n < (int)sizeof(ext_name) - 1) - n++; - continue; - } - ext_name[n] = '\0'; - - ignore = 0; - if (!*c) - more = 0; - else { - c++; - if (!n) - continue; - } - - while (args && *args && *args == ' ') - args++; - - /* check a client's extension against our support */ - - ext = wsi->vhost->ws.extensions; - - while (ext && ext->callback) { - - if (strcmp(ext_name, ext->name)) { - ext++; - continue; - } - - /* - * oh, we do support this one he asked for... but let's - * confirm he only gave it once - */ - for (m = 0; m < wsi->ws->count_act_ext; m++) - if (wsi->ws->active_extensions[m] == ext) { - lwsl_info("extension mentioned twice\n"); - return 1; /* shenanigans */ - } - - /* - * ask user code if it's OK to apply it on this - * particular connection + protocol - */ - m = (wsi->protocol->callback)(wsi, - LWS_CALLBACK_CONFIRM_EXTENSION_OKAY, - wsi->user_space, ext_name, 0); - - /* - * zero return from callback means go ahead and allow - * the extension, it's what we get if the callback is - * unhandled - */ - if (m) { - ext++; - continue; - } - - /* apply it */ - - ext_count++; - - /* instantiate the extension on this conn */ - - wsi->ws->active_extensions[wsi->ws->count_act_ext] = ext; - - /* allow him to construct his context */ - - if (ext->callback(lws_get_context(wsi), ext, wsi, - LWS_EXT_CB_CONSTRUCT, - (void *)&wsi->ws->act_ext_user[ - wsi->ws->count_act_ext], - (void *)&opts, 0)) { - lwsl_info("ext %s failed construction\n", - ext_name); - ext_count--; - ext++; - - continue; - } - - if (ext_count > 1) - *(*p)++ = ','; - else - LWS_CPYAPP(*p, - "\x0d\x0aSec-WebSocket-Extensions: "); - *p += lws_snprintf(*p, (end - *p), "%s", ext_name); - - /* - * The client may send a bunch of different option - * sets for the same extension, we are supposed to - * pick one we like the look of. The option sets are - * separated by comma. - * - * Actually we just either accept the first one or - * nothing. - * - * Go through the options trying to apply the - * recognized ones - */ - - lwsl_info("ext args %s\n", args); - - while (args && *args && *args != ',') { - while (*args == ' ') - args++; - po = opts; - while (po->name) { - /* only support arg-less options... */ - if (po->type != EXTARG_NONE || - strncmp(args, po->name, - strlen(po->name))) { - po++; - continue; - } - oa.option_name = NULL; - oa.option_index = (int)(po - opts); - oa.start = NULL; - oa.len = 0; - lwsl_info("setting '%s'\n", po->name); - if (!ext->callback(lws_get_context(wsi), - ext, wsi, - LWS_EXT_CB_OPTION_SET, - wsi->ws->act_ext_user[ - wsi->ws->count_act_ext], - &oa, (end - *p))) { - - *p += lws_snprintf(*p, (end - *p), - "; %s", po->name); - lwsl_debug("adding option %s\n", - po->name); - } - po++; - } - while (*args && *args != ',' && *args != ';') - args++; - - if (*args == ';') - args++; - } - - wsi->ws->count_act_ext++; - lwsl_parser("cnt_act_ext <- %d\n", wsi->ws->count_act_ext); - - if (args && *args == ',') - more = 0; - - ext++; - } - - n = 0; - args = NULL; - } - - return 0; -} -#endif - - - -int -lws_process_ws_upgrade(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - char protocol_list[128], protocol_name[64], *p; - int protocol_len, hit, n = 0, non_space_char_found = 0; - - if (!wsi->protocol) - lwsl_err("NULL protocol at lws_read\n"); - - /* - * It's either websocket or h2->websocket - * - * Select the first protocol we support from the list - * the client sent us. - * - * Copy it to remove header fragmentation - */ - - if (lws_hdr_copy(wsi, protocol_list, sizeof(protocol_list) - 1, - WSI_TOKEN_PROTOCOL) < 0) { - lwsl_err("protocol list too long"); - return 1; - } - - protocol_len = lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL); - protocol_list[protocol_len] = '\0'; - p = protocol_list; - hit = 0; - - while (*p && !hit) { - n = 0; - non_space_char_found = 0; - while (n < (int)sizeof(protocol_name) - 1 && - *p && *p != ',') { - /* ignore leading spaces */ - if (!non_space_char_found && *p == ' ') { - n++; - continue; - } - non_space_char_found = 1; - protocol_name[n++] = *p++; - } - protocol_name[n] = '\0'; - if (*p) - p++; - - lwsl_debug("checking %s\n", protocol_name); - - n = 0; - while (wsi->vhost->protocols[n].callback) { - lwsl_debug("try %s\n", - wsi->vhost->protocols[n].name); - - if (wsi->vhost->protocols[n].name && - !strcmp(wsi->vhost->protocols[n].name, - protocol_name)) { - wsi->protocol = &wsi->vhost->protocols[n]; - hit = 1; - break; - } - - n++; - } - } - - /* we didn't find a protocol he wanted? */ - - if (!hit) { - if (lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL)) { - lwsl_notice("No protocol from \"%s\" supported\n", - protocol_list); - return 1; - } - /* - * some clients only have one protocol and - * do not send the protocol list header... - * allow it and match to the vhost's default - * protocol (which itself defaults to zero) - */ - lwsl_info("defaulting to prot handler %d\n", - wsi->vhost->default_protocol_index); - n = wsi->vhost->default_protocol_index; - wsi->protocol = &wsi->vhost->protocols[ - (int)wsi->vhost->default_protocol_index]; - } - - /* allocate the ws struct for the wsi */ - wsi->ws = lws_zalloc(sizeof(*wsi->ws), "ws struct"); - if (!wsi->ws) { - lwsl_notice("OOM\n"); - return 1; - } - - if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION)) - wsi->ws->ietf_spec_revision = - atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION)); - - /* allocate wsi->user storage */ - if (lws_ensure_user_space(wsi)) { - lwsl_notice("problem with user space\n"); - return 1; - } - - /* - * Give the user code a chance to study the request and - * have the opportunity to deny it - */ - if ((wsi->protocol->callback)(wsi, - LWS_CALLBACK_FILTER_PROTOCOL_CONNECTION, - wsi->user_space, - lws_hdr_simple_ptr(wsi, WSI_TOKEN_PROTOCOL), 0)) { - lwsl_warn("User code denied connection\n"); - return 1; - } - - /* - * Perform the handshake according to the protocol version the - * client announced - */ - - switch (wsi->ws->ietf_spec_revision) { - default: - lwsl_notice("Unknown client spec version %d\n", - wsi->ws->ietf_spec_revision); - wsi->ws->ietf_spec_revision = 13; - //return 1; - /* fallthru */ - case 13: -#if defined(LWS_WITH_HTTP2) - if (wsi->h2_stream_carries_ws) { - if (lws_h2_ws_handshake(wsi)) { - lwsl_notice("h2 ws handshake failed\n"); - return 1; - } - } else -#endif - { - lwsl_parser("lws_parse calling handshake_04\n"); - if (handshake_0405(wsi->context, wsi)) { - lwsl_notice("hs0405 has failed the connection\n"); - return 1; - } - } - break; - } - - lws_same_vh_protocol_insert(wsi, n); - - /* - * We are upgrading to ws, so http/1.1 + h2 and keepalive + pipelined - * header considerations about keeping the ah around no longer apply. - * - * However it's common for the first ws protocol data to have been - * coalesced with the browser upgrade request and to already be in the - * ah rx buffer. - */ - - lws_pt_lock(pt, __func__); - - if (wsi->h2_stream_carries_ws) - lws_role_transition(wsi, LWSIFR_SERVER | LWSIFR_P_ENCAP_H2, - LRS_ESTABLISHED, &role_ops_ws); - else - lws_role_transition(wsi, LWSIFR_SERVER, LRS_ESTABLISHED, - &role_ops_ws); - - lws_pt_unlock(pt); - - lws_server_init_wsi_for_ws(wsi); - lwsl_parser("accepted v%02d connection\n", wsi->ws->ietf_spec_revision); - - lwsl_info("%s: %p: dropping ah on ws upgrade\n", __func__, wsi); - lws_header_table_detach(wsi, 1); - - return 0; -} - -int -handshake_0405(struct lws_context *context, struct lws *wsi) -{ - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - struct lws_process_html_args args; - unsigned char hash[20]; - int n, accept_len; - char *response; - char *p; - - if (!lws_hdr_total_length(wsi, WSI_TOKEN_HOST) || - !lws_hdr_total_length(wsi, WSI_TOKEN_KEY)) { - lwsl_info("handshake_04 missing pieces\n"); - /* completed header processing, but missing some bits */ - goto bail; - } - - if (lws_hdr_total_length(wsi, WSI_TOKEN_KEY) >= MAX_WEBSOCKET_04_KEY_LEN) { - lwsl_warn("Client key too long %d\n", MAX_WEBSOCKET_04_KEY_LEN); - goto bail; - } - - /* - * since key length is restricted above (currently 128), cannot - * overflow - */ - n = sprintf((char *)pt->serv_buf, - "%s258EAFA5-E914-47DA-95CA-C5AB0DC85B11", - lws_hdr_simple_ptr(wsi, WSI_TOKEN_KEY)); - - lws_SHA1(pt->serv_buf, n, hash); - - accept_len = lws_b64_encode_string((char *)hash, 20, - (char *)pt->serv_buf, context->pt_serv_buf_size); - if (accept_len < 0) { - lwsl_warn("Base64 encoded hash too long\n"); - goto bail; - } - - /* allocate the per-connection user memory (if any) */ - if (lws_ensure_user_space(wsi)) - goto bail; - - /* create the response packet */ - - /* make a buffer big enough for everything */ - - response = (char *)pt->serv_buf + MAX_WEBSOCKET_04_KEY_LEN + 256 + LWS_PRE; - p = response; - LWS_CPYAPP(p, "HTTP/1.1 101 Switching Protocols\x0d\x0a" - "Upgrade: WebSocket\x0d\x0a" - "Connection: Upgrade\x0d\x0a" - "Sec-WebSocket-Accept: "); - strcpy(p, (char *)pt->serv_buf); - p += accept_len; - - /* we can only return the protocol header if: - * - one came in, and ... */ - if (lws_hdr_total_length(wsi, WSI_TOKEN_PROTOCOL) && - /* - it is not an empty string */ - wsi->protocol->name && - wsi->protocol->name[0]) { - LWS_CPYAPP(p, "\x0d\x0aSec-WebSocket-Protocol: "); - p += lws_snprintf(p, 128, "%s", wsi->protocol->name); - } - -#if !defined(LWS_WITHOUT_EXTENSIONS) - /* - * Figure out which extensions the client has that we want to - * enable on this connection, and give him back the list. - * - * Give him a limited write bugdet - */ - if (lws_extension_server_handshake(wsi, &p, 192)) - goto bail; -#endif - LWS_CPYAPP(p, "\x0d\x0a"); - - args.p = p; - args.max_len = lws_ptr_diff((char *)pt->serv_buf + - context->pt_serv_buf_size, p); - if (user_callback_handle_rxflow(wsi->protocol->callback, wsi, - LWS_CALLBACK_ADD_HEADERS, - wsi->user_space, &args, 0)) - goto bail; - - p = args.p; - - /* end of response packet */ - - LWS_CPYAPP(p, "\x0d\x0a"); - - /* okay send the handshake response accepting the connection */ - - lwsl_parser("issuing resp pkt %d len\n", - lws_ptr_diff(p, response)); -#if defined(DEBUG) - fwrite(response, 1, p - response, stderr); -#endif - n = lws_write(wsi, (unsigned char *)response, p - response, - LWS_WRITE_HTTP_HEADERS); - if (n != (p - response)) { - lwsl_info("%s: ERROR writing to socket %d\n", __func__, n); - goto bail; - } - - /* alright clean up and set ourselves into established state */ - - lwsi_set_state(wsi, LRS_ESTABLISHED); - wsi->lws_rx_parse_state = LWS_RXPS_NEW; - - { - const char * uri_ptr = - lws_hdr_simple_ptr(wsi, WSI_TOKEN_GET_URI); - int uri_len = lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI); - const struct lws_http_mount *hit = - lws_find_mount(wsi, uri_ptr, uri_len); - if (hit && hit->cgienv && - wsi->protocol->callback(wsi, LWS_CALLBACK_HTTP_PMO, - wsi->user_space, (void *)hit->cgienv, 0)) - return 1; - } - - return 0; - -bail: - /* caller will free up his parsing allocations */ - return -1; -} - - - -/* - * Once we reach LWS_RXPS_WS_FRAME_PAYLOAD, we know how much - * to expect in that state and can deal with it in bulk more efficiently. - */ - -static int -lws_ws_frame_rest_is_payload(struct lws *wsi, uint8_t **buf, size_t len) -{ - uint8_t *buffer = *buf, mask[4]; - struct lws_tokens ebuf; - unsigned int avail = (unsigned int)len; -#if !defined(LWS_WITHOUT_EXTENSIONS) - unsigned int old_packet_length = (int)wsi->ws->rx_packet_length; -#endif - int n = 0; - - /* - * With zlib, we can give it as much input as we like. The pmd - * extension will draw it down in chunks (default 1024). - * - * If we try to restrict how much we give it, because we must go - * back to the event loop each time, we will drop the remainder... - */ - -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (!wsi->ws->count_act_ext) -#endif - { - if (wsi->protocol->rx_buffer_size) - avail = (int)wsi->protocol->rx_buffer_size; - else - avail = wsi->context->pt_serv_buf_size; - } - - /* do not consume more than we should */ - if (avail > wsi->ws->rx_packet_length) - avail = (unsigned int)wsi->ws->rx_packet_length; - - /* do not consume more than what is in the buffer */ - if (avail > len) - avail = (unsigned int)len; - - if (avail <= 0) - return 0; - - ebuf.token = (char *)buffer; - ebuf.len = avail; - - //lwsl_hexdump_notice(ebuf.token, ebuf.len); - - if (!wsi->ws->all_zero_nonce) { - - for (n = 0; n < 4; n++) - mask[n] = wsi->ws->mask[(wsi->ws->mask_idx + n) & 3]; - - /* deal with 4-byte chunks using unwrapped loop */ - n = avail >> 2; - while (n--) { - *(buffer) = *(buffer) ^ mask[0]; - buffer++; - *(buffer) = *(buffer) ^ mask[1]; - buffer++; - *(buffer) = *(buffer) ^ mask[2]; - buffer++; - *(buffer) = *(buffer) ^ mask[3]; - buffer++; - } - /* and the remaining bytes bytewise */ - for (n = 0; n < (int)(avail & 3); n++) { - *(buffer) = *(buffer) ^ mask[n]; - buffer++; - } - - wsi->ws->mask_idx = (wsi->ws->mask_idx + avail) & 3; - } - - lwsl_info("%s: using %d of raw input (total %d on offer)\n", __func__, - avail, (int)len); - - (*buf) += avail; - len -= avail; - -#if !defined(LWS_WITHOUT_EXTENSIONS) - n = lws_ext_cb_active(wsi, LWS_EXT_CB_PAYLOAD_RX, &ebuf, 0); - lwsl_info("%s: ext says %d / ebuf.len %d\n", __func__, n, ebuf.len); -#endif - /* - * ebuf may be pointing somewhere completely different now, - * it's the output - */ - -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (n < 0) { - /* - * we may rely on this to get RX, just drop connection - */ - lwsl_notice("%s: LWS_EXT_CB_PAYLOAD_RX blew out\n", __func__); - wsi->socket_is_permanently_unusable = 1; - return -1; - } -#endif - - wsi->ws->rx_packet_length -= avail; - -#if !defined(LWS_WITHOUT_EXTENSIONS) - /* - * if we had an rx fragment right at the last compressed byte of the - * message, we can get a zero length inflated output, where no prior - * rx inflated output marked themselves with FIN, since there was - * raw ws payload still to drain at that time. - * - * Then we need to generate a zero length ws rx that can be understood - * as the message completion. - */ - - if (!ebuf.len && /* zero-length inflation output */ - !n && /* nothing left to drain from the inflator */ - wsi->ws->count_act_ext && /* we are using pmd */ - old_packet_length && /* we gave the inflator new input */ - !wsi->ws->rx_packet_length && /* raw ws packet payload all gone */ - wsi->ws->final && /* the raw ws packet is a FIN guy */ - wsi->protocol->callback && - !wsi->wsistate_pre_close) { - - if (user_callback_handle_rxflow(wsi->protocol->callback, wsi, - LWS_CALLBACK_RECEIVE, - wsi->user_space, NULL, 0)) - return -1; - - return avail; - } -#endif - - if (!ebuf.len) - return avail; - - if ( -#if !defined(LWS_WITHOUT_EXTENSIONS) - n && -#endif - ebuf.len) - /* extension had more... main loop will come back */ - lws_add_wsi_to_draining_ext_list(wsi); - else - lws_remove_wsi_from_draining_ext_list(wsi); - - if (wsi->ws->check_utf8 && !wsi->ws->defeat_check_utf8) { - if (lws_check_utf8(&wsi->ws->utf8, - (unsigned char *)ebuf.token, ebuf.len)) { - lws_close_reason(wsi, LWS_CLOSE_STATUS_INVALID_PAYLOAD, - (uint8_t *)"bad utf8", 8); - goto utf8_fail; - } - - /* we are ending partway through utf-8 character? */ - if (!wsi->ws->rx_packet_length && wsi->ws->final && - wsi->ws->utf8 && !n) { - lwsl_info("FINAL utf8 error\n"); - lws_close_reason(wsi, LWS_CLOSE_STATUS_INVALID_PAYLOAD, - (uint8_t *)"partial utf8", 12); - -utf8_fail: - lwsl_info("utf8 error\n"); - lwsl_hexdump_info(ebuf.token, ebuf.len); - - return -1; - } - } - - if (wsi->protocol->callback && !wsi->wsistate_pre_close) - if (user_callback_handle_rxflow(wsi->protocol->callback, wsi, - LWS_CALLBACK_RECEIVE, - wsi->user_space, - ebuf.token, ebuf.len)) - return -1; - - wsi->ws->first_fragment = 0; - -#if !defined(LWS_WITHOUT_EXTENSIONS) - lwsl_info("%s: input used %d, output %d, rem len %d, rx_draining_ext %d\n", - __func__, avail, ebuf.len, (int)len, wsi->ws->rx_draining_ext); -#endif - - return avail; /* how much we used from the input */ -} - - -int -lws_parse_ws(struct lws *wsi, unsigned char **buf, size_t len) -{ - int m, bulk = 0; - - lwsl_debug("%s: received %d byte packet\n", __func__, (int)len); - - //lwsl_hexdump_notice(*buf, len); - - /* let the rx protocol state machine have as much as it needs */ - - while (len) { - /* - * we were accepting input but now we stopped doing so - */ - if (wsi->rxflow_bitmap) { - lwsl_info("%s: doing rxflow\n", __func__); - lws_rxflow_cache(wsi, *buf, 0, (int)len); - lwsl_parser("%s: cached %ld\n", __func__, (long)len); - *buf += len; /* stashing it is taking care of it */ - return 1; - } -#if !defined(LWS_WITHOUT_EXTENSIONS) - if (wsi->ws->rx_draining_ext) { - lwsl_debug("%s: draining rx ext\n", __func__); - m = lws_ws_rx_sm(wsi, ALREADY_PROCESSED_IGNORE_CHAR, 0); - if (m < 0) - return -1; - continue; - } -#endif - - /* consume payload bytes efficiently */ - while (wsi->lws_rx_parse_state == LWS_RXPS_WS_FRAME_PAYLOAD && - (wsi->ws->opcode == LWSWSOPC_TEXT_FRAME || - wsi->ws->opcode == LWSWSOPC_BINARY_FRAME || - wsi->ws->opcode == LWSWSOPC_CONTINUATION) && - len) { - uint8_t *bin = *buf; - - bulk = 1; - m = lws_ws_frame_rest_is_payload(wsi, buf, len); - assert((int)lws_ptr_diff(*buf, bin) <= (int)len); - len -= lws_ptr_diff(*buf, bin); - - if (!m) { - - break; - } - if (m < 0) { - lwsl_info("%s: rest_is_payload bailed\n", - __func__); - return -1; - } - } - - if (!bulk) { - /* process the byte */ - m = lws_ws_rx_sm(wsi, 0, *(*buf)++); - len--; - } else { - /* - * We already handled this byte in bulk, just deal - * with the ramifications - */ -#if !defined(LWS_WITHOUT_EXTENSIONS) - lwsl_debug("%s: coming out of bulk with len %d, " - "wsi->ws->rx_draining_ext %d\n", - __func__, (int)len, - wsi->ws->rx_draining_ext); -#endif - m = lws_ws_rx_sm(wsi, ALREADY_PROCESSED_IGNORE_CHAR | - ALREADY_PROCESSED_NO_CB, 0); - } - - if (m < 0) { - lwsl_info("%s: lws_ws_rx_sm bailed %d\n", __func__, - bulk); - - return -1; - } - - bulk = 0; - } - - lwsl_debug("%s: exit with %d unused\n", __func__, (int)len); - - return 0; -} diff --git a/thirdparty/libwebsockets/tls/mbedtls/lws-genhash.c b/thirdparty/libwebsockets/tls/mbedtls/lws-genhash.c deleted file mode 100644 index ce4ee6e382..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/lws-genhash.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * libwebsockets - generic hash and HMAC api hiding the backend - * - * Copyright (C) 2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * lws_genhash provides a hash / hmac abstraction api in lws that works the - * same whether you are using openssl or mbedtls hash functions underneath. - */ -#include "libwebsockets.h" -#include <mbedtls/version.h> - -#if (MBEDTLS_VERSION_NUMBER >= 0x02070000) -#define MBA(fn) fn##_ret -#else -#define MBA(fn) fn -#endif - -size_t -lws_genhash_size(enum lws_genhash_types type) -{ - switch(type) { - case LWS_GENHASH_TYPE_SHA1: - return 20; - case LWS_GENHASH_TYPE_SHA256: - return 32; - case LWS_GENHASH_TYPE_SHA384: - return 48; - case LWS_GENHASH_TYPE_SHA512: - return 64; - } - - return 0; -} - -int -lws_genhash_init(struct lws_genhash_ctx *ctx, enum lws_genhash_types type) -{ - ctx->type = type; - - switch (ctx->type) { - case LWS_GENHASH_TYPE_SHA1: - mbedtls_sha1_init(&ctx->u.sha1); - MBA(mbedtls_sha1_starts)(&ctx->u.sha1); - break; - case LWS_GENHASH_TYPE_SHA256: - mbedtls_sha256_init(&ctx->u.sha256); - MBA(mbedtls_sha256_starts)(&ctx->u.sha256, 0); - break; - case LWS_GENHASH_TYPE_SHA384: - mbedtls_sha512_init(&ctx->u.sha512); - MBA(mbedtls_sha512_starts)(&ctx->u.sha512, 1 /* is384 */); - break; - case LWS_GENHASH_TYPE_SHA512: - mbedtls_sha512_init(&ctx->u.sha512); - MBA(mbedtls_sha512_starts)(&ctx->u.sha512, 0); - break; - default: - return 1; - } - - return 0; -} - -int -lws_genhash_update(struct lws_genhash_ctx *ctx, const void *in, size_t len) -{ - switch (ctx->type) { - case LWS_GENHASH_TYPE_SHA1: - MBA(mbedtls_sha1_update)(&ctx->u.sha1, in, len); - break; - case LWS_GENHASH_TYPE_SHA256: - MBA(mbedtls_sha256_update)(&ctx->u.sha256, in, len); - break; - case LWS_GENHASH_TYPE_SHA384: - MBA(mbedtls_sha512_update)(&ctx->u.sha512, in, len); - break; - case LWS_GENHASH_TYPE_SHA512: - MBA(mbedtls_sha512_update)(&ctx->u.sha512, in, len); - break; - } - - return 0; -} - -int -lws_genhash_destroy(struct lws_genhash_ctx *ctx, void *result) -{ - switch (ctx->type) { - case LWS_GENHASH_TYPE_SHA1: - MBA(mbedtls_sha1_finish)(&ctx->u.sha1, result); - mbedtls_sha1_free(&ctx->u.sha1); - break; - case LWS_GENHASH_TYPE_SHA256: - MBA(mbedtls_sha256_finish)(&ctx->u.sha256, result); - mbedtls_sha256_free(&ctx->u.sha256); - break; - case LWS_GENHASH_TYPE_SHA384: - MBA(mbedtls_sha512_finish)(&ctx->u.sha512, result); - mbedtls_sha512_free(&ctx->u.sha512); - break; - case LWS_GENHASH_TYPE_SHA512: - MBA(mbedtls_sha512_finish)(&ctx->u.sha512, result); - mbedtls_sha512_free(&ctx->u.sha512); - break; - } - - return 0; -} - -size_t -lws_genhmac_size(enum lws_genhmac_types type) -{ - switch(type) { - case LWS_GENHMAC_TYPE_SHA256: - return 32; - case LWS_GENHMAC_TYPE_SHA384: - return 48; - case LWS_GENHMAC_TYPE_SHA512: - return 64; - } - - return 0; -} - -int -lws_genhmac_init(struct lws_genhmac_ctx *ctx, enum lws_genhmac_types type, - const uint8_t *key, size_t key_len) -{ - int t; - - ctx->type = type; - - switch (type) { - case LWS_GENHMAC_TYPE_SHA256: - t = MBEDTLS_MD_SHA256; - break; - case LWS_GENHMAC_TYPE_SHA384: - t = MBEDTLS_MD_SHA384; - break; - case LWS_GENHMAC_TYPE_SHA512: - t = MBEDTLS_MD_SHA512; - break; - default: - return -1; - } - - ctx->hmac = mbedtls_md_info_from_type(t); - if (!ctx->hmac) - return -1; - - if (mbedtls_md_init_ctx(&ctx->ctx, ctx->hmac)) - return -1; - - if (mbedtls_md_hmac_starts(&ctx->ctx, key, key_len)) { - mbedtls_md_free(&ctx->ctx); - ctx->hmac = NULL; - - return -1; - } - - return 0; -} - -int -lws_genhmac_update(struct lws_genhmac_ctx *ctx, const void *in, size_t len) -{ - if (mbedtls_md_hmac_update(&ctx->ctx, in, len)) - return -1; - - return 0; -} - -int -lws_genhmac_destroy(struct lws_genhmac_ctx *ctx, void *result) -{ - int n = 0; - - if (result) - n = mbedtls_md_hmac_finish(&ctx->ctx, result); - - mbedtls_md_free(&ctx->ctx); - ctx->hmac = NULL; - if (n) - return -1; - - return 0; -} diff --git a/thirdparty/libwebsockets/tls/mbedtls/lws-genrsa.c b/thirdparty/libwebsockets/tls/mbedtls/lws-genrsa.c deleted file mode 100644 index 70a9fcf42c..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/lws-genrsa.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * libwebsockets - generic RSA api hiding the backend - * - * Copyright (C) 2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * lws_genhash provides a hash / hmac abstraction api in lws that works the - * same whether you are using openssl or mbedtls hash functions underneath. - */ -#include "core/private.h" - -LWS_VISIBLE void -lws_jwk_destroy_genrsa_elements(struct lws_genrsa_elements *el) -{ - int n; - - for (n = 0; n < LWS_COUNT_RSA_ELEMENTS; n++) - if (el->e[n].buf) - lws_free_set_NULL(el->e[n].buf); -} - -LWS_VISIBLE int -lws_genrsa_create(struct lws_genrsa_ctx *ctx, struct lws_genrsa_elements *el) -{ - int n; - - memset(ctx, 0, sizeof(*ctx)); - ctx->ctx = lws_zalloc(sizeof(*ctx->ctx), "genrsa"); - if (!ctx->ctx) - return 1; - - mbedtls_rsa_init(ctx->ctx, MBEDTLS_RSA_PKCS_V15, 0); - - { - mbedtls_mpi *mpi[LWS_COUNT_RSA_ELEMENTS] = { - &ctx->ctx->E, &ctx->ctx->N, &ctx->ctx->D, &ctx->ctx->P, - &ctx->ctx->Q, &ctx->ctx->DP, &ctx->ctx->DQ, - &ctx->ctx->QP, - }; - - for (n = 0; n < LWS_COUNT_RSA_ELEMENTS; n++) - if (el->e[n].buf && - mbedtls_mpi_read_binary(mpi[n], el->e[n].buf, - el->e[n].len)) { - lwsl_notice("mpi load failed\n"); - lws_free_set_NULL(ctx->ctx); - - return -1; - } - } - - ctx->ctx->len = el->e[JWK_KEY_N].len; - - return 0; -} - -static int -_rngf(void *context, unsigned char *buf, size_t len) -{ - if ((size_t)lws_get_random(context, buf, len) == len) - return 0; - - return -1; -} - -LWS_VISIBLE int -lws_genrsa_new_keypair(struct lws_context *context, struct lws_genrsa_ctx *ctx, - struct lws_genrsa_elements *el, int bits) -{ - int n; - - memset(ctx, 0, sizeof(*ctx)); - ctx->ctx = lws_zalloc(sizeof(*ctx->ctx), "genrsa"); - if (!ctx->ctx) - return -1; - - mbedtls_rsa_init(ctx->ctx, MBEDTLS_RSA_PKCS_V15, 0); - - n = mbedtls_rsa_gen_key(ctx->ctx, _rngf, context, bits, 65537); - if (n) { - lwsl_err("mbedtls_rsa_gen_key failed 0x%x\n", -n); - goto cleanup_1; - } - - { - mbedtls_mpi *mpi[LWS_COUNT_RSA_ELEMENTS] = { - &ctx->ctx->E, &ctx->ctx->N, &ctx->ctx->D, &ctx->ctx->P, - &ctx->ctx->Q, &ctx->ctx->DP, &ctx->ctx->DQ, - &ctx->ctx->QP, - }; - - for (n = 0; n < LWS_COUNT_RSA_ELEMENTS; n++) - if (mbedtls_mpi_size(mpi[n])) { - el->e[n].buf = lws_malloc( - mbedtls_mpi_size(mpi[n]), "genrsakey"); - if (!el->e[n].buf) - goto cleanup; - el->e[n].len = mbedtls_mpi_size(mpi[n]); - mbedtls_mpi_write_binary(mpi[n], el->e[n].buf, - el->e[n].len); - } - } - - return 0; - -cleanup: - for (n = 0; n < LWS_COUNT_RSA_ELEMENTS; n++) - if (el->e[n].buf) - lws_free_set_NULL(el->e[n].buf); -cleanup_1: - lws_free(ctx->ctx); - - return -1; -} - -LWS_VISIBLE int -lws_genrsa_public_decrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in, - size_t in_len, uint8_t *out, size_t out_max) -{ - size_t olen = 0; - int n; - - ctx->ctx->len = in_len; - n = mbedtls_rsa_rsaes_pkcs1_v15_decrypt(ctx->ctx, NULL, NULL, - MBEDTLS_RSA_PUBLIC, - &olen, in, out, out_max); - if (n) { - lwsl_notice("%s: -0x%x\n", __func__, -n); - - return -1; - } - - return olen; -} - -LWS_VISIBLE int -lws_genrsa_public_encrypt(struct lws_genrsa_ctx *ctx, const uint8_t *in, - size_t in_len, uint8_t *out) -{ - int n; - - ctx->ctx->len = in_len; - n = mbedtls_rsa_rsaes_pkcs1_v15_encrypt(ctx->ctx, NULL, NULL, - MBEDTLS_RSA_PRIVATE, - in_len, in, out); - if (n) { - lwsl_notice("%s: -0x%x\n", __func__, -n); - - return -1; - } - - return 0; -} - -static int -lws_genrsa_genrsa_hash_to_mbed_hash(enum lws_genhash_types hash_type) -{ - int h = -1; - - switch (hash_type) { - case LWS_GENHASH_TYPE_SHA1: - h = MBEDTLS_MD_SHA1; - break; - case LWS_GENHASH_TYPE_SHA256: - h = MBEDTLS_MD_SHA256; - break; - case LWS_GENHASH_TYPE_SHA384: - h = MBEDTLS_MD_SHA384; - break; - case LWS_GENHASH_TYPE_SHA512: - h = MBEDTLS_MD_SHA512; - break; - } - - return h; -} - -LWS_VISIBLE int -lws_genrsa_public_verify(struct lws_genrsa_ctx *ctx, const uint8_t *in, - enum lws_genhash_types hash_type, const uint8_t *sig, - size_t sig_len) -{ - int n, h = lws_genrsa_genrsa_hash_to_mbed_hash(hash_type); - - if (h < 0) - return -1; - - n = mbedtls_rsa_rsassa_pkcs1_v15_verify(ctx->ctx, NULL, NULL, - MBEDTLS_RSA_PUBLIC, - h, 0, in, sig); - if (n < 0) { - lwsl_notice("%s: -0x%x\n", __func__, -n); - - return -1; - } - - return n; -} - -LWS_VISIBLE int -lws_genrsa_public_sign(struct lws_genrsa_ctx *ctx, const uint8_t *in, - enum lws_genhash_types hash_type, uint8_t *sig, - size_t sig_len) -{ - int n, h = lws_genrsa_genrsa_hash_to_mbed_hash(hash_type); - - if (h < 0) - return -1; - - /* - * The "sig" buffer must be as large as the size of ctx->N - * (eg. 128 bytes if RSA-1024 is used). - */ - if (sig_len < ctx->ctx->len) - return -1; - - n = mbedtls_rsa_rsassa_pkcs1_v15_sign(ctx->ctx, NULL, NULL, - MBEDTLS_RSA_PRIVATE, h, 0, in, - sig); - if (n < 0) { - lwsl_notice("%s: -0x%x\n", __func__, -n); - - return -1; - } - - return ctx->ctx->len; -} - -LWS_VISIBLE int -lws_genrsa_render_pkey_asn1(struct lws_genrsa_ctx *ctx, int _private, - uint8_t *pkey_asn1, size_t pkey_asn1_len) -{ - uint8_t *p = pkey_asn1, *totlen, *end = pkey_asn1 + pkey_asn1_len - 1; - mbedtls_mpi *mpi[LWS_COUNT_RSA_ELEMENTS] = { - &ctx->ctx->N, &ctx->ctx->E, &ctx->ctx->D, &ctx->ctx->P, - &ctx->ctx->Q, &ctx->ctx->DP, &ctx->ctx->DQ, - &ctx->ctx->QP, - }; - int n; - - /* 30 82 - sequence - * 09 29 <-- length(0x0929) less 4 bytes - * 02 01 <- length (1) - * 00 - * 02 82 - * 02 01 <- length (513) N - * ... - * - * 02 03 <- length (3) E - * 01 00 01 - * - * 02 82 - * 02 00 <- length (512) D P Q EXP1 EXP2 COEFF - * - * */ - - *p++ = 0x30; - *p++ = 0x82; - totlen = p; - p += 2; - - *p++ = 0x02; - *p++ = 0x01; - *p++ = 0x00; - - for (n = 0; n < LWS_COUNT_RSA_ELEMENTS; n++) { - int m = mbedtls_mpi_size(mpi[n]); - uint8_t *elen; - - *p++ = 0x02; - elen = p; - if (m < 0x7f) - *p++ = m; - else { - *p++ = 0x82; - *p++ = m >> 8; - *p++ = m & 0xff; - } - - if (p + m > end) - return -1; - - mbedtls_mpi_write_binary(mpi[n], p, m); - if (p[0] & 0x80) { - p[0] = 0x00; - mbedtls_mpi_write_binary(mpi[n], &p[1], m); - m++; - } - if (m < 0x7f) - *elen = m; - else { - *elen++ = 0x82; - *elen++ = m >> 8; - *elen = m & 0xff; - } - p += m; - } - - n = lws_ptr_diff(p, pkey_asn1); - - *totlen++ = (n - 4) >> 8; - *totlen = (n - 4) & 0xff; - - return n; -} - -LWS_VISIBLE void -lws_genrsa_destroy(struct lws_genrsa_ctx *ctx) -{ - if (!ctx->ctx) - return; - mbedtls_rsa_free(ctx->ctx); - lws_free(ctx->ctx); - ctx->ctx = NULL; -} diff --git a/thirdparty/libwebsockets/tls/mbedtls/mbedtls-client.c b/thirdparty/libwebsockets/tls/mbedtls/mbedtls-client.c deleted file mode 100644 index a7864ab790..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/mbedtls-client.c +++ /dev/null @@ -1,240 +0,0 @@ -/* - * libwebsockets - mbedtls-specific client TLS code - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -static int -OpenSSL_client_verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) -{ - return 0; -} - -int -lws_ssl_client_bio_create(struct lws *wsi) -{ - X509_VERIFY_PARAM *param; - char hostname[128], *p; - const char *alpn_comma = wsi->context->tls.alpn_default; - struct alpn_ctx protos; - - if (lws_hdr_copy(wsi, hostname, sizeof(hostname), - _WSI_TOKEN_CLIENT_HOST) <= 0) { - lwsl_err("%s: Unable to get hostname\n", __func__); - - return -1; - } - - /* - * remove any :port part on the hostname... necessary for network - * connection but typical certificates do not contain it - */ - p = hostname; - while (*p) { - if (*p == ':') { - *p = '\0'; - break; - } - p++; - } - - wsi->tls.ssl = SSL_new(wsi->vhost->tls.ssl_client_ctx); - if (!wsi->tls.ssl) - return -1; - - if (wsi->vhost->tls.ssl_info_event_mask) - SSL_set_info_callback(wsi->tls.ssl, lws_ssl_info_callback); - - if (!(wsi->tls.use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) { - param = SSL_get0_param(wsi->tls.ssl); - /* Enable automatic hostname checks */ - // X509_VERIFY_PARAM_set_hostflags(param, - // X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); - X509_VERIFY_PARAM_set1_host(param, hostname, 0); - } - - if (wsi->vhost->tls.alpn) - alpn_comma = wsi->vhost->tls.alpn; - - if (lws_hdr_copy(wsi, hostname, sizeof(hostname), - _WSI_TOKEN_CLIENT_ALPN) > 0) - alpn_comma = hostname; - - lwsl_info("%s: %p: client conn sending ALPN list '%s'\n", - __func__, wsi, alpn_comma); - - protos.len = lws_alpn_comma_to_openssl(alpn_comma, protos.data, - sizeof(protos.data) - 1); - - /* with mbedtls, protos is not pointed to after exit from this call */ - SSL_set_alpn_select_cb(wsi->tls.ssl, &protos); - - /* - * use server name indication (SNI), if supported, - * when establishing connection - */ - SSL_set_verify(wsi->tls.ssl, SSL_VERIFY_PEER, - OpenSSL_client_verify_callback); - - SSL_set_fd(wsi->tls.ssl, wsi->desc.sockfd); - - return 0; -} - -int ERR_get_error(void) -{ - return 0; -} - -enum lws_ssl_capable_status -lws_tls_client_connect(struct lws *wsi) -{ - int m, n = SSL_connect(wsi->tls.ssl); - const unsigned char *prot; - unsigned int len; - - if (n == 1) { - SSL_get0_alpn_selected(wsi->tls.ssl, &prot, &len); - lws_role_call_alpn_negotiated(wsi, (const char *)prot); - lwsl_info("client connect OK\n"); - return LWS_SSL_CAPABLE_DONE; - } - - m = SSL_get_error(wsi->tls.ssl, n); - - if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) - return LWS_SSL_CAPABLE_MORE_SERVICE_READ; - - if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) - return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE; - - if (!n) /* we don't know what he wants, but he says to retry */ - return LWS_SSL_CAPABLE_MORE_SERVICE; - - return LWS_SSL_CAPABLE_ERROR; -} - -int -lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len) -{ - int n; - X509 *peer = SSL_get_peer_certificate(wsi->tls.ssl); - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - char *sb = (char *)&pt->serv_buf[0]; - - if (!peer) { - lwsl_info("peer did not provide cert\n"); - - return -1; - } - lwsl_info("peer provided cert\n"); - - n = SSL_get_verify_result(wsi->tls.ssl); - lws_latency(wsi->context, wsi, - "SSL_get_verify_result LWS_CONNMODE..HANDSHAKE", n, n > 0); - - lwsl_debug("get_verify says %d\n", n); - - if (n == X509_V_OK) - return 0; - - if (n == X509_V_ERR_HOSTNAME_MISMATCH && - (wsi->tls.use_ssl & LCCSCF_SKIP_SERVER_CERT_HOSTNAME_CHECK)) { - lwsl_info("accepting certificate for invalid hostname\n"); - return 0; - } - - if (n == X509_V_ERR_INVALID_CA && - (wsi->tls.use_ssl & LCCSCF_ALLOW_SELFSIGNED)) { - lwsl_info("accepting certificate from untrusted CA\n"); - return 0; - } - - if ((n == X509_V_ERR_CERT_NOT_YET_VALID || - n == X509_V_ERR_CERT_HAS_EXPIRED) && - (wsi->tls.use_ssl & LCCSCF_ALLOW_EXPIRED)) { - lwsl_info("accepting expired or not yet valid certificate\n"); - - return 0; - } - lws_snprintf(ebuf, ebuf_len, - "server's cert didn't look good, X509_V_ERR = %d: %s\n", - n, ERR_error_string(n, sb)); - lwsl_info("%s\n", ebuf); - lws_ssl_elaborate_error(); - - return -1; -} - -int -lws_tls_client_create_vhost_context(struct lws_vhost *vh, - const struct lws_context_creation_info *info, - const char *cipher_list, - const char *ca_filepath, - const char *cert_filepath, - const char *private_key_filepath) -{ - X509 *d2i_X509(X509 **cert, const unsigned char *buffer, long len); - SSL_METHOD *method = (SSL_METHOD *)TLS_client_method(); - unsigned long error; - lws_filepos_t len; - uint8_t *buf; - - if (!method) { - error = ERR_get_error(); - lwsl_err("problem creating ssl method %lu: %s\n", - error, ERR_error_string(error, - (char *)vh->context->pt[0].serv_buf)); - return 1; - } - /* create context */ - vh->tls.ssl_client_ctx = SSL_CTX_new(method); - if (!vh->tls.ssl_client_ctx) { - error = ERR_get_error(); - lwsl_err("problem creating ssl context %lu: %s\n", - error, ERR_error_string(error, - (char *)vh->context->pt[0].serv_buf)); - return 1; - } - - if (!ca_filepath) - return 0; - - if (alloc_file(vh->context, ca_filepath, &buf, &len)) { - lwsl_err("Load CA cert file %s failed\n", ca_filepath); - return 1; - } - - vh->tls.x509_client_CA = d2i_X509(NULL, buf, len); - free(buf); - if (!vh->tls.x509_client_CA) { - lwsl_err("client CA: x509 parse failed\n"); - return 1; - } - - if (!vh->tls.ssl_ctx) - SSL_CTX_add_client_CA(vh->tls.ssl_client_ctx, vh->tls.x509_client_CA); - else - SSL_CTX_add_client_CA(vh->tls.ssl_ctx, vh->tls.x509_client_CA); - - lwsl_notice("client loaded CA for verification %s\n", ca_filepath); - - return 0; -} diff --git a/thirdparty/libwebsockets/tls/mbedtls/mbedtls-server.c b/thirdparty/libwebsockets/tls/mbedtls/mbedtls-server.c deleted file mode 100644 index f17c7e5494..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/mbedtls-server.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - * libwebsockets - mbedTLS-specific server functions - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" -#include <mbedtls/x509_csr.h> - -int -lws_tls_server_client_cert_verify_config(struct lws_vhost *vh) -{ - int verify_options = SSL_VERIFY_PEER; - - /* as a server, are we requiring clients to identify themselves? */ - if (!lws_check_opt(vh->options, - LWS_SERVER_OPTION_REQUIRE_VALID_OPENSSL_CLIENT_CERT)) { - lwsl_notice("no client cert required\n"); - return 0; - } - - /* - * The wrapper has this messed-up mapping: - * - * else if (ctx->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT) - * mode = MBEDTLS_SSL_VERIFY_OPTIONAL; - * - * ie the meaning is inverted. So where we should test for ! we don't - */ - if (lws_check_opt(vh->options, LWS_SERVER_OPTION_PEER_CERT_NOT_REQUIRED)) - verify_options = SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - - lwsl_notice("%s: vh %s requires client cert %d\n", __func__, vh->name, - verify_options); - - SSL_CTX_set_verify(vh->tls.ssl_ctx, verify_options, NULL); - - return 0; -} - -static int -lws_mbedtls_sni_cb(void *arg, mbedtls_ssl_context *mbedtls_ctx, - const unsigned char *servername, size_t len) -{ - SSL *ssl = SSL_SSL_from_mbedtls_ssl_context(mbedtls_ctx); - struct lws_context *context = (struct lws_context *)arg; - struct lws_vhost *vhost, *vh; - - lwsl_notice("%s: %s\n", __func__, servername); - - /* - * We can only get ssl accepted connections by using a vhost's ssl_ctx - * find out which listening one took us and only match vhosts on the - * same port. - */ - vh = context->vhost_list; - while (vh) { - if (!vh->being_destroyed && - vh->tls.ssl_ctx == SSL_get_SSL_CTX(ssl)) - break; - vh = vh->vhost_next; - } - - if (!vh) { - assert(vh); /* can't match the incoming vh? */ - return 0; - } - - vhost = lws_select_vhost(context, vh->listen_port, - (const char *)servername); - if (!vhost) { - lwsl_info("SNI: none: %s:%d\n", servername, vh->listen_port); - - return 0; - } - - lwsl_info("SNI: Found: %s:%d at vhost '%s'\n", servername, - vh->listen_port, vhost->name); - - /* select the ssl ctx from the selected vhost for this conn */ - SSL_set_SSL_CTX(ssl, vhost->tls.ssl_ctx); - - return 0; -} - -int -lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi, - const char *cert, const char *private_key, - const char *mem_cert, size_t len_mem_cert, - const char *mem_privkey, size_t mem_privkey_len) -{ - int n, f = 0; - const char *filepath = private_key; - uint8_t *mem = NULL, *p = NULL; - size_t mem_len = 0; - lws_filepos_t flen; - long err; - - if ((!cert || !private_key) && (!mem_cert || !mem_privkey)) { - lwsl_notice("%s: no usable input\n", __func__); - return 0; - } - - n = lws_tls_generic_cert_checks(vhost, cert, private_key); - - if (n == LWS_TLS_EXTANT_NO && (!mem_cert || !mem_privkey)) - return 0; - - /* - * we can't read the root-privs files. But if mem_cert is provided, - * we should use that. - */ - if (n == LWS_TLS_EXTANT_NO) - n = LWS_TLS_EXTANT_ALTERNATIVE; - - if (n == LWS_TLS_EXTANT_ALTERNATIVE && (!mem_cert || !mem_privkey)) - return 1; /* no alternative */ - - if (n == LWS_TLS_EXTANT_ALTERNATIVE) { - /* - * Although we have prepared update certs, we no longer have - * the rights to read our own cert + key we saved. - * - * If we were passed copies in memory buffers, use those - * instead. - * - * The passed memory-buffer cert image is in DER, and the - * memory-buffer private key image is PEM. - */ - /* mem cert is already DER */ - p = (uint8_t *)mem_cert; - flen = len_mem_cert; - /* mem private key is PEM, so go through the motions */ - mem = (uint8_t *)mem_privkey; - mem_len = mem_privkey_len; - filepath = NULL; - } else { - if (lws_tls_alloc_pem_to_der_file(vhost->context, cert, NULL, - 0, &p, &flen)) { - lwsl_err("couldn't find cert file %s\n", cert); - - return 1; - } - f = 1; - } - err = SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx, flen, p); - if (!err) { - free(p); - lwsl_err("Problem loading cert\n"); - return 1; - } - - if (f) - free(p); - p = NULL; - - if (private_key || n == LWS_TLS_EXTANT_ALTERNATIVE) { - if (lws_tls_alloc_pem_to_der_file(vhost->context, filepath, - (char *)mem, mem_len, &p, - &flen)) { - lwsl_err("couldn't find private key file %s\n", - private_key); - - return 1; - } - err = SSL_CTX_use_PrivateKey_ASN1(0, vhost->tls.ssl_ctx, p, flen); - if (!err) { - free(p); - lwsl_err("Problem loading key\n"); - - return 1; - } - } - - if (p && !mem_privkey) { - free(p); - p = NULL; - } - - if (!private_key && !mem_privkey && - vhost->protocols[0].callback(wsi, - LWS_CALLBACK_OPENSSL_CONTEXT_REQUIRES_PRIVATE_KEY, - vhost->tls.ssl_ctx, NULL, 0)) { - lwsl_err("ssl private key not set\n"); - - return 1; - } - - vhost->tls.skipped_certs = 0; - - return 0; -} - -int -lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info, - struct lws_vhost *vhost, struct lws *wsi) -{ - const SSL_METHOD *method = TLS_server_method(); - uint8_t *p; - lws_filepos_t flen; - int n; - - vhost->tls.ssl_ctx = SSL_CTX_new(method); /* create context */ - if (!vhost->tls.ssl_ctx) { - lwsl_err("problem creating ssl context\n"); - return 1; - } - - if (!vhost->tls.use_ssl || !info->ssl_cert_filepath) - return 0; - - if (info->ssl_ca_filepath) { - lwsl_notice("%s: vh %s: loading CA filepath %s\n", __func__, - vhost->name, info->ssl_ca_filepath); - if (lws_tls_alloc_pem_to_der_file(vhost->context, - info->ssl_ca_filepath, NULL, 0, &p, &flen)) { - lwsl_err("couldn't find client CA file %s\n", - info->ssl_ca_filepath); - - return 1; - } - - if (SSL_CTX_add_client_CA_ASN1(vhost->tls.ssl_ctx, (int)flen, p) != 1) { - lwsl_err("%s: SSL_CTX_add_client_CA_ASN1 unhappy\n", - __func__); - free(p); - return 1; - } - free(p); - } - - n = lws_tls_server_certs_load(vhost, wsi, info->ssl_cert_filepath, - info->ssl_private_key_filepath, NULL, - 0, NULL, 0); - if (n) - return n; - - return 0; -} - -int -lws_tls_server_new_nonblocking(struct lws *wsi, lws_sockfd_type accept_fd) -{ - errno = 0; - wsi->tls.ssl = SSL_new(wsi->vhost->tls.ssl_ctx); - if (wsi->tls.ssl == NULL) { - lwsl_err("SSL_new failed: errno %d\n", errno); - - lws_ssl_elaborate_error(); - return 1; - } - - SSL_set_fd(wsi->tls.ssl, accept_fd); - - if (wsi->vhost->tls.ssl_info_event_mask) - SSL_set_info_callback(wsi->tls.ssl, lws_ssl_info_callback); - - SSL_set_sni_callback(wsi->tls.ssl, lws_mbedtls_sni_cb, wsi->context); - - return 0; -} - -int -lws_tls_server_abort_connection(struct lws *wsi) -{ - __lws_tls_shutdown(wsi); - SSL_free(wsi->tls.ssl); - - return 0; -} - -enum lws_ssl_capable_status -lws_tls_server_accept(struct lws *wsi) -{ - union lws_tls_cert_info_results ir; - int m, n; - - n = SSL_accept(wsi->tls.ssl); - if (n == 1) { - - if (strstr(wsi->vhost->name, ".invalid")) { - lwsl_notice("%s: vhost has .invalid, rejecting accept\n", __func__); - - return LWS_SSL_CAPABLE_ERROR; - } - - n = lws_tls_peer_cert_info(wsi, LWS_TLS_CERT_INFO_COMMON_NAME, &ir, - sizeof(ir.ns.name)); - if (!n) - lwsl_notice("%s: client cert CN '%s'\n", - __func__, ir.ns.name); - else - lwsl_info("%s: couldn't get client cert CN\n", __func__); - return LWS_SSL_CAPABLE_DONE; - } - - m = SSL_get_error(wsi->tls.ssl, n); - lwsl_debug("%s: %p: accept SSL_get_error %d errno %d\n", __func__, - wsi, m, errno); - - // mbedtls wrapper only - if (m == SSL_ERROR_SYSCALL && errno == 11) - return LWS_SSL_CAPABLE_MORE_SERVICE_READ; - - if (m == SSL_ERROR_SYSCALL || m == SSL_ERROR_SSL) - return LWS_SSL_CAPABLE_ERROR; - - if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) { - if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) { - lwsl_info("%s: WANT_READ change_pollfd failed\n", __func__); - return LWS_SSL_CAPABLE_ERROR; - } - - lwsl_info("SSL_ERROR_WANT_READ\n"); - return LWS_SSL_CAPABLE_MORE_SERVICE_READ; - } - if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) { - lwsl_debug("%s: WANT_WRITE\n", __func__); - - if (lws_change_pollfd(wsi, 0, LWS_POLLOUT)) { - lwsl_info("%s: WANT_WRITE change_pollfd failed\n", __func__); - return LWS_SSL_CAPABLE_ERROR; - } - return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE; - } - - return LWS_SSL_CAPABLE_ERROR; -} - -#if defined(LWS_WITH_ACME) -/* - * mbedtls doesn't support SAN for cert creation. So we use a known-good - * tls-sni-01 cert from OpenSSL that worked on Let's Encrypt, and just replace - * the pubkey n part and the signature part. - * - * This will need redoing for tls-sni-02... - */ - -static uint8_t ss_cert_leadin[] = { - 0x30, 0x82, - 0x05, 0x56, /* total length: LEN1 (+2 / +3) (correct for 513 + 512)*/ - - 0x30, 0x82, /* length: LEN2 (+6 / +7) (correct for 513) */ - 0x03, 0x3e, - - /* addition: v3 cert (+5 bytes)*/ - 0xa0, 0x03, - 0x02, 0x01, 0x02, - - 0x02, 0x01, 0x01, - 0x30, 0x0d, 0x06, 0x09, 0x2a, - 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3f, - 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x47, - 0x42, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0b, - 0x73, 0x6f, 0x6d, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x31, - 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x74, 0x65, - 0x6d, 0x70, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x69, 0x6e, 0x76, 0x61, - 0x6c, 0x69, 0x64, 0x30, 0x1e, 0x17, 0x0d, - - /* from 2017-10-29 ... */ - 0x31, 0x37, 0x31, 0x30, 0x32, 0x39, 0x31, 0x31, 0x34, 0x39, 0x34, 0x35, - 0x5a, 0x17, 0x0d, - - /* thru 2049-10-29 we immediately discard the private key, no worries */ - 0x34, 0x39, 0x31, 0x30, 0x32, 0x39, 0x31, 0x32, 0x34, 0x39, 0x34, 0x35, - 0x5a, - - 0x30, 0x3f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, - 0x02, 0x47, 0x42, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0a, - 0x0c, 0x0b, 0x73, 0x6f, 0x6d, 0x65, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x6e, - 0x79, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, - 0x74, 0x65, 0x6d, 0x70, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x69, 0x6e, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x30, - - 0x82, - 0x02, 0x22, /* LEN3 (+C3 / C4) */ - 0x30, 0x0d, 0x06, - 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, - 0x03, - - 0x82, - 0x02, 0x0f, /* LEN4 (+D6 / D7) */ - - 0x00, 0x30, 0x82, - - 0x02, 0x0a, /* LEN5 (+ DB / DC) */ - - 0x02, 0x82, - - //0x02, 0x01, /* length of n in bytes (including leading 00 if any) */ - }, - - /* 1 + (keybits / 8) bytes N */ - - ss_cert_san_leadin[] = { - /* e - fixed */ - 0x02, 0x03, 0x01, 0x00, 0x01, - - 0xa3, 0x5d, 0x30, 0x5b, 0x30, 0x59, 0x06, 0x03, 0x55, 0x1d, - 0x11, 0x04, 0x52, 0x30, 0x50, /* <-- SAN length + 2 */ - - 0x82, 0x4e, /* <-- SAN length */ - }, - - /* 78 bytes of SAN (tls-sni-01) - 0x61, 0x64, 0x34, 0x31, 0x61, 0x66, 0x62, 0x65, 0x30, 0x63, 0x61, 0x34, - 0x36, 0x34, 0x32, 0x66, 0x30, 0x61, 0x34, 0x34, 0x39, 0x64, 0x39, 0x63, - 0x61, 0x37, 0x36, 0x65, 0x62, 0x61, 0x61, 0x62, 0x2e, 0x32, 0x38, 0x39, - 0x34, 0x64, 0x34, 0x31, 0x36, 0x63, 0x39, 0x38, 0x33, 0x66, 0x31, 0x32, - 0x65, 0x64, 0x37, 0x33, 0x31, 0x61, 0x33, 0x30, 0x66, 0x35, 0x63, 0x34, - 0x34, 0x37, 0x37, 0x66, 0x65, 0x2e, 0x61, 0x63, 0x6d, 0x65, 0x2e, 0x69, - 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, */ - - /* end of LEN2 area */ - - ss_cert_sig_leadin[] = { - /* it's saying that the signature is SHA256 + RSA */ - 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, - 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, - - 0x82, - 0x02, 0x01, - 0x00, - }; - - /* (keybits / 8) bytes signature to end of LEN1 area */ - -#define SAN_A_LENGTH 78 - -LWS_VISIBLE int -lws_tls_acme_sni_cert_create(struct lws_vhost *vhost, const char *san_a, - const char *san_b) -{ - int buflen = 0x560; - uint8_t *buf = lws_malloc(buflen, "tmp cert buf"), *p = buf, *pkey_asn1; - struct lws_genrsa_ctx ctx; - struct lws_genrsa_elements el; - uint8_t digest[32]; - struct lws_genhash_ctx hash_ctx; - int pkey_asn1_len = 3 * 1024; - int n, m, keybits = lws_plat_recommended_rsa_bits(), adj; - - if (!buf) - return 1; - - n = lws_genrsa_new_keypair(vhost->context, &ctx, &el, keybits); - if (n < 0) { - lws_jwk_destroy_genrsa_elements(&el); - goto bail1; - } - - n = sizeof(ss_cert_leadin); - memcpy(p, ss_cert_leadin, n); - p += n; - - adj = (0x0556 - 0x401) + (keybits / 4) + 1; - buf[2] = adj >> 8; - buf[3] = adj & 0xff; - - adj = (0x033e - 0x201) + (keybits / 8) + 1; - buf[6] = adj >> 8; - buf[7] = adj & 0xff; - - adj = (0x0222 - 0x201) + (keybits / 8) + 1; - buf[0xc3] = adj >> 8; - buf[0xc4] = adj & 0xff; - - adj = (0x020f - 0x201) + (keybits / 8) + 1; - buf[0xd6] = adj >> 8; - buf[0xd7] = adj & 0xff; - - adj = (0x020a - 0x201) + (keybits / 8) + 1; - buf[0xdb] = adj >> 8; - buf[0xdc] = adj & 0xff; - - *p++ = ((keybits / 8) + 1) >> 8; - *p++ = ((keybits / 8) + 1) & 0xff; - - /* we need to drop 1 + (keybits / 8) bytes of n in here, 00 + key */ - - *p++ = 0x00; - memcpy(p, el.e[JWK_KEY_N].buf, el.e[JWK_KEY_N].len); - p += el.e[JWK_KEY_N].len; - - memcpy(p, ss_cert_san_leadin, sizeof(ss_cert_san_leadin)); - p += sizeof(ss_cert_san_leadin); - - /* drop in 78 bytes of san_a */ - - memcpy(p, san_a, SAN_A_LENGTH); - p += SAN_A_LENGTH; - memcpy(p, ss_cert_sig_leadin, sizeof(ss_cert_sig_leadin)); - - p[17] = ((keybits / 8) + 1) >> 8; - p[18] = ((keybits / 8) + 1) & 0xff; - - p += sizeof(ss_cert_sig_leadin); - - /* hash the cert plaintext */ - - if (lws_genhash_init(&hash_ctx, LWS_GENHASH_TYPE_SHA256)) - goto bail2; - - if (lws_genhash_update(&hash_ctx, buf, lws_ptr_diff(p, buf))) { - lws_genhash_destroy(&hash_ctx, NULL); - - goto bail2; - } - if (lws_genhash_destroy(&hash_ctx, digest)) - goto bail2; - - /* sign the hash */ - - n = lws_genrsa_public_sign(&ctx, digest, LWS_GENHASH_TYPE_SHA256, p, - buflen - lws_ptr_diff(p, buf)); - if (n < 0) - goto bail2; - p += n; - - pkey_asn1 = lws_malloc(pkey_asn1_len, "mbed crt tmp"); - if (!pkey_asn1) - goto bail2; - - m = lws_genrsa_render_pkey_asn1(&ctx, 1, pkey_asn1, pkey_asn1_len); - if (m < 0) { - lws_free(pkey_asn1); - goto bail2; - } - -// lwsl_hexdump_level(LLL_DEBUG, buf, lws_ptr_diff(p, buf)); - n = SSL_CTX_use_certificate_ASN1(vhost->tls.ssl_ctx, - lws_ptr_diff(p, buf), buf); - if (n != 1) { - lws_free(pkey_asn1); - lwsl_err("%s: generated cert failed to load 0x%x\n", - __func__, -n); - } else { - //lwsl_debug("private key\n"); - //lwsl_hexdump_level(LLL_DEBUG, pkey_asn1, n); - - /* and to use our generated private key */ - n = SSL_CTX_use_PrivateKey_ASN1(0, vhost->tls.ssl_ctx, pkey_asn1, m); - lws_free(pkey_asn1); - if (n != 1) { - lwsl_err("%s: SSL_CTX_use_PrivateKey_ASN1 failed\n", - __func__); - } - } - - lws_genrsa_destroy(&ctx); - lws_jwk_destroy_genrsa_elements(&el); - - lws_free(buf); - - return n != 1; - -bail2: - lws_genrsa_destroy(&ctx); - lws_jwk_destroy_genrsa_elements(&el); -bail1: - lws_free(buf); - - return -1; -} - -void -lws_tls_acme_sni_cert_destroy(struct lws_vhost *vhost) -{ -} - -#if defined(LWS_WITH_JWS) -static int -_rngf(void *context, unsigned char *buf, size_t len) -{ - if ((size_t)lws_get_random(context, buf, len) == len) - return 0; - - return -1; -} - -static const char *x5[] = { "C", "ST", "L", "O", "CN" }; - -/* - * CSR is output formatted as b64url(DER) - * Private key is output as a PEM in memory - */ -LWS_VISIBLE LWS_EXTERN int -lws_tls_acme_sni_csr_create(struct lws_context *context, const char *elements[], - uint8_t *dcsr, size_t csr_len, char **privkey_pem, - size_t *privkey_len) -{ - mbedtls_x509write_csr csr; - mbedtls_pk_context mpk; - int buf_size = 4096, n; - char subject[200], *p = subject, *end = p + sizeof(subject) - 1; - uint8_t *buf = malloc(buf_size); /* malloc because given to user code */ - - if (!buf) - return -1; - - mbedtls_x509write_csr_init(&csr); - - mbedtls_pk_init(&mpk); - if (mbedtls_pk_setup(&mpk, mbedtls_pk_info_from_type(MBEDTLS_PK_RSA))) { - lwsl_notice("%s: pk_setup failed\n", __func__); - goto fail; - } - - n = mbedtls_rsa_gen_key(mbedtls_pk_rsa(mpk), _rngf, context, - lws_plat_recommended_rsa_bits(), 65537); - if (n) { - lwsl_notice("%s: failed to generate keys\n", __func__); - - goto fail1; - } - - /* subject must be formatted like "C=TW,O=warmcat,CN=myserver" */ - - for (n = 0; n < (int)LWS_ARRAY_SIZE(x5); n++) { - if (p != subject) - *p++ = ','; - if (elements[n]) - p += lws_snprintf(p, end - p, "%s=%s", x5[n], - elements[n]); - } - - if (mbedtls_x509write_csr_set_subject_name(&csr, subject)) - goto fail1; - - mbedtls_x509write_csr_set_key(&csr, &mpk); - mbedtls_x509write_csr_set_md_alg(&csr, MBEDTLS_MD_SHA256); - - /* - * data is written at the end of the buffer! Use the - * return value to determine where you should start - * using the buffer - */ - n = mbedtls_x509write_csr_der(&csr, buf, buf_size, _rngf, context); - if (n < 0) { - lwsl_notice("%s: write csr der failed\n", __func__); - goto fail1; - } - - /* we have it in DER, we need it in b64URL */ - - n = lws_jws_base64_enc((char *)(buf + buf_size) - n, n, - (char *)dcsr, csr_len); - if (n < 0) - goto fail1; - - /* - * okay, the CSR is done, last we need the private key in PEM - * re-use the DER CSR buf as the result buffer since we cn do it in - * one step - */ - - if (mbedtls_pk_write_key_pem(&mpk, buf, buf_size)) { - lwsl_notice("write key pem failed\n"); - goto fail1; - } - - *privkey_pem = (char *)buf; - *privkey_len = strlen((const char *)buf); - - mbedtls_pk_free(&mpk); - mbedtls_x509write_csr_free(&csr); - - return n; - -fail1: - mbedtls_pk_free(&mpk); -fail: - mbedtls_x509write_csr_free(&csr); - free(buf); - - return -1; -} -#endif -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/ssl.c b/thirdparty/libwebsockets/tls/mbedtls/ssl.c deleted file mode 100644 index f311ef50e3..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/ssl.c +++ /dev/null @@ -1,518 +0,0 @@ -/* - * libwebsockets - mbedTLS-specific lws apis - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" -#include <mbedtls/oid.h> - -void -lws_ssl_elaborate_error(void) -{ -} - -int -lws_context_init_ssl_library(const struct lws_context_creation_info *info) -{ - lwsl_info(" Compiled with MbedTLS support\n"); - - if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) - lwsl_info(" SSL disabled: no LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT\n"); - - return 0; -} - -LWS_VISIBLE void -lws_ssl_destroy(struct lws_vhost *vhost) -{ - if (!lws_check_opt(vhost->context->options, - LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) - return; - - if (vhost->tls.ssl_ctx) - SSL_CTX_free(vhost->tls.ssl_ctx); - if (!vhost->tls.user_supplied_ssl_ctx && vhost->tls.ssl_client_ctx) - SSL_CTX_free(vhost->tls.ssl_client_ctx); - - if (vhost->tls.x509_client_CA) - X509_free(vhost->tls.x509_client_CA); -} - -LWS_VISIBLE int -lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len) -{ - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - int n = 0, m; - - if (!wsi->tls.ssl) - return lws_ssl_capable_read_no_ssl(wsi, buf, len); - - lws_stats_atomic_bump(context, pt, LWSSTATS_C_API_READ, 1); - - errno = 0; - n = SSL_read(wsi->tls.ssl, buf, len); -#if defined(LWS_WITH_ESP32) - if (!n && errno == ENOTCONN) { - lwsl_debug("%p: SSL_read ENOTCONN\n", wsi); - return LWS_SSL_CAPABLE_ERROR; - } -#endif -#if defined(LWS_WITH_STATS) - if (!wsi->seen_rx) { - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_MS_SSL_RX_DELAY, - time_in_microseconds() - wsi->accept_start_us); - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_C_SSL_CONNS_HAD_RX, 1); - wsi->seen_rx = 1; - } -#endif - - - lwsl_debug("%p: SSL_read says %d\n", wsi, n); - /* manpage: returning 0 means connection shut down */ - if (!n) { - wsi->socket_is_permanently_unusable = 1; - - return LWS_SSL_CAPABLE_ERROR; - } - - if (n < 0) { - m = SSL_get_error(wsi->tls.ssl, n); - lwsl_debug("%p: ssl err %d errno %d\n", wsi, m, errno); - if (m == SSL_ERROR_ZERO_RETURN || - m == SSL_ERROR_SYSCALL) - return LWS_SSL_CAPABLE_ERROR; - - if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) { - lwsl_debug("%s: WANT_READ\n", __func__); - lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi); - return LWS_SSL_CAPABLE_MORE_SERVICE; - } - if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) { - lwsl_debug("%s: WANT_WRITE\n", __func__); - lwsl_debug("%p: LWS_SSL_CAPABLE_MORE_SERVICE\n", wsi); - return LWS_SSL_CAPABLE_MORE_SERVICE; - } - wsi->socket_is_permanently_unusable = 1; - - return LWS_SSL_CAPABLE_ERROR; - } - - lws_stats_atomic_bump(context, pt, LWSSTATS_B_READ, n); - - if (wsi->vhost) - wsi->vhost->conn_stats.rx += n; - - /* - * if it was our buffer that limited what we read, - * check if SSL has additional data pending inside SSL buffers. - * - * Because these won't signal at the network layer with POLLIN - * and if we don't realize, this data will sit there forever - */ - if (n != len) - goto bail; - if (!wsi->tls.ssl) - goto bail; - - if (!SSL_pending(wsi->tls.ssl)) - goto bail; - - if (wsi->tls.pending_read_list_next) - return n; - if (wsi->tls.pending_read_list_prev) - return n; - if (pt->tls.pending_read_list == wsi) - return n; - - /* add us to the linked list of guys with pending ssl */ - if (pt->tls.pending_read_list) - pt->tls.pending_read_list->tls.pending_read_list_prev = wsi; - - wsi->tls.pending_read_list_next = pt->tls.pending_read_list; - wsi->tls.pending_read_list_prev = NULL; - pt->tls.pending_read_list = wsi; - - return n; -bail: - lws_ssl_remove_wsi_from_buffered_list(wsi); - - return n; -} - -LWS_VISIBLE int -lws_ssl_pending(struct lws *wsi) -{ - if (!wsi->tls.ssl) - return 0; - - return SSL_pending(wsi->tls.ssl); -} - -LWS_VISIBLE int -lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len) -{ - int n, m; - - if (!wsi->tls.ssl) - return lws_ssl_capable_write_no_ssl(wsi, buf, len); - - n = SSL_write(wsi->tls.ssl, buf, len); - if (n > 0) - return n; - - m = SSL_get_error(wsi->tls.ssl, n); - if (m != SSL_ERROR_SYSCALL) { - if (m == SSL_ERROR_WANT_READ || SSL_want_read(wsi->tls.ssl)) { - lwsl_notice("%s: want read\n", __func__); - - return LWS_SSL_CAPABLE_MORE_SERVICE; - } - - if (m == SSL_ERROR_WANT_WRITE || SSL_want_write(wsi->tls.ssl)) { - lws_set_blocking_send(wsi); - lwsl_notice("%s: want write\n", __func__); - - return LWS_SSL_CAPABLE_MORE_SERVICE; - } - } - - lwsl_debug("%s failed: %d\n",__func__, m); - wsi->socket_is_permanently_unusable = 1; - - return LWS_SSL_CAPABLE_ERROR; -} - -int openssl_SSL_CTX_private_data_index; - -void -lws_ssl_info_callback(const SSL *ssl, int where, int ret) -{ - struct lws *wsi; - struct lws_context *context; - struct lws_ssl_info si; - - context = (struct lws_context *)SSL_CTX_get_ex_data( - SSL_get_SSL_CTX(ssl), - openssl_SSL_CTX_private_data_index); - if (!context) - return; - wsi = wsi_from_fd(context, SSL_get_fd(ssl)); - if (!wsi) - return; - - if (!(where & wsi->vhost->tls.ssl_info_event_mask)) - return; - - si.where = where; - si.ret = ret; - - if (user_callback_handle_rxflow(wsi->protocol->callback, - wsi, LWS_CALLBACK_SSL_INFO, - wsi->user_space, &si, 0)) - lws_set_timeout(wsi, PENDING_TIMEOUT_KILLED_BY_SSL_INFO, -1); -} - - -LWS_VISIBLE int -lws_ssl_close(struct lws *wsi) -{ - lws_sockfd_type n; - - if (!wsi->tls.ssl) - return 0; /* not handled */ - -#if defined (LWS_HAVE_SSL_SET_INFO_CALLBACK) - /* kill ssl callbacks, becausse we will remove the fd from the - * table linking it to the wsi - */ - if (wsi->vhost->tls.ssl_info_event_mask) - SSL_set_info_callback(wsi->tls.ssl, NULL); -#endif - - n = SSL_get_fd(wsi->tls.ssl); - if (!wsi->socket_is_permanently_unusable) - SSL_shutdown(wsi->tls.ssl); - compatible_close(n); - SSL_free(wsi->tls.ssl); - wsi->tls.ssl = NULL; - - if (!lwsi_role_client(wsi) && - wsi->context->simultaneous_ssl_restriction && - wsi->context->simultaneous_ssl-- == - wsi->context->simultaneous_ssl_restriction) - /* we made space and can do an accept */ - lws_gate_accepts(wsi->context, 1); - -#if defined(LWS_WITH_STATS) - wsi->context->updated = 1; -#endif - - return 1; /* handled */ -} - -void -lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost) -{ - if (vhost->tls.ssl_ctx) - SSL_CTX_free(vhost->tls.ssl_ctx); - - if (!vhost->tls.user_supplied_ssl_ctx && vhost->tls.ssl_client_ctx) - SSL_CTX_free(vhost->tls.ssl_client_ctx); -#if defined(LWS_WITH_ACME) - lws_tls_acme_sni_cert_destroy(vhost); -#endif -} - -void -lws_ssl_context_destroy(struct lws_context *context) -{ -} - -lws_tls_ctx * -lws_tls_ctx_from_wsi(struct lws *wsi) -{ - if (!wsi->tls.ssl) - return NULL; - - return SSL_get_SSL_CTX(wsi->tls.ssl); -} - -enum lws_ssl_capable_status -__lws_tls_shutdown(struct lws *wsi) -{ - int n = SSL_shutdown(wsi->tls.ssl); - - lwsl_debug("SSL_shutdown=%d for fd %d\n", n, wsi->desc.sockfd); - - switch (n) { - case 1: /* successful completion */ - n = shutdown(wsi->desc.sockfd, SHUT_WR); - return LWS_SSL_CAPABLE_DONE; - - case 0: /* needs a retry */ - __lws_change_pollfd(wsi, 0, LWS_POLLIN); - return LWS_SSL_CAPABLE_MORE_SERVICE; - - default: /* fatal error, or WANT */ - n = SSL_get_error(wsi->tls.ssl, n); - if (n != SSL_ERROR_SYSCALL && n != SSL_ERROR_SSL) { - if (SSL_want_read(wsi->tls.ssl)) { - lwsl_debug("(wants read)\n"); - __lws_change_pollfd(wsi, 0, LWS_POLLIN); - return LWS_SSL_CAPABLE_MORE_SERVICE_READ; - } - if (SSL_want_write(wsi->tls.ssl)) { - lwsl_debug("(wants write)\n"); - __lws_change_pollfd(wsi, 0, LWS_POLLOUT); - return LWS_SSL_CAPABLE_MORE_SERVICE_WRITE; - } - } - return LWS_SSL_CAPABLE_ERROR; - } -} - -static time_t -lws_tls_mbedtls_time_to_unix(mbedtls_x509_time *xtime) -{ - struct tm t; - - if (!xtime || !xtime->year || xtime->year < 0) - return (time_t)(long long)-1; - - memset(&t, 0, sizeof(t)); - - t.tm_year = xtime->year - 1900; - t.tm_mon = xtime->mon - 1; /* mbedtls months are 1+, tm are 0+ */ - t.tm_mday = xtime->day - 1; /* mbedtls days are 1+, tm are 0+ */ - t.tm_hour = xtime->hour; - t.tm_min = xtime->min; - t.tm_sec = xtime->sec; - t.tm_isdst = -1; - - return mktime(&t); -} - -static int -lws_tls_mbedtls_get_x509_name(mbedtls_x509_name *name, - union lws_tls_cert_info_results *buf, size_t len) -{ - while (name) { - if (MBEDTLS_OID_CMP(MBEDTLS_OID_AT_CN, &name->oid)) { - name = name->next; - continue; - } - - if (len - 1 < name->val.len) - return -1; - - memcpy(&buf->ns.name[0], name->val.p, name->val.len); - buf->ns.name[name->val.len] = '\0'; - buf->ns.len = name->val.len; - - return 0; - } - - return -1; -} - -static int -lws_tls_mbedtls_cert_info(mbedtls_x509_crt *x509, enum lws_tls_cert_info type, - union lws_tls_cert_info_results *buf, size_t len) -{ - if (!x509) - return -1; - - switch (type) { - case LWS_TLS_CERT_INFO_VALIDITY_FROM: - buf->time = lws_tls_mbedtls_time_to_unix(&x509->valid_from); - if (buf->time == (time_t)(long long)-1) - return -1; - break; - - case LWS_TLS_CERT_INFO_VALIDITY_TO: - buf->time = lws_tls_mbedtls_time_to_unix(&x509->valid_to); - if (buf->time == (time_t)(long long)-1) - return -1; - break; - - case LWS_TLS_CERT_INFO_COMMON_NAME: - return lws_tls_mbedtls_get_x509_name(&x509->subject, buf, len); - - case LWS_TLS_CERT_INFO_ISSUER_NAME: - return lws_tls_mbedtls_get_x509_name(&x509->issuer, buf, len); - - case LWS_TLS_CERT_INFO_USAGE: - buf->usage = x509->key_usage; - break; - - case LWS_TLS_CERT_INFO_OPAQUE_PUBLIC_KEY: - { - char *p = buf->ns.name; - size_t r = len, u; - - switch (mbedtls_pk_get_type(&x509->pk)) { - case MBEDTLS_PK_RSA: - { - mbedtls_rsa_context *rsa = mbedtls_pk_rsa(x509->pk); - - if (mbedtls_mpi_write_string(&rsa->N, 16, p, r, &u)) - return -1; - r -= u; - p += u; - if (mbedtls_mpi_write_string(&rsa->E, 16, p, r, &u)) - return -1; - - p += u; - buf->ns.len = lws_ptr_diff(p, buf->ns.name); - break; - } - case MBEDTLS_PK_ECKEY: - { - mbedtls_ecp_keypair *ecp = mbedtls_pk_ec(x509->pk); - - if (mbedtls_mpi_write_string(&ecp->Q.X, 16, p, r, &u)) - return -1; - r -= u; - p += u; - if (mbedtls_mpi_write_string(&ecp->Q.Y, 16, p, r, &u)) - return -1; - r -= u; - p += u; - if (mbedtls_mpi_write_string(&ecp->Q.Z, 16, p, r, &u)) - return -1; - p += u; - buf->ns.len = lws_ptr_diff(p, buf->ns.name); - break; - } - default: - lwsl_notice("%s: x509 has unsupported pubkey type %d\n", - __func__, - mbedtls_pk_get_type(&x509->pk)); - - return -1; - } - break; - } - - default: - return -1; - } - - return 0; -} - -LWS_VISIBLE LWS_EXTERN int -lws_tls_vhost_cert_info(struct lws_vhost *vhost, enum lws_tls_cert_info type, - union lws_tls_cert_info_results *buf, size_t len) -{ - mbedtls_x509_crt *x509 = ssl_ctx_get_mbedtls_x509_crt(vhost->tls.ssl_ctx); - - return lws_tls_mbedtls_cert_info(x509, type, buf, len); -} - -LWS_VISIBLE int -lws_tls_peer_cert_info(struct lws *wsi, enum lws_tls_cert_info type, - union lws_tls_cert_info_results *buf, size_t len) -{ - mbedtls_x509_crt *x509; - - wsi = lws_get_network_wsi(wsi); - - x509 = ssl_get_peer_mbedtls_x509_crt(wsi->tls.ssl); - - if (!x509) - return -1; - - switch (type) { - case LWS_TLS_CERT_INFO_VERIFIED: - buf->verified = SSL_get_verify_result(wsi->tls.ssl) == X509_V_OK; - return 0; - default: - return lws_tls_mbedtls_cert_info(x509, type, buf, len); - } - - return -1; -} - -static int -tops_fake_POLLIN_for_buffered_mbedtls(struct lws_context_per_thread *pt) -{ - return lws_tls_fake_POLLIN_for_buffered(pt); -} - -static int -tops_periodic_housekeeping_mbedtls(struct lws_context *context, time_t now) -{ - int n; - - n = lws_compare_time_t(context, now, context->tls.last_cert_check_s); - if ((!context->tls.last_cert_check_s || n > (24 * 60 * 60)) && - !lws_tls_check_all_cert_lifetimes(context)) - context->tls.last_cert_check_s = now; - - return 0; -} - -const struct lws_tls_ops tls_ops_mbedtls = { - /* fake_POLLIN_for_buffered */ tops_fake_POLLIN_for_buffered_mbedtls, - /* periodic_housekeeping */ tops_periodic_housekeeping_mbedtls, -}; diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl3.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl3.h deleted file mode 100644 index 007b392f3e..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl3.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL3_H_ -#define _SSL3_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -# define SSL3_AD_CLOSE_NOTIFY 0 -# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ -# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ -# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */ -# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */ -# define SSL3_AD_NO_CERTIFICATE 41 -# define SSL3_AD_BAD_CERTIFICATE 42 -# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 -# define SSL3_AD_CERTIFICATE_REVOKED 44 -# define SSL3_AD_CERTIFICATE_EXPIRED 45 -# define SSL3_AD_CERTIFICATE_UNKNOWN 46 -# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */ - -# define SSL3_AL_WARNING 1 -# define SSL3_AL_FATAL 2 - -#define SSL3_VERSION 0x0300 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_cert.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_cert.h deleted file mode 100644 index 86cf31ad51..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_cert.h +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_CERT_H_ -#define _SSL_CERT_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "ssl_types.h" - -/** - * @brief create a certification object include private key object according to input certification - * - * @param ic - input certification point - * - * @return certification object point - */ -CERT *__ssl_cert_new(CERT *ic); - -/** - * @brief create a certification object include private key object - * - * @param none - * - * @return certification object point - */ -CERT* ssl_cert_new(void); - -/** - * @brief free a certification object - * - * @param cert - certification object point - * - * @return none - */ -void ssl_cert_free(CERT *cert); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_code.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_code.h deleted file mode 100644 index 80fdbb20f3..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_code.h +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_CODE_H_ -#define _SSL_CODE_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "ssl3.h" -#include "tls1.h" -#include "x509_vfy.h" - -/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ -# define SSL_SENT_SHUTDOWN 1 -# define SSL_RECEIVED_SHUTDOWN 2 - -# define SSL_VERIFY_NONE 0x00 -# define SSL_VERIFY_PEER 0x01 -# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 -# define SSL_VERIFY_CLIENT_ONCE 0x04 - -/* - * The following 3 states are kept in ssl->rlayer.rstate when reads fail, you - * should not need these - */ -# define SSL_ST_READ_HEADER 0xF0 -# define SSL_ST_READ_BODY 0xF1 -# define SSL_ST_READ_DONE 0xF2 - -# define SSL_NOTHING 1 -# define SSL_WRITING 2 -# define SSL_READING 3 -# define SSL_X509_LOOKUP 4 -# define SSL_ASYNC_PAUSED 5 -# define SSL_ASYNC_NO_JOBS 6 - - -# define SSL_ERROR_NONE 0 -# define SSL_ERROR_SSL 1 -# define SSL_ERROR_WANT_READ 2 -# define SSL_ERROR_WANT_WRITE 3 -# define SSL_ERROR_WANT_X509_LOOKUP 4 -# define SSL_ERROR_SYSCALL 5/* look at error stack/return value/errno */ -# define SSL_ERROR_ZERO_RETURN 6 -# define SSL_ERROR_WANT_CONNECT 7 -# define SSL_ERROR_WANT_ACCEPT 8 -# define SSL_ERROR_WANT_ASYNC 9 -# define SSL_ERROR_WANT_ASYNC_JOB 10 - -/* Message flow states */ -typedef enum { - /* No handshake in progress */ - MSG_FLOW_UNINITED, - /* A permanent error with this connection */ - MSG_FLOW_ERROR, - /* We are about to renegotiate */ - MSG_FLOW_RENEGOTIATE, - /* We are reading messages */ - MSG_FLOW_READING, - /* We are writing messages */ - MSG_FLOW_WRITING, - /* Handshake has finished */ - MSG_FLOW_FINISHED -} MSG_FLOW_STATE; - -/* SSL subsystem states */ -typedef enum { - TLS_ST_BEFORE, - TLS_ST_OK, - DTLS_ST_CR_HELLO_VERIFY_REQUEST, - TLS_ST_CR_SRVR_HELLO, - TLS_ST_CR_CERT, - TLS_ST_CR_CERT_STATUS, - TLS_ST_CR_KEY_EXCH, - TLS_ST_CR_CERT_REQ, - TLS_ST_CR_SRVR_DONE, - TLS_ST_CR_SESSION_TICKET, - TLS_ST_CR_CHANGE, - TLS_ST_CR_FINISHED, - TLS_ST_CW_CLNT_HELLO, - TLS_ST_CW_CERT, - TLS_ST_CW_KEY_EXCH, - TLS_ST_CW_CERT_VRFY, - TLS_ST_CW_CHANGE, - TLS_ST_CW_NEXT_PROTO, - TLS_ST_CW_FINISHED, - TLS_ST_SW_HELLO_REQ, - TLS_ST_SR_CLNT_HELLO, - DTLS_ST_SW_HELLO_VERIFY_REQUEST, - TLS_ST_SW_SRVR_HELLO, - TLS_ST_SW_CERT, - TLS_ST_SW_KEY_EXCH, - TLS_ST_SW_CERT_REQ, - TLS_ST_SW_SRVR_DONE, - TLS_ST_SR_CERT, - TLS_ST_SR_KEY_EXCH, - TLS_ST_SR_CERT_VRFY, - TLS_ST_SR_NEXT_PROTO, - TLS_ST_SR_CHANGE, - TLS_ST_SR_FINISHED, - TLS_ST_SW_SESSION_TICKET, - TLS_ST_SW_CERT_STATUS, - TLS_ST_SW_CHANGE, - TLS_ST_SW_FINISHED -} OSSL_HANDSHAKE_STATE; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_dbg.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_dbg.h deleted file mode 100644 index ad32cb92ff..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_dbg.h +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_DEBUG_H_ -#define _SSL_DEBUG_H_ - -#include "platform/ssl_port.h" - -#ifdef __cplusplus - extern "C" { -#endif - -#ifdef CONFIG_OPENSSL_DEBUG_LEVEL - #define SSL_DEBUG_LEVEL CONFIG_OPENSSL_DEBUG_LEVEL -#else - #define SSL_DEBUG_LEVEL 0 -#endif - -#define SSL_DEBUG_ON (SSL_DEBUG_LEVEL + 1) -#define SSL_DEBUG_OFF (SSL_DEBUG_LEVEL - 1) - -#ifdef CONFIG_OPENSSL_DEBUG - #ifndef SSL_DEBUG_LOG - #error "SSL_DEBUG_LOG is not defined" - #endif - - #ifndef SSL_DEBUG_FL - #define SSL_DEBUG_FL "\n" - #endif - - #define SSL_SHOW_LOCATION() \ - SSL_DEBUG_LOG("SSL assert : %s %d\n", \ - __FILE__, __LINE__) - - #define SSL_DEBUG(level, fmt, ...) \ - { \ - if (level > SSL_DEBUG_LEVEL) { \ - SSL_DEBUG_LOG(fmt SSL_DEBUG_FL, ##__VA_ARGS__); \ - } \ - } -#else /* CONFIG_OPENSSL_DEBUG */ - #define SSL_SHOW_LOCATION() - - #define SSL_DEBUG(level, fmt, ...) -#endif /* CONFIG_OPENSSL_DEBUG */ - -/** - * OpenSSL assert function - * - * if select "CONFIG_OPENSSL_ASSERT_DEBUG", SSL_ASSERT* will show error file name and line - * if select "CONFIG_OPENSSL_ASSERT_EXIT", SSL_ASSERT* will just return error code. - * if select "CONFIG_OPENSSL_ASSERT_DEBUG_EXIT" SSL_ASSERT* will show error file name and line, - * then return error code. - * if select "CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK", SSL_ASSERT* will show error file name and line, - * then block here with "while (1)" - * - * SSL_ASSERT1 may will return "-1", so function's return argument is integer. - * SSL_ASSERT2 may will return "NULL", so function's return argument is a point. - * SSL_ASSERT2 may will return nothing, so function's return argument is "void". - */ -#if defined(CONFIG_OPENSSL_ASSERT_DEBUG) - #define SSL_ASSERT1(s) \ - { \ - if (!(s)) { \ - SSL_SHOW_LOCATION(); \ - } \ - } - - #define SSL_ASSERT2(s) \ - { \ - if (!(s)) { \ - SSL_SHOW_LOCATION(); \ - } \ - } - - #define SSL_ASSERT3(s) \ - { \ - if (!(s)) { \ - SSL_SHOW_LOCATION(); \ - } \ - } -#elif defined(CONFIG_OPENSSL_ASSERT_EXIT) - #define SSL_ASSERT1(s) \ - { \ - if (!(s)) { \ - return -1; \ - } \ - } - - #define SSL_ASSERT2(s) \ - { \ - if (!(s)) { \ - return NULL; \ - } \ - } - - #define SSL_ASSERT3(s) \ - { \ - if (!(s)) { \ - return ; \ - } \ - } -#elif defined(CONFIG_OPENSSL_ASSERT_DEBUG_EXIT) - #define SSL_ASSERT1(s) \ - { \ - if (!(s)) { \ - SSL_SHOW_LOCATION(); \ - return -1; \ - } \ - } - - #define SSL_ASSERT2(s) \ - { \ - if (!(s)) { \ - SSL_SHOW_LOCATION(); \ - return NULL; \ - } \ - } - - #define SSL_ASSERT3(s) \ - { \ - if (!(s)) { \ - SSL_SHOW_LOCATION(); \ - return ; \ - } \ - } -#elif defined(CONFIG_OPENSSL_ASSERT_DEBUG_BLOCK) - #define SSL_ASSERT1(s) \ - { \ - if (!(s)) { \ - SSL_SHOW_LOCATION(); \ - while (1); \ - } \ - } - - #define SSL_ASSERT2(s) \ - { \ - if (!(s)) { \ - SSL_SHOW_LOCATION(); \ - while (1); \ - } \ - } - - #define SSL_ASSERT3(s) \ - { \ - if (!(s)) { \ - SSL_SHOW_LOCATION(); \ - while (1); \ - } \ - } -#else - #define SSL_ASSERT1(s) - #define SSL_ASSERT2(s) - #define SSL_ASSERT3(s) -#endif - -#define SSL_PLATFORM_DEBUG_LEVEL SSL_DEBUG_OFF -#define SSL_PLATFORM_ERROR_LEVEL SSL_DEBUG_ON - -#define SSL_CERT_DEBUG_LEVEL SSL_DEBUG_OFF -#define SSL_CERT_ERROR_LEVEL SSL_DEBUG_ON - -#define SSL_PKEY_DEBUG_LEVEL SSL_DEBUG_OFF -#define SSL_PKEY_ERROR_LEVEL SSL_DEBUG_ON - -#define SSL_X509_DEBUG_LEVEL SSL_DEBUG_OFF -#define SSL_X509_ERROR_LEVEL SSL_DEBUG_ON - -#define SSL_LIB_DEBUG_LEVEL SSL_DEBUG_OFF -#define SSL_LIB_ERROR_LEVEL SSL_DEBUG_ON - -#define SSL_STACK_DEBUG_LEVEL SSL_DEBUG_OFF -#define SSL_STACK_ERROR_LEVEL SSL_DEBUG_ON - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_lib.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_lib.h deleted file mode 100644 index 42b2de7501..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_lib.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_LIB_H_ -#define _SSL_LIB_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "ssl_types.h" - - void _ssl_set_alpn_list(const SSL *ssl); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_methods.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_methods.h deleted file mode 100644 index cd2f8c0533..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_methods.h +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_METHODS_H_ -#define _SSL_METHODS_H_ - -#include "ssl_types.h" - -#ifdef __cplusplus - extern "C" { -#endif - -/** - * TLS method function implement - */ -#define IMPLEMENT_TLS_METHOD_FUNC(func_name, \ - new, free, \ - handshake, shutdown, clear, \ - read, send, pending, \ - set_fd, get_fd, \ - set_bufflen, \ - get_verify_result, \ - get_state) \ - static const SSL_METHOD_FUNC func_name LOCAL_ATRR = { \ - new, \ - free, \ - handshake, \ - shutdown, \ - clear, \ - read, \ - send, \ - pending, \ - set_fd, \ - get_fd, \ - set_bufflen, \ - get_verify_result, \ - get_state \ - }; - -#define IMPLEMENT_TLS_METHOD(ver, mode, fun, func_name) \ - const SSL_METHOD* func_name(void) { \ - static const SSL_METHOD func_name##_data LOCAL_ATRR = { \ - ver, \ - mode, \ - &(fun), \ - }; \ - return &func_name##_data; \ - } - -#define IMPLEMENT_SSL_METHOD(ver, mode, fun, func_name) \ - const SSL_METHOD* func_name(void) { \ - static const SSL_METHOD func_name##_data LOCAL_ATRR = { \ - ver, \ - mode, \ - &(fun), \ - }; \ - return &func_name##_data; \ - } - -#define IMPLEMENT_X509_METHOD(func_name, \ - new, \ - free, \ - load, \ - show_info) \ - const X509_METHOD* func_name(void) { \ - static const X509_METHOD func_name##_data LOCAL_ATRR = { \ - new, \ - free, \ - load, \ - show_info \ - }; \ - return &func_name##_data; \ - } - -#define IMPLEMENT_PKEY_METHOD(func_name, \ - new, \ - free, \ - load) \ - const PKEY_METHOD* func_name(void) { \ - static const PKEY_METHOD func_name##_data LOCAL_ATRR = { \ - new, \ - free, \ - load \ - }; \ - return &func_name##_data; \ - } - -/** - * @brief get X509 object method - * - * @param none - * - * @return X509 object method point - */ -const X509_METHOD* X509_method(void); - -/** - * @brief get private key object method - * - * @param none - * - * @return private key object method point - */ -const PKEY_METHOD* EVP_PKEY_method(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_pkey.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_pkey.h deleted file mode 100644 index e790fcc995..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_pkey.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_PKEY_H_ -#define _SSL_PKEY_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "ssl_types.h" - -/** - * @brief create a private key object according to input private key - * - * @param ipk - input private key point - * - * @return new private key object point - */ -EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk); - -/** - * @brief create a private key object - * - * @param none - * - * @return private key object point - */ -EVP_PKEY* EVP_PKEY_new(void); - -/** - * @brief load a character key context into system context. If '*a' is pointed to the - * private key, then load key into it. Or create a new private key object - * - * @param type - private key type - * @param a - a point pointed to a private key point - * @param pp - a point pointed to the key context memory point - * @param length - key bytes - * - * @return private key object point - */ -EVP_PKEY* d2i_PrivateKey(int type, - EVP_PKEY **a, - const unsigned char **pp, - long length); - -/** - * @brief free a private key object - * - * @param pkey - private key object point - * - * @return none - */ -void EVP_PKEY_free(EVP_PKEY *x); - -/** - * @brief load private key into the SSL - * - * @param type - private key type - * @param ssl - SSL point - * @param len - data bytes - * @param d - data point - * - * @return result - * 0 : failed - * 1 : OK - */ - int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, long len); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_stack.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_stack.h deleted file mode 100644 index 7a7051a026..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_stack.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef _SSL_STACK_H_ -#define _SSL_STACK_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "ssl_types.h" - -#define STACK_OF(type) struct stack_st_##type - -#define SKM_DEFINE_STACK_OF(t1, t2, t3) \ - STACK_OF(t1); \ - static ossl_inline STACK_OF(t1) *sk_##t1##_new_null(void) \ - { \ - return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ - } \ - -#define DEFINE_STACK_OF(t) SKM_DEFINE_STACK_OF(t, t, t) - -/** - * @brief create a openssl stack object - * - * @param c - stack function - * - * @return openssl stack object point - */ -OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c); - -/** - * @brief create a NULL function openssl stack object - * - * @param none - * - * @return openssl stack object point - */ -OPENSSL_STACK *OPENSSL_sk_new_null(void); - -/** - * @brief free openssl stack object - * - * @param openssl stack object point - * - * @return none - */ -void OPENSSL_sk_free(OPENSSL_STACK *stack); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_types.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_types.h deleted file mode 100644 index 68ac748a28..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_types.h +++ /dev/null @@ -1,303 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_TYPES_H_ -#define _SSL_TYPES_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include <lws_config.h> -#if defined(LWS_WITH_ESP32) -#undef MBEDTLS_CONFIG_FILE -#define MBEDTLS_CONFIG_FILE <mbedtls/esp_config.h> -#endif - -#include "ssl_code.h" - -typedef void SSL_CIPHER; - -typedef void X509_STORE_CTX; -typedef void X509_STORE; - -typedef void RSA; - -typedef void STACK; -typedef void BIO; - -#if defined(WIN32) || defined(_WIN32) -#define ossl_inline __inline -#else -#define ossl_inline inline -#endif - -#define SSL_METHOD_CALL(f, s, ...) s->method->func->ssl_##f(s, ##__VA_ARGS__) -#define X509_METHOD_CALL(f, x, ...) x->method->x509_##f(x, ##__VA_ARGS__) -#define EVP_PKEY_METHOD_CALL(f, k, ...) k->method->pkey_##f(k, ##__VA_ARGS__) - -typedef int (*OPENSSL_sk_compfunc)(const void *, const void *); - -struct stack_st; -typedef struct stack_st OPENSSL_STACK; - -struct ssl_method_st; -typedef struct ssl_method_st SSL_METHOD; - -struct ssl_method_func_st; -typedef struct ssl_method_func_st SSL_METHOD_FUNC; - -struct record_layer_st; -typedef struct record_layer_st RECORD_LAYER; - -struct ossl_statem_st; -typedef struct ossl_statem_st OSSL_STATEM; - -struct ssl_session_st; -typedef struct ssl_session_st SSL_SESSION; - -struct ssl_ctx_st; -typedef struct ssl_ctx_st SSL_CTX; - -struct ssl_st; -typedef struct ssl_st SSL; - -struct cert_st; -typedef struct cert_st CERT; - -struct x509_st; -typedef struct x509_st X509; - -struct X509_VERIFY_PARAM_st; -typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; - -struct evp_pkey_st; -typedef struct evp_pkey_st EVP_PKEY; - -struct x509_method_st; -typedef struct x509_method_st X509_METHOD; - -struct pkey_method_st; -typedef struct pkey_method_st PKEY_METHOD; - -struct stack_st { - - char **data; - - int num_alloc; - - OPENSSL_sk_compfunc c; -}; - -struct evp_pkey_st { - - void *pkey_pm; - - const PKEY_METHOD *method; -}; - -struct x509_st { - - /* X509 certification platform private point */ - void *x509_pm; - - const X509_METHOD *method; -}; - -struct cert_st { - - int sec_level; - - X509 *x509; - - EVP_PKEY *pkey; - -}; - -struct ossl_statem_st { - - MSG_FLOW_STATE state; - - int hand_state; -}; - -struct record_layer_st { - - int rstate; - - int read_ahead; -}; - -struct ssl_session_st { - - long timeout; - - long time; - - X509 *peer; -}; - -struct X509_VERIFY_PARAM_st { - - int depth; - -}; - -typedef int (*next_proto_cb)(SSL *ssl, unsigned char **out, - unsigned char *outlen, const unsigned char *in, - unsigned int inlen, void *arg); - -struct ssl_ctx_st -{ - int version; - - int references; - - unsigned long options; - - const SSL_METHOD *method; - - CERT *cert; - - X509 *client_CA; - - const char **alpn_protos; - - next_proto_cb alpn_cb; - - int verify_mode; - - int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx); - - long session_timeout; - - int read_ahead; - - int read_buffer_len; - - X509_VERIFY_PARAM param; -}; - -struct ssl_st -{ - /* protocol version(one of SSL3.0, TLS1.0, etc.) */ - int version; - - unsigned long options; - - /* shut things down(0x01 : sent, 0x02 : received) */ - int shutdown; - - CERT *cert; - - X509 *client_CA; - - SSL_CTX *ctx; - - const SSL_METHOD *method; - - const char **alpn_protos; - - RECORD_LAYER rlayer; - - /* where we are */ - OSSL_STATEM statem; - - SSL_SESSION *session; - - int verify_mode; - - int (*verify_callback) (int ok, X509_STORE_CTX *ctx); - - int rwstate; - int interrupted_remaining_write; - - long verify_result; - - X509_VERIFY_PARAM param; - - int err; - - void (*info_callback) (const SSL *ssl, int type, int val); - - /* SSL low-level system arch point */ - void *ssl_pm; -}; - -struct ssl_method_st { - /* protocol version(one of SSL3.0, TLS1.0, etc.) */ - int version; - - /* SSL mode(client(0) , server(1), not known(-1)) */ - int endpoint; - - const SSL_METHOD_FUNC *func; -}; - -struct ssl_method_func_st { - - int (*ssl_new)(SSL *ssl); - - void (*ssl_free)(SSL *ssl); - - int (*ssl_handshake)(SSL *ssl); - - int (*ssl_shutdown)(SSL *ssl); - - int (*ssl_clear)(SSL *ssl); - - int (*ssl_read)(SSL *ssl, void *buffer, int len); - - int (*ssl_send)(SSL *ssl, const void *buffer, int len); - - int (*ssl_pending)(const SSL *ssl); - - void (*ssl_set_fd)(SSL *ssl, int fd, int mode); - - int (*ssl_get_fd)(const SSL *ssl, int mode); - - void (*ssl_set_bufflen)(SSL *ssl, int len); - - long (*ssl_get_verify_result)(const SSL *ssl); - - OSSL_HANDSHAKE_STATE (*ssl_get_state)(const SSL *ssl); -}; - -struct x509_method_st { - - int (*x509_new)(X509 *x, X509 *m_x); - - void (*x509_free)(X509 *x); - - int (*x509_load)(X509 *x, const unsigned char *buf, int len); - - int (*x509_show_info)(X509 *x); -}; - -struct pkey_method_st { - - int (*pkey_new)(EVP_PKEY *pkey, EVP_PKEY *m_pkey); - - void (*pkey_free)(EVP_PKEY *pkey); - - int (*pkey_load)(EVP_PKEY *pkey, const unsigned char *buf, int len); -}; - -#define OPENSSL_NPN_NEGOTIATED 1 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_x509.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_x509.h deleted file mode 100644 index 7594d064b4..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/ssl_x509.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_X509_H_ -#define _SSL_X509_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "ssl_types.h" -#include "ssl_stack.h" - -DEFINE_STACK_OF(X509_NAME) - -/** - * @brief create a X509 certification object according to input X509 certification - * - * @param ix - input X509 certification point - * - * @return new X509 certification object point - */ -X509* __X509_new(X509 *ix); - -/** - * @brief create a X509 certification object - * - * @param none - * - * @return X509 certification object point - */ -X509* X509_new(void); - -/** - * @brief load a character certification context into system context. If '*cert' is pointed to the - * certification, then load certification into it. Or create a new X509 certification object - * - * @param cert - a point pointed to X509 certification - * @param buffer - a point pointed to the certification context memory point - * @param length - certification bytes - * - * @return X509 certification object point - */ -X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len); - -/** - * @brief free a X509 certification object - * - * @param x - X509 certification object point - * - * @return none - */ -void X509_free(X509 *x); - -/** - * @brief set SSL context client CA certification - * - * @param ctx - SSL context point - * @param x - X509 certification point - * - * @return result - * 0 : failed - * 1 : OK - */ -int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); - -/** - * @brief add CA client certification into the SSL - * - * @param ssl - SSL point - * @param x - X509 certification point - * - * @return result - * 0 : failed - * 1 : OK - */ -int SSL_add_client_CA(SSL *ssl, X509 *x); - -/** - * @brief load certification into the SSL - * - * @param ssl - SSL point - * @param len - data bytes - * @param d - data point - * - * @return result - * 0 : failed - * 1 : OK - * - */ -int SSL_use_certificate_ASN1(SSL *ssl, int len, const unsigned char *d); - -const char *X509_verify_cert_error_string(long n); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/tls1.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/tls1.h deleted file mode 100644 index 7af1b0157d..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/tls1.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _TLS1_H_ -#define _TLS1_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -# define TLS1_AD_DECRYPTION_FAILED 21 -# define TLS1_AD_RECORD_OVERFLOW 22 -# define TLS1_AD_UNKNOWN_CA 48/* fatal */ -# define TLS1_AD_ACCESS_DENIED 49/* fatal */ -# define TLS1_AD_DECODE_ERROR 50/* fatal */ -# define TLS1_AD_DECRYPT_ERROR 51 -# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ -# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ -# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ -# define TLS1_AD_INTERNAL_ERROR 80/* fatal */ -# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ -# define TLS1_AD_USER_CANCELLED 90 -# define TLS1_AD_NO_RENEGOTIATION 100 -/* codes 110-114 are from RFC3546 */ -# define TLS1_AD_UNSUPPORTED_EXTENSION 110 -# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 -# define TLS1_AD_UNRECOGNIZED_NAME 112 -# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 -# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 -# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ -# define TLS1_AD_NO_APPLICATION_PROTOCOL 120 /* fatal */ - -/* Special value for method supporting multiple versions */ -#define TLS_ANY_VERSION 0x10000 - -#define TLS1_VERSION 0x0301 -#define TLS1_1_VERSION 0x0302 -#define TLS1_2_VERSION 0x0303 - -#define SSL_TLSEXT_ERR_OK 0 -#define SSL_TLSEXT_ERR_NOACK 3 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/x509_vfy.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/x509_vfy.h deleted file mode 100644 index 26bf6c88a8..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/internal/x509_vfy.h +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _X509_VFY_H_ -#define _X509_VFY_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#define X509_V_OK 0 -#define X509_V_ERR_UNSPECIFIED 1 -#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 -#define X509_V_ERR_UNABLE_TO_GET_CRL 3 -#define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 -#define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 -#define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 -#define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 -#define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 -#define X509_V_ERR_CERT_NOT_YET_VALID 9 -#define X509_V_ERR_CERT_HAS_EXPIRED 10 -#define X509_V_ERR_CRL_NOT_YET_VALID 11 -#define X509_V_ERR_CRL_HAS_EXPIRED 12 -#define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 -#define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 -#define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 -#define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 -#define X509_V_ERR_OUT_OF_MEM 17 -#define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 -#define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 -#define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 -#define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 -#define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 -#define X509_V_ERR_CERT_REVOKED 23 -#define X509_V_ERR_INVALID_CA 24 -#define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 -#define X509_V_ERR_INVALID_PURPOSE 26 -#define X509_V_ERR_CERT_UNTRUSTED 27 -#define X509_V_ERR_CERT_REJECTED 28 -/* These are 'informational' when looking for issuer cert */ -#define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 -#define X509_V_ERR_AKID_SKID_MISMATCH 30 -#define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 -#define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 -#define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 -#define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 -#define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 -#define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 -#define X509_V_ERR_INVALID_NON_CA 37 -#define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 -#define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 -#define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 -#define X509_V_ERR_INVALID_EXTENSION 41 -#define X509_V_ERR_INVALID_POLICY_EXTENSION 42 -#define X509_V_ERR_NO_EXPLICIT_POLICY 43 -#define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 -#define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 -#define X509_V_ERR_UNNESTED_RESOURCE 46 -#define X509_V_ERR_PERMITTED_VIOLATION 47 -#define X509_V_ERR_EXCLUDED_VIOLATION 48 -#define X509_V_ERR_SUBTREE_MINMAX 49 -/* The application is not happy */ -#define X509_V_ERR_APPLICATION_VERIFICATION 50 -#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 -#define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 -#define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 -#define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 -/* Another issuer check debug option */ -#define X509_V_ERR_PATH_LOOP 55 -/* Suite B mode algorithm violation */ -#define X509_V_ERR_SUITE_B_INVALID_VERSION 56 -#define X509_V_ERR_SUITE_B_INVALID_ALGORITHM 57 -#define X509_V_ERR_SUITE_B_INVALID_CURVE 58 -#define X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM 59 -#define X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED 60 -#define X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256 61 -/* Host, email and IP check errors */ -#define X509_V_ERR_HOSTNAME_MISMATCH 62 -#define X509_V_ERR_EMAIL_MISMATCH 63 -#define X509_V_ERR_IP_ADDRESS_MISMATCH 64 -/* DANE TLSA errors */ -#define X509_V_ERR_DANE_NO_MATCH 65 -/* security level errors */ -#define X509_V_ERR_EE_KEY_TOO_SMALL 66 -#define X509_V_ERR_CA_KEY_TOO_SMALL 67 -#define X509_V_ERR_CA_MD_TOO_WEAK 68 -/* Caller error */ -#define X509_V_ERR_INVALID_CALL 69 -/* Issuer lookup error */ -#define X509_V_ERR_STORE_LOOKUP 70 -/* Certificate transparency */ -#define X509_V_ERR_NO_VALID_SCTS 71 - -#define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72 - -typedef void X509_STORE_CTX; -int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); -int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/openssl/ssl.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/openssl/ssl.h deleted file mode 100755 index e2b74fc6af..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/openssl/ssl.h +++ /dev/null @@ -1,1833 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_H_ -#define _SSL_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include <stdlib.h> -#include "internal/ssl_x509.h" -#include "internal/ssl_pkey.h" - -/* -{ -*/ - -#define SSL_CB_ALERT 0x4000 - -#define X509_CHECK_FLAG_ALWAYS_CHECK_SUBJECT (1 << 0) -#define X509_CHECK_FLAG_NO_WILDCARDS (1 << 1) -#define X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS (1 << 2) -#define X509_CHECK_FLAG_MULTI_LABEL_WILDCARDS (1 << 3) -#define X509_CHECK_FLAG_SINGLE_LABEL_SUBDOMAINS (1 << 4) - - mbedtls_x509_crt * - ssl_ctx_get_mbedtls_x509_crt(SSL_CTX *ssl_ctx); - - mbedtls_x509_crt * - ssl_get_peer_mbedtls_x509_crt(SSL *ssl); - - int SSL_set_sni_callback(SSL *ssl, int(*cb)(void *, mbedtls_ssl_context *, - const unsigned char *, size_t), void *param); - - void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); - - int SSL_CTX_add_client_CA_ASN1(SSL_CTX *ssl, int len, - const unsigned char *d); - - SSL *SSL_SSL_from_mbedtls_ssl_context(mbedtls_ssl_context *msc); - -/** - * @brief create a SSL context - * - * @param method - the SSL context method point - * - * @return the context point - */ -SSL_CTX* SSL_CTX_new(const SSL_METHOD *method); - -/** - * @brief free a SSL context - * - * @param method - the SSL context point - * - * @return none - */ -void SSL_CTX_free(SSL_CTX *ctx); - -/** - * @brief create a SSL - * - * @param ctx - the SSL context point - * - * @return the SSL point - */ -SSL* SSL_new(SSL_CTX *ctx); - -/** - * @brief free the SSL - * - * @param ssl - the SSL point - * - * @return none - */ -void SSL_free(SSL *ssl); - -/** - * @brief connect to the remote SSL server - * - * @param ssl - the SSL point - * - * @return result - * 1 : OK - * -1 : failed - */ -int SSL_connect(SSL *ssl); - -/** - * @brief accept the remote connection - * - * @param ssl - the SSL point - * - * @return result - * 1 : OK - * -1 : failed - */ -int SSL_accept(SSL *ssl); - -/** - * @brief read data from to remote - * - * @param ssl - the SSL point which has been connected - * @param buffer - the received data buffer point - * @param len - the received data length - * - * @return result - * > 0 : OK, and return received data bytes - * = 0 : connection is closed - * < 0 : an error catch - */ -int SSL_read(SSL *ssl, void *buffer, int len); - -/** - * @brief send the data to remote - * - * @param ssl - the SSL point which has been connected - * @param buffer - the send data buffer point - * @param len - the send data length - * - * @return result - * > 0 : OK, and return sent data bytes - * = 0 : connection is closed - * < 0 : an error catch - */ -int SSL_write(SSL *ssl, const void *buffer, int len); - -/** - * @brief get the verifying result of the SSL certification - * - * @param ssl - the SSL point - * - * @return the result of verifying - */ -long SSL_get_verify_result(const SSL *ssl); - -/** - * @brief shutdown the connection - * - * @param ssl - the SSL point - * - * @return result - * 1 : OK - * 0 : shutdown is not finished - * -1 : an error catch - */ -int SSL_shutdown(SSL *ssl); - -/** - * @brief bind the socket file description into the SSL - * - * @param ssl - the SSL point - * @param fd - socket handle - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_set_fd(SSL *ssl, int fd); - -/** - * @brief These functions load the private key into the SSL_CTX or SSL object - * - * @param ctx - the SSL context point - * @param pkey - private key object point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); - -/** - * @brief These functions load the certification into the SSL_CTX or SSL object - * - * @param ctx - the SSL context point - * @param pkey - certification object point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the SSLV2.3 version SSL context client method - */ -const SSL_METHOD* SSLv23_client_method(void); - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the TLSV1.0 version SSL context client method - */ -const SSL_METHOD* TLSv1_client_method(void); - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the SSLV1.0 version SSL context client method - */ -const SSL_METHOD* SSLv3_client_method(void); - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the TLSV1.1 version SSL context client method - */ -const SSL_METHOD* TLSv1_1_client_method(void); - -/** - * @brief create the target SSL context client method - * - * @param none - * - * @return the TLSV1.2 version SSL context client method - */ -const SSL_METHOD* TLSv1_2_client_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLS any version SSL context client method - */ -const SSL_METHOD* TLS_client_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the SSLV2.3 version SSL context server method - */ -const SSL_METHOD* SSLv23_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLSV1.1 version SSL context server method - */ -const SSL_METHOD* TLSv1_1_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLSV1.2 version SSL context server method - */ -const SSL_METHOD* TLSv1_2_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLSV1.0 version SSL context server method - */ -const SSL_METHOD* TLSv1_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the SSLV3.0 version SSL context server method - */ -const SSL_METHOD* SSLv3_server_method(void); - -/** - * @brief create the target SSL context server method - * - * @param none - * - * @return the TLS any version SSL context server method - */ -const SSL_METHOD* TLS_server_method(void); - - -/** - * @brief set the SSL context ALPN select callback function - * - * @param ctx - SSL context point - * @param cb - ALPN select callback function - * @param arg - ALPN select callback function entry private data point - * - * @return none - */ -void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - const unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg), - void *arg); - -void SSL_set_alpn_select_cb(SSL *ssl, void *arg); - -/** - * @brief set the SSL context ALPN select protocol - * - * @param ctx - SSL context point - * @param protos - ALPN protocol name - * @param protos_len - ALPN protocol name bytes - * - * @return result - * 0 : OK - * 1 : failed - */ -int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const unsigned char *protos, unsigned int protos_len); - -/** - * @brief set the SSL context next ALPN select callback function - * - * @param ctx - SSL context point - * @param cb - ALPN select callback function - * @param arg - ALPN select callback function entry private data point - * - * @return none - */ -void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, - int (*cb) (SSL *ssl, - unsigned char **out, - unsigned char *outlen, - const unsigned char *in, - unsigned int inlen, - void *arg), - void *arg); - -void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, - unsigned int *len); - -void _ssl_set_alpn_list(const SSL *ssl); - -/** - * @brief get SSL error code - * - * @param ssl - SSL point - * @param ret_code - SSL return code - * - * @return SSL error number - */ -int SSL_get_error(const SSL *ssl, int ret_code); - -/** - * @brief clear the SSL error code - * - * @param none - * - * @return none - */ -void ERR_clear_error(void); - -/** - * @brief get the current SSL error code - * - * @param none - * - * @return current SSL error number - */ -int ERR_get_error(void); - -/** - * @brief register the SSL error strings - * - * @param none - * - * @return none - */ -void ERR_load_SSL_strings(void); - -/** - * @brief initialize the SSL library - * - * @param none - * - * @return none - */ -void SSL_library_init(void); - -/** - * @brief generates a human-readable string representing the error code e - * and store it into the "ret" point memory - * - * @param e - error code - * @param ret - memory point to store the string - * - * @return the result string point - */ -char *ERR_error_string(unsigned long e, char *ret); - -/** - * @brief add the SSL context option - * - * @param ctx - SSL context point - * @param opt - new SSL context option - * - * @return the SSL context option - */ -unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt); - -/** - * @brief add the SSL context mode - * - * @param ctx - SSL context point - * @param mod - new SSL context mod - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_mode(SSL_CTX *ctx, int mod); - -/* -} -*/ - -/** - * @brief perform the SSL handshake - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - * -1 : a error catch - */ -int SSL_do_handshake(SSL *ssl); - -/** - * @brief get the SSL current version - * - * @param ssl - SSL point - * - * @return the version string - */ -const char *SSL_get_version(const SSL *ssl); - -/** - * @brief set the SSL context version - * - * @param ctx - SSL context point - * @param meth - SSL method point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); - -/** - * @brief get the bytes numbers which are to be read - * - * @param ssl - SSL point - * - * @return bytes number - */ -int SSL_pending(const SSL *ssl); - -/** - * @brief check if SSL want nothing - * - * @param ssl - SSL point - * - * @return result - * 0 : false - * 1 : true - */ -int SSL_want_nothing(const SSL *ssl); - -/** - * @brief check if SSL want to read - * - * @param ssl - SSL point - * - * @return result - * 0 : false - * 1 : true - */ -int SSL_want_read(const SSL *ssl); - -/** - * @brief check if SSL want to write - * - * @param ssl - SSL point - * - * @return result - * 0 : false - * 1 : true - */ -int SSL_want_write(const SSL *ssl); - -/** - * @brief get the SSL context current method - * - * @param ctx - SSL context point - * - * @return the SSL context current method - */ -const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx); - -/** - * @brief get the SSL current method - * - * @param ssl - SSL point - * - * @return the SSL current method - */ -const SSL_METHOD *SSL_get_ssl_method(SSL *ssl); - -/** - * @brief set the SSL method - * - * @param ssl - SSL point - * @param meth - SSL method point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method); - -/** - * @brief add CA client certification into the SSL - * - * @param ssl - SSL point - * @param x - CA certification point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_add_client_CA(SSL *ssl, X509 *x); - -/** - * @brief add CA client certification into the SSL context - * - * @param ctx - SSL context point - * @param x - CA certification point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); - -/** - * @brief set the SSL CA certification list - * - * @param ssl - SSL point - * @param name_list - CA certification list - * - * @return none - */ -void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list); - -/** - * @brief set the SSL context CA certification list - * - * @param ctx - SSL context point - * @param name_list - CA certification list - * - * @return none - */ -void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); - -/** - * @briefget the SSL CA certification list - * - * @param ssl - SSL point - * - * @return CA certification list - */ -STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); - -/** - * @brief get the SSL context CA certification list - * - * @param ctx - SSL context point - * - * @return CA certification list - */ -STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); - -/** - * @brief get the SSL certification point - * - * @param ssl - SSL point - * - * @return SSL certification point - */ -X509 *SSL_get_certificate(const SSL *ssl); - -/** - * @brief get the SSL private key point - * - * @param ssl - SSL point - * - * @return SSL private key point - */ -EVP_PKEY *SSL_get_privatekey(const SSL *ssl); - -/** - * @brief set the SSL information callback function - * - * @param ssl - SSL point - * @param cb - information callback function - * - * @return none - */ -void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)); - -/** - * @brief get the SSL state - * - * @param ssl - SSL point - * - * @return SSL state - */ -OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl); - -/** - * @brief set the SSL context read buffer length - * - * @param ctx - SSL context point - * @param len - read buffer length - * - * @return none - */ -void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len); - -/** - * @brief set the SSL read buffer length - * - * @param ssl - SSL point - * @param len - read buffer length - * - * @return none - */ -void SSL_set_default_read_buffer_len(SSL *ssl, size_t len); - -/** - * @brief set the SSL security level - * - * @param ssl - SSL point - * @param level - security level - * - * @return none - */ -void SSL_set_security_level(SSL *ssl, int level); - -/** - * @brief get the SSL security level - * - * @param ssl - SSL point - * - * @return security level - */ -int SSL_get_security_level(const SSL *ssl); - -/** - * @brief get the SSL verifying mode of the SSL context - * - * @param ctx - SSL context point - * - * @return verifying mode - */ -int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); - -/** - * @brief get the SSL verifying depth of the SSL context - * - * @param ctx - SSL context point - * - * @return verifying depth - */ -int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); - -/** - * @brief set the SSL context verifying of the SSL context - * - * @param ctx - SSL context point - * @param mode - verifying mode - * @param verify_callback - verifying callback function - * - * @return none - */ -void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); - -/** - * @brief set the SSL verifying of the SSL context - * - * @param ctx - SSL point - * @param mode - verifying mode - * @param verify_callback - verifying callback function - * - * @return none - */ -void SSL_set_verify(SSL *s, int mode, int (*verify_callback)(int, X509_STORE_CTX *)); - -/** - * @brief set the SSL verify depth of the SSL context - * - * @param ctx - SSL context point - * @param depth - verifying depth - * - * @return none - */ -void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); - -/** - * @brief certification verifying callback function - * - * @param preverify_ok - verifying result - * @param x509_ctx - X509 certification point - * - * @return verifying result - */ -int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx); - -/** - * @brief set the session timeout time - * - * @param ctx - SSL context point - * @param t - new session timeout time - * - * @return old session timeout time - */ -long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); - -/** - * @brief get the session timeout time - * - * @param ctx - SSL context point - * - * @return current session timeout time - */ -long SSL_CTX_get_timeout(const SSL_CTX *ctx); - -/** - * @brief set the SSL context cipher through the list string - * - * @param ctx - SSL context point - * @param str - cipher controller list string - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); - -/** - * @brief set the SSL cipher through the list string - * - * @param ssl - SSL point - * @param str - cipher controller list string - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_set_cipher_list(SSL *ssl, const char *str); - -/** - * @brief get the SSL cipher list string - * - * @param ssl - SSL point - * - * @return cipher controller list string - */ -const char *SSL_get_cipher_list(const SSL *ssl, int n); - -/** - * @brief get the SSL cipher - * - * @param ssl - SSL point - * - * @return current cipher - */ -const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); - -/** - * @brief get the SSL cipher string - * - * @param ssl - SSL point - * - * @return cipher string - */ -const char *SSL_get_cipher(const SSL *ssl); - -/** - * @brief get the SSL context object X509 certification storage - * - * @param ctx - SSL context point - * - * @return x509 certification storage - */ -X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); - -/** - * @brief set the SSL context object X509 certification store - * - * @param ctx - SSL context point - * @param store - X509 certification store - * - * @return none - */ -void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); - -/** - * @brief get the SSL specifical statement - * - * @param ssl - SSL point - * - * @return specifical statement - */ -int SSL_want(const SSL *ssl); - -/** - * @brief check if the SSL is SSL_X509_LOOKUP state - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_want_x509_lookup(const SSL *ssl); - -/** - * @brief reset the SSL - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_clear(SSL *ssl); - -/** - * @brief get the socket handle of the SSL - * - * @param ssl - SSL point - * - * @return result - * >= 0 : yes, and return socket handle - * < 0 : a error catch - */ -int SSL_get_fd(const SSL *ssl); - -/** - * @brief get the read only socket handle of the SSL - * - * @param ssl - SSL point - * - * @return result - * >= 0 : yes, and return socket handle - * < 0 : a error catch - */ -int SSL_get_rfd(const SSL *ssl); - -/** - * @brief get the write only socket handle of the SSL - * - * @param ssl - SSL point - * - * @return result - * >= 0 : yes, and return socket handle - * < 0 : a error catch - */ -int SSL_get_wfd(const SSL *ssl); - -/** - * @brief set the SSL if we can read as many as data - * - * @param ssl - SSL point - * @param yes - enable the function - * - * @return none - */ -void SSL_set_read_ahead(SSL *s, int yes); - -/** - * @brief set the SSL context if we can read as many as data - * - * @param ctx - SSL context point - * @param yes - enbale the function - * - * @return none - */ -void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); - -/** - * @brief get the SSL ahead signal if we can read as many as data - * - * @param ssl - SSL point - * - * @return SSL context ahead signal - */ -int SSL_get_read_ahead(const SSL *ssl); - -/** - * @brief get the SSL context ahead signal if we can read as many as data - * - * @param ctx - SSL context point - * - * @return SSL context ahead signal - */ -long SSL_CTX_get_read_ahead(SSL_CTX *ctx); - -/** - * @brief check if some data can be read - * - * @param ssl - SSL point - * - * @return - * 1 : there are bytes to be read - * 0 : no data - */ -int SSL_has_pending(const SSL *ssl); - -/** - * @brief load the X509 certification into SSL context - * - * @param ctx - SSL context point - * @param x - X509 certification point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);//loads the certificate x into ctx - -/** - * @brief load the ASN1 certification into SSL context - * - * @param ctx - SSL context point - * @param len - certification length - * @param d - data point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const unsigned char *d); - -/** - * @brief load the certification file into SSL context - * - * @param ctx - SSL context point - * @param file - certification file name - * @param type - certification encoding type - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); - -/** - * @brief load the certification chain file into SSL context - * - * @param ctx - SSL context point - * @param file - certification chain file name - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); - - -/** - * @brief load the ASN1 private key into SSL context - * - * @param ctx - SSL context point - * @param d - data point - * @param len - private key length - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, const unsigned char *d, long len);//adds the private key of type pk stored at memory location d (length len) to ctx - -/** - * @brief load the private key file into SSL context - * - * @param ctx - SSL context point - * @param file - private key file name - * @param type - private key encoding type - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); - -/** - * @brief load the RSA private key into SSL context - * - * @param ctx - SSL context point - * @param x - RSA private key point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); - -/** - * @brief load the RSA ASN1 private key into SSL context - * - * @param ctx - SSL context point - * @param d - data point - * @param len - RSA private key length - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len); - -/** - * @brief load the RSA private key file into SSL context - * - * @param ctx - SSL context point - * @param file - RSA private key file name - * @param type - private key encoding type - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); - - -/** - * @brief check if the private key and certification is matched - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_check_private_key(const SSL_CTX *ctx); - -/** - * @brief set the SSL context server information - * - * @param ctx - SSL context point - * @param serverinfo - server information string - * @param serverinfo_length - server information length - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo, size_t serverinfo_length); - -/** - * @brief load the SSL context server infomation file into SSL context - * - * @param ctx - SSL context point - * @param file - server information file - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file); - -/** - * @brief SSL select next function - * - * @param out - point of output data point - * @param outlen - output data length - * @param in - input data - * @param inlen - input data length - * @param client - client data point - * @param client_len -client data length - * - * @return NPN state - * OPENSSL_NPN_UNSUPPORTED : not support - * OPENSSL_NPN_NEGOTIATED : negotiated - * OPENSSL_NPN_NO_OVERLAP : no overlap - */ -int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, - const unsigned char *client, unsigned int client_len); - -/** - * @brief load the extra certification chain into the SSL context - * - * @param ctx - SSL context point - * @param x509 - X509 certification - * - * @return result - * 1 : OK - * 0 : failed - */ -long SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *); - -/** - * @brief control the SSL context - * - * @param ctx - SSL context point - * @param cmd - command - * @param larg - parameter length - * @param parg - parameter point - * - * @return result - * 1 : OK - * 0 : failed - */ -long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, char *parg); - -/** - * @brief get the SSL context cipher - * - * @param ctx - SSL context point - * - * @return SSL context cipher - */ -STACK *SSL_CTX_get_ciphers(const SSL_CTX *ctx); - -/** - * @brief check if the SSL context can read as many as data - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx); - -/** - * @brief get the SSL context extra data - * - * @param ctx - SSL context point - * @param idx - index - * - * @return data point - */ -char *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); - -/** - * @brief get the SSL context quiet shutdown option - * - * @param ctx - SSL context point - * - * @return quiet shutdown option - */ -int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); - -/** - * @brief load the SSL context CA file - * - * @param ctx - SSL context point - * @param CAfile - CA certification file - * @param CApath - CA certification file path - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath); - -/** - * @brief add SSL context reference count by '1' - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_up_ref(SSL_CTX *ctx); - -/** - * @brief set SSL context application private data - * - * @param ctx - SSL context point - * @param arg - private data - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_app_data(SSL_CTX *ctx, void *arg); - -/** - * @brief set SSL context client certification callback function - * - * @param ctx - SSL context point - * @param cb - callback function - * - * @return none - */ -void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey)); - -/** - * @brief set the SSL context if we can read as many as data - * - * @param ctx - SSL context point - * @param m - enable the fuction - * - * @return none - */ -void SSL_CTX_set_default_read_ahead(SSL_CTX *ctx, int m); - -/** - * @brief set SSL context default verifying path - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); - -/** - * @brief set SSL context default verifying directory - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_default_verify_dir(SSL_CTX *ctx); - -/** - * @brief set SSL context default verifying file - * - * @param ctx - SSL context point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_default_verify_file(SSL_CTX *ctx); - -/** - * @brief set SSL context extra data - * - * @param ctx - SSL context point - * @param idx - data index - * @param arg - data point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, char *arg); - -/** - * @brief clear the SSL context option bit of "op" - * - * @param ctx - SSL context point - * @param op - option - * - * @return SSL context option - */ -unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op); - -/** - * @brief get the SSL context option - * - * @param ctx - SSL context point - * @param op - option - * - * @return SSL context option - */ -unsigned long SSL_CTX_get_options(SSL_CTX *ctx); - -/** - * @brief set the SSL context quiet shutdown mode - * - * @param ctx - SSL context point - * @param mode - mode - * - * @return none - */ -void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); - -/** - * @brief get the SSL context X509 certification - * - * @param ctx - SSL context point - * - * @return X509 certification - */ -X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); - -/** - * @brief get the SSL context private key - * - * @param ctx - SSL context point - * - * @return private key - */ -EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); - -/** - * @brief set SSL context PSK identity hint - * - * @param ctx - SSL context point - * @param hint - PSK identity hint - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *hint); - -/** - * @brief set SSL context PSK server callback function - * - * @param ctx - SSL context point - * @param callback - callback function - * - * @return none - */ -void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, - unsigned int (*callback)(SSL *ssl, - const char *identity, - unsigned char *psk, - int max_psk_len)); -/** - * @brief get alert description string - * - * @param value - alert value - * - * @return alert description string - */ -const char *SSL_alert_desc_string(int value); - -/** - * @brief get alert description long string - * - * @param value - alert value - * - * @return alert description long string - */ -const char *SSL_alert_desc_string_long(int value); - -/** - * @brief get alert type string - * - * @param value - alert value - * - * @return alert type string - */ -const char *SSL_alert_type_string(int value); - -/** - * @brief get alert type long string - * - * @param value - alert value - * - * @return alert type long string - */ -const char *SSL_alert_type_string_long(int value); - -/** - * @brief get SSL context of the SSL - * - * @param ssl - SSL point - * - * @return SSL context - */ -SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); - -/** - * @brief get SSL application data - * - * @param ssl - SSL point - * - * @return application data - */ -char *SSL_get_app_data(SSL *ssl); - -/** - * @brief get SSL cipher bits - * - * @param ssl - SSL point - * @param alg_bits - algorithm bits - * - * @return strength bits - */ -int SSL_get_cipher_bits(const SSL *ssl, int *alg_bits); - -/** - * @brief get SSL cipher name - * - * @param ssl - SSL point - * - * @return SSL cipher name - */ -char *SSL_get_cipher_name(const SSL *ssl); - -/** - * @brief get SSL cipher version - * - * @param ssl - SSL point - * - * @return SSL cipher version - */ -char *SSL_get_cipher_version(const SSL *ssl); - -/** - * @brief get SSL extra data - * - * @param ssl - SSL point - * @param idx - data index - * - * @return extra data - */ -char *SSL_get_ex_data(const SSL *ssl, int idx); - -/** - * @brief get index of the SSL extra data X509 storage context - * - * @param none - * - * @return data index - */ -int SSL_get_ex_data_X509_STORE_CTX_idx(void); - -/** - * @brief get peer certification chain - * - * @param ssl - SSL point - * - * @return certification chain - */ -STACK *SSL_get_peer_cert_chain(const SSL *ssl); - -/** - * @brief get peer certification - * - * @param ssl - SSL point - * - * @return certification - */ -X509 *SSL_get_peer_certificate(const SSL *ssl); - -/** - * @brief get SSL quiet shutdown mode - * - * @param ssl - SSL point - * - * @return quiet shutdown mode - */ -int SSL_get_quiet_shutdown(const SSL *ssl); - -/** - * @brief get SSL read only IO handle - * - * @param ssl - SSL point - * - * @return IO handle - */ -BIO *SSL_get_rbio(const SSL *ssl); - -/** - * @brief get SSL shared ciphers - * - * @param ssl - SSL point - * @param buf - buffer to store the ciphers - * @param len - buffer len - * - * @return shared ciphers - */ -char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); - -/** - * @brief get SSL shutdown mode - * - * @param ssl - SSL point - * - * @return shutdown mode - */ -int SSL_get_shutdown(const SSL *ssl); - -/** - * @brief get SSL session time - * - * @param ssl - SSL point - * - * @return session time - */ -long SSL_get_time(const SSL *ssl); - -/** - * @brief get SSL session timeout time - * - * @param ssl - SSL point - * - * @return session timeout time - */ -long SSL_get_timeout(const SSL *ssl); - -/** - * @brief get SSL verifying mode - * - * @param ssl - SSL point - * - * @return verifying mode - */ -int SSL_get_verify_mode(const SSL *ssl); - -/** - * @brief get SSL verify parameters - * - * @param ssl - SSL point - * - * @return verify parameters - */ -X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); - -/** - * @brief set expected hostname the peer cert CN should have - * - * @param param - verify parameters from SSL_get0_param() - * - * @param name - the expected hostname - * - * @param namelen - the length of the hostname, or 0 if NUL terminated - * - * @return verify parameters - */ -int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen); - -/** - * @brief set parameters for X509 host verify action - * - * @param param -verify parameters from SSL_get0_param() - * - * @param flags - bitfield of X509_CHECK_FLAG_... parameters to set - * - * @return 1 for success, 0 for failure - */ -int X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, - unsigned long flags); - -/** - * @brief clear parameters for X509 host verify action - * - * @param param -verify parameters from SSL_get0_param() - * - * @param flags - bitfield of X509_CHECK_FLAG_... parameters to clear - * - * @return 1 for success, 0 for failure - */ -int X509_VERIFY_PARAM_clear_hostflags(X509_VERIFY_PARAM *param, - unsigned long flags); - -/** - * @brief get SSL write only IO handle - * - * @param ssl - SSL point - * - * @return IO handle - */ -BIO *SSL_get_wbio(const SSL *ssl); - -/** - * @brief load SSL client CA certification file - * - * @param file - file name - * - * @return certification loading object - */ -STACK *SSL_load_client_CA_file(const char *file); - -/** - * @brief add SSL reference by '1' - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_up_ref(SSL *ssl); - -/** - * @brief read and put data into buf, but not clear the SSL low-level storage - * - * @param ssl - SSL point - * @param buf - storage buffer point - * @param num - data bytes - * - * @return result - * > 0 : OK, and return read bytes - * = 0 : connect is closed - * < 0 : a error catch - */ -int SSL_peek(SSL *ssl, void *buf, int num); - -/** - * @brief make SSL renegotiate - * - * @param ssl - SSL point - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_renegotiate(SSL *ssl); - -/** - * @brief get the state string where SSL is reading - * - * @param ssl - SSL point - * - * @return state string - */ -const char *SSL_rstate_string(SSL *ssl); - -/** - * @brief get the statement long string where SSL is reading - * - * @param ssl - SSL point - * - * @return statement long string - */ -const char *SSL_rstate_string_long(SSL *ssl); - -/** - * @brief set SSL accept statement - * - * @param ssl - SSL point - * - * @return none - */ -void SSL_set_accept_state(SSL *ssl); - -/** - * @brief set SSL application data - * - * @param ssl - SSL point - * @param arg - SSL application data point - * - * @return none - */ -void SSL_set_app_data(SSL *ssl, char *arg); - -/** - * @brief set SSL BIO - * - * @param ssl - SSL point - * @param rbio - read only IO - * @param wbio - write only IO - * - * @return none - */ -void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); - -/** - * @brief clear SSL option - * - * @param ssl - SSL point - * @param op - clear option - * - * @return SSL option - */ -unsigned long SSL_clear_options(SSL *ssl, unsigned long op); - -/** - * @brief get SSL option - * - * @param ssl - SSL point - * - * @return SSL option - */ -unsigned long SSL_get_options(SSL *ssl); - -/** - * @brief clear SSL option - * - * @param ssl - SSL point - * @param op - setting option - * - * @return SSL option - */ -unsigned long SSL_set_options(SSL *ssl, unsigned long op); - -/** - * @brief set SSL quiet shutdown mode - * - * @param ssl - SSL point - * @param mode - quiet shutdown mode - * - * @return none - */ -void SSL_set_quiet_shutdown(SSL *ssl, int mode); - -/** - * @brief set SSL shutdown mode - * - * @param ssl - SSL point - * @param mode - shutdown mode - * - * @return none - */ -void SSL_set_shutdown(SSL *ssl, int mode); - -/** - * @brief set SSL session time - * - * @param ssl - SSL point - * @param t - session time - * - * @return session time - */ -void SSL_set_time(SSL *ssl, long t); - -/** - * @brief set SSL session timeout time - * - * @param ssl - SSL point - * @param t - session timeout time - * - * @return session timeout time - */ -void SSL_set_timeout(SSL *ssl, long t); - -/** - * @brief get SSL statement string - * - * @param ssl - SSL point - * - * @return SSL statement string - */ -char *SSL_state_string(const SSL *ssl); - -/** - * @brief get SSL statement long string - * - * @param ssl - SSL point - * - * @return SSL statement long string - */ -char *SSL_state_string_long(const SSL *ssl); - -/** - * @brief get SSL renegotiation count - * - * @param ssl - SSL point - * - * @return renegotiation count - */ -long SSL_total_renegotiations(SSL *ssl); - -/** - * @brief get SSL version - * - * @param ssl - SSL point - * - * @return SSL version - */ -int SSL_version(const SSL *ssl); - -/** - * @brief set SSL PSK identity hint - * - * @param ssl - SSL point - * @param hint - identity hint - * - * @return result - * 1 : OK - * 0 : failed - */ -int SSL_use_psk_identity_hint(SSL *ssl, const char *hint); - -/** - * @brief get SSL PSK identity hint - * - * @param ssl - SSL point - * - * @return identity hint - */ -const char *SSL_get_psk_identity_hint(SSL *ssl); - -/** - * @brief get SSL PSK identity - * - * @param ssl - SSL point - * - * @return identity - */ -const char *SSL_get_psk_identity(SSL *ssl); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/platform/ssl_pm.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/platform/ssl_pm.h deleted file mode 100644 index cbbe3aa3a2..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/platform/ssl_pm.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_PM_H_ -#define _SSL_PM_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include <string.h> -#include "ssl_types.h" -#include "ssl_port.h" - -#define LOCAL_ATRR - -int ssl_pm_new(SSL *ssl); -void ssl_pm_free(SSL *ssl); - -int ssl_pm_handshake(SSL *ssl); -int ssl_pm_shutdown(SSL *ssl); -int ssl_pm_clear(SSL *ssl); - -int ssl_pm_read(SSL *ssl, void *buffer, int len); -int ssl_pm_send(SSL *ssl, const void *buffer, int len); -int ssl_pm_pending(const SSL *ssl); - -void ssl_pm_set_fd(SSL *ssl, int fd, int mode); -int ssl_pm_get_fd(const SSL *ssl, int mode); - -OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl); - -void ssl_pm_set_bufflen(SSL *ssl, int len); - -int x509_pm_show_info(X509 *x); -int x509_pm_new(X509 *x, X509 *m_x); -void x509_pm_free(X509 *x); -int x509_pm_load(X509 *x, const unsigned char *buffer, int len); - -int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pk); -void pkey_pm_free(EVP_PKEY *pk); -int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len); - -long ssl_pm_get_verify_result(const SSL *ssl); - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/platform/ssl_port.h b/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/platform/ssl_port.h deleted file mode 100644 index 74c7634355..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/include/platform/ssl_port.h +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#ifndef _SSL_PORT_H_ -#define _SSL_PORT_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#include "string.h" -#include "stdlib.h" -#if defined(LWS_HAVE_MALLOC_H) -#include "malloc.h" -#endif - -void *ssl_mem_zalloc(size_t size); - -#define ssl_mem_malloc malloc -#define ssl_mem_free free - -#define ssl_memcpy memcpy -#define ssl_strlen strlen - -#define ssl_speed_up_enter() -#define ssl_speed_up_exit() - -#define SSL_DEBUG_FL -#define SSL_DEBUG_LOG(fmt, ...) ESP_LOGI("openssl", fmt, ##__VA_ARGS__) - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_cert.c b/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_cert.c deleted file mode 100644 index 5c608125ac..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_cert.c +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#include "ssl_cert.h" -#include "ssl_pkey.h" -#include "ssl_x509.h" -#include "ssl_dbg.h" -#include "ssl_port.h" - -/** - * @brief create a certification object according to input certification - */ -CERT *__ssl_cert_new(CERT *ic) -{ - CERT *cert; - - X509 *ix; - EVP_PKEY *ipk; - - cert = ssl_mem_zalloc(sizeof(CERT)); - if (!cert) { - SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "no enough memory > (cert)"); - goto no_mem; - } - - if (ic) { - ipk = ic->pkey; - ix = ic->x509; - } else { - ipk = NULL; - ix = NULL; - } - - cert->pkey = __EVP_PKEY_new(ipk); - if (!cert->pkey) { - SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "__EVP_PKEY_new() return NULL"); - goto pkey_err; - } - - cert->x509 = __X509_new(ix); - if (!cert->x509) { - SSL_DEBUG(SSL_CERT_ERROR_LEVEL, "__X509_new() return NULL"); - goto x509_err; - } - - return cert; - -x509_err: - EVP_PKEY_free(cert->pkey); -pkey_err: - ssl_mem_free(cert); -no_mem: - return NULL; -} - -/** - * @brief create a certification object include private key object - */ -CERT *ssl_cert_new(void) -{ - return __ssl_cert_new(NULL); -} - -/** - * @brief free a certification object - */ -void ssl_cert_free(CERT *cert) -{ - SSL_ASSERT3(cert); - - X509_free(cert->x509); - - EVP_PKEY_free(cert->pkey); - - ssl_mem_free(cert); -} diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_lib.c b/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_lib.c deleted file mode 100644 index 2f688ca9ef..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_lib.c +++ /dev/null @@ -1,1736 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#include "ssl_lib.h" -#include "ssl_pkey.h" -#include "ssl_x509.h" -#include "ssl_cert.h" -#include "ssl_dbg.h" -#include "ssl_port.h" - -char * -lws_strncpy(char *dest, const char *src, size_t size); - -#define SSL_SEND_DATA_MAX_LENGTH 1460 - -/** - * @brief create a new SSL session object - */ -static SSL_SESSION* SSL_SESSION_new(void) -{ - SSL_SESSION *session; - - session = ssl_mem_zalloc(sizeof(SSL_SESSION)); - if (!session) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (session)"); - goto failed1; - } - - session->peer = X509_new(); - if (!session->peer) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "X509_new() return NULL"); - goto failed2; - } - - return session; - -failed2: - ssl_mem_free(session); -failed1: - return NULL; -} - -/** - * @brief free a new SSL session object - */ -static void SSL_SESSION_free(SSL_SESSION *session) -{ - X509_free(session->peer); - ssl_mem_free(session); -} - -/** - * @brief Discover whether the current connection is in the error state - */ -int ossl_statem_in_error(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - if (ssl->statem.state == MSG_FLOW_ERROR) - return 1; - - return 0; -} - -/** - * @brief get the SSL specifical statement - */ -int SSL_want(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return ssl->rwstate; -} - -/** - * @brief check if SSL want nothing - */ -int SSL_want_nothing(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - if (ssl->err) - return 1; - - return (SSL_want(ssl) == SSL_NOTHING); -} - -/** - * @brief check if SSL want to read - */ -int SSL_want_read(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - if (ssl->err) - return 0; - - return (SSL_want(ssl) == SSL_READING); -} - -/** - * @brief check if SSL want to write - */ -int SSL_want_write(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - if (ssl->err) - return 0; - - return (SSL_want(ssl) == SSL_WRITING); -} - -/** - * @brief check if SSL want to lookup X509 certification - */ -int SSL_want_x509_lookup(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return (SSL_want(ssl) == SSL_WRITING); -} - -/** - * @brief get SSL error code - */ -int SSL_get_error(const SSL *ssl, int ret_code) -{ - int ret = SSL_ERROR_SYSCALL; - - SSL_ASSERT1(ssl); - - if (ret_code > 0) - ret = SSL_ERROR_NONE; - else if (ret_code < 0) - { - if (ssl->err == SSL_ERROR_WANT_READ || SSL_want_read(ssl)) - ret = SSL_ERROR_WANT_READ; - else if (ssl->err == SSL_ERROR_WANT_WRITE || SSL_want_write(ssl)) - ret = SSL_ERROR_WANT_WRITE; - else - ret = SSL_ERROR_SYSCALL; //unknown - } - else // ret_code == 0 - { - if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) - ret = SSL_ERROR_ZERO_RETURN; - else - ret = SSL_ERROR_SYSCALL; - } - - return ret; -} - -/** - * @brief get the SSL state - */ -OSSL_HANDSHAKE_STATE SSL_get_state(const SSL *ssl) -{ - OSSL_HANDSHAKE_STATE state; - - SSL_ASSERT1(ssl); - - state = SSL_METHOD_CALL(get_state, ssl); - - return state; -} - -/** - * @brief create a SSL context - */ -SSL_CTX* SSL_CTX_new(const SSL_METHOD *method) -{ - SSL_CTX *ctx; - CERT *cert; - X509 *client_ca; - - if (!method) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no no_method"); - return NULL; - } - - client_ca = X509_new(); - if (!client_ca) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "X509_new() return NULL"); - goto failed1; - } - - cert = ssl_cert_new(); - if (!cert) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "ssl_cert_new() return NULL"); - goto failed2; - } - - ctx = (SSL_CTX *)ssl_mem_zalloc(sizeof(SSL_CTX)); - if (!ctx) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (ctx)"); - goto failed3; - } - - ctx->method = method; - ctx->client_CA = client_ca; - ctx->cert = cert; - - ctx->version = method->version; - - return ctx; - -failed3: - ssl_cert_free(cert); -failed2: - X509_free(client_ca); -failed1: - return NULL; -} - -/** - * @brief free a SSL context - */ -void SSL_CTX_free(SSL_CTX* ctx) -{ - SSL_ASSERT3(ctx); - - ssl_cert_free(ctx->cert); - - X509_free(ctx->client_CA); - - if (ctx->alpn_protos) - ssl_mem_free(ctx->alpn_protos); - - ssl_mem_free(ctx); -} - -/** - * @brief set the SSL context version - */ -int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) -{ - SSL_ASSERT1(ctx); - SSL_ASSERT1(meth); - - ctx->method = meth; - - ctx->version = meth->version; - - return 1; -} - -/** - * @brief get the SSL context current method - */ -const SSL_METHOD *SSL_CTX_get_ssl_method(SSL_CTX *ctx) -{ - SSL_ASSERT2(ctx); - - return ctx->method; -} - -/** - * @brief create a SSL - */ -SSL *SSL_new(SSL_CTX *ctx) -{ - int ret = 0; - SSL *ssl; - - if (!ctx) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no ctx"); - return NULL; - } - - ssl = (SSL *)ssl_mem_zalloc(sizeof(SSL)); - if (!ssl) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "no enough memory > (ssl)"); - goto failed1; - } - - ssl->session = SSL_SESSION_new(); - if (!ssl->session) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_SESSION_new() return NULL"); - goto failed2; - } - - ssl->cert = __ssl_cert_new(ctx->cert); - if (!ssl->cert) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "__ssl_cert_new() return NULL"); - goto failed3; - } - - ssl->client_CA = __X509_new(ctx->client_CA); - if (!ssl->client_CA) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "__X509_new() return NULL"); - goto failed4; - } - - ssl->ctx = ctx; - ssl->method = ctx->method; - - ssl->version = ctx->version; - ssl->options = ctx->options; - - ssl->verify_mode = ctx->verify_mode; - - ret = SSL_METHOD_CALL(new, ssl); - if (ret) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret); - goto failed5; - } - - _ssl_set_alpn_list(ssl); - - ssl->rwstate = SSL_NOTHING; - - return ssl; - -failed5: - X509_free(ssl->client_CA); -failed4: - ssl_cert_free(ssl->cert); -failed3: - SSL_SESSION_free(ssl->session); -failed2: - ssl_mem_free(ssl); -failed1: - return NULL; -} - -/** - * @brief free the SSL - */ -void SSL_free(SSL *ssl) -{ - SSL_ASSERT3(ssl); - - SSL_METHOD_CALL(free, ssl); - - X509_free(ssl->client_CA); - - ssl_cert_free(ssl->cert); - - SSL_SESSION_free(ssl->session); - - if (ssl->alpn_protos) - ssl_mem_free(ssl->alpn_protos); - - ssl_mem_free(ssl); -} - -/** - * @brief perform the SSL handshake - */ -int SSL_do_handshake(SSL *ssl) -{ - int ret; - - SSL_ASSERT1(ssl); - - ret = SSL_METHOD_CALL(handshake, ssl); - - return ret; -} - -/** - * @brief connect to the remote SSL server - */ -int SSL_connect(SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return SSL_do_handshake(ssl); -} - -/** - * @brief accept the remote connection - */ -int SSL_accept(SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return SSL_do_handshake(ssl); -} - -/** - * @brief shutdown the connection - */ -int SSL_shutdown(SSL *ssl) -{ - int ret; - - SSL_ASSERT1(ssl); - - if (SSL_get_state(ssl) != TLS_ST_OK) return 1; - - ret = SSL_METHOD_CALL(shutdown, ssl); - - return ret; -} - -/** - * @brief reset the SSL - */ -int SSL_clear(SSL *ssl) -{ - int ret; - - SSL_ASSERT1(ssl); - - ret = SSL_shutdown(ssl); - if (1 != ret) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_shutdown return %d", ret); - goto failed1; - } - - SSL_METHOD_CALL(free, ssl); - - ret = SSL_METHOD_CALL(new, ssl); - if (!ret) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret); - goto failed1; - } - - return 1; - -failed1: - return ret; -} - -/** - * @brief read data from to remote - */ -int SSL_read(SSL *ssl, void *buffer, int len) -{ - int ret; - - SSL_ASSERT1(ssl); - SSL_ASSERT1(buffer); - SSL_ASSERT1(len); - - ssl->rwstate = SSL_READING; - - ret = SSL_METHOD_CALL(read, ssl, buffer, len); - - if (ret == len) - ssl->rwstate = SSL_NOTHING; - - return ret; -} - -/** - * @brief send the data to remote - */ -int SSL_write(SSL *ssl, const void *buffer, int len) -{ - int ret; - int send_bytes, bytes; - const unsigned char *pbuf; - - SSL_ASSERT1(ssl); - SSL_ASSERT1(buffer); - SSL_ASSERT1(len); - - ssl->rwstate = SSL_WRITING; - - send_bytes = len; - pbuf = (const unsigned char *)buffer; - - do { - if (send_bytes > SSL_SEND_DATA_MAX_LENGTH) - bytes = SSL_SEND_DATA_MAX_LENGTH; - else - bytes = send_bytes; - - if (ssl->interrupted_remaining_write) { - bytes = ssl->interrupted_remaining_write; - ssl->interrupted_remaining_write = 0; - } - - ret = SSL_METHOD_CALL(send, ssl, pbuf, bytes); - //printf("%s: ssl_pm said %d for %d requested (cum %d)\n", __func__, ret, bytes, len -send_bytes); - /* the return is a NEGATIVE OpenSSL error code, or the length sent */ - if (ret > 0) { - pbuf += ret; - send_bytes -= ret; - } else - ssl->interrupted_remaining_write = bytes; - } while (ret > 0 && send_bytes && ret == bytes); - - if (ret >= 0) { - ret = len - send_bytes; - if (!ret) - ssl->rwstate = SSL_NOTHING; - } else { - if (send_bytes == len) - ret = -1; - else - ret = len - send_bytes; - } - - return ret; -} - -/** - * @brief get SSL context of the SSL - */ -SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) -{ - SSL_ASSERT2(ssl); - - return ssl->ctx; -} - -/** - * @brief get the SSL current method - */ -const SSL_METHOD *SSL_get_ssl_method(SSL *ssl) -{ - SSL_ASSERT2(ssl); - - return ssl->method; -} - -/** - * @brief set the SSL method - */ -int SSL_set_ssl_method(SSL *ssl, const SSL_METHOD *method) -{ - int ret; - - SSL_ASSERT1(ssl); - SSL_ASSERT1(method); - - if (ssl->version != method->version) { - - ret = SSL_shutdown(ssl); - if (1 != ret) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_shutdown return %d", ret); - goto failed1; - } - - SSL_METHOD_CALL(free, ssl); - - ssl->method = method; - - ret = SSL_METHOD_CALL(new, ssl); - if (!ret) { - SSL_DEBUG(SSL_LIB_ERROR_LEVEL, "SSL_METHOD_CALL(new) return %d", ret); - goto failed1; - } - } else { - ssl->method = method; - } - - - return 1; - -failed1: - return ret; -} - -/** - * @brief get SSL shutdown mode - */ -int SSL_get_shutdown(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return ssl->shutdown; -} - -/** - * @brief set SSL shutdown mode - */ -void SSL_set_shutdown(SSL *ssl, int mode) -{ - SSL_ASSERT3(ssl); - - ssl->shutdown = mode; -} - - -/** - * @brief get the number of the bytes to be read - */ -int SSL_pending(const SSL *ssl) -{ - int ret; - - SSL_ASSERT1(ssl); - - ret = SSL_METHOD_CALL(pending, ssl); - - return ret; -} - -/** - * @brief check if some data can be read - */ -int SSL_has_pending(const SSL *ssl) -{ - int ret; - - SSL_ASSERT1(ssl); - - if (SSL_pending(ssl)) - ret = 1; - else - ret = 0; - - return ret; -} - -/** - * @brief clear the SSL context option bit of "op" - */ -unsigned long SSL_CTX_clear_options(SSL_CTX *ctx, unsigned long op) -{ - SSL_ASSERT1(ctx); - - return ctx->options &= ~op; -} - -/** - * @brief get the SSL context option - */ -unsigned long SSL_CTX_get_options(SSL_CTX *ctx) -{ - SSL_ASSERT1(ctx); - - return ctx->options; -} - -/** - * @brief set the option of the SSL context - */ -unsigned long SSL_CTX_set_options(SSL_CTX *ctx, unsigned long opt) -{ - SSL_ASSERT1(ctx); - - return ctx->options |= opt; -} - -/** - * @brief clear SSL option - */ -unsigned long SSL_clear_options(SSL *ssl, unsigned long op) -{ - SSL_ASSERT1(ssl); - - return ssl->options & ~op; -} - -/** - * @brief get SSL option - */ -unsigned long SSL_get_options(SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return ssl->options; -} - -/** - * @brief clear SSL option - */ -unsigned long SSL_set_options(SSL *ssl, unsigned long op) -{ - SSL_ASSERT1(ssl); - - return ssl->options |= op; -} - -/** - * @brief get the socket handle of the SSL - */ -int SSL_get_fd(const SSL *ssl) -{ - int ret; - - SSL_ASSERT1(ssl); - - ret = SSL_METHOD_CALL(get_fd, ssl, 0); - - return ret; -} - -/** - * @brief get the read only socket handle of the SSL - */ -int SSL_get_rfd(const SSL *ssl) -{ - int ret; - - SSL_ASSERT1(ssl); - - ret = SSL_METHOD_CALL(get_fd, ssl, 0); - - return ret; -} - -/** - * @brief get the write only socket handle of the SSL - */ -int SSL_get_wfd(const SSL *ssl) -{ - int ret; - - SSL_ASSERT1(ssl); - - ret = SSL_METHOD_CALL(get_fd, ssl, 0); - - return ret; -} - -/** - * @brief bind the socket file description into the SSL - */ -int SSL_set_fd(SSL *ssl, int fd) -{ - SSL_ASSERT1(ssl); - SSL_ASSERT1(fd >= 0); - - SSL_METHOD_CALL(set_fd, ssl, fd, 0); - - return 1; -} - -/** - * @brief bind the read only socket file description into the SSL - */ -int SSL_set_rfd(SSL *ssl, int fd) -{ - SSL_ASSERT1(ssl); - SSL_ASSERT1(fd >= 0); - - SSL_METHOD_CALL(set_fd, ssl, fd, 0); - - return 1; -} - -/** - * @brief bind the write only socket file description into the SSL - */ -int SSL_set_wfd(SSL *ssl, int fd) -{ - SSL_ASSERT1(ssl); - SSL_ASSERT1(fd >= 0); - - SSL_METHOD_CALL(set_fd, ssl, fd, 0); - - return 1; -} - -/** - * @brief get SSL version - */ -int SSL_version(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return ssl->version; -} - -/** - * @brief get the SSL version string - */ -static const char* ssl_protocol_to_string(int version) -{ - const char *str; - - if (version == TLS1_2_VERSION) - str = "TLSv1.2"; - else if (version == TLS1_1_VERSION) - str = "TLSv1.1"; - else if (version == TLS1_VERSION) - str = "TLSv1"; - else if (version == SSL3_VERSION) - str = "SSLv3"; - else - str = "unknown"; - - return str; -} - -/** - * @brief get the SSL current version - */ -const char *SSL_get_version(const SSL *ssl) -{ - SSL_ASSERT2(ssl); - - return ssl_protocol_to_string(SSL_version(ssl)); -} - -/** - * @brief get alert description string - */ -const char* SSL_alert_desc_string(int value) -{ - const char *str; - - switch (value & 0xff) - { - case SSL3_AD_CLOSE_NOTIFY: - str = "CN"; - break; - case SSL3_AD_UNEXPECTED_MESSAGE: - str = "UM"; - break; - case SSL3_AD_BAD_RECORD_MAC: - str = "BM"; - break; - case SSL3_AD_DECOMPRESSION_FAILURE: - str = "DF"; - break; - case SSL3_AD_HANDSHAKE_FAILURE: - str = "HF"; - break; - case SSL3_AD_NO_CERTIFICATE: - str = "NC"; - break; - case SSL3_AD_BAD_CERTIFICATE: - str = "BC"; - break; - case SSL3_AD_UNSUPPORTED_CERTIFICATE: - str = "UC"; - break; - case SSL3_AD_CERTIFICATE_REVOKED: - str = "CR"; - break; - case SSL3_AD_CERTIFICATE_EXPIRED: - str = "CE"; - break; - case SSL3_AD_CERTIFICATE_UNKNOWN: - str = "CU"; - break; - case SSL3_AD_ILLEGAL_PARAMETER: - str = "IP"; - break; - case TLS1_AD_DECRYPTION_FAILED: - str = "DC"; - break; - case TLS1_AD_RECORD_OVERFLOW: - str = "RO"; - break; - case TLS1_AD_UNKNOWN_CA: - str = "CA"; - break; - case TLS1_AD_ACCESS_DENIED: - str = "AD"; - break; - case TLS1_AD_DECODE_ERROR: - str = "DE"; - break; - case TLS1_AD_DECRYPT_ERROR: - str = "CY"; - break; - case TLS1_AD_EXPORT_RESTRICTION: - str = "ER"; - break; - case TLS1_AD_PROTOCOL_VERSION: - str = "PV"; - break; - case TLS1_AD_INSUFFICIENT_SECURITY: - str = "IS"; - break; - case TLS1_AD_INTERNAL_ERROR: - str = "IE"; - break; - case TLS1_AD_USER_CANCELLED: - str = "US"; - break; - case TLS1_AD_NO_RENEGOTIATION: - str = "NR"; - break; - case TLS1_AD_UNSUPPORTED_EXTENSION: - str = "UE"; - break; - case TLS1_AD_CERTIFICATE_UNOBTAINABLE: - str = "CO"; - break; - case TLS1_AD_UNRECOGNIZED_NAME: - str = "UN"; - break; - case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: - str = "BR"; - break; - case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: - str = "BH"; - break; - case TLS1_AD_UNKNOWN_PSK_IDENTITY: - str = "UP"; - break; - default: - str = "UK"; - break; - } - - return str; -} - -/** - * @brief get alert description long string - */ -const char* SSL_alert_desc_string_long(int value) -{ - const char *str; - - switch (value & 0xff) - { - case SSL3_AD_CLOSE_NOTIFY: - str = "close notify"; - break; - case SSL3_AD_UNEXPECTED_MESSAGE: - str = "unexpected_message"; - break; - case SSL3_AD_BAD_RECORD_MAC: - str = "bad record mac"; - break; - case SSL3_AD_DECOMPRESSION_FAILURE: - str = "decompression failure"; - break; - case SSL3_AD_HANDSHAKE_FAILURE: - str = "handshake failure"; - break; - case SSL3_AD_NO_CERTIFICATE: - str = "no certificate"; - break; - case SSL3_AD_BAD_CERTIFICATE: - str = "bad certificate"; - break; - case SSL3_AD_UNSUPPORTED_CERTIFICATE: - str = "unsupported certificate"; - break; - case SSL3_AD_CERTIFICATE_REVOKED: - str = "certificate revoked"; - break; - case SSL3_AD_CERTIFICATE_EXPIRED: - str = "certificate expired"; - break; - case SSL3_AD_CERTIFICATE_UNKNOWN: - str = "certificate unknown"; - break; - case SSL3_AD_ILLEGAL_PARAMETER: - str = "illegal parameter"; - break; - case TLS1_AD_DECRYPTION_FAILED: - str = "decryption failed"; - break; - case TLS1_AD_RECORD_OVERFLOW: - str = "record overflow"; - break; - case TLS1_AD_UNKNOWN_CA: - str = "unknown CA"; - break; - case TLS1_AD_ACCESS_DENIED: - str = "access denied"; - break; - case TLS1_AD_DECODE_ERROR: - str = "decode error"; - break; - case TLS1_AD_DECRYPT_ERROR: - str = "decrypt error"; - break; - case TLS1_AD_EXPORT_RESTRICTION: - str = "export restriction"; - break; - case TLS1_AD_PROTOCOL_VERSION: - str = "protocol version"; - break; - case TLS1_AD_INSUFFICIENT_SECURITY: - str = "insufficient security"; - break; - case TLS1_AD_INTERNAL_ERROR: - str = "internal error"; - break; - case TLS1_AD_USER_CANCELLED: - str = "user canceled"; - break; - case TLS1_AD_NO_RENEGOTIATION: - str = "no renegotiation"; - break; - case TLS1_AD_UNSUPPORTED_EXTENSION: - str = "unsupported extension"; - break; - case TLS1_AD_CERTIFICATE_UNOBTAINABLE: - str = "certificate unobtainable"; - break; - case TLS1_AD_UNRECOGNIZED_NAME: - str = "unrecognized name"; - break; - case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: - str = "bad certificate status response"; - break; - case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: - str = "bad certificate hash value"; - break; - case TLS1_AD_UNKNOWN_PSK_IDENTITY: - str = "unknown PSK identity"; - break; - default: - str = "unknown"; - break; - } - - return str; -} - -/** - * @brief get alert type string - */ -const char *SSL_alert_type_string(int value) -{ - const char *str; - - switch (value >> 8) - { - case SSL3_AL_WARNING: - str = "W"; - break; - case SSL3_AL_FATAL: - str = "F"; - break; - default: - str = "U"; - break; - } - - return str; -} - -/** - * @brief get alert type long string - */ -const char *SSL_alert_type_string_long(int value) -{ - const char *str; - - switch (value >> 8) - { - case SSL3_AL_WARNING: - str = "warning"; - break; - case SSL3_AL_FATAL: - str = "fatal"; - break; - default: - str = "unknown"; - break; - } - - return str; -} - -/** - * @brief get the state string where SSL is reading - */ -const char *SSL_rstate_string(SSL *ssl) -{ - const char *str; - - SSL_ASSERT2(ssl); - - switch (ssl->rlayer.rstate) - { - case SSL_ST_READ_HEADER: - str = "RH"; - break; - case SSL_ST_READ_BODY: - str = "RB"; - break; - case SSL_ST_READ_DONE: - str = "RD"; - break; - default: - str = "unknown"; - break; - } - - return str; -} - -/** - * @brief get the statement long string where SSL is reading - */ -const char *SSL_rstate_string_long(SSL *ssl) -{ - const char *str = "unknown"; - - SSL_ASSERT2(ssl); - - switch (ssl->rlayer.rstate) - { - case SSL_ST_READ_HEADER: - str = "read header"; - break; - case SSL_ST_READ_BODY: - str = "read body"; - break; - case SSL_ST_READ_DONE: - str = "read done"; - break; - default: - break; - } - - return str; -} - -/** - * @brief get SSL statement string - */ -char *SSL_state_string(const SSL *ssl) -{ - char *str = "UNKWN "; - - SSL_ASSERT2(ssl); - - if (ossl_statem_in_error(ssl)) - str = "SSLERR"; - else - { - switch (SSL_get_state(ssl)) - { - case TLS_ST_BEFORE: - str = "PINIT "; - break; - case TLS_ST_OK: - str = "SSLOK "; - break; - case TLS_ST_CW_CLNT_HELLO: - str = "TWCH"; - break; - case TLS_ST_CR_SRVR_HELLO: - str = "TRSH"; - break; - case TLS_ST_CR_CERT: - str = "TRSC"; - break; - case TLS_ST_CR_KEY_EXCH: - str = "TRSKE"; - break; - case TLS_ST_CR_CERT_REQ: - str = "TRCR"; - break; - case TLS_ST_CR_SRVR_DONE: - str = "TRSD"; - break; - case TLS_ST_CW_CERT: - str = "TWCC"; - break; - case TLS_ST_CW_KEY_EXCH: - str = "TWCKE"; - break; - case TLS_ST_CW_CERT_VRFY: - str = "TWCV"; - break; - case TLS_ST_SW_CHANGE: - case TLS_ST_CW_CHANGE: - str = "TWCCS"; - break; - case TLS_ST_SW_FINISHED: - case TLS_ST_CW_FINISHED: - str = "TWFIN"; - break; - case TLS_ST_SR_CHANGE: - case TLS_ST_CR_CHANGE: - str = "TRCCS"; - break; - case TLS_ST_SR_FINISHED: - case TLS_ST_CR_FINISHED: - str = "TRFIN"; - break; - case TLS_ST_SW_HELLO_REQ: - str = "TWHR"; - break; - case TLS_ST_SR_CLNT_HELLO: - str = "TRCH"; - break; - case TLS_ST_SW_SRVR_HELLO: - str = "TWSH"; - break; - case TLS_ST_SW_CERT: - str = "TWSC"; - break; - case TLS_ST_SW_KEY_EXCH: - str = "TWSKE"; - break; - case TLS_ST_SW_CERT_REQ: - str = "TWCR"; - break; - case TLS_ST_SW_SRVR_DONE: - str = "TWSD"; - break; - case TLS_ST_SR_CERT: - str = "TRCC"; - break; - case TLS_ST_SR_KEY_EXCH: - str = "TRCKE"; - break; - case TLS_ST_SR_CERT_VRFY: - str = "TRCV"; - break; - case DTLS_ST_CR_HELLO_VERIFY_REQUEST: - str = "DRCHV"; - break; - case DTLS_ST_SW_HELLO_VERIFY_REQUEST: - str = "DWCHV"; - break; - default: - break; - } - } - - return str; -} - -/** - * @brief get SSL statement long string - */ -char *SSL_state_string_long(const SSL *ssl) -{ - char *str = "UNKWN "; - - SSL_ASSERT2(ssl); - - if (ossl_statem_in_error(ssl)) - str = "SSLERR"; - else - { - switch (SSL_get_state(ssl)) - { - case TLS_ST_BEFORE: - str = "before SSL initialization"; - break; - case TLS_ST_OK: - str = "SSL negotiation finished successfully"; - break; - case TLS_ST_CW_CLNT_HELLO: - str = "SSLv3/TLS write client hello"; - break; - case TLS_ST_CR_SRVR_HELLO: - str = "SSLv3/TLS read server hello"; - break; - case TLS_ST_CR_CERT: - str = "SSLv3/TLS read server certificate"; - break; - case TLS_ST_CR_KEY_EXCH: - str = "SSLv3/TLS read server key exchange"; - break; - case TLS_ST_CR_CERT_REQ: - str = "SSLv3/TLS read server certificate request"; - break; - case TLS_ST_CR_SESSION_TICKET: - str = "SSLv3/TLS read server session ticket"; - break; - case TLS_ST_CR_SRVR_DONE: - str = "SSLv3/TLS read server done"; - break; - case TLS_ST_CW_CERT: - str = "SSLv3/TLS write client certificate"; - break; - case TLS_ST_CW_KEY_EXCH: - str = "SSLv3/TLS write client key exchange"; - break; - case TLS_ST_CW_CERT_VRFY: - str = "SSLv3/TLS write certificate verify"; - break; - case TLS_ST_CW_CHANGE: - case TLS_ST_SW_CHANGE: - str = "SSLv3/TLS write change cipher spec"; - break; - case TLS_ST_CW_FINISHED: - case TLS_ST_SW_FINISHED: - str = "SSLv3/TLS write finished"; - break; - case TLS_ST_CR_CHANGE: - case TLS_ST_SR_CHANGE: - str = "SSLv3/TLS read change cipher spec"; - break; - case TLS_ST_CR_FINISHED: - case TLS_ST_SR_FINISHED: - str = "SSLv3/TLS read finished"; - break; - case TLS_ST_SR_CLNT_HELLO: - str = "SSLv3/TLS read client hello"; - break; - case TLS_ST_SW_HELLO_REQ: - str = "SSLv3/TLS write hello request"; - break; - case TLS_ST_SW_SRVR_HELLO: - str = "SSLv3/TLS write server hello"; - break; - case TLS_ST_SW_CERT: - str = "SSLv3/TLS write certificate"; - break; - case TLS_ST_SW_KEY_EXCH: - str = "SSLv3/TLS write key exchange"; - break; - case TLS_ST_SW_CERT_REQ: - str = "SSLv3/TLS write certificate request"; - break; - case TLS_ST_SW_SESSION_TICKET: - str = "SSLv3/TLS write session ticket"; - break; - case TLS_ST_SW_SRVR_DONE: - str = "SSLv3/TLS write server done"; - break; - case TLS_ST_SR_CERT: - str = "SSLv3/TLS read client certificate"; - break; - case TLS_ST_SR_KEY_EXCH: - str = "SSLv3/TLS read client key exchange"; - break; - case TLS_ST_SR_CERT_VRFY: - str = "SSLv3/TLS read certificate verify"; - break; - case DTLS_ST_CR_HELLO_VERIFY_REQUEST: - str = "DTLS1 read hello verify request"; - break; - case DTLS_ST_SW_HELLO_VERIFY_REQUEST: - str = "DTLS1 write hello verify request"; - break; - default: - break; - } - } - - return str; -} - -/** - * @brief set the SSL context read buffer length - */ -void SSL_CTX_set_default_read_buffer_len(SSL_CTX *ctx, size_t len) -{ - SSL_ASSERT3(ctx); - - ctx->read_buffer_len = len; -} - -/** - * @brief set the SSL read buffer length - */ -void SSL_set_default_read_buffer_len(SSL *ssl, size_t len) -{ - SSL_ASSERT3(ssl); - SSL_ASSERT3(len); - - SSL_METHOD_CALL(set_bufflen, ssl, len); -} - -/** - * @brief set the SSL information callback function - */ -void SSL_set_info_callback(SSL *ssl, void (*cb) (const SSL *ssl, int type, int val)) -{ - SSL_ASSERT3(ssl); - - ssl->info_callback = cb; -} - -/** - * @brief add SSL context reference count by '1' - */ -int SSL_CTX_up_ref(SSL_CTX *ctx) -{ - SSL_ASSERT1(ctx); - - /** - * no support multi-thread SSL here - */ - ctx->references++; - - return 1; -} - -/** - * @brief set the SSL security level - */ -void SSL_set_security_level(SSL *ssl, int level) -{ - SSL_ASSERT3(ssl); - - ssl->cert->sec_level = level; -} - -/** - * @brief get the SSL security level - */ -int SSL_get_security_level(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return ssl->cert->sec_level; -} - -/** - * @brief get the SSL verifying mode of the SSL context - */ -int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) -{ - SSL_ASSERT1(ctx); - - return ctx->verify_mode; -} - -/** - * @brief set the session timeout time - */ -long SSL_CTX_set_timeout(SSL_CTX *ctx, long t) -{ - long l; - - SSL_ASSERT1(ctx); - - l = ctx->session_timeout; - ctx->session_timeout = t; - - return l; -} - -/** - * @brief get the session timeout time - */ -long SSL_CTX_get_timeout(const SSL_CTX *ctx) -{ - SSL_ASSERT1(ctx); - - return ctx->session_timeout; -} - -/** - * @brief set the SSL if we can read as many as data - */ -void SSL_set_read_ahead(SSL *ssl, int yes) -{ - SSL_ASSERT3(ssl); - - ssl->rlayer.read_ahead = yes; -} - -/** - * @brief set the SSL context if we can read as many as data - */ -void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) -{ - SSL_ASSERT3(ctx); - - ctx->read_ahead = yes; -} - -/** - * @brief get the SSL ahead signal if we can read as many as data - */ -int SSL_get_read_ahead(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return ssl->rlayer.read_ahead; -} - -/** - * @brief get the SSL context ahead signal if we can read as many as data - */ -long SSL_CTX_get_read_ahead(SSL_CTX *ctx) -{ - SSL_ASSERT1(ctx); - - return ctx->read_ahead; -} - -/** - * @brief check if the SSL context can read as many as data - */ -long SSL_CTX_get_default_read_ahead(SSL_CTX *ctx) -{ - SSL_ASSERT1(ctx); - - return ctx->read_ahead; -} - -/** - * @brief set SSL session time - */ -long SSL_set_time(SSL *ssl, long t) -{ - SSL_ASSERT1(ssl); - - ssl->session->time = t; - - return t; -} - -/** - * @brief set SSL session timeout time - */ -long SSL_set_timeout(SSL *ssl, long t) -{ - SSL_ASSERT1(ssl); - - ssl->session->timeout = t; - - return t; -} - -/** - * @brief get the verifying result of the SSL certification - */ -long SSL_get_verify_result(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return SSL_METHOD_CALL(get_verify_result, ssl); -} - -/** - * @brief get the SSL verifying depth of the SSL context - */ -int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) -{ - SSL_ASSERT1(ctx); - - return ctx->param.depth; -} - -/** - * @brief set the SSL verify depth of the SSL context - */ -void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) -{ - SSL_ASSERT3(ctx); - - ctx->param.depth = depth; -} - -/** - * @brief get the SSL verifying depth of the SSL - */ -int SSL_get_verify_depth(const SSL *ssl) -{ - SSL_ASSERT1(ssl); - - return ssl->param.depth; -} - -/** - * @brief set the SSL verify depth of the SSL - */ -void SSL_set_verify_depth(SSL *ssl, int depth) -{ - SSL_ASSERT3(ssl); - - ssl->param.depth = depth; -} - -/** - * @brief set the SSL context verifying of the SSL context - */ -void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) -{ - SSL_ASSERT3(ctx); - - ctx->verify_mode = mode; - ctx->default_verify_callback = verify_callback; -} - -/** - * @brief set the SSL verifying of the SSL context - */ -void SSL_set_verify(SSL *ssl, int mode, int (*verify_callback)(int, X509_STORE_CTX *)) -{ - SSL_ASSERT3(ssl); - - ssl->verify_mode = mode; - ssl->verify_callback = verify_callback; -} - -void ERR_error_string_n(unsigned long e, char *buf, size_t len) -{ - lws_strncpy(buf, "unknown", len); -} - -void ERR_free_strings(void) -{ -} - -char *ERR_error_string(unsigned long e, char *buf) -{ - if (!buf) - return "unknown"; - - switch(e) { - case X509_V_ERR_INVALID_CA: - strcpy(buf, "CA is not trusted"); - break; - case X509_V_ERR_HOSTNAME_MISMATCH: - strcpy(buf, "Hostname mismatch"); - break; - case X509_V_ERR_CA_KEY_TOO_SMALL: - strcpy(buf, "CA key too small"); - break; - case X509_V_ERR_CA_MD_TOO_WEAK: - strcpy(buf, "MD key too weak"); - break; - case X509_V_ERR_CERT_NOT_YET_VALID: - strcpy(buf, "Cert from the future"); - break; - case X509_V_ERR_CERT_HAS_EXPIRED: - strcpy(buf, "Cert expired"); - break; - default: - strcpy(buf, "unknown"); - break; - } - - return buf; -} - -void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) -{ - return NULL; -} - -/* - * Openssl wants the valid protocol names supplied like this: - * - * (unsigned char *)"\x02h2\x08http/1.1", 6 + 9 - * - * Mbedtls wants this: - * - * Pointer to a NULL-terminated list of supported protocols, in decreasing - * preference order. The pointer to the list is recorded by the library for - * later reference as required, so the lifetime of the table must be at least - * as long as the lifetime of the SSL configuration structure. - * - * So accept the OpenSSL style and convert to mbedtls style - */ - -struct alpn_ctx { - unsigned char data[23]; - unsigned char len; -}; - -static void -_openssl_alpn_to_mbedtls(struct alpn_ctx *ac, char ***palpn_protos) -{ - unsigned char *p = ac->data, *q; - unsigned char len; - char **alpn_protos; - int count = 0; - - /* find out how many entries he gave us */ - - len = *p++; - while (p - ac->data < ac->len) { - if (len--) { - p++; - continue; - } - count++; - len = *p++; - if (!len) - break; - } - - if (!len) - count++; - - if (!count) - return; - - /* allocate space for count + 1 pointers and the data afterwards */ - - alpn_protos = ssl_mem_zalloc((count + 1) * sizeof(char *) + ac->len + 1); - if (!alpn_protos) - return; - - *palpn_protos = alpn_protos; - - /* convert to mbedtls format */ - - q = (unsigned char *)alpn_protos + (count + 1) * sizeof(char *); - p = ac->data; - count = 0; - - len = *p++; - alpn_protos[count] = (char *)q; - while (p - ac->data < ac->len) { - if (len--) { - *q++ = *p++; - continue; - } - *q++ = '\0'; - count++; - len = *p++; - alpn_protos[count] = (char *)q; - if (!len) - break; - } - if (!len) { - *q++ = '\0'; - count++; - len = *p++; - alpn_protos[count] = (char *)q; - } - alpn_protos[count] = NULL; /* last pointer ends list with NULL */ -} - -void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, next_proto_cb cb, void *arg) -{ - struct alpn_ctx *ac = arg; - - ctx->alpn_cb = cb; - - _openssl_alpn_to_mbedtls(ac, (char ***)&ctx->alpn_protos); -} - -void SSL_set_alpn_select_cb(SSL *ssl, void *arg) -{ - struct alpn_ctx *ac = arg; - - _openssl_alpn_to_mbedtls(ac, (char ***)&ssl->alpn_protos); - - _ssl_set_alpn_list(ssl); -} diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_methods.c b/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_methods.c deleted file mode 100644 index 0002360846..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_methods.c +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#include "ssl_methods.h" -#include "ssl_pm.h" - -/** - * TLS method function collection - */ -IMPLEMENT_TLS_METHOD_FUNC(TLS_method_func, - ssl_pm_new, ssl_pm_free, - ssl_pm_handshake, ssl_pm_shutdown, ssl_pm_clear, - ssl_pm_read, ssl_pm_send, ssl_pm_pending, - ssl_pm_set_fd, ssl_pm_get_fd, - ssl_pm_set_bufflen, - ssl_pm_get_verify_result, - ssl_pm_get_state); - -/** - * TLS or SSL client method collection - */ -IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 0, TLS_method_func, TLS_client_method); - -IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 0, TLS_method_func, TLSv1_2_client_method); - -IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 0, TLS_method_func, TLSv1_1_client_method); - -IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_client_method); - -IMPLEMENT_SSL_METHOD(SSL3_VERSION, 0, TLS_method_func, SSLv3_client_method); - -/** - * TLS or SSL server method collection - */ -IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, 1, TLS_method_func, TLS_server_method); - -IMPLEMENT_TLS_METHOD(TLS1_1_VERSION, 1, TLS_method_func, TLSv1_1_server_method); - -IMPLEMENT_TLS_METHOD(TLS1_2_VERSION, 1, TLS_method_func, TLSv1_2_server_method); - -IMPLEMENT_TLS_METHOD(TLS1_VERSION, 0, TLS_method_func, TLSv1_server_method); - -IMPLEMENT_SSL_METHOD(SSL3_VERSION, 1, TLS_method_func, SSLv3_server_method); - -/** - * TLS or SSL method collection - */ -IMPLEMENT_TLS_METHOD(TLS_ANY_VERSION, -1, TLS_method_func, TLS_method); - -IMPLEMENT_SSL_METHOD(TLS1_2_VERSION, -1, TLS_method_func, TLSv1_2_method); - -IMPLEMENT_SSL_METHOD(TLS1_1_VERSION, -1, TLS_method_func, TLSv1_1_method); - -IMPLEMENT_SSL_METHOD(TLS1_VERSION, -1, TLS_method_func, TLSv1_method); - -IMPLEMENT_SSL_METHOD(SSL3_VERSION, -1, TLS_method_func, SSLv3_method); - -/** - * @brief get X509 object method - */ -IMPLEMENT_X509_METHOD(X509_method, - x509_pm_new, x509_pm_free, - x509_pm_load, x509_pm_show_info); - -/** - * @brief get private key object method - */ -IMPLEMENT_PKEY_METHOD(EVP_PKEY_method, - pkey_pm_new, pkey_pm_free, - pkey_pm_load); diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_pkey.c b/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_pkey.c deleted file mode 100644 index 567a33e2c2..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_pkey.c +++ /dev/null @@ -1,239 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#include "ssl_pkey.h" -#include "ssl_methods.h" -#include "ssl_dbg.h" -#include "ssl_port.h" - -/** - * @brief create a private key object according to input private key - */ -EVP_PKEY* __EVP_PKEY_new(EVP_PKEY *ipk) -{ - int ret; - EVP_PKEY *pkey; - - pkey = ssl_mem_zalloc(sizeof(EVP_PKEY)); - if (!pkey) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "no enough memory > (pkey)"); - goto no_mem; - } - - if (ipk) { - pkey->method = ipk->method; - } else { - pkey->method = EVP_PKEY_method(); - } - - ret = EVP_PKEY_METHOD_CALL(new, pkey, ipk); - if (ret) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(new) return %d", ret); - goto failed; - } - - return pkey; - -failed: - ssl_mem_free(pkey); -no_mem: - return NULL; -} - -/** - * @brief create a private key object - */ -EVP_PKEY* EVP_PKEY_new(void) -{ - return __EVP_PKEY_new(NULL); -} - -/** - * @brief free a private key object - */ -void EVP_PKEY_free(EVP_PKEY *pkey) -{ - SSL_ASSERT3(pkey); - - EVP_PKEY_METHOD_CALL(free, pkey); - - ssl_mem_free(pkey); -} - -/** - * @brief load a character key context into system context. If '*a' is pointed to the - * private key, then load key into it. Or create a new private key object - */ -EVP_PKEY *d2i_PrivateKey(int type, - EVP_PKEY **a, - const unsigned char **pp, - long length) -{ - int m = 0; - int ret; - EVP_PKEY *pkey; - - SSL_ASSERT2(pp); - SSL_ASSERT2(*pp); - SSL_ASSERT2(length); - - if (a && *a) { - pkey = *a; - } else { - pkey = EVP_PKEY_new();; - if (!pkey) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_new() return NULL"); - goto failed1; - } - - m = 1; - } - - ret = EVP_PKEY_METHOD_CALL(load, pkey, *pp, length); - if (ret) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "EVP_PKEY_METHOD_CALL(load) return %d", ret); - goto failed2; - } - - if (a) - *a = pkey; - - return pkey; - -failed2: - if (m) - EVP_PKEY_free(pkey); -failed1: - return NULL; -} - -/** - * @brief set the SSL context private key - */ -int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) -{ - SSL_ASSERT1(ctx); - SSL_ASSERT1(pkey); - - if (ctx->cert->pkey == pkey) - return 1; - - if (ctx->cert->pkey) - EVP_PKEY_free(ctx->cert->pkey); - - ctx->cert->pkey = pkey; - - return 1; -} - -/** - * @brief set the SSL private key - */ -int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) -{ - SSL_ASSERT1(ssl); - SSL_ASSERT1(pkey); - - if (ssl->cert->pkey == pkey) - return 1; - - if (ssl->cert->pkey) - EVP_PKEY_free(ssl->cert->pkey); - - ssl->cert->pkey = pkey; - - return 1; -} - -/** - * @brief load private key into the SSL context - */ -int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, - const unsigned char *d, long len) -{ - int ret; - EVP_PKEY *pk; - - pk = d2i_PrivateKey(0, NULL, &d, len); - if (!pk) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL"); - goto failed1; - } - - ret = SSL_CTX_use_PrivateKey(ctx, pk); - if (!ret) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_PrivateKey() return %d", ret); - goto failed2; - } - - return 1; - -failed2: - EVP_PKEY_free(pk); -failed1: - return 0; -} - -/** - * @brief load private key into the SSL - */ -int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, - const unsigned char *d, long len) -{ - int ret; - EVP_PKEY *pk; - - pk = d2i_PrivateKey(0, NULL, &d, len); - if (!pk) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_PrivateKey() return NULL"); - goto failed1; - } - - ret = SSL_use_PrivateKey(ssl, pk); - if (!ret) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_PrivateKey() return %d", ret); - goto failed2; - } - - return 1; - -failed2: - EVP_PKEY_free(pk); -failed1: - return 0; -} - -/** - * @brief load the private key file into SSL context - */ -int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) -{ - return 0; -} - -/** - * @brief load the private key file into SSL - */ -int SSL_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) -{ - return 0; -} - -/** - * @brief load the RSA ASN1 private key into SSL context - */ -int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, long len) -{ - return SSL_CTX_use_PrivateKey_ASN1(0, ctx, d, len); -} diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_stack.c b/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_stack.c deleted file mode 100644 index da836daf9c..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_stack.c +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#include "ssl_stack.h" -#include "ssl_dbg.h" -#include "ssl_port.h" - -#ifndef CONFIG_MIN_NODES - #define MIN_NODES 4 -#else - #define MIN_NODES CONFIG_MIN_NODES -#endif - -/** - * @brief create a openssl stack object - */ -OPENSSL_STACK* OPENSSL_sk_new(OPENSSL_sk_compfunc c) -{ - OPENSSL_STACK *stack; - char **data; - - stack = ssl_mem_zalloc(sizeof(OPENSSL_STACK)); - if (!stack) { - SSL_DEBUG(SSL_STACK_ERROR_LEVEL, "no enough memory > (stack)"); - goto no_mem1; - } - - data = ssl_mem_zalloc(sizeof(*data) * MIN_NODES); - if (!data) { - SSL_DEBUG(SSL_STACK_ERROR_LEVEL, "no enough memory > (data)"); - goto no_mem2; - } - - stack->data = data; - stack->num_alloc = MIN_NODES; - stack->c = c; - - return stack; - -no_mem2: - ssl_mem_free(stack); -no_mem1: - return NULL; -} - -/** - * @brief create a NULL function openssl stack object - */ -OPENSSL_STACK *OPENSSL_sk_new_null(void) -{ - return OPENSSL_sk_new((OPENSSL_sk_compfunc)NULL); -} - -/** - * @brief free openssl stack object - */ -void OPENSSL_sk_free(OPENSSL_STACK *stack) -{ - SSL_ASSERT3(stack); - - ssl_mem_free(stack->data); - ssl_mem_free(stack); -} diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_x509.c b/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_x509.c deleted file mode 100644 index ed79150831..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/library/ssl_x509.c +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#include "ssl_x509.h" -#include "ssl_methods.h" -#include "ssl_dbg.h" -#include "ssl_port.h" - -#include <assert.h> - -/** - * @brief show X509 certification information - */ -int __X509_show_info(X509 *x) -{ - return X509_METHOD_CALL(show_info, x); -} - -/** - * @brief create a X509 certification object according to input X509 certification - */ -X509* __X509_new(X509 *ix) -{ - int ret; - X509 *x; - - x = ssl_mem_zalloc(sizeof(X509)); - if (!x) { - SSL_DEBUG(SSL_X509_ERROR_LEVEL, "no enough memory > (x)"); - goto no_mem; - } - - if (ix) - x->method = ix->method; - else - x->method = X509_method(); - - ret = X509_METHOD_CALL(new, x, ix); - if (ret) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(new) return %d", ret); - goto failed; - } - - return x; - -failed: - ssl_mem_free(x); -no_mem: - return NULL; -} - -/** - * @brief create a X509 certification object - */ -X509* X509_new(void) -{ - return __X509_new(NULL); -} - -/** - * @brief free a X509 certification object - */ -void X509_free(X509 *x) -{ - SSL_ASSERT3(x); - - X509_METHOD_CALL(free, x); - - ssl_mem_free(x); -}; - -/** - * @brief load a character certification context into system context. If '*cert' is pointed to the - * certification, then load certification into it. Or create a new X509 certification object - */ -X509* d2i_X509(X509 **cert, const unsigned char *buffer, long len) -{ - int m = 0; - int ret; - X509 *x; - - SSL_ASSERT2(buffer); - SSL_ASSERT2(len); - - if (cert && *cert) { - x = *cert; - } else { - x = X509_new(); - if (!x) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_new() return NULL"); - goto failed1; - } - m = 1; - } - - ret = X509_METHOD_CALL(load, x, buffer, len); - if (ret) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "X509_METHOD_CALL(load) return %d", ret); - goto failed2; - } - - return x; - -failed2: - if (m) - X509_free(x); -failed1: - return NULL; -} - -/** - * @brief return SSL X509 verify parameters - */ - -X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) -{ - return &ssl->param; -} - -/** - * @brief set X509 host verification flags - */ - -int X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, - unsigned long flags) -{ - /* flags not supported yet */ - return 0; -} - -/** - * @brief clear X509 host verification flags - */ - -int X509_VERIFY_PARAM_clear_hostflags(X509_VERIFY_PARAM *param, - unsigned long flags) -{ - /* flags not supported yet */ - return 0; -} - -/** - * @brief set SSL context client CA certification - */ -int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) -{ - SSL_ASSERT1(ctx); - SSL_ASSERT1(x); - assert(ctx); - if (ctx->client_CA == x) - return 1; - - X509_free(ctx->client_CA); - - ctx->client_CA = x; - - return 1; -} - -/** - * @brief add CA client certification into the SSL - */ -int SSL_CTX_add_client_CA_ASN1(SSL_CTX *ctx, int len, - const unsigned char *d) -{ - X509 *x; - - x = d2i_X509(NULL, d, len); - if (!x) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); - return 0; - } - SSL_ASSERT1(ctx); - - X509_free(ctx->client_CA); - - ctx->client_CA = x; - - return 1; -} - -/** - * @brief add CA client certification into the SSL - */ -int SSL_add_client_CA(SSL *ssl, X509 *x) -{ - SSL_ASSERT1(ssl); - SSL_ASSERT1(x); - - if (ssl->client_CA == x) - return 1; - - X509_free(ssl->client_CA); - - ssl->client_CA = x; - - return 1; -} - -/** - * @brief set the SSL context certification - */ -int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) -{ - SSL_ASSERT1(ctx); - SSL_ASSERT1(x); - - if (ctx->cert->x509 == x) - return 1; - - X509_free(ctx->cert->x509); - - ctx->cert->x509 = x; - - return 1; -} - -/** - * @brief set the SSL certification - */ -int SSL_use_certificate(SSL *ssl, X509 *x) -{ - SSL_ASSERT1(ssl); - SSL_ASSERT1(x); - - if (ssl->cert->x509 == x) - return 1; - - X509_free(ssl->cert->x509); - - ssl->cert->x509 = x; - - return 1; -} - -/** - * @brief get the SSL certification point - */ -X509 *SSL_get_certificate(const SSL *ssl) -{ - SSL_ASSERT2(ssl); - - return ssl->cert->x509; -} - -/** - * @brief load certification into the SSL context - */ -int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, - const unsigned char *d) -{ - int ret; - X509 *x; - - x = d2i_X509(NULL, d, len); - if (!x) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); - goto failed1; - } - - ret = SSL_CTX_use_certificate(ctx, x); - if (!ret) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_CTX_use_certificate() return %d", ret); - goto failed2; - } - - return 1; - -failed2: - X509_free(x); -failed1: - return 0; -} - -/** - * @brief load certification into the SSL - */ -int SSL_use_certificate_ASN1(SSL *ssl, int len, - const unsigned char *d) -{ - int ret; - X509 *x; - - x = d2i_X509(NULL, d, len); - if (!x) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "d2i_X509() return NULL"); - goto failed1; - } - - ret = SSL_use_certificate(ssl, x); - if (!ret) { - SSL_DEBUG(SSL_PKEY_ERROR_LEVEL, "SSL_use_certificate() return %d", ret); - goto failed2; - } - - return 1; - -failed2: - X509_free(x); -failed1: - return 0; -} - -/** - * @brief load the certification file into SSL context - */ -int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) -{ - return 0; -} - -/** - * @brief load the certification file into SSL - */ -int SSL_use_certificate_file(SSL *ssl, const char *file, int type) -{ - return 0; -} - -/** - * @brief get peer certification - */ -X509 *SSL_get_peer_certificate(const SSL *ssl) -{ - SSL_ASSERT2(ssl); - - return ssl->session->peer; -} - -int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) -{ - return X509_V_ERR_UNSPECIFIED; -} - -int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) -{ - return 0; -} - -const char *X509_verify_cert_error_string(long n) -{ - return "unknown"; -} diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/platform/ssl_pm.c b/thirdparty/libwebsockets/tls/mbedtls/wrapper/platform/ssl_pm.c deleted file mode 100755 index 4716c1ff56..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/platform/ssl_pm.c +++ /dev/null @@ -1,907 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#include "ssl_pm.h" -#include "ssl_port.h" -#include "ssl_dbg.h" - -/* mbedtls include */ -#include "mbedtls/platform.h" -#include "mbedtls/net_sockets.h" -#include "mbedtls/debug.h" -#include "mbedtls/entropy.h" -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/error.h" -#include "mbedtls/certs.h" - -#include <libwebsockets.h> - -#define X509_INFO_STRING_LENGTH 8192 - -struct ssl_pm -{ - /* local socket file description */ - mbedtls_net_context fd; - /* remote client socket file description */ - mbedtls_net_context cl_fd; - - mbedtls_ssl_config conf; - - mbedtls_ctr_drbg_context ctr_drbg; - - mbedtls_ssl_context ssl; - - mbedtls_entropy_context entropy; - - SSL *owner; -}; - -struct x509_pm -{ - mbedtls_x509_crt *x509_crt; - - mbedtls_x509_crt *ex_crt; -}; - -struct pkey_pm -{ - mbedtls_pk_context *pkey; - - mbedtls_pk_context *ex_pkey; -}; - -unsigned int max_content_len; - -/*********************************************************************************************/ -/************************************ SSL arch interface *************************************/ - -//#ifdef CONFIG_OPENSSL_LOWLEVEL_DEBUG - -/* mbedtls debug level */ -#define MBEDTLS_DEBUG_LEVEL 4 - -/** - * @brief mbedtls debug function - */ -static void ssl_platform_debug(void *ctx, int level, - const char *file, int line, - const char *str) -{ - /* Shorten 'file' from the whole file path to just the filename - - This is a bit wasteful because the macros are compiled in with - the full _FILE_ path in each case. - */ -// char *file_sep = rindex(file, '/'); - // if(file_sep) - // file = file_sep + 1; - - printf("%s:%d %s", file, line, str); -} -//#endif - -/** - * @brief create SSL low-level object - */ -int ssl_pm_new(SSL *ssl) -{ - struct ssl_pm *ssl_pm; - int ret; - - const unsigned char pers[] = "OpenSSL PM"; - size_t pers_len = sizeof(pers); - - int endpoint; - int version; - - const SSL_METHOD *method = ssl->method; - - ssl_pm = ssl_mem_zalloc(sizeof(struct ssl_pm)); - if (!ssl_pm) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (ssl_pm)"); - goto no_mem; - } - - ssl_pm->owner = ssl; - - if (!ssl->ctx->read_buffer_len) - ssl->ctx->read_buffer_len = 2048; - - max_content_len = ssl->ctx->read_buffer_len; - // printf("ssl->ctx->read_buffer_len = %d ++++++++++++++++++++\n", ssl->ctx->read_buffer_len); - - mbedtls_net_init(&ssl_pm->fd); - mbedtls_net_init(&ssl_pm->cl_fd); - - mbedtls_ssl_config_init(&ssl_pm->conf); - mbedtls_ctr_drbg_init(&ssl_pm->ctr_drbg); - mbedtls_entropy_init(&ssl_pm->entropy); - mbedtls_ssl_init(&ssl_pm->ssl); - - ret = mbedtls_ctr_drbg_seed(&ssl_pm->ctr_drbg, mbedtls_entropy_func, &ssl_pm->entropy, pers, pers_len); - if (ret) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ctr_drbg_seed() return -0x%x", -ret); - goto mbedtls_err1; - } - - if (method->endpoint) { - endpoint = MBEDTLS_SSL_IS_SERVER; - } else { - endpoint = MBEDTLS_SSL_IS_CLIENT; - } - ret = mbedtls_ssl_config_defaults(&ssl_pm->conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); - if (ret) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_config_defaults() return -0x%x", -ret); - goto mbedtls_err2; - } - - if (TLS_ANY_VERSION != ssl->version) { - if (TLS1_2_VERSION == ssl->version) - version = MBEDTLS_SSL_MINOR_VERSION_3; - else if (TLS1_1_VERSION == ssl->version) - version = MBEDTLS_SSL_MINOR_VERSION_2; - else if (TLS1_VERSION == ssl->version) - version = MBEDTLS_SSL_MINOR_VERSION_1; - else - version = MBEDTLS_SSL_MINOR_VERSION_0; - - mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); - mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, version); - } else { - mbedtls_ssl_conf_max_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); - mbedtls_ssl_conf_min_version(&ssl_pm->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0); - } - - mbedtls_ssl_conf_rng(&ssl_pm->conf, mbedtls_ctr_drbg_random, &ssl_pm->ctr_drbg); - -//#ifdef CONFIG_OPENSSL_LOWLEVEL_DEBUG - // mbedtls_debug_set_threshold(MBEDTLS_DEBUG_LEVEL); -// mbedtls_ssl_conf_dbg(&ssl_pm->conf, ssl_platform_debug, NULL); -//#else - mbedtls_ssl_conf_dbg(&ssl_pm->conf, ssl_platform_debug, NULL); -//#endif - - ret = mbedtls_ssl_setup(&ssl_pm->ssl, &ssl_pm->conf); - if (ret) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_setup() return -0x%x", -ret); - goto mbedtls_err2; - } - - mbedtls_ssl_set_bio(&ssl_pm->ssl, &ssl_pm->fd, mbedtls_net_send, mbedtls_net_recv, NULL); - - ssl->ssl_pm = ssl_pm; - - return 0; - -mbedtls_err2: - mbedtls_ssl_config_free(&ssl_pm->conf); - mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); -mbedtls_err1: - mbedtls_entropy_free(&ssl_pm->entropy); - ssl_mem_free(ssl_pm); -no_mem: - return -1; -} - -/** - * @brief free SSL low-level object - */ -void ssl_pm_free(SSL *ssl) -{ - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - mbedtls_ctr_drbg_free(&ssl_pm->ctr_drbg); - mbedtls_entropy_free(&ssl_pm->entropy); - mbedtls_ssl_config_free(&ssl_pm->conf); - mbedtls_ssl_free(&ssl_pm->ssl); - - ssl_mem_free(ssl_pm); - ssl->ssl_pm = NULL; -} - -/** - * @brief reload SSL low-level certification object - */ -static int ssl_pm_reload_crt(SSL *ssl) -{ - int ret; - int mode; - struct ssl_pm *ssl_pm = ssl->ssl_pm; - struct x509_pm *ca_pm = (struct x509_pm *)ssl->client_CA->x509_pm; - - struct pkey_pm *pkey_pm = (struct pkey_pm *)ssl->cert->pkey->pkey_pm; - struct x509_pm *crt_pm = (struct x509_pm *)ssl->cert->x509->x509_pm; - - if (ssl->verify_mode == SSL_VERIFY_PEER) - mode = MBEDTLS_SSL_VERIFY_OPTIONAL; - else if (ssl->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT) - mode = MBEDTLS_SSL_VERIFY_OPTIONAL; - else if (ssl->verify_mode == SSL_VERIFY_CLIENT_ONCE) - mode = MBEDTLS_SSL_VERIFY_UNSET; - else - mode = MBEDTLS_SSL_VERIFY_NONE; - - mbedtls_ssl_conf_authmode(&ssl_pm->conf, mode); - - if (ca_pm->x509_crt) { - mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->x509_crt, NULL); - } else if (ca_pm->ex_crt) { - mbedtls_ssl_conf_ca_chain(&ssl_pm->conf, ca_pm->ex_crt, NULL); - } - - if (crt_pm->x509_crt && pkey_pm->pkey) { - ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->x509_crt, pkey_pm->pkey); - } else if (crt_pm->ex_crt && pkey_pm->ex_pkey) { - ret = mbedtls_ssl_conf_own_cert(&ssl_pm->conf, crt_pm->ex_crt, pkey_pm->ex_pkey); - } else { - ret = 0; - } - - if (ret) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_conf_own_cert() return -0x%x", -ret); - ret = -1; - } - - return ret; -} - -/* - * Perform the mbedtls SSL handshake instead of mbedtls_ssl_handshake. - * We can add debug here. - */ -static int mbedtls_handshake( mbedtls_ssl_context *ssl ) -{ - int ret = 0; - - while (ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER) { - ret = mbedtls_ssl_handshake_step(ssl); - - lwsl_info("%s: ssl ret -%x state %d\n", __func__, -ret, ssl->state); - - if (ret != 0) - break; - } - - return ret; -} - -#include <errno.h> - -int ssl_pm_handshake(SSL *ssl) -{ - int ret; - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - ssl->err = 0; - errno = 0; - - ret = ssl_pm_reload_crt(ssl); - if (ret) { - printf("%s: cert reload failed\n", __func__); - return 0; - } - - if (ssl_pm->ssl.state != MBEDTLS_SSL_HANDSHAKE_OVER) { - ssl_speed_up_enter(); - - /* mbedtls return codes - * 0 = successful, or MBEDTLS_ERR_SSL_WANT_READ/WRITE - * anything else = death - */ - ret = mbedtls_handshake(&ssl_pm->ssl); - ssl_speed_up_exit(); - } else - ret = 0; - - /* - * OpenSSL return codes: - * 0 = did not complete, but may be retried - * 1 = successfully completed - * <0 = death - */ - if (ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE) { - ssl->err = ret; - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_handshake() return -0x%x", -ret); - return 0; /* OpenSSL: did not complete but may be retried */ - } - - if (ret == 0) { /* successful */ - struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; - - x509_pm->ex_crt = (mbedtls_x509_crt *)mbedtls_ssl_get_peer_cert(&ssl_pm->ssl); - return 1; /* openssl successful */ - } - - if (errno == 11) { - ssl->err = ret == MBEDTLS_ERR_SSL_WANT_READ; - - return 0; - } - - printf("%s: mbedtls_ssl_handshake() returned -0x%x\n", __func__, -ret); - - /* it's had it */ - - ssl->err = SSL_ERROR_SYSCALL; - - return -1; /* openssl death */ -} - -mbedtls_x509_crt * -ssl_ctx_get_mbedtls_x509_crt(SSL_CTX *ssl_ctx) -{ - struct x509_pm *x509_pm = (struct x509_pm *)ssl_ctx->cert->x509->x509_pm; - - if (!x509_pm) - return NULL; - - return x509_pm->x509_crt; -} - -mbedtls_x509_crt * -ssl_get_peer_mbedtls_x509_crt(SSL *ssl) -{ - struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; - - if (!x509_pm) - return NULL; - - return x509_pm->ex_crt; -} - -int ssl_pm_shutdown(SSL *ssl) -{ - int ret; - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - ret = mbedtls_ssl_close_notify(&ssl_pm->ssl); - if (ret) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_close_notify() return -0x%x", -ret); - if (ret == MBEDTLS_ERR_NET_CONN_RESET) - ssl->err = SSL_ERROR_SYSCALL; - ret = -1; /* OpenSSL: "Call SSL_get_error with the return value to find the reason */ - } else { - struct x509_pm *x509_pm = (struct x509_pm *)ssl->session->peer->x509_pm; - - x509_pm->ex_crt = NULL; - ret = 1; /* OpenSSL: "The shutdown was successfully completed" - ...0 means retry */ - } - - return ret; -} - -int ssl_pm_clear(SSL *ssl) -{ - return ssl_pm_shutdown(ssl); -} - - -int ssl_pm_read(SSL *ssl, void *buffer, int len) -{ - int ret; - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - ret = mbedtls_ssl_read(&ssl_pm->ssl, buffer, len); - if (ret < 0) { - // lwsl_notice("%s: mbedtls_ssl_read says -0x%x\n", __func__, -ret); - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_read() return -0x%x", -ret); - if (ret == MBEDTLS_ERR_NET_CONN_RESET || - ret <= MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) /* fatal errors */ - ssl->err = SSL_ERROR_SYSCALL; - ret = -1; - } - - return ret; -} - -/* - * This returns -1, or the length sent. - * If -1, then you need to find out if the error was - * fatal or recoverable using SSL_get_error() - */ -int ssl_pm_send(SSL *ssl, const void *buffer, int len) -{ - int ret; - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - ret = mbedtls_ssl_write(&ssl_pm->ssl, buffer, len); - /* - * We can get a positive number, which may be less than len... that - * much was sent successfully and you can call again to send more. - * - * We can get a negative mbedtls error code... if WANT_WRITE or WANT_READ, - * it's nonfatal and means it should be retried as-is. If something else, - * it's fatal actually. - * - * If this function returns something other than a positive value or - * MBEDTLS_ERR_SSL_WANT_READ/WRITE, the ssl context becomes unusable, and - * you should either free it or call mbedtls_ssl_session_reset() on it - * before re-using it for a new connection; the current connection must - * be closed. - * - * When this function returns MBEDTLS_ERR_SSL_WANT_WRITE/READ, it must be - * called later with the same arguments, until it returns a positive value. - */ - - if (ret < 0) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_ssl_write() return -0x%x", -ret); - switch (ret) { - case MBEDTLS_ERR_NET_SEND_FAILED: - case MBEDTLS_ERR_NET_CONN_RESET: - ssl->err = SSL_ERROR_SYSCALL; - break; - case MBEDTLS_ERR_SSL_WANT_WRITE: - ssl->err = SSL_ERROR_WANT_WRITE; - break; - case MBEDTLS_ERR_SSL_WANT_READ: - ssl->err = SSL_ERROR_WANT_READ; - break; - default: - break; - } - - ret = -1; - } - - return ret; -} - -int ssl_pm_pending(const SSL *ssl) -{ - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - return mbedtls_ssl_get_bytes_avail(&ssl_pm->ssl); -} - -void ssl_pm_set_fd(SSL *ssl, int fd, int mode) -{ - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - ssl_pm->fd.fd = fd; -} - -int ssl_pm_get_fd(const SSL *ssl, int mode) -{ - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - return ssl_pm->fd.fd; -} - -OSSL_HANDSHAKE_STATE ssl_pm_get_state(const SSL *ssl) -{ - OSSL_HANDSHAKE_STATE state; - - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - switch (ssl_pm->ssl.state) - { - case MBEDTLS_SSL_CLIENT_HELLO: - state = TLS_ST_CW_CLNT_HELLO; - break; - case MBEDTLS_SSL_SERVER_HELLO: - state = TLS_ST_SW_SRVR_HELLO; - break; - case MBEDTLS_SSL_SERVER_CERTIFICATE: - state = TLS_ST_SW_CERT; - break; - case MBEDTLS_SSL_SERVER_HELLO_DONE: - state = TLS_ST_SW_SRVR_DONE; - break; - case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: - state = TLS_ST_CW_KEY_EXCH; - break; - case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: - state = TLS_ST_CW_CHANGE; - break; - case MBEDTLS_SSL_CLIENT_FINISHED: - state = TLS_ST_CW_FINISHED; - break; - case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: - state = TLS_ST_SW_CHANGE; - break; - case MBEDTLS_SSL_SERVER_FINISHED: - state = TLS_ST_SW_FINISHED; - break; - case MBEDTLS_SSL_CLIENT_CERTIFICATE: - state = TLS_ST_CW_CERT; - break; - case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: - state = TLS_ST_SR_KEY_EXCH; - break; - case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET: - state = TLS_ST_SW_SESSION_TICKET; - break; - case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT: - state = TLS_ST_SW_CERT_REQ; - break; - case MBEDTLS_SSL_HANDSHAKE_OVER: - state = TLS_ST_OK; - break; - default : - state = TLS_ST_BEFORE; - break; - } - - return state; -} - -int x509_pm_show_info(X509 *x) -{ - int ret; - char *buf; - mbedtls_x509_crt *x509_crt; - struct x509_pm *x509_pm = x->x509_pm; - - if (x509_pm->x509_crt) - x509_crt = x509_pm->x509_crt; - else if (x509_pm->ex_crt) - x509_crt = x509_pm->ex_crt; - else - x509_crt = NULL; - - if (!x509_crt) - return -1; - - buf = ssl_mem_malloc(X509_INFO_STRING_LENGTH); - if (!buf) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (buf)"); - goto no_mem; - } - - ret = mbedtls_x509_crt_info(buf, X509_INFO_STRING_LENGTH - 1, "", x509_crt); - if (ret <= 0) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_x509_crt_info() return -0x%x", -ret); - goto mbedtls_err1; - } - - buf[ret] = 0; - - ssl_mem_free(buf); - - SSL_DEBUG(SSL_DEBUG_ON, "%s", buf); - - return 0; - -mbedtls_err1: - ssl_mem_free(buf); -no_mem: - return -1; -} - -int x509_pm_new(X509 *x, X509 *m_x) -{ - struct x509_pm *x509_pm; - - x509_pm = ssl_mem_zalloc(sizeof(struct x509_pm)); - if (!x509_pm) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (x509_pm)"); - goto failed1; - } - - x->x509_pm = x509_pm; - - if (m_x) { - struct x509_pm *m_x509_pm = (struct x509_pm *)m_x->x509_pm; - - x509_pm->ex_crt = m_x509_pm->x509_crt; - } - - return 0; - -failed1: - return -1; -} - -void x509_pm_free(X509 *x) -{ - struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; - - if (x509_pm->x509_crt) { - mbedtls_x509_crt_free(x509_pm->x509_crt); - - ssl_mem_free(x509_pm->x509_crt); - x509_pm->x509_crt = NULL; - } - - ssl_mem_free(x->x509_pm); - x->x509_pm = NULL; -} - -int x509_pm_load(X509 *x, const unsigned char *buffer, int len) -{ - int ret; - unsigned char *load_buf; - struct x509_pm *x509_pm = (struct x509_pm *)x->x509_pm; - - if (x509_pm->x509_crt) - mbedtls_x509_crt_free(x509_pm->x509_crt); - - if (!x509_pm->x509_crt) { - x509_pm->x509_crt = ssl_mem_malloc(sizeof(mbedtls_x509_crt)); - if (!x509_pm->x509_crt) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (x509_pm->x509_crt)"); - goto no_mem; - } - } - - mbedtls_x509_crt_init(x509_pm->x509_crt); - if (buffer[0] != 0x30) { - load_buf = ssl_mem_malloc(len + 1); - if (!load_buf) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (load_buf)"); - goto failed; - } - - ssl_memcpy(load_buf, buffer, len); - load_buf[len] = '\0'; - - ret = mbedtls_x509_crt_parse(x509_pm->x509_crt, load_buf, len + 1); - ssl_mem_free(load_buf); - } else { - printf("parsing as der\n"); - - ret = mbedtls_x509_crt_parse_der(x509_pm->x509_crt, buffer, len); - } - - if (ret) { - printf("mbedtls_x509_crt_parse return -0x%x", -ret); - goto failed; - } - - return 0; - -failed: - mbedtls_x509_crt_free(x509_pm->x509_crt); - ssl_mem_free(x509_pm->x509_crt); - x509_pm->x509_crt = NULL; -no_mem: - return -1; -} - -int pkey_pm_new(EVP_PKEY *pk, EVP_PKEY *m_pkey) -{ - struct pkey_pm *pkey_pm; - - pkey_pm = ssl_mem_zalloc(sizeof(struct pkey_pm)); - if (!pkey_pm) - return -1; - - pk->pkey_pm = pkey_pm; - - if (m_pkey) { - struct pkey_pm *m_pkey_pm = (struct pkey_pm *)m_pkey->pkey_pm; - - pkey_pm->ex_pkey = m_pkey_pm->pkey; - } - - return 0; -} - -void pkey_pm_free(EVP_PKEY *pk) -{ - struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm; - - if (pkey_pm->pkey) { - mbedtls_pk_free(pkey_pm->pkey); - - ssl_mem_free(pkey_pm->pkey); - pkey_pm->pkey = NULL; - } - - ssl_mem_free(pk->pkey_pm); - pk->pkey_pm = NULL; -} - -int pkey_pm_load(EVP_PKEY *pk, const unsigned char *buffer, int len) -{ - int ret; - unsigned char *load_buf; - struct pkey_pm *pkey_pm = (struct pkey_pm *)pk->pkey_pm; - - if (pkey_pm->pkey) - mbedtls_pk_free(pkey_pm->pkey); - - if (!pkey_pm->pkey) { - pkey_pm->pkey = ssl_mem_malloc(sizeof(mbedtls_pk_context)); - if (!pkey_pm->pkey) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (pkey_pm->pkey)"); - goto no_mem; - } - } - - load_buf = ssl_mem_malloc(len + 1); - if (!load_buf) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "no enough memory > (load_buf)"); - goto failed; - } - - ssl_memcpy(load_buf, buffer, len); - load_buf[len] = '\0'; - - mbedtls_pk_init(pkey_pm->pkey); - - ret = mbedtls_pk_parse_key(pkey_pm->pkey, load_buf, len + 1, NULL, 0); - ssl_mem_free(load_buf); - - if (ret) { - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, "mbedtls_pk_parse_key return -0x%x", -ret); - goto failed; - } - - return 0; - -failed: - mbedtls_pk_free(pkey_pm->pkey); - ssl_mem_free(pkey_pm->pkey); - pkey_pm->pkey = NULL; -no_mem: - return -1; -} - - - -void ssl_pm_set_bufflen(SSL *ssl, int len) -{ - max_content_len = len; -} - -long ssl_pm_get_verify_result(const SSL *ssl) -{ - uint32_t ret; - long verify_result; - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - ret = mbedtls_ssl_get_verify_result(&ssl_pm->ssl); - if (!ret) - return X509_V_OK; - - if (ret & MBEDTLS_X509_BADCERT_NOT_TRUSTED || - (ret & MBEDTLS_X509_BADCRL_NOT_TRUSTED)) - verify_result = X509_V_ERR_INVALID_CA; - - else if (ret & MBEDTLS_X509_BADCERT_CN_MISMATCH) - verify_result = X509_V_ERR_HOSTNAME_MISMATCH; - - else if ((ret & MBEDTLS_X509_BADCERT_BAD_KEY) || - (ret & MBEDTLS_X509_BADCRL_BAD_KEY)) - verify_result = X509_V_ERR_CA_KEY_TOO_SMALL; - - else if ((ret & MBEDTLS_X509_BADCERT_BAD_MD) || - (ret & MBEDTLS_X509_BADCRL_BAD_MD)) - verify_result = X509_V_ERR_CA_MD_TOO_WEAK; - - else if ((ret & MBEDTLS_X509_BADCERT_FUTURE) || - (ret & MBEDTLS_X509_BADCRL_FUTURE)) - verify_result = X509_V_ERR_CERT_NOT_YET_VALID; - - else if ((ret & MBEDTLS_X509_BADCERT_EXPIRED) || - (ret & MBEDTLS_X509_BADCRL_EXPIRED)) - verify_result = X509_V_ERR_CERT_HAS_EXPIRED; - - else - verify_result = X509_V_ERR_UNSPECIFIED; - - SSL_DEBUG(SSL_PLATFORM_ERROR_LEVEL, - "mbedtls_ssl_get_verify_result() return 0x%x", ret); - - return verify_result; -} - -/** - * @brief set expected hostname on peer cert CN - */ - -int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, - const char *name, size_t namelen) -{ - SSL *ssl = (SSL *)((char *)param - offsetof(SSL, param)); - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - char *name_cstr = NULL; - - if (namelen) { - name_cstr = malloc(namelen + 1); - if (!name_cstr) - return 0; - memcpy(name_cstr, name, namelen); - name_cstr[namelen] = '\0'; - name = name_cstr; - } - - mbedtls_ssl_set_hostname(&ssl_pm->ssl, name); - - if (namelen) - free(name_cstr); - - return 1; -} - -void _ssl_set_alpn_list(const SSL *ssl) -{ - if (ssl->alpn_protos) { - if (mbedtls_ssl_conf_alpn_protocols(&((struct ssl_pm *)(ssl->ssl_pm))->conf, ssl->alpn_protos)) - fprintf(stderr, "mbedtls_ssl_conf_alpn_protocols failed\n"); - - return; - } - if (!ssl->ctx->alpn_protos) - return; - if (mbedtls_ssl_conf_alpn_protocols(&((struct ssl_pm *)(ssl->ssl_pm))->conf, ssl->ctx->alpn_protos)) - fprintf(stderr, "mbedtls_ssl_conf_alpn_protocols failed\n"); -} - -void SSL_get0_alpn_selected(const SSL *ssl, const unsigned char **data, - unsigned int *len) -{ - const char *alp = mbedtls_ssl_get_alpn_protocol(&((struct ssl_pm *)(ssl->ssl_pm))->ssl); - - *data = (const unsigned char *)alp; - if (alp) - *len = strlen(alp); - else - *len = 0; -} - -int SSL_set_sni_callback(SSL *ssl, int(*cb)(void *, mbedtls_ssl_context *, - const unsigned char *, size_t), void *param) -{ - struct ssl_pm *ssl_pm = (struct ssl_pm *)ssl->ssl_pm; - - mbedtls_ssl_conf_sni(&ssl_pm->conf, cb, param); - - return 0; -} - -SSL *SSL_SSL_from_mbedtls_ssl_context(mbedtls_ssl_context *msc) -{ - struct ssl_pm *ssl_pm = (struct ssl_pm *)((char *)msc - offsetof(struct ssl_pm, ssl)); - - return ssl_pm->owner; -} - -#include "ssl_cert.h" - -void SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) -{ - struct ssl_pm *ssl_pm = ssl->ssl_pm; - struct x509_pm *x509_pm = (struct x509_pm *)ctx->cert->x509->x509_pm; - struct x509_pm *x509_pm_ca = (struct x509_pm *)ctx->client_CA->x509_pm; - - struct pkey_pm *pkey_pm = (struct pkey_pm *)ctx->cert->pkey->pkey_pm; - int mode; - - if (ssl->cert) - ssl_cert_free(ssl->cert); - ssl->ctx = ctx; - ssl->cert = __ssl_cert_new(ctx->cert); - - if (ctx->verify_mode == SSL_VERIFY_PEER) - mode = MBEDTLS_SSL_VERIFY_OPTIONAL; - else if (ctx->verify_mode == SSL_VERIFY_FAIL_IF_NO_PEER_CERT) - mode = MBEDTLS_SSL_VERIFY_OPTIONAL; - else if (ctx->verify_mode == SSL_VERIFY_CLIENT_ONCE) - mode = MBEDTLS_SSL_VERIFY_UNSET; - else - mode = MBEDTLS_SSL_VERIFY_NONE; - - // printf("ssl: %p, client ca x509_crt %p, mbedtls mode %d\n", ssl, x509_pm_ca->x509_crt, mode); - - /* apply new ctx cert to ssl */ - - ssl->verify_mode = ctx->verify_mode; - - mbedtls_ssl_set_hs_ca_chain(&ssl_pm->ssl, x509_pm_ca->x509_crt, NULL); - mbedtls_ssl_set_hs_own_cert(&ssl_pm->ssl, x509_pm->x509_crt, pkey_pm->pkey); - mbedtls_ssl_set_hs_authmode(&ssl_pm->ssl, mode); -} diff --git a/thirdparty/libwebsockets/tls/mbedtls/wrapper/platform/ssl_port.c b/thirdparty/libwebsockets/tls/mbedtls/wrapper/platform/ssl_port.c deleted file mode 100644 index 8c7a31338b..0000000000 --- a/thirdparty/libwebsockets/tls/mbedtls/wrapper/platform/ssl_port.c +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD -// -// 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. - -#include "ssl_port.h" - -/*********************************************************************************************/ -/********************************* SSL general interface *************************************/ - -void *ssl_mem_zalloc(size_t size) -{ - void *p = malloc(size); - - if (p) - memset(p, 0, size); - - return p; -} - diff --git a/thirdparty/libwebsockets/tls/private.h b/thirdparty/libwebsockets/tls/private.h deleted file mode 100644 index 606e2574dc..0000000000 --- a/thirdparty/libwebsockets/tls/private.h +++ /dev/null @@ -1,281 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010 - 2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - * - * This is included from core/private.h if LWS_WITH_TLS - */ - -#if defined(LWS_WITH_TLS) - -#if defined(USE_WOLFSSL) - #if defined(USE_OLD_CYASSL) - #if defined(_WIN32) - #include <IDE/WIN/user_settings.h> - #include <cyassl/ctaocrypt/settings.h> - #else - #include <cyassl/options.h> - #endif - #include <cyassl/openssl/ssl.h> - #include <cyassl/error-ssl.h> - #else - #if defined(_WIN32) - #include <IDE/WIN/user_settings.h> - #include <wolfssl/wolfcrypt/settings.h> - #else - #include <wolfssl/options.h> - #endif - #include <wolfssl/openssl/ssl.h> - #include <wolfssl/error-ssl.h> - #define OPENSSL_NO_TLSEXT - #endif /* not USE_OLD_CYASSL */ -#else /* WOLFSSL */ - #if defined(LWS_WITH_ESP32) - #define OPENSSL_NO_TLSEXT - #undef MBEDTLS_CONFIG_FILE - #define MBEDTLS_CONFIG_FILE <mbedtls/esp_config.h> - #include <mbedtls/ssl.h> - #include <mbedtls/x509_crt.h> - #include "tls/mbedtls/wrapper/include/openssl/ssl.h" /* wrapper !!!! */ - #else /* not esp32 */ - #if defined(LWS_WITH_MBEDTLS) - #include <mbedtls/ssl.h> - #include <mbedtls/x509_crt.h> - #include <mbedtls/x509_csr.h> - #include "tls/mbedtls/wrapper/include/openssl/ssl.h" /* wrapper !!!! */ - #else - #include <openssl/ssl.h> - #include <openssl/evp.h> - #include <openssl/err.h> - #include <openssl/md5.h> - #include <openssl/sha.h> - #ifdef LWS_HAVE_OPENSSL_ECDH_H - #include <openssl/ecdh.h> - #endif - #include <openssl/x509v3.h> - #endif /* not mbedtls */ - #if defined(OPENSSL_VERSION_NUMBER) - #if (OPENSSL_VERSION_NUMBER < 0x0009080afL) -/* later openssl defines this to negate the presence of tlsext... but it was only - * introduced at 0.9.8j. Earlier versions don't know it exists so don't - * define it... making it look like the feature exists... - */ - #define OPENSSL_NO_TLSEXT - #endif - #endif - #endif /* not ESP32 */ -#endif /* not USE_WOLFSSL */ - -#endif /* LWS_WITH_TLS */ - -enum lws_tls_extant { - LWS_TLS_EXTANT_NO, - LWS_TLS_EXTANT_YES, - LWS_TLS_EXTANT_ALTERNATIVE -}; - -struct lws_context_per_thread; - -struct lws_tls_ops { - int (*fake_POLLIN_for_buffered)(struct lws_context_per_thread *pt); - int (*periodic_housekeeping)(struct lws_context *context, time_t now); -}; - -#if defined(LWS_WITH_TLS) - -typedef SSL lws_tls_conn; -typedef SSL_CTX lws_tls_ctx; -typedef BIO lws_tls_bio; -typedef X509 lws_tls_x509; - - -#define LWS_SSL_ENABLED(context) (context->tls.use_ssl) - -extern const struct lws_tls_ops tls_ops_openssl, tls_ops_mbedtls; - -struct lws_context_tls { - char alpn_discovered[32]; - const char *alpn_default; - time_t last_cert_check_s; -}; - -struct lws_pt_tls { - struct lws *pending_read_list; /* linked list */ -}; - -struct lws_tls_ss_pieces; - -struct alpn_ctx { - uint8_t data[23]; - uint8_t len; -}; - -struct lws_vhost_tls { - lws_tls_ctx *ssl_ctx; - lws_tls_ctx *ssl_client_ctx; - const char *alpn; - struct lws_tls_ss_pieces *ss; /* for acme tls certs */ - char *alloc_cert_path; - char *key_path; -#if defined(LWS_WITH_MBEDTLS) - lws_tls_x509 *x509_client_CA; -#endif - char ecdh_curve[16]; - struct alpn_ctx alpn_ctx; - - int use_ssl; - int allow_non_ssl_on_ssl_port; - int ssl_info_event_mask; - - unsigned int user_supplied_ssl_ctx:1; - unsigned int skipped_certs:1; -}; - -struct lws_lws_tls { - lws_tls_conn *ssl; - lws_tls_bio *client_bio; - struct lws *pending_read_list_prev, *pending_read_list_next; - unsigned int use_ssl; - unsigned int redirect_to_https:1; -}; - -LWS_EXTERN void -lws_context_init_alpn(struct lws_vhost *vhost); -LWS_EXTERN enum lws_tls_extant -lws_tls_use_any_upgrade_check_extant(const char *name); -LWS_EXTERN int openssl_websocket_private_data_index; -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_ssl_capable_read(struct lws *wsi, unsigned char *buf, int len); -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_ssl_capable_write(struct lws *wsi, unsigned char *buf, int len); -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_ssl_pending(struct lws *wsi); -LWS_EXTERN int -lws_context_init_ssl_library(const struct lws_context_creation_info *info); -LWS_EXTERN int LWS_WARN_UNUSED_RESULT -lws_server_socket_service_ssl(struct lws *new_wsi, lws_sockfd_type accept_fd); -LWS_EXTERN int -lws_ssl_close(struct lws *wsi); -LWS_EXTERN void -lws_ssl_SSL_CTX_destroy(struct lws_vhost *vhost); -LWS_EXTERN void -lws_ssl_context_destroy(struct lws_context *context); -void -__lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi); -LWS_VISIBLE void -lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi); -LWS_EXTERN int -lws_ssl_client_bio_create(struct lws *wsi); -LWS_EXTERN int -lws_ssl_client_connect1(struct lws *wsi); -LWS_EXTERN int -lws_ssl_client_connect2(struct lws *wsi, char *errbuf, int len); -LWS_EXTERN void -lws_ssl_elaborate_error(void); -LWS_EXTERN int -lws_tls_fake_POLLIN_for_buffered(struct lws_context_per_thread *pt); -LWS_EXTERN int -lws_gate_accepts(struct lws_context *context, int on); -LWS_EXTERN void -lws_ssl_bind_passphrase(lws_tls_ctx *ssl_ctx, - const struct lws_context_creation_info *info); -LWS_EXTERN void -lws_ssl_info_callback(const lws_tls_conn *ssl, int where, int ret); -LWS_EXTERN int -lws_tls_openssl_cert_info(X509 *x509, enum lws_tls_cert_info type, - union lws_tls_cert_info_results *buf, size_t len); -LWS_EXTERN int -lws_tls_check_all_cert_lifetimes(struct lws_context *context); -LWS_EXTERN int -lws_tls_server_certs_load(struct lws_vhost *vhost, struct lws *wsi, - const char *cert, const char *private_key, - const char *mem_cert, size_t len_mem_cert, - const char *mem_privkey, size_t mem_privkey_len); -LWS_EXTERN enum lws_tls_extant -lws_tls_generic_cert_checks(struct lws_vhost *vhost, const char *cert, - const char *private_key); -LWS_EXTERN int -lws_tls_alloc_pem_to_der_file(struct lws_context *context, const char *filename, - const char *inbuf, lws_filepos_t inlen, - uint8_t **buf, lws_filepos_t *amount); - -#if !defined(LWS_NO_SERVER) - LWS_EXTERN int - lws_context_init_server_ssl(const struct lws_context_creation_info *info, - struct lws_vhost *vhost); - void - lws_tls_acme_sni_cert_destroy(struct lws_vhost *vhost); -#else - #define lws_context_init_server_ssl(_a, _b) (0) - #define lws_tls_acme_sni_cert_destroy(_a) -#endif - -LWS_EXTERN void -lws_ssl_destroy(struct lws_vhost *vhost); -LWS_EXTERN char * -lws_ssl_get_error_string(int status, int ret, char *buf, size_t len); - -/* - * lws_tls_ abstract backend implementations - */ - -LWS_EXTERN int -lws_tls_server_client_cert_verify_config(struct lws_vhost *vh); -LWS_EXTERN int -lws_tls_server_vhost_backend_init(const struct lws_context_creation_info *info, - struct lws_vhost *vhost, struct lws *wsi); -LWS_EXTERN int -lws_tls_server_new_nonblocking(struct lws *wsi, lws_sockfd_type accept_fd); - -LWS_EXTERN enum lws_ssl_capable_status -lws_tls_server_accept(struct lws *wsi); - -LWS_EXTERN enum lws_ssl_capable_status -lws_tls_server_abort_connection(struct lws *wsi); - -LWS_EXTERN enum lws_ssl_capable_status -__lws_tls_shutdown(struct lws *wsi); - -LWS_EXTERN enum lws_ssl_capable_status -lws_tls_client_connect(struct lws *wsi); -LWS_EXTERN int -lws_tls_client_confirm_peer_cert(struct lws *wsi, char *ebuf, int ebuf_len); -LWS_EXTERN int -lws_tls_client_create_vhost_context(struct lws_vhost *vh, - const struct lws_context_creation_info *info, - const char *cipher_list, - const char *ca_filepath, - const char *cert_filepath, - const char *private_key_filepath); - -LWS_EXTERN lws_tls_ctx * -lws_tls_ctx_from_wsi(struct lws *wsi); -LWS_EXTERN int -lws_ssl_get_error(struct lws *wsi, int n); - -LWS_EXTERN int -lws_context_init_client_ssl(const struct lws_context_creation_info *info, - struct lws_vhost *vhost); - -LWS_EXTERN void -lws_ssl_info_callback(const lws_tls_conn *ssl, int where, int ret); - -int -lws_tls_fake_POLLIN_for_buffered(struct lws_context_per_thread *pt); - -#endif
\ No newline at end of file diff --git a/thirdparty/libwebsockets/tls/tls-client.c b/thirdparty/libwebsockets/tls/tls-client.c deleted file mode 100644 index 70eb6f6078..0000000000 --- a/thirdparty/libwebsockets/tls/tls-client.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * libwebsockets - client-related ssl code independent of backend - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -int -lws_ssl_client_connect1(struct lws *wsi) -{ - struct lws_context *context = wsi->context; - int n = 0; - - lws_latency_pre(context, wsi); - n = lws_tls_client_connect(wsi); - lws_latency(context, wsi, "SSL_connect hs", n, n > 0); - - switch (n) { - case LWS_SSL_CAPABLE_ERROR: - return -1; - case LWS_SSL_CAPABLE_DONE: - return 1; /* connected */ - case LWS_SSL_CAPABLE_MORE_SERVICE_WRITE: - lws_callback_on_writable(wsi); - /* fallthru */ - case LWS_SSL_CAPABLE_MORE_SERVICE_READ: - lwsi_set_state(wsi, LRS_WAITING_SSL); - break; - case LWS_SSL_CAPABLE_MORE_SERVICE: - break; - } - - return 0; /* retry */ -} - -int -lws_ssl_client_connect2(struct lws *wsi, char *errbuf, int len) -{ - int n = 0; - - if (lwsi_state(wsi) == LRS_WAITING_SSL) { - lws_latency_pre(wsi->context, wsi); - - n = lws_tls_client_connect(wsi); - lwsl_debug("%s: SSL_connect says %d\n", __func__, n); - lws_latency(wsi->context, wsi, - "SSL_connect LRS_WAITING_SSL", n, n > 0); - - switch (n) { - case LWS_SSL_CAPABLE_ERROR: - lws_snprintf(errbuf, len, "client connect failed"); - return -1; - case LWS_SSL_CAPABLE_DONE: - break; /* connected */ - case LWS_SSL_CAPABLE_MORE_SERVICE_WRITE: - lws_callback_on_writable(wsi); - /* fallthru */ - case LWS_SSL_CAPABLE_MORE_SERVICE_READ: - lwsi_set_state(wsi, LRS_WAITING_SSL); - /* fallthru */ - case LWS_SSL_CAPABLE_MORE_SERVICE: - return 0; - } - } - - if (lws_tls_client_confirm_peer_cert(wsi, errbuf, len)) - return -1; - - return 1; -} - - -int lws_context_init_client_ssl(const struct lws_context_creation_info *info, - struct lws_vhost *vhost) -{ - const char *ca_filepath = info->ssl_ca_filepath; - const char *cipher_list = info->ssl_cipher_list; - const char *private_key_filepath = info->ssl_private_key_filepath; - const char *cert_filepath = info->ssl_cert_filepath; - struct lws wsi; - - if (vhost->options & LWS_SERVER_OPTION_ONLY_RAW) - return 0; - - /* - * for backwards-compatibility default to using ssl_... members, but - * if the newer client-specific ones are given, use those - */ - if (info->client_ssl_cipher_list) - cipher_list = info->client_ssl_cipher_list; - if (info->client_ssl_cert_filepath) - cert_filepath = info->client_ssl_cert_filepath; - if (info->client_ssl_private_key_filepath) - private_key_filepath = info->client_ssl_private_key_filepath; - - if (info->client_ssl_ca_filepath) - ca_filepath = info->client_ssl_ca_filepath; - - if (!lws_check_opt(info->options, LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) - return 0; - - if (vhost->tls.ssl_client_ctx) - return 0; - - if (info->provided_client_ssl_ctx) { - /* use the provided OpenSSL context if given one */ - vhost->tls.ssl_client_ctx = info->provided_client_ssl_ctx; - /* nothing for lib to delete */ - vhost->tls.user_supplied_ssl_ctx = 1; - - return 0; - } - - if (lws_tls_client_create_vhost_context(vhost, info, cipher_list, - ca_filepath, cert_filepath, - private_key_filepath)) - return 1; - - lwsl_notice("created client ssl context for %s\n", vhost->name); - - /* - * give him a fake wsi with context set, so he can use - * lws_get_context() in the callback - */ - memset(&wsi, 0, sizeof(wsi)); - wsi.vhost = vhost; - wsi.context = vhost->context; - - vhost->protocols[0].callback(&wsi, - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_CLIENT_VERIFY_CERTS, - vhost->tls.ssl_client_ctx, NULL, 0); - - return 0; -} diff --git a/thirdparty/libwebsockets/tls/tls-server.c b/thirdparty/libwebsockets/tls/tls-server.c deleted file mode 100644 index 440e790660..0000000000 --- a/thirdparty/libwebsockets/tls/tls-server.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2018 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -#if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) && \ - OPENSSL_VERSION_NUMBER >= 0x10002000L) -static int -alpn_cb(SSL *s, const unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, void *arg) -{ -#if !defined(LWS_WITH_MBEDTLS) - struct alpn_ctx *alpn_ctx = (struct alpn_ctx *)arg; - - if (SSL_select_next_proto((unsigned char **)out, outlen, alpn_ctx->data, - alpn_ctx->len, in, inlen) != - OPENSSL_NPN_NEGOTIATED) - return SSL_TLSEXT_ERR_NOACK; -#endif - - return SSL_TLSEXT_ERR_OK; -} -#endif - -void -lws_context_init_alpn(struct lws_vhost *vhost) -{ -#if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) && \ - OPENSSL_VERSION_NUMBER >= 0x10002000L) - const char *alpn_comma = vhost->context->tls.alpn_default; - - if (vhost->tls.alpn) - alpn_comma = vhost->tls.alpn; - - lwsl_info(" Server '%s' advertising ALPN: %s\n", - vhost->name, alpn_comma); - vhost->tls.alpn_ctx.len = lws_alpn_comma_to_openssl(alpn_comma, - vhost->tls.alpn_ctx.data, - sizeof(vhost->tls.alpn_ctx.data) - 1); - - SSL_CTX_set_alpn_select_cb(vhost->tls.ssl_ctx, alpn_cb, &vhost->tls.alpn_ctx); -#else - lwsl_err( - " HTTP2 / ALPN configured but not supported by OpenSSL 0x%lx\n", - OPENSSL_VERSION_NUMBER); -#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L -} - -int -lws_tls_server_conn_alpn(struct lws *wsi) -{ -#if defined(LWS_WITH_MBEDTLS) || (defined(OPENSSL_VERSION_NUMBER) && \ - OPENSSL_VERSION_NUMBER >= 0x10002000L) - const unsigned char *name = NULL; - char cstr[10]; - unsigned len; - - SSL_get0_alpn_selected(wsi->tls.ssl, &name, &len); - if (!len) { - lwsl_info("no ALPN upgrade\n"); - return 0; - } - - if (len > sizeof(cstr) - 1) - len = sizeof(cstr) - 1; - - memcpy(cstr, name, len); - cstr[len] = '\0'; - - lwsl_info("negotiated '%s' using ALPN\n", cstr); - wsi->tls.use_ssl |= LCCSCF_USE_SSL; - - return lws_role_call_alpn_negotiated(wsi, (const char *)cstr); -#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L - - return 0; -} - -LWS_VISIBLE int -lws_context_init_server_ssl(const struct lws_context_creation_info *info, - struct lws_vhost *vhost) -{ - struct lws_context *context = vhost->context; - struct lws wsi; - - if (!lws_check_opt(info->options, - LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT)) { - vhost->tls.use_ssl = 0; - - return 0; - } - - /* - * If he is giving a cert filepath, take it as a sign he wants to use - * it on this vhost. User code can leave the cert filepath NULL and - * set the LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX option itself, in - * which case he's expected to set up the cert himself at - * LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS, which - * provides the vhost SSL_CTX * in the user parameter. - */ - if (info->ssl_cert_filepath) - vhost->options |= LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX; - - if (info->port != CONTEXT_PORT_NO_LISTEN) { - - vhost->tls.use_ssl = lws_check_opt(vhost->options, - LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX); - - if (vhost->tls.use_ssl && info->ssl_cipher_list) - lwsl_notice(" SSL ciphers: '%s'\n", - info->ssl_cipher_list); - - if (vhost->tls.use_ssl) - lwsl_notice(" Using SSL mode\n"); - else - lwsl_notice(" Using non-SSL mode\n"); - } - - /* - * give him a fake wsi with context + vhost set, so he can use - * lws_get_context() in the callback - */ - memset(&wsi, 0, sizeof(wsi)); - wsi.vhost = vhost; - wsi.context = context; - - /* - * as a server, if we are requiring clients to identify themselves - * then set the backend up for it - */ - if (lws_check_opt(info->options, - LWS_SERVER_OPTION_ALLOW_NON_SSL_ON_SSL_PORT)) - /* Normally SSL listener rejects non-ssl, optionally allow */ - vhost->tls.allow_non_ssl_on_ssl_port = 1; - - /* - * give user code a chance to load certs into the server - * allowing it to verify incoming client certs - */ - if (vhost->tls.use_ssl) { - if (lws_tls_server_vhost_backend_init(info, vhost, &wsi)) - return -1; - - lws_tls_server_client_cert_verify_config(vhost); - - if (vhost->protocols[0].callback(&wsi, - LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS, - vhost->tls.ssl_ctx, vhost, 0)) - return -1; - } - - if (vhost->tls.use_ssl) - lws_context_init_alpn(vhost); - - return 0; -} - -LWS_VISIBLE int -lws_server_socket_service_ssl(struct lws *wsi, lws_sockfd_type accept_fd) -{ - struct lws_context *context = wsi->context; - struct lws_vhost *vh; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - int n; - char buf[256]; - - (void)buf; - - if (!LWS_SSL_ENABLED(wsi->vhost)) - return 0; - - switch (lwsi_state(wsi)) { - case LRS_SSL_INIT: - - if (wsi->tls.ssl) - lwsl_err("%s: leaking ssl\n", __func__); - if (accept_fd == LWS_SOCK_INVALID) - assert(0); - if (context->simultaneous_ssl_restriction && - context->simultaneous_ssl >= - context->simultaneous_ssl_restriction) { - lwsl_notice("unable to deal with SSL connection\n"); - return 1; - } - - if (lws_tls_server_new_nonblocking(wsi, accept_fd)) { - if (accept_fd != LWS_SOCK_INVALID) - compatible_close(accept_fd); - goto fail; - } - - if (context->simultaneous_ssl_restriction && - ++context->simultaneous_ssl == - context->simultaneous_ssl_restriction) - /* that was the last allowed SSL connection */ - lws_gate_accepts(context, 0); - -#if defined(LWS_WITH_STATS) - context->updated = 1; -#endif - /* - * we are not accepted yet, but we need to enter ourselves - * as a live connection. That way we can retry when more - * pieces come if we're not sorted yet - */ - lwsi_set_state(wsi, LRS_SSL_ACK_PENDING); - - lws_pt_lock(pt, __func__); - if (__insert_wsi_socket_into_fds(context, wsi)) { - lwsl_err("%s: failed to insert into fds\n", __func__); - goto fail; - } - lws_pt_unlock(pt); - - lws_set_timeout(wsi, PENDING_TIMEOUT_SSL_ACCEPT, - context->timeout_secs); - - lwsl_debug("inserted SSL accept into fds, trying SSL_accept\n"); - - /* fallthru */ - - case LRS_SSL_ACK_PENDING: - - if (lws_change_pollfd(wsi, LWS_POLLOUT, 0)) { - lwsl_err("%s: lws_change_pollfd failed\n", __func__); - goto fail; - } - - lws_latency_pre(context, wsi); - - if (wsi->vhost->tls.allow_non_ssl_on_ssl_port) { - - n = recv(wsi->desc.sockfd, (char *)pt->serv_buf, - context->pt_serv_buf_size, MSG_PEEK); - - /* - * optionally allow non-SSL connect on SSL listening socket - * This is disabled by default, if enabled it goes around any - * SSL-level access control (eg, client-side certs) so leave - * it disabled unless you know it's not a problem for you - */ - if (n >= 1 && pt->serv_buf[0] >= ' ') { - /* - * TLS content-type for Handshake is 0x16, and - * for ChangeCipherSpec Record, it's 0x14 - * - * A non-ssl session will start with the HTTP - * method in ASCII. If we see it's not a legit - * SSL handshake kill the SSL for this - * connection and try to handle as a HTTP - * connection upgrade directly. - */ - wsi->tls.use_ssl = 0; - - lws_tls_server_abort_connection(wsi); - /* - * care... this creates wsi with no ssl - * when ssl is enabled and normally - * mandatory - */ - wsi->tls.ssl = NULL; - if (lws_check_opt(context->options, - LWS_SERVER_OPTION_REDIRECT_HTTP_TO_HTTPS)) - wsi->tls.redirect_to_https = 1; - lwsl_debug("accepted as non-ssl\n"); - goto accepted; - } - if (!n) { - /* - * connection is gone, fail out - */ - lwsl_debug("PEEKed 0\n"); - goto fail; - } - if (n < 0 && (LWS_ERRNO == LWS_EAGAIN || - LWS_ERRNO == LWS_EWOULDBLOCK)) { - /* - * well, we get no way to know ssl or not - * so go around again waiting for something - * to come and give us a hint, or timeout the - * connection. - */ - if (lws_change_pollfd(wsi, 0, LWS_POLLIN)) { - lwsl_info("%s: change_pollfd failed\n", - __func__); - return -1; - } - - lwsl_info("SSL_ERROR_WANT_READ\n"); - return 0; - } - } - - /* normal SSL connection processing path */ - -#if defined(LWS_WITH_STATS) - if (!wsi->accept_start_us) - wsi->accept_start_us = time_in_microseconds(); -#endif - errno = 0; - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_C_SSL_CONNECTIONS_ACCEPT_SPIN, 1); - n = lws_tls_server_accept(wsi); - lws_latency(context, wsi, - "SSL_accept LRS_SSL_ACK_PENDING\n", n, n == 1); - lwsl_info("SSL_accept says %d\n", n); - switch (n) { - case LWS_SSL_CAPABLE_DONE: - break; - case LWS_SSL_CAPABLE_ERROR: - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_C_SSL_CONNECTIONS_FAILED, 1); - lwsl_info("SSL_accept failed socket %u: %d\n", - wsi->desc.sockfd, n); - wsi->socket_is_permanently_unusable = 1; - goto fail; - - default: /* MORE_SERVICE */ - return 0; - } - - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_C_SSL_CONNECTIONS_ACCEPTED, 1); -#if defined(LWS_WITH_STATS) - lws_stats_atomic_bump(wsi->context, pt, - LWSSTATS_MS_SSL_CONNECTIONS_ACCEPTED_DELAY, - time_in_microseconds() - wsi->accept_start_us); - wsi->accept_start_us = time_in_microseconds(); -#endif - -accepted: - - /* adapt our vhost to match the SNI SSL_CTX that was chosen */ - vh = context->vhost_list; - while (vh) { - if (!vh->being_destroyed && wsi->tls.ssl && - vh->tls.ssl_ctx == lws_tls_ctx_from_wsi(wsi)) { - lwsl_info("setting wsi to vh %s\n", vh->name); - wsi->vhost = vh; - break; - } - vh = vh->vhost_next; - } - - /* OK, we are accepted... give him some time to negotiate */ - lws_set_timeout(wsi, PENDING_TIMEOUT_ESTABLISH_WITH_SERVER, - context->timeout_secs); - - lwsi_set_state(wsi, LRS_ESTABLISHED); - if (lws_tls_server_conn_alpn(wsi)) - goto fail; - lwsl_debug("accepted new SSL conn\n"); - break; - - default: - break; - } - - return 0; - -fail: - return 1; -} - diff --git a/thirdparty/libwebsockets/tls/tls.c b/thirdparty/libwebsockets/tls/tls.c deleted file mode 100644 index 92b7c5593c..0000000000 --- a/thirdparty/libwebsockets/tls/tls.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * libwebsockets - small server side websockets and web server implementation - * - * Copyright (C) 2010-2017 Andy Green <andy@warmcat.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation: - * version 2.1 of the License. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301 USA - */ - -#include "core/private.h" - -/* - * fakes POLLIN on all tls guys with buffered rx - * - * returns nonzero if any tls guys had POLLIN faked - */ - -int -lws_tls_fake_POLLIN_for_buffered(struct lws_context_per_thread *pt) -{ - struct lws *wsi, *wsi_next; - int ret = 0; - - wsi = pt->tls.pending_read_list; - while (wsi && wsi->position_in_fds_table != LWS_NO_FDS_POS) { - wsi_next = wsi->tls.pending_read_list_next; - pt->fds[wsi->position_in_fds_table].revents |= - pt->fds[wsi->position_in_fds_table].events & LWS_POLLIN; - ret |= pt->fds[wsi->position_in_fds_table].revents & LWS_POLLIN; - - wsi = wsi_next; - } - - return !!ret; -} - -void -__lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi) -{ - struct lws_context *context = wsi->context; - struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; - - if (!wsi->tls.pending_read_list_prev && - !wsi->tls.pending_read_list_next && - pt->tls.pending_read_list != wsi) - /* we are not on the list */ - return; - - /* point previous guy's next to our next */ - if (!wsi->tls.pending_read_list_prev) - pt->tls.pending_read_list = wsi->tls.pending_read_list_next; - else - wsi->tls.pending_read_list_prev->tls.pending_read_list_next = - wsi->tls.pending_read_list_next; - - /* point next guy's previous to our previous */ - if (wsi->tls.pending_read_list_next) - wsi->tls.pending_read_list_next->tls.pending_read_list_prev = - wsi->tls.pending_read_list_prev; - - wsi->tls.pending_read_list_prev = NULL; - wsi->tls.pending_read_list_next = NULL; -} - -void -lws_ssl_remove_wsi_from_buffered_list(struct lws *wsi) -{ - struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - - lws_pt_lock(pt, __func__); - __lws_ssl_remove_wsi_from_buffered_list(wsi); - lws_pt_unlock(pt); -} - -#if defined(LWS_WITH_ESP32) -int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf, - lws_filepos_t *amount) -{ - nvs_handle nvh; - size_t s; - int n = 0; - - ESP_ERROR_CHECK(nvs_open("lws-station", NVS_READWRITE, &nvh)); - if (nvs_get_blob(nvh, filename, NULL, &s) != ESP_OK) { - n = 1; - goto bail; - } - *buf = lws_malloc(s + 1, "alloc_file"); - if (!*buf) { - n = 2; - goto bail; - } - if (nvs_get_blob(nvh, filename, (char *)*buf, &s) != ESP_OK) { - lws_free(*buf); - n = 1; - goto bail; - } - - *amount = s; - (*buf)[s] = '\0'; - - lwsl_notice("%s: nvs: read %s, %d bytes\n", __func__, filename, (int)s); - -bail: - nvs_close(nvh); - - return n; -} -#else -int alloc_file(struct lws_context *context, const char *filename, uint8_t **buf, - lws_filepos_t *amount) -{ - FILE *f; - size_t s; - int n = 0; - - f = fopen(filename, "rb"); - if (f == NULL) { - n = 1; - goto bail; - } - - if (fseek(f, 0, SEEK_END) != 0) { - n = 1; - goto bail; - } - - s = ftell(f); - if (s == (size_t)-1) { - n = 1; - goto bail; - } - - if (fseek(f, 0, SEEK_SET) != 0) { - n = 1; - goto bail; - } - - *buf = lws_malloc(s, "alloc_file"); - if (!*buf) { - n = 2; - goto bail; - } - - if (fread(*buf, s, 1, f) != 1) { - lws_free(*buf); - n = 1; - goto bail; - } - - *amount = s; - -bail: - if (f) - fclose(f); - - return n; - -} -#endif - -int -lws_tls_alloc_pem_to_der_file(struct lws_context *context, const char *filename, - const char *inbuf, lws_filepos_t inlen, - uint8_t **buf, lws_filepos_t *amount) -{ - const uint8_t *pem, *p, *end; - uint8_t *q; - lws_filepos_t len; - int n; - - if (filename) { - n = alloc_file(context, filename, (uint8_t **)&pem, &len); - if (n) - return n; - } else { - pem = (const uint8_t *)inbuf; - len = inlen; - } - - /* trim the first line */ - - p = pem; - end = p + len; - if (strncmp((char *)p, "-----", 5)) - goto bail; - p += 5; - while (p < end && *p != '\n' && *p != '-') - p++; - - if (*p != '-') - goto bail; - - while (p < end && *p != '\n') - p++; - - if (p >= end) - goto bail; - - p++; - - /* trim the last line */ - - q = (uint8_t *)end - 2; - - while (q > pem && *q != '\n') - q--; - - if (*q != '\n') - goto bail; - - *q = '\0'; - - *amount = lws_b64_decode_string((char *)p, (char *)pem, - (int)(long long)len); - *buf = (uint8_t *)pem; - - return 0; - -bail: - lws_free((uint8_t *)pem); - - return 4; -} - -int -lws_tls_check_cert_lifetime(struct lws_vhost *v) -{ - union lws_tls_cert_info_results ir; - time_t now = (time_t)lws_now_secs(), life = 0; - struct lws_acme_cert_aging_args caa; - int n; - - if (v->tls.ssl_ctx && !v->tls.skipped_certs) { - - if (now < 1464083026) /* May 2016 */ - /* our clock is wrong and we can't judge the certs */ - return -1; - - n = lws_tls_vhost_cert_info(v, LWS_TLS_CERT_INFO_VALIDITY_TO, &ir, 0); - if (n) - return 1; - - life = (ir.time - now) / (24 * 3600); - lwsl_notice(" vhost %s: cert expiry: %dd\n", v->name, (int)life); - } else - lwsl_notice(" vhost %s: no cert\n", v->name); - - memset(&caa, 0, sizeof(caa)); - caa.vh = v; - lws_broadcast(v->context, LWS_CALLBACK_VHOST_CERT_AGING, (void *)&caa, - (size_t)(ssize_t)life); - - return 0; -} - -int -lws_tls_check_all_cert_lifetimes(struct lws_context *context) -{ - struct lws_vhost *v = context->vhost_list; - - while (v) { - if (lws_tls_check_cert_lifetime(v) < 0) - return -1; - v = v->vhost_next; - } - - return 0; -} -#if !defined(LWS_WITH_ESP32) && !defined(LWS_PLAT_OPTEE) -static int -lws_tls_extant(const char *name) -{ - /* it exists if we can open it... */ - int fd = open(name, O_RDONLY), n; - char buf[1]; - - if (fd < 0) - return 1; - - /* and we can read at least one byte out of it */ - n = read(fd, buf, 1); - close(fd); - - return n != 1; -} -#endif -/* - * Returns 0 if the filepath "name" exists and can be read from. - * - * In addition, if "name".upd exists, backup "name" to "name.old.1" - * and rename "name".upd to "name" before reporting its existence. - * - * There are four situations and three results possible: - * - * 1) LWS_TLS_EXTANT_NO: There are no certs at all (we are waiting for them to - * be provisioned). We also feel like this if we need privs we don't have - * any more to look in the directory. - * - * 2) There are provisioned certs written (xxx.upd) and we still have root - * privs... in this case we rename any existing cert to have a backup name - * and move the upd cert into place with the correct name. This then becomes - * situation 4 for the caller. - * - * 3) LWS_TLS_EXTANT_ALTERNATIVE: There are provisioned certs written (xxx.upd) - * but we no longer have the privs needed to read or rename them. In this - * case, indicate that the caller should use temp copies if any we do have - * rights to access. This is normal after we have updated the cert. - * - * But if we dropped privs, we can't detect the provisioned xxx.upd cert + - * key, because we can't see in the dir. So we have to upgrade NO to - * ALTERNATIVE when we actually have the in-memory alternative. - * - * 4) LWS_TLS_EXTANT_YES: The certs are present with the correct name and we - * have the rights to read them. - */ -enum lws_tls_extant -lws_tls_use_any_upgrade_check_extant(const char *name) -{ -#if !defined(LWS_PLAT_OPTEE) - - int n; - -#if !defined(LWS_WITH_ESP32) - char buf[256]; - - lws_snprintf(buf, sizeof(buf) - 1, "%s.upd", name); - if (!lws_tls_extant(buf)) { - /* ah there is an updated file... how about the desired file? */ - if (!lws_tls_extant(name)) { - /* rename the desired file */ - for (n = 0; n < 50; n++) { - lws_snprintf(buf, sizeof(buf) - 1, - "%s.old.%d", name, n); - if (!rename(name, buf)) - break; - } - if (n == 50) { - lwsl_notice("unable to rename %s\n", name); - - return LWS_TLS_EXTANT_ALTERNATIVE; - } - lws_snprintf(buf, sizeof(buf) - 1, "%s.upd", name); - } - /* desired file is out of the way, rename the updated file */ - if (rename(buf, name)) { - lwsl_notice("unable to rename %s to %s\n", buf, name); - - return LWS_TLS_EXTANT_ALTERNATIVE; - } - } - - if (lws_tls_extant(name)) - return LWS_TLS_EXTANT_NO; -#else - nvs_handle nvh; - size_t s = 8192; - - if (nvs_open("lws-station", NVS_READWRITE, &nvh)) { - lwsl_notice("%s: can't open nvs\n", __func__); - return LWS_TLS_EXTANT_NO; - } - - n = nvs_get_blob(nvh, name, NULL, &s); - nvs_close(nvh); - - if (n) - return LWS_TLS_EXTANT_NO; -#endif -#endif - return LWS_TLS_EXTANT_YES; -} - -/* - * LWS_TLS_EXTANT_NO : skip adding the cert - * LWS_TLS_EXTANT_YES : use the cert and private key paths normally - * LWS_TLS_EXTANT_ALTERNATIVE: normal paths not usable, try alternate if poss - */ -enum lws_tls_extant -lws_tls_generic_cert_checks(struct lws_vhost *vhost, const char *cert, - const char *private_key) -{ - int n, m; - - /* - * The user code can choose to either pass the cert and - * key filepaths using the info members like this, or it can - * leave them NULL; force the vhost SSL_CTX init using the info - * options flag LWS_SERVER_OPTION_CREATE_VHOST_SSL_CTX; and - * set up the cert himself using the user callback - * LWS_CALLBACK_OPENSSL_LOAD_EXTRA_SERVER_VERIFY_CERTS, which - * happened just above and has the vhost SSL_CTX * in the user - * parameter. - */ - - if (!cert || !private_key) - return LWS_TLS_EXTANT_NO; - - n = lws_tls_use_any_upgrade_check_extant(cert); - if (n == LWS_TLS_EXTANT_ALTERNATIVE) - return LWS_TLS_EXTANT_ALTERNATIVE; - m = lws_tls_use_any_upgrade_check_extant(private_key); - if (m == LWS_TLS_EXTANT_ALTERNATIVE) - return LWS_TLS_EXTANT_ALTERNATIVE; - - if ((n == LWS_TLS_EXTANT_NO || m == LWS_TLS_EXTANT_NO) && - (vhost->options & LWS_SERVER_OPTION_IGNORE_MISSING_CERT)) { - lwsl_notice("Ignoring missing %s or %s\n", cert, private_key); - vhost->tls.skipped_certs = 1; - - return LWS_TLS_EXTANT_NO; - } - - /* - * the cert + key exist - */ - - return LWS_TLS_EXTANT_YES; -} - -#if !defined(LWS_NO_SERVER) -/* - * update the cert for every vhost using the given path - */ - -LWS_VISIBLE int -lws_tls_cert_updated(struct lws_context *context, const char *certpath, - const char *keypath, - const char *mem_cert, size_t len_mem_cert, - const char *mem_privkey, size_t len_mem_privkey) -{ - struct lws wsi; - - wsi.context = context; - - lws_start_foreach_ll(struct lws_vhost *, v, context->vhost_list) { - wsi.vhost = v; - if (v->tls.alloc_cert_path && v->tls.key_path && - !strcmp(v->tls.alloc_cert_path, certpath) && - !strcmp(v->tls.key_path, keypath)) { - lws_tls_server_certs_load(v, &wsi, certpath, keypath, - mem_cert, len_mem_cert, - mem_privkey, len_mem_privkey); - - if (v->tls.skipped_certs) - lwsl_notice("%s: vhost %s: cert unset\n", - __func__, v->name); - } - } lws_end_foreach_ll(v, vhost_next); - - return 0; -} -#endif - -int -lws_gate_accepts(struct lws_context *context, int on) -{ - struct lws_vhost *v = context->vhost_list; - - lwsl_notice("%s: on = %d\n", __func__, on); - -#if defined(LWS_WITH_STATS) - context->updated = 1; -#endif - - while (v) { - if (v->tls.use_ssl && v->lserv_wsi && - lws_change_pollfd(v->lserv_wsi, (LWS_POLLIN) * !on, - (LWS_POLLIN) * on)) - lwsl_notice("Unable to set accept POLLIN %d\n", on); - - v = v->vhost_next; - } - - return 0; -} - -/* comma-separated alpn list, like "h2,http/1.1" to openssl alpn format */ - -int -lws_alpn_comma_to_openssl(const char *comma, uint8_t *os, int len) -{ - uint8_t *oos = os, *plen = NULL; - - while (*comma && len > 1) { - if (!plen && *comma == ' ') { - comma++; - continue; - } - if (!plen) { - plen = os++; - len--; - } - - if (*comma == ',') { - *plen = lws_ptr_diff(os, plen + 1); - plen = NULL; - comma++; - } else { - *os++ = *comma++; - len--; - } - } - - if (plen) - *plen = lws_ptr_diff(os, plen + 1); - - return lws_ptr_diff(os, oos); -} - diff --git a/thirdparty/libwebsockets/uwp_fixes.diff b/thirdparty/libwebsockets/uwp_fixes.diff deleted file mode 100644 index 21c3275bba..0000000000 --- a/thirdparty/libwebsockets/uwp_fixes.diff +++ /dev/null @@ -1,47 +0,0 @@ -diff --git a/thirdparty/libwebsockets/plat/lws-plat-win.c b/thirdparty/libwebsockets/plat/lws-plat-win.c -index bd513b494..1850b6425 100644 ---- a/thirdparty/libwebsockets/plat/lws-plat-win.c -+++ b/thirdparty/libwebsockets/plat/lws-plat-win.c -@@ -641,9 +641,20 @@ _lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, - HANDLE ret; - WCHAR buf[MAX_PATH]; - lws_fop_fd_t fop_fd; -- LARGE_INTEGER llFileSize = {0}; -+ FILE_STANDARD_INFO fInfo = {0}; - - MultiByteToWideChar(CP_UTF8, 0, filename, -1, buf, LWS_ARRAY_SIZE(buf)); -+ -+#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0602 // Windows 8 (minimum when UWP_ENABLED, but can be used in Windows builds) -+ CREATEFILE2_EXTENDED_PARAMETERS extParams = {0}; -+ extParams.dwFileAttributes = FILE_ATTRIBUTE_NORMAL; -+ -+ if (((*flags) & 7) == _O_RDONLY) { -+ ret = CreateFile2(buf, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, &extParams); -+ } else { -+ ret = CreateFile2(buf, GENERIC_WRITE, 0, CREATE_ALWAYS, &extParams); -+ } -+#else - if (((*flags) & 7) == _O_RDONLY) { - ret = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -@@ -651,6 +662,7 @@ _lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, - ret = CreateFileW(buf, GENERIC_WRITE, 0, NULL, - CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - } -+#endif - - if (ret == LWS_INVALID_FILE) - goto bail; -@@ -663,9 +675,9 @@ _lws_plat_file_open(const struct lws_plat_file_ops *fops, const char *filename, - fop_fd->fd = ret; - fop_fd->filesystem_priv = NULL; /* we don't use it */ - fop_fd->flags = *flags; -- fop_fd->len = GetFileSize(ret, NULL); -- if(GetFileSizeEx(ret, &llFileSize)) -- fop_fd->len = llFileSize.QuadPart; -+ fop_fd->len = 0; -+ if(GetFileInformationByHandleEx(ret, FileStandardInfo, &fInfo, sizeof(fInfo))) -+ fop_fd->len = fInfo.EndOfFile.QuadPart; - - fop_fd->pos = 0; - diff --git a/thirdparty/libwebsockets/win32helpers/getopt.c b/thirdparty/libwebsockets/win32helpers/getopt.c deleted file mode 100644 index 3bb21f6f28..0000000000 --- a/thirdparty/libwebsockets/win32helpers/getopt.c +++ /dev/null @@ -1,153 +0,0 @@ -/* $NetBSD: getopt.c,v 1.16 1999/12/02 13:15:56 kleink Exp $ */ - -/* - * Copyright (c) 1987, 1993, 1994 - * The Regents of the University of California. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -#if 0 -static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; -#endif - -#include <assert.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> - -#define __P(x) x -#define _DIAGASSERT(x) assert(x) - -#ifdef __weak_alias -__weak_alias(getopt,_getopt); -#endif - - -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt, /* character checked for validity */ - optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ - -static char * _progname __P((char *)); -int getopt_internal __P((int, char * const *, const char *)); - -static char * -_progname(nargv0) - char * nargv0; -{ - char * tmp; - - _DIAGASSERT(nargv0 != NULL); - - tmp = strrchr(nargv0, '/'); - if (tmp) - tmp++; - else - tmp = nargv0; - return(tmp); -} - -#define BADCH (int)'?' -#define BADARG (int)':' -#define EMSG "" - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int -getopt(nargc, nargv, ostr) - int nargc; - char * const nargv[]; - const char *ostr; -{ - static char *__progname = 0; - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - __progname = __progname?__progname:_progname(*nargv); - - _DIAGASSERT(nargv != NULL); - _DIAGASSERT(ostr != NULL); - - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc || *(place = nargv[optind]) != '-') { - place = EMSG; - return (-1); - } - if (place[1] && *++place == '-' /* found "--" */ - && place[1] == '\0') { - ++optind; - place = EMSG; - return (-1); - } - } /* option letter okay? */ - if ((optopt = (int)*place++) == (int)':' || - !(oli = strchr(ostr, optopt))) { - /* - * if the user didn't specify '-' as an option, - * assume it means -1. - */ - if (optopt == (int)'-') - return (-1); - if (!*place) - ++optind; - if (opterr && *ostr != ':') - (void)fprintf(stderr, - "%s: illegal option -- %c\n", __progname, optopt); - return (BADCH); - } - if (*++oli != ':') { /* don't need argument */ - optarg = NULL; - if (!*place) - ++optind; - } - else { /* need an argument */ - if (*place) /* no white space */ - optarg = place; - else if (nargc <= ++optind) { /* no arg */ - place = EMSG; - if (*ostr == ':') - return (BADARG); - if (opterr) - (void)fprintf(stderr, - "%s: option requires an argument -- %c\n", - __progname, optopt); - return (BADCH); - } - else /* white space */ - optarg = nargv[optind]; - place = EMSG; - ++optind; - } - return (optopt); /* dump back option letter */ -} - diff --git a/thirdparty/libwebsockets/win32helpers/getopt.h b/thirdparty/libwebsockets/win32helpers/getopt.h deleted file mode 100644 index 7137f0379c..0000000000 --- a/thirdparty/libwebsockets/win32helpers/getopt.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __GETOPT_H__ -#define __GETOPT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -extern int opterr; /* if error message should be printed */ -extern int optind; /* index into parent argv vector */ -extern int optopt; /* character checked for validity */ -extern int optreset; /* reset getopt */ -extern char *optarg; /* argument associated with option */ - -struct option -{ - const char *name; - int has_arg; - int *flag; - int val; -}; - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -int getopt(int, char**, char*); -int getopt_long(int, char**, char*, struct option*, int*); - -#ifdef __cplusplus -} -#endif - -#endif /* __GETOPT_H__ */ diff --git a/thirdparty/libwebsockets/win32helpers/getopt_long.c b/thirdparty/libwebsockets/win32helpers/getopt_long.c deleted file mode 100644 index 6dfccf367d..0000000000 --- a/thirdparty/libwebsockets/win32helpers/getopt_long.c +++ /dev/null @@ -1,240 +0,0 @@ - -/* - * Copyright (c) 1987, 1993, 1994, 1996 - * The Regents of the University of California. 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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 <assert.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "getopt.h" - -#define lws_ptr_diff(head, tail) \ - ((int)((char *)(head) - (char *)(tail))) - -extern int opterr; /* if error message should be printed */ -extern int optind; /* index into parent argv vector */ -extern int optopt; /* character checked for validity */ -extern int optreset; /* reset getopt */ -extern char *optarg; /* argument associated with option */ - -#define __P(x) x -#define _DIAGASSERT(x) assert(x) - -static char * __progname __P((char *)); -int getopt_internal __P((int, char * const *, const char *)); - -static char * -__progname(nargv0) - char * nargv0; -{ - char * tmp; - - _DIAGASSERT(nargv0 != NULL); - - tmp = strrchr(nargv0, '/'); - if (tmp) - tmp++; - else - tmp = nargv0; - return(tmp); -} - -#define BADCH (int)'?' -#define BADARG (int)':' -#define EMSG "" - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int -getopt_internal(nargc, nargv, ostr) - int nargc; - char * const *nargv; - const char *ostr; -{ - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - - _DIAGASSERT(nargv != NULL); - _DIAGASSERT(ostr != NULL); - - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc || *(place = nargv[optind]) != '-') { - place = EMSG; - return (-1); - } - if (place[1] && *++place == '-') { /* found "--" */ - /* ++optind; */ - place = EMSG; - return (-2); - } - } /* option letter okay? */ - if ((optopt = (int)*place++) == (int)':' || - !(oli = strchr(ostr, optopt))) { - /* - * if the user didn't specify '-' as an option, - * assume it means -1. - */ - if (optopt == (int)'-') - return (-1); - if (!*place) - ++optind; - if (opterr && *ostr != ':') - (void)fprintf(stderr, - "%s: illegal option -- %c\n", __progname(nargv[0]), optopt); - return (BADCH); - } - if (*++oli != ':') { /* don't need argument */ - optarg = NULL; - if (!*place) - ++optind; - } else { /* need an argument */ - if (*place) /* no white space */ - optarg = place; - else if (nargc <= ++optind) { /* no arg */ - place = EMSG; - if ((opterr) && (*ostr != ':')) - (void)fprintf(stderr, - "%s: option requires an argument -- %c\n", - __progname(nargv[0]), optopt); - return (BADARG); - } else /* white space */ - optarg = nargv[optind]; - place = EMSG; - ++optind; - } - return (optopt); /* dump back option letter */ -} - -#if 0 -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int -getopt2(nargc, nargv, ostr) - int nargc; - char * const *nargv; - const char *ostr; -{ - int retval; - - if ((retval = getopt_internal(nargc, nargv, ostr)) == -2) { - retval = -1; - ++optind; - } - return(retval); -} -#endif - -/* - * getopt_long -- - * Parse argc/argv argument vector. - */ -int -getopt_long(nargc, nargv, options, long_options, index) - int nargc; - char ** nargv; - char * options; - struct option * long_options; - int * index; -{ - int retval; - - _DIAGASSERT(nargv != NULL); - _DIAGASSERT(options != NULL); - _DIAGASSERT(long_options != NULL); - /* index may be NULL */ - - if ((retval = getopt_internal(nargc, nargv, options)) == -2) { - char *current_argv = nargv[optind++] + 2, *has_equal; - int i, current_argv_len, match = -1; - - if (*current_argv == '\0') { - return(-1); - } - if ((has_equal = strchr(current_argv, '=')) != NULL) { - current_argv_len = lws_ptr_diff(has_equal, current_argv); - has_equal++; - } else - current_argv_len = (int)strlen(current_argv); - - for (i = 0; long_options[i].name; i++) { - if (strncmp(current_argv, long_options[i].name, current_argv_len)) - continue; - - if (strlen(long_options[i].name) == (unsigned)current_argv_len) { - match = i; - break; - } - if (match == -1) - match = i; - } - if (match != -1) { - if (long_options[match].has_arg == required_argument || - long_options[match].has_arg == optional_argument) { - if (has_equal) - optarg = has_equal; - else - optarg = nargv[optind++]; - } - if ((long_options[match].has_arg == required_argument) - && (optarg == NULL)) { - /* - * Missing argument, leading : - * indicates no error should be generated - */ - if ((opterr) && (*options != ':')) - (void)fprintf(stderr, - "%s: option requires an argument -- %s\n", - __progname(nargv[0]), current_argv); - return (BADARG); - } - } else { /* No matching argument */ - if ((opterr) && (*options != ':')) - (void)fprintf(stderr, - "%s: illegal option -- %s\n", __progname(nargv[0]), current_argv); - return (BADCH); - } - if (long_options[match].flag) { - *long_options[match].flag = long_options[match].val; - retval = 0; - } else - retval = long_options[match].val; - if (index) - *index = match; - } - return(retval); -} diff --git a/thirdparty/libwebsockets/win32helpers/gettimeofday.c b/thirdparty/libwebsockets/win32helpers/gettimeofday.c deleted file mode 100644 index 35dd73531d..0000000000 --- a/thirdparty/libwebsockets/win32helpers/gettimeofday.c +++ /dev/null @@ -1,36 +0,0 @@ -#include <time.h> -#include <windows.h> //I've omitted context line - -#include "gettimeofday.h" - -int gettimeofday(struct timeval *tv, struct timezone *tz) -{ - FILETIME ft; - unsigned __int64 tmpres = 0; - static int tzflag; - - if (NULL != tv) { - GetSystemTimeAsFileTime(&ft); - - tmpres |= ft.dwHighDateTime; - tmpres <<= 32; - tmpres |= ft.dwLowDateTime; - - /*converting file time to unix epoch*/ - tmpres /= 10; /*convert into microseconds*/ - tmpres -= DELTA_EPOCH_IN_MICROSECS; - tv->tv_sec = (long)(tmpres / 1000000UL); - tv->tv_usec = (long)(tmpres % 1000000UL); - } - - if (NULL != tz) { - if (!tzflag) { - _tzset(); - tzflag++; - } - tz->tz_minuteswest = _timezone / 60; - tz->tz_dsttime = _daylight; - } - - return 0; -} diff --git a/thirdparty/libwebsockets/win32helpers/gettimeofday.h b/thirdparty/libwebsockets/win32helpers/gettimeofday.h deleted file mode 100644 index 33e7a750fe..0000000000 --- a/thirdparty/libwebsockets/win32helpers/gettimeofday.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _GET_TIME_OF_DAY_H -#define _GET_TIME_OF_DAY_H - -#include <time.h> - -#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) - #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 -#else - #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL -#endif - -#ifdef LWS_MINGW_SUPPORT - #include <winsock2.h> -#endif - -#ifndef _TIMEZONE_DEFINED -struct timezone -{ - int tz_minuteswest; /* minutes W of Greenwich */ - int tz_dsttime; /* type of dst correction */ -}; - -#endif - -int gettimeofday(struct timeval *tv, struct timezone *tz); - -#endif diff --git a/thirdparty/mbedtls/include/godot_core_mbedtls_config.h b/thirdparty/mbedtls/include/godot_core_mbedtls_config.h new file mode 100644 index 0000000000..0e90a98886 --- /dev/null +++ b/thirdparty/mbedtls/include/godot_core_mbedtls_config.h @@ -0,0 +1,13 @@ +// For AES +#define MBEDTLS_CIPHER_MODE_CBC +#define MBEDTLS_CIPHER_MODE_CFB +#define MBEDTLS_CIPHER_MODE_CTR +#define MBEDTLS_CIPHER_MODE_OFB +#define MBEDTLS_CIPHER_MODE_XTS + +#define MBEDTLS_AES_C +#define MBEDTLS_BASE64_C +#define MBEDTLS_MD5_C +#define MBEDTLS_SHA1_C +#define MBEDTLS_SHA256_C +#define MBEDTLS_PLATFORM_ZEROIZE_ALT diff --git a/thirdparty/mbedtls/include/mbedtls/aes.h b/thirdparty/mbedtls/include/mbedtls/aes.h index b42e564efc..94e7282d36 100644 --- a/thirdparty/mbedtls/include/mbedtls/aes.h +++ b/thirdparty/mbedtls/include/mbedtls/aes.h @@ -655,6 +655,8 @@ MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#if defined(MBEDTLS_SELF_TEST) /** * \brief Checkup routine. * @@ -663,6 +665,8 @@ MBEDTLS_DEPRECATED void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, */ int mbedtls_aes_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/aesni.h b/thirdparty/mbedtls/include/mbedtls/aesni.h index 0196f49b87..a4ca012f8a 100644 --- a/thirdparty/mbedtls/include/mbedtls/aesni.h +++ b/thirdparty/mbedtls/include/mbedtls/aesni.h @@ -27,6 +27,12 @@ #ifndef MBEDTLS_AESNI_H #define MBEDTLS_AESNI_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "aes.h" #define MBEDTLS_AESNI_AES 0x02000000u diff --git a/thirdparty/mbedtls/include/mbedtls/arc4.h b/thirdparty/mbedtls/include/mbedtls/arc4.h index c43f4065f1..fb044d5b7f 100644 --- a/thirdparty/mbedtls/include/mbedtls/arc4.h +++ b/thirdparty/mbedtls/include/mbedtls/arc4.h @@ -123,6 +123,8 @@ void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, unsigned char *output ); +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -135,6 +137,8 @@ int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned */ int mbedtls_arc4_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/asn1write.h b/thirdparty/mbedtls/include/mbedtls/asn1write.h index 76c1780b59..a194243696 100644 --- a/thirdparty/mbedtls/include/mbedtls/asn1write.h +++ b/thirdparty/mbedtls/include/mbedtls/asn1write.h @@ -24,14 +24,21 @@ #ifndef MBEDTLS_ASN1_WRITE_H #define MBEDTLS_ASN1_WRITE_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "asn1.h" #define MBEDTLS_ASN1_CHK_ADD(g, f) \ - do { \ - if( ( ret = f ) < 0 ) \ + do \ + { \ + if( ( ret = (f) ) < 0 ) \ return( ret ); \ else \ - g += ret; \ + (g) += ret; \ } while( 0 ) #ifdef __cplusplus diff --git a/thirdparty/mbedtls/include/mbedtls/base64.h b/thirdparty/mbedtls/include/mbedtls/base64.h index 7a64f52163..0d024164c5 100644 --- a/thirdparty/mbedtls/include/mbedtls/base64.h +++ b/thirdparty/mbedtls/include/mbedtls/base64.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_BASE64_H #define MBEDTLS_BASE64_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include <stddef.h> #define MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ @@ -75,6 +81,7 @@ int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, const unsigned char *src, size_t slen ); +#if defined(MBEDTLS_SELF_TEST) /** * \brief Checkup routine * @@ -82,6 +89,8 @@ int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, */ int mbedtls_base64_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/bignum.h b/thirdparty/mbedtls/include/mbedtls/bignum.h index 141a8e9adf..1c8607264f 100644 --- a/thirdparty/mbedtls/include/mbedtls/bignum.h +++ b/thirdparty/mbedtls/include/mbedtls/bignum.h @@ -46,7 +46,12 @@ #define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ #define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 /**< Memory allocation failed. */ -#define MBEDTLS_MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 ) +#define MBEDTLS_MPI_CHK(f) \ + do \ + { \ + if( ( ret = (f) ) != 0 ) \ + goto cleanup; \ + } while( 0 ) /* * Maximum size MPIs are allowed to grow to in number of limbs. @@ -943,6 +948,8 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -950,6 +957,8 @@ int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags, */ int mbedtls_mpi_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/bn_mul.h b/thirdparty/mbedtls/include/mbedtls/bn_mul.h index 2f7b72fe4c..c33bd8d4ab 100644 --- a/thirdparty/mbedtls/include/mbedtls/bn_mul.h +++ b/thirdparty/mbedtls/include/mbedtls/bn_mul.h @@ -38,6 +38,12 @@ #ifndef MBEDTLS_BN_MUL_H #define MBEDTLS_BN_MUL_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "bignum.h" #if defined(MBEDTLS_HAVE_ASM) @@ -750,7 +756,7 @@ "sw $10, %2 \n\t" \ : "=m" (c), "=m" (d), "=m" (s) \ : "m" (s), "m" (d), "m" (c), "m" (b) \ - : "$9", "$10", "$11", "$12", "$13", "$14", "$15" \ + : "$9", "$10", "$11", "$12", "$13", "$14", "$15", "lo", "hi" \ ); #endif /* MIPS */ diff --git a/thirdparty/mbedtls/include/mbedtls/camellia.h b/thirdparty/mbedtls/include/mbedtls/camellia.h index 0f7c42c92d..3eeb66366d 100644 --- a/thirdparty/mbedtls/include/mbedtls/camellia.h +++ b/thirdparty/mbedtls/include/mbedtls/camellia.h @@ -308,6 +308,8 @@ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, unsigned char *output ); #endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -315,6 +317,8 @@ int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, */ int mbedtls_camellia_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/ccm.h b/thirdparty/mbedtls/include/mbedtls/ccm.h index 3f6b8f6709..f03e3b580e 100644 --- a/thirdparty/mbedtls/include/mbedtls/ccm.h +++ b/thirdparty/mbedtls/include/mbedtls/ccm.h @@ -49,6 +49,12 @@ #ifndef MBEDTLS_CCM_H #define MBEDTLS_CCM_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "cipher.h" #define MBEDTLS_ERR_CCM_BAD_INPUT -0x000D /**< Bad input parameters to the function. */ diff --git a/thirdparty/mbedtls/include/mbedtls/certs.h b/thirdparty/mbedtls/include/mbedtls/certs.h index 8dab7b5ce8..179ebbbad2 100644 --- a/thirdparty/mbedtls/include/mbedtls/certs.h +++ b/thirdparty/mbedtls/include/mbedtls/certs.h @@ -24,74 +24,226 @@ #ifndef MBEDTLS_CERTS_H #define MBEDTLS_CERTS_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include <stddef.h> #ifdef __cplusplus extern "C" { #endif +/* List of all PEM-encoded CA certificates, terminated by NULL; + * PEM encoded if MBEDTLS_PEM_PARSE_C is enabled, DER encoded + * otherwise. */ +extern const char * mbedtls_test_cas[]; +extern const size_t mbedtls_test_cas_len[]; + +/* List of all DER-encoded CA certificates, terminated by NULL */ +extern const unsigned char * mbedtls_test_cas_der[]; +extern const size_t mbedtls_test_cas_der_len[]; + #if defined(MBEDTLS_PEM_PARSE_C) /* Concatenation of all CA certificates in PEM format if available */ extern const char mbedtls_test_cas_pem[]; extern const size_t mbedtls_test_cas_pem_len; -#endif - -/* List of all CA certificates, terminated by NULL */ -extern const char * mbedtls_test_cas[]; -extern const size_t mbedtls_test_cas_len[]; +#endif /* MBEDTLS_PEM_PARSE_C */ /* - * Convenience for users who just want a certificate: - * RSA by default, or ECDSA if RSA is not available + * CA test certificates */ + +extern const char mbedtls_test_ca_crt_ec_pem[]; +extern const char mbedtls_test_ca_key_ec_pem[]; +extern const char mbedtls_test_ca_pwd_ec_pem[]; +extern const char mbedtls_test_ca_key_rsa_pem[]; +extern const char mbedtls_test_ca_pwd_rsa_pem[]; +extern const char mbedtls_test_ca_crt_rsa_sha1_pem[]; +extern const char mbedtls_test_ca_crt_rsa_sha256_pem[]; + +extern const unsigned char mbedtls_test_ca_crt_ec_der[]; +extern const unsigned char mbedtls_test_ca_key_ec_der[]; +extern const unsigned char mbedtls_test_ca_key_rsa_der[]; +extern const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[]; +extern const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[]; + +extern const size_t mbedtls_test_ca_crt_ec_pem_len; +extern const size_t mbedtls_test_ca_key_ec_pem_len; +extern const size_t mbedtls_test_ca_pwd_ec_pem_len; +extern const size_t mbedtls_test_ca_key_rsa_pem_len; +extern const size_t mbedtls_test_ca_pwd_rsa_pem_len; +extern const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len; +extern const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len; + +extern const size_t mbedtls_test_ca_crt_ec_der_len; +extern const size_t mbedtls_test_ca_key_ec_der_len; +extern const size_t mbedtls_test_ca_pwd_ec_der_len; +extern const size_t mbedtls_test_ca_key_rsa_der_len; +extern const size_t mbedtls_test_ca_pwd_rsa_der_len; +extern const size_t mbedtls_test_ca_crt_rsa_sha1_der_len; +extern const size_t mbedtls_test_ca_crt_rsa_sha256_der_len; + +/* Config-dependent dispatch between PEM and DER encoding + * (PEM if enabled, otherwise DER) */ + +extern const char mbedtls_test_ca_crt_ec[]; +extern const char mbedtls_test_ca_key_ec[]; +extern const char mbedtls_test_ca_pwd_ec[]; +extern const char mbedtls_test_ca_key_rsa[]; +extern const char mbedtls_test_ca_pwd_rsa[]; +extern const char mbedtls_test_ca_crt_rsa_sha1[]; +extern const char mbedtls_test_ca_crt_rsa_sha256[]; + +extern const size_t mbedtls_test_ca_crt_ec_len; +extern const size_t mbedtls_test_ca_key_ec_len; +extern const size_t mbedtls_test_ca_pwd_ec_len; +extern const size_t mbedtls_test_ca_key_rsa_len; +extern const size_t mbedtls_test_ca_pwd_rsa_len; +extern const size_t mbedtls_test_ca_crt_rsa_sha1_len; +extern const size_t mbedtls_test_ca_crt_rsa_sha256_len; + +/* Config-dependent dispatch between SHA-1 and SHA-256 + * (SHA-256 if enabled, otherwise SHA-1) */ + +extern const char mbedtls_test_ca_crt_rsa[]; +extern const size_t mbedtls_test_ca_crt_rsa_len; + +/* Config-dependent dispatch between EC and RSA + * (RSA if enabled, otherwise EC) */ + extern const char * mbedtls_test_ca_crt; -extern const size_t mbedtls_test_ca_crt_len; extern const char * mbedtls_test_ca_key; -extern const size_t mbedtls_test_ca_key_len; extern const char * mbedtls_test_ca_pwd; +extern const size_t mbedtls_test_ca_crt_len; +extern const size_t mbedtls_test_ca_key_len; extern const size_t mbedtls_test_ca_pwd_len; + +/* + * Server test certificates + */ + +extern const char mbedtls_test_srv_crt_ec_pem[]; +extern const char mbedtls_test_srv_key_ec_pem[]; +extern const char mbedtls_test_srv_pwd_ec_pem[]; +extern const char mbedtls_test_srv_key_rsa_pem[]; +extern const char mbedtls_test_srv_pwd_rsa_pem[]; +extern const char mbedtls_test_srv_crt_rsa_sha1_pem[]; +extern const char mbedtls_test_srv_crt_rsa_sha256_pem[]; + +extern const unsigned char mbedtls_test_srv_crt_ec_der[]; +extern const unsigned char mbedtls_test_srv_key_ec_der[]; +extern const unsigned char mbedtls_test_srv_key_rsa_der[]; +extern const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[]; +extern const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[]; + +extern const size_t mbedtls_test_srv_crt_ec_pem_len; +extern const size_t mbedtls_test_srv_key_ec_pem_len; +extern const size_t mbedtls_test_srv_pwd_ec_pem_len; +extern const size_t mbedtls_test_srv_key_rsa_pem_len; +extern const size_t mbedtls_test_srv_pwd_rsa_pem_len; +extern const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len; +extern const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len; + +extern const size_t mbedtls_test_srv_crt_ec_der_len; +extern const size_t mbedtls_test_srv_key_ec_der_len; +extern const size_t mbedtls_test_srv_pwd_ec_der_len; +extern const size_t mbedtls_test_srv_key_rsa_der_len; +extern const size_t mbedtls_test_srv_pwd_rsa_der_len; +extern const size_t mbedtls_test_srv_crt_rsa_sha1_der_len; +extern const size_t mbedtls_test_srv_crt_rsa_sha256_der_len; + +/* Config-dependent dispatch between PEM and DER encoding + * (PEM if enabled, otherwise DER) */ + +extern const char mbedtls_test_srv_crt_ec[]; +extern const char mbedtls_test_srv_key_ec[]; +extern const char mbedtls_test_srv_pwd_ec[]; +extern const char mbedtls_test_srv_key_rsa[]; +extern const char mbedtls_test_srv_pwd_rsa[]; +extern const char mbedtls_test_srv_crt_rsa_sha1[]; +extern const char mbedtls_test_srv_crt_rsa_sha256[]; + +extern const size_t mbedtls_test_srv_crt_ec_len; +extern const size_t mbedtls_test_srv_key_ec_len; +extern const size_t mbedtls_test_srv_pwd_ec_len; +extern const size_t mbedtls_test_srv_key_rsa_len; +extern const size_t mbedtls_test_srv_pwd_rsa_len; +extern const size_t mbedtls_test_srv_crt_rsa_sha1_len; +extern const size_t mbedtls_test_srv_crt_rsa_sha256_len; + +/* Config-dependent dispatch between SHA-1 and SHA-256 + * (SHA-256 if enabled, otherwise SHA-1) */ + +extern const char mbedtls_test_srv_crt_rsa[]; +extern const size_t mbedtls_test_srv_crt_rsa_len; + +/* Config-dependent dispatch between EC and RSA + * (RSA if enabled, otherwise EC) */ + extern const char * mbedtls_test_srv_crt; -extern const size_t mbedtls_test_srv_crt_len; extern const char * mbedtls_test_srv_key; +extern const char * mbedtls_test_srv_pwd; +extern const size_t mbedtls_test_srv_crt_len; extern const size_t mbedtls_test_srv_key_len; -extern const char * mbedtls_test_cli_crt; -extern const size_t mbedtls_test_cli_crt_len; -extern const char * mbedtls_test_cli_key; -extern const size_t mbedtls_test_cli_key_len; +extern const size_t mbedtls_test_srv_pwd_len; + +/* + * Client test certificates + */ + +extern const char mbedtls_test_cli_crt_ec_pem[]; +extern const char mbedtls_test_cli_key_ec_pem[]; +extern const char mbedtls_test_cli_pwd_ec_pem[]; +extern const char mbedtls_test_cli_key_rsa_pem[]; +extern const char mbedtls_test_cli_pwd_rsa_pem[]; +extern const char mbedtls_test_cli_crt_rsa_pem[]; + +extern const unsigned char mbedtls_test_cli_crt_ec_der[]; +extern const unsigned char mbedtls_test_cli_key_ec_der[]; +extern const unsigned char mbedtls_test_cli_key_rsa_der[]; +extern const unsigned char mbedtls_test_cli_crt_rsa_der[]; + +extern const size_t mbedtls_test_cli_crt_ec_pem_len; +extern const size_t mbedtls_test_cli_key_ec_pem_len; +extern const size_t mbedtls_test_cli_pwd_ec_pem_len; +extern const size_t mbedtls_test_cli_key_rsa_pem_len; +extern const size_t mbedtls_test_cli_pwd_rsa_pem_len; +extern const size_t mbedtls_test_cli_crt_rsa_pem_len; + +extern const size_t mbedtls_test_cli_crt_ec_der_len; +extern const size_t mbedtls_test_cli_key_ec_der_len; +extern const size_t mbedtls_test_cli_key_rsa_der_len; +extern const size_t mbedtls_test_cli_crt_rsa_der_len; + +/* Config-dependent dispatch between PEM and DER encoding + * (PEM if enabled, otherwise DER) */ + +extern const char mbedtls_test_cli_crt_ec[]; +extern const char mbedtls_test_cli_key_ec[]; +extern const char mbedtls_test_cli_pwd_ec[]; +extern const char mbedtls_test_cli_key_rsa[]; +extern const char mbedtls_test_cli_pwd_rsa[]; +extern const char mbedtls_test_cli_crt_rsa[]; -#if defined(MBEDTLS_ECDSA_C) -extern const char mbedtls_test_ca_crt_ec[]; -extern const size_t mbedtls_test_ca_crt_ec_len; -extern const char mbedtls_test_ca_key_ec[]; -extern const size_t mbedtls_test_ca_key_ec_len; -extern const char mbedtls_test_ca_pwd_ec[]; -extern const size_t mbedtls_test_ca_pwd_ec_len; -extern const char mbedtls_test_srv_crt_ec[]; -extern const size_t mbedtls_test_srv_crt_ec_len; -extern const char mbedtls_test_srv_key_ec[]; -extern const size_t mbedtls_test_srv_key_ec_len; -extern const char mbedtls_test_cli_crt_ec[]; extern const size_t mbedtls_test_cli_crt_ec_len; -extern const char mbedtls_test_cli_key_ec[]; extern const size_t mbedtls_test_cli_key_ec_len; -#endif - -#if defined(MBEDTLS_RSA_C) -extern const char mbedtls_test_ca_crt_rsa[]; -extern const size_t mbedtls_test_ca_crt_rsa_len; -extern const char mbedtls_test_ca_key_rsa[]; -extern const size_t mbedtls_test_ca_key_rsa_len; -extern const char mbedtls_test_ca_pwd_rsa[]; -extern const size_t mbedtls_test_ca_pwd_rsa_len; -extern const char mbedtls_test_srv_crt_rsa[]; -extern const size_t mbedtls_test_srv_crt_rsa_len; -extern const char mbedtls_test_srv_key_rsa[]; -extern const size_t mbedtls_test_srv_key_rsa_len; -extern const char mbedtls_test_cli_crt_rsa[]; -extern const size_t mbedtls_test_cli_crt_rsa_len; -extern const char mbedtls_test_cli_key_rsa[]; +extern const size_t mbedtls_test_cli_pwd_ec_len; extern const size_t mbedtls_test_cli_key_rsa_len; -#endif +extern const size_t mbedtls_test_cli_pwd_rsa_len; +extern const size_t mbedtls_test_cli_crt_rsa_len; + +/* Config-dependent dispatch between EC and RSA + * (RSA if enabled, otherwise EC) */ + +extern const char * mbedtls_test_cli_crt; +extern const char * mbedtls_test_cli_key; +extern const char * mbedtls_test_cli_pwd; +extern const size_t mbedtls_test_cli_crt_len; +extern const size_t mbedtls_test_cli_key_len; +extern const size_t mbedtls_test_cli_pwd_len; #ifdef __cplusplus } diff --git a/thirdparty/mbedtls/include/mbedtls/cipher.h b/thirdparty/mbedtls/include/mbedtls/cipher.h index 922b6c32c6..082a691741 100644 --- a/thirdparty/mbedtls/include/mbedtls/cipher.h +++ b/thirdparty/mbedtls/include/mbedtls/cipher.h @@ -36,7 +36,7 @@ #endif #include <stddef.h> -#include "mbedtls/platform_util.h" +#include "platform_util.h" #if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) || defined(MBEDTLS_CHACHAPOLY_C) #define MBEDTLS_CIPHER_MODE_AEAD diff --git a/thirdparty/mbedtls/include/mbedtls/cmac.h b/thirdparty/mbedtls/include/mbedtls/cmac.h index c196793531..9d42b3f209 100644 --- a/thirdparty/mbedtls/include/mbedtls/cmac.h +++ b/thirdparty/mbedtls/include/mbedtls/cmac.h @@ -28,6 +28,12 @@ #ifndef MBEDTLS_CMAC_H #define MBEDTLS_CMAC_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "cipher.h" #ifdef __cplusplus diff --git a/thirdparty/mbedtls/include/mbedtls/compat-1.3.h b/thirdparty/mbedtls/include/mbedtls/compat-1.3.h index 213b691403..a58b47243d 100644 --- a/thirdparty/mbedtls/include/mbedtls/compat-1.3.h +++ b/thirdparty/mbedtls/include/mbedtls/compat-1.3.h @@ -25,6 +25,12 @@ * This file is part of mbed TLS (https://tls.mbed.org) */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #if ! defined(MBEDTLS_DEPRECATED_REMOVED) #if defined(MBEDTLS_DEPRECATED_WARNING) diff --git a/thirdparty/mbedtls/include/mbedtls/config.h b/thirdparty/mbedtls/include/mbedtls/config.h index 51d66291a5..e16e1e53d3 100644 --- a/thirdparty/mbedtls/include/mbedtls/config.h +++ b/thirdparty/mbedtls/include/mbedtls/config.h @@ -687,6 +687,26 @@ #define MBEDTLS_REMOVE_ARC4_CIPHERSUITES /** + * \def MBEDTLS_REMOVE_3DES_CIPHERSUITES + * + * Remove 3DES ciphersuites by default in SSL / TLS. + * This flag removes the ciphersuites based on 3DES from the default list as + * returned by mbedtls_ssl_list_ciphersuites(). However, it is still possible + * to enable (some of) them with mbedtls_ssl_conf_ciphersuites() by including + * them explicitly. + * + * A man-in-the-browser attacker can recover authentication tokens sent through + * a TLS connection using a 3DES based cipher suite (see "On the Practical + * (In-)Security of 64-bit Block Ciphers" by Karthikeyan Bhargavan and Gaëtan + * Leurent, see https://sweet32.info/SWEET32_CCS16.pdf). If this attack falls + * in your threat model or you are unsure, then you should keep this option + * enabled to remove 3DES based cipher suites. + * + * Comment this macro to keep 3DES in the default ciphersuite list. + */ +#define MBEDTLS_REMOVE_3DES_CIPHERSUITES + +/** * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED * * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve @@ -1622,7 +1642,9 @@ * * Uncomment this to enable pthread mutexes. */ +// -- GODOT start -- //#define MBEDTLS_THREADING_PTHREAD +// -- GODOT end -- /** * \def MBEDTLS_VERSION_FEATURES @@ -2816,7 +2838,9 @@ * * Enable this layer to allow use of mutexes within mbed TLS */ +// -- GODOT start -- //#define MBEDTLS_THREADING_C +// -- GODOT end -- /** * \def MBEDTLS_TIMING_C diff --git a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h index 10f9389d9f..cc3df7b113 100644 --- a/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h +++ b/thirdparty/mbedtls/include/mbedtls/ctr_drbg.h @@ -36,6 +36,12 @@ #ifndef MBEDTLS_CTR_DRBG_H #define MBEDTLS_CTR_DRBG_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "aes.h" #if defined(MBEDTLS_THREADING_C) @@ -350,6 +356,8 @@ int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ); #endif /* MBEDTLS_FS_IO */ +#if defined(MBEDTLS_SELF_TEST) + /** * \brief The CTR_DRBG checkup routine. * @@ -358,6 +366,8 @@ int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char */ int mbedtls_ctr_drbg_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + /* Internal functions (do not call directly) */ int mbedtls_ctr_drbg_seed_entropy_len( mbedtls_ctr_drbg_context *, int (*)(void *, unsigned char *, size_t), void *, diff --git a/thirdparty/mbedtls/include/mbedtls/des.h b/thirdparty/mbedtls/include/mbedtls/des.h index d62042d14e..54e6b7894b 100644 --- a/thirdparty/mbedtls/include/mbedtls/des.h +++ b/thirdparty/mbedtls/include/mbedtls/des.h @@ -338,6 +338,8 @@ int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -345,6 +347,8 @@ void mbedtls_des_setkey( uint32_t SK[32], */ int mbedtls_des_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/dhm.h b/thirdparty/mbedtls/include/mbedtls/dhm.h index a5452c199a..2909f5fbc8 100644 --- a/thirdparty/mbedtls/include/mbedtls/dhm.h +++ b/thirdparty/mbedtls/include/mbedtls/dhm.h @@ -334,6 +334,8 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ); #endif /* MBEDTLS_FS_IO */ #endif /* MBEDTLS_ASN1_PARSE_C */ +#if defined(MBEDTLS_SELF_TEST) + /** * \brief The DMH checkup routine. * @@ -342,6 +344,7 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ); */ int mbedtls_dhm_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/ecdh.h b/thirdparty/mbedtls/include/mbedtls/ecdh.h index 05b2b03970..4479a1d46f 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecdh.h +++ b/thirdparty/mbedtls/include/mbedtls/ecdh.h @@ -34,6 +34,12 @@ #ifndef MBEDTLS_ECDH_H #define MBEDTLS_ECDH_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "ecp.h" /* diff --git a/thirdparty/mbedtls/include/mbedtls/ecdsa.h b/thirdparty/mbedtls/include/mbedtls/ecdsa.h index 40fdab3729..f8b28507c2 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecdsa.h +++ b/thirdparty/mbedtls/include/mbedtls/ecdsa.h @@ -32,6 +32,12 @@ #ifndef MBEDTLS_ECDSA_H #define MBEDTLS_ECDSA_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "ecp.h" #include "md.h" diff --git a/thirdparty/mbedtls/include/mbedtls/ecjpake.h b/thirdparty/mbedtls/include/mbedtls/ecjpake.h index b967af8385..3d8d02ae64 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecjpake.h +++ b/thirdparty/mbedtls/include/mbedtls/ecjpake.h @@ -40,6 +40,11 @@ * The payloads are serialized in a way suitable for use in TLS, but could * also be use outside TLS. */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif #include "ecp.h" #include "md.h" diff --git a/thirdparty/mbedtls/include/mbedtls/ecp.h b/thirdparty/mbedtls/include/mbedtls/ecp.h index de3a343cb6..065a4cc0b9 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecp.h +++ b/thirdparty/mbedtls/include/mbedtls/ecp.h @@ -36,6 +36,12 @@ #ifndef MBEDTLS_ECP_H #define MBEDTLS_ECP_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "bignum.h" /* @@ -189,6 +195,68 @@ typedef struct mbedtls_ecp_group } mbedtls_ecp_group; +/** + * \name SECTION: Module settings + * + * The configuration options you can set for this module are in this section. + * Either change them in config.h, or define them using the compiler command line. + * \{ + */ + +#if !defined(MBEDTLS_ECP_MAX_BITS) +/** + * The maximum size of the groups, that is, of \c N and \c P. + */ +#define MBEDTLS_ECP_MAX_BITS 521 /**< The maximum size of groups, in bits. */ +#endif + +#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 ) +#define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 ) + +#if !defined(MBEDTLS_ECP_WINDOW_SIZE) +/* + * Maximum "window" size used for point multiplication. + * Default: 6. + * Minimum value: 2. Maximum value: 7. + * + * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) + * points used for point multiplication. This value is directly tied to EC + * peak memory usage, so decreasing it by one should roughly cut memory usage + * by two (if large curves are in use). + * + * Reduction in size may reduce speed, but larger curves are impacted first. + * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): + * w-size: 6 5 4 3 2 + * 521 145 141 135 120 97 + * 384 214 209 198 177 146 + * 256 320 320 303 262 226 + * 224 475 475 453 398 342 + * 192 640 640 633 587 476 + */ +#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< The maximum window size used. */ +#endif /* MBEDTLS_ECP_WINDOW_SIZE */ + +#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) +/* + * Trade memory for speed on fixed-point multiplication. + * + * This speeds up repeated multiplication of the generator (that is, the + * multiplication in ECDSA signatures, and half of the multiplications in + * ECDSA verification and ECDHE) by a factor roughly 3 to 4. + * + * The cost is increasing EC peak memory usage by a factor roughly 2. + * + * Change this value to 0 to reduce peak memory usage. + */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */ +#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ + +/* \} name SECTION: Module settings */ + +#else /* MBEDTLS_ECP_ALT */ +#include "ecp_alt.h" +#endif /* MBEDTLS_ECP_ALT */ + #if defined(MBEDTLS_ECP_RESTARTABLE) /** @@ -254,68 +322,6 @@ typedef void mbedtls_ecp_restart_ctx; #endif /* MBEDTLS_ECP_RESTARTABLE */ /** - * \name SECTION: Module settings - * - * The configuration options you can set for this module are in this section. - * Either change them in config.h, or define them using the compiler command line. - * \{ - */ - -#if !defined(MBEDTLS_ECP_MAX_BITS) -/** - * The maximum size of the groups, that is, of \c N and \c P. - */ -#define MBEDTLS_ECP_MAX_BITS 521 /**< The maximum size of groups, in bits. */ -#endif - -#define MBEDTLS_ECP_MAX_BYTES ( ( MBEDTLS_ECP_MAX_BITS + 7 ) / 8 ) -#define MBEDTLS_ECP_MAX_PT_LEN ( 2 * MBEDTLS_ECP_MAX_BYTES + 1 ) - -#if !defined(MBEDTLS_ECP_WINDOW_SIZE) -/* - * Maximum "window" size used for point multiplication. - * Default: 6. - * Minimum value: 2. Maximum value: 7. - * - * Result is an array of at most ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) - * points used for point multiplication. This value is directly tied to EC - * peak memory usage, so decreasing it by one should roughly cut memory usage - * by two (if large curves are in use). - * - * Reduction in size may reduce speed, but larger curves are impacted first. - * Sample performances (in ECDHE handshakes/s, with FIXED_POINT_OPTIM = 1): - * w-size: 6 5 4 3 2 - * 521 145 141 135 120 97 - * 384 214 209 198 177 146 - * 256 320 320 303 262 226 - * 224 475 475 453 398 342 - * 192 640 640 633 587 476 - */ -#define MBEDTLS_ECP_WINDOW_SIZE 6 /**< The maximum window size used. */ -#endif /* MBEDTLS_ECP_WINDOW_SIZE */ - -#if !defined(MBEDTLS_ECP_FIXED_POINT_OPTIM) -/* - * Trade memory for speed on fixed-point multiplication. - * - * This speeds up repeated multiplication of the generator (that is, the - * multiplication in ECDSA signatures, and half of the multiplications in - * ECDSA verification and ECDHE) by a factor roughly 3 to 4. - * - * The cost is increasing EC peak memory usage by a factor roughly 2. - * - * Change this value to 0 to reduce peak memory usage. - */ -#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up. */ -#endif /* MBEDTLS_ECP_FIXED_POINT_OPTIM */ - -/* \} name SECTION: Module settings */ - -#else /* MBEDTLS_ECP_ALT */ -#include "ecp_alt.h" -#endif /* MBEDTLS_ECP_ALT */ - -/** * \brief The ECP key-pair structure. * * A generic key-pair that may be used for ECDSA and fixed ECDH, for example. @@ -476,7 +482,7 @@ void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ); * * \note After this function is called, domain parameters * for various ECP groups can be loaded through the - * mbedtls_ecp_load() or mbedtls_ecp_tls_read_group() + * mbedtls_ecp_group_load() or mbedtls_ecp_tls_read_group() * functions. */ void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ); diff --git a/thirdparty/mbedtls/include/mbedtls/ecp_internal.h b/thirdparty/mbedtls/include/mbedtls/ecp_internal.h index 18040697ad..7625ed48e1 100644 --- a/thirdparty/mbedtls/include/mbedtls/ecp_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/ecp_internal.h @@ -61,6 +61,12 @@ #ifndef MBEDTLS_ECP_INTERNAL_H #define MBEDTLS_ECP_INTERNAL_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #if defined(MBEDTLS_ECP_INTERNAL_ALT) /** diff --git a/thirdparty/mbedtls/include/mbedtls/error.h b/thirdparty/mbedtls/include/mbedtls/error.h index 647a11a566..bee0fe485a 100644 --- a/thirdparty/mbedtls/include/mbedtls/error.h +++ b/thirdparty/mbedtls/include/mbedtls/error.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_ERROR_H #define MBEDTLS_ERROR_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include <stddef.h> /** diff --git a/thirdparty/mbedtls/include/mbedtls/gcm.h b/thirdparty/mbedtls/include/mbedtls/gcm.h index fccabb0d97..fd130abd7c 100644 --- a/thirdparty/mbedtls/include/mbedtls/gcm.h +++ b/thirdparty/mbedtls/include/mbedtls/gcm.h @@ -33,6 +33,12 @@ #ifndef MBEDTLS_GCM_H #define MBEDTLS_GCM_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "cipher.h" #include <stdint.h> @@ -300,6 +306,8 @@ int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, */ void mbedtls_gcm_free( mbedtls_gcm_context *ctx ); +#if defined(MBEDTLS_SELF_TEST) + /** * \brief The GCM checkup routine. * @@ -308,6 +316,8 @@ void mbedtls_gcm_free( mbedtls_gcm_context *ctx ); */ int mbedtls_gcm_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/havege.h b/thirdparty/mbedtls/include/mbedtls/havege.h index 57e8c40943..4c1c86087a 100644 --- a/thirdparty/mbedtls/include/mbedtls/havege.h +++ b/thirdparty/mbedtls/include/mbedtls/havege.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_HAVEGE_H #define MBEDTLS_HAVEGE_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include <stddef.h> #define MBEDTLS_HAVEGE_COLLECT_SIZE 1024 diff --git a/thirdparty/mbedtls/include/mbedtls/hkdf.h b/thirdparty/mbedtls/include/mbedtls/hkdf.h index e6ed7cde97..40ee64eb03 100644 --- a/thirdparty/mbedtls/include/mbedtls/hkdf.h +++ b/thirdparty/mbedtls/include/mbedtls/hkdf.h @@ -27,6 +27,12 @@ #ifndef MBEDTLS_HKDF_H #define MBEDTLS_HKDF_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "md.h" /** diff --git a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h index 146367b9de..7eae32bbd6 100644 --- a/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h +++ b/thirdparty/mbedtls/include/mbedtls/hmac_drbg.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_HMAC_DRBG_H #define MBEDTLS_HMAC_DRBG_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "md.h" #if defined(MBEDTLS_THREADING_C) diff --git a/thirdparty/mbedtls/include/mbedtls/md2.h b/thirdparty/mbedtls/include/mbedtls/md2.h index f9bd98f804..fe97cf08d4 100644 --- a/thirdparty/mbedtls/include/mbedtls/md2.h +++ b/thirdparty/mbedtls/include/mbedtls/md2.h @@ -283,6 +283,8 @@ MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -295,6 +297,8 @@ MBEDTLS_DEPRECATED void mbedtls_md2( const unsigned char *input, */ int mbedtls_md2_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/md4.h b/thirdparty/mbedtls/include/mbedtls/md4.h index dc3c048949..ce703c0ba4 100644 --- a/thirdparty/mbedtls/include/mbedtls/md4.h +++ b/thirdparty/mbedtls/include/mbedtls/md4.h @@ -288,6 +288,8 @@ MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -300,6 +302,8 @@ MBEDTLS_DEPRECATED void mbedtls_md4( const unsigned char *input, */ int mbedtls_md4_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/md5.h b/thirdparty/mbedtls/include/mbedtls/md5.h index 6c3354fd30..6eed6cc864 100644 --- a/thirdparty/mbedtls/include/mbedtls/md5.h +++ b/thirdparty/mbedtls/include/mbedtls/md5.h @@ -288,6 +288,8 @@ MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -300,6 +302,8 @@ MBEDTLS_DEPRECATED void mbedtls_md5( const unsigned char *input, */ int mbedtls_md5_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/net.h b/thirdparty/mbedtls/include/mbedtls/net.h index 6c13b53fb9..8cead58e5d 100644 --- a/thirdparty/mbedtls/include/mbedtls/net.h +++ b/thirdparty/mbedtls/include/mbedtls/net.h @@ -23,6 +23,11 @@ * * This file is part of mbed TLS (https://tls.mbed.org) */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif #if !defined(MBEDTLS_DEPRECATED_REMOVED) #include "net_sockets.h" diff --git a/thirdparty/mbedtls/include/mbedtls/nist_kw.h b/thirdparty/mbedtls/include/mbedtls/nist_kw.h index 5a0f656a8f..3b67b59cd2 100644 --- a/thirdparty/mbedtls/include/mbedtls/nist_kw.h +++ b/thirdparty/mbedtls/include/mbedtls/nist_kw.h @@ -37,6 +37,12 @@ #ifndef MBEDTLS_NIST_KW_H #define MBEDTLS_NIST_KW_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "cipher.h" #ifdef __cplusplus diff --git a/thirdparty/mbedtls/include/mbedtls/padlock.h b/thirdparty/mbedtls/include/mbedtls/padlock.h index 7a5d083a95..721a5d4930 100644 --- a/thirdparty/mbedtls/include/mbedtls/padlock.h +++ b/thirdparty/mbedtls/include/mbedtls/padlock.h @@ -28,6 +28,12 @@ #ifndef MBEDTLS_PADLOCK_H #define MBEDTLS_PADLOCK_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "aes.h" #define MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED -0x0030 /**< Input data should be aligned. */ @@ -53,7 +59,7 @@ #define MBEDTLS_PADLOCK_PHE 0x0C00 #define MBEDTLS_PADLOCK_PMM 0x3000 -#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) x & ~15)) +#define MBEDTLS_PADLOCK_ALIGN16(x) (uint32_t *) (16 + ((int32_t) (x) & ~15)) #ifdef __cplusplus extern "C" { diff --git a/thirdparty/mbedtls/include/mbedtls/pem.h b/thirdparty/mbedtls/include/mbedtls/pem.h index fa82f7bdbd..a29e9ce300 100644 --- a/thirdparty/mbedtls/include/mbedtls/pem.h +++ b/thirdparty/mbedtls/include/mbedtls/pem.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_PEM_H #define MBEDTLS_PEM_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include <stddef.h> /** diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs12.h b/thirdparty/mbedtls/include/mbedtls/pkcs12.h index 69f04177c8..d441357b7f 100644 --- a/thirdparty/mbedtls/include/mbedtls/pkcs12.h +++ b/thirdparty/mbedtls/include/mbedtls/pkcs12.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_PKCS12_H #define MBEDTLS_PKCS12_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "md.h" #include "cipher.h" #include "asn1.h" diff --git a/thirdparty/mbedtls/include/mbedtls/pkcs5.h b/thirdparty/mbedtls/include/mbedtls/pkcs5.h index d4bb36dfae..c92185f7a6 100644 --- a/thirdparty/mbedtls/include/mbedtls/pkcs5.h +++ b/thirdparty/mbedtls/include/mbedtls/pkcs5.h @@ -26,6 +26,12 @@ #ifndef MBEDTLS_PKCS5_H #define MBEDTLS_PKCS5_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "asn1.h" #include "md.h" @@ -85,6 +91,8 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p unsigned int iteration_count, uint32_t key_length, unsigned char *output ); +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -92,6 +100,8 @@ int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *p */ int mbedtls_pkcs5_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/platform_util.h b/thirdparty/mbedtls/include/mbedtls/platform_util.h index b0e72ad149..dba6d45982 100644 --- a/thirdparty/mbedtls/include/mbedtls/platform_util.h +++ b/thirdparty/mbedtls/include/mbedtls/platform_util.h @@ -26,14 +26,14 @@ #define MBEDTLS_PLATFORM_UTIL_H #if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" +#include "config.h" #else #include MBEDTLS_CONFIG_FILE #endif #include <stddef.h> #if defined(MBEDTLS_HAVE_TIME_DATE) -#include "mbedtls/platform_time.h" +#include "platform_time.h" #include <time.h> #endif /* MBEDTLS_HAVE_TIME_DATE */ diff --git a/thirdparty/mbedtls/include/mbedtls/poly1305.h b/thirdparty/mbedtls/include/mbedtls/poly1305.h index 05866a2da6..f0ec44c968 100644 --- a/thirdparty/mbedtls/include/mbedtls/poly1305.h +++ b/thirdparty/mbedtls/include/mbedtls/poly1305.h @@ -34,7 +34,7 @@ #define MBEDTLS_POLY1305_H #if !defined(MBEDTLS_CONFIG_FILE) -#include "mbedtls/config.h" +#include "config.h" #else #include MBEDTLS_CONFIG_FILE #endif diff --git a/thirdparty/mbedtls/include/mbedtls/ripemd160.h b/thirdparty/mbedtls/include/mbedtls/ripemd160.h index c74b7d2c6c..b42f6d2a95 100644 --- a/thirdparty/mbedtls/include/mbedtls/ripemd160.h +++ b/thirdparty/mbedtls/include/mbedtls/ripemd160.h @@ -219,6 +219,8 @@ MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -226,6 +228,8 @@ MBEDTLS_DEPRECATED void mbedtls_ripemd160( const unsigned char *input, */ int mbedtls_ripemd160_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/rsa.h b/thirdparty/mbedtls/include/mbedtls/rsa.h index ed65a34452..906c427332 100644 --- a/thirdparty/mbedtls/include/mbedtls/rsa.h +++ b/thirdparty/mbedtls/include/mbedtls/rsa.h @@ -1252,6 +1252,8 @@ int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ) */ void mbedtls_rsa_free( mbedtls_rsa_context *ctx ); +#if defined(MBEDTLS_SELF_TEST) + /** * \brief The RSA checkup routine. * @@ -1260,6 +1262,8 @@ void mbedtls_rsa_free( mbedtls_rsa_context *ctx ); */ int mbedtls_rsa_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/sha1.h b/thirdparty/mbedtls/include/mbedtls/sha1.h index 38ea10b137..bb6ecf05a4 100644 --- a/thirdparty/mbedtls/include/mbedtls/sha1.h +++ b/thirdparty/mbedtls/include/mbedtls/sha1.h @@ -328,6 +328,8 @@ MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#if defined(MBEDTLS_SELF_TEST) + /** * \brief The SHA-1 checkup routine. * @@ -341,6 +343,8 @@ MBEDTLS_DEPRECATED void mbedtls_sha1( const unsigned char *input, */ int mbedtls_sha1_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/sha256.h b/thirdparty/mbedtls/include/mbedtls/sha256.h index 0e42f0abba..d64739820c 100644 --- a/thirdparty/mbedtls/include/mbedtls/sha256.h +++ b/thirdparty/mbedtls/include/mbedtls/sha256.h @@ -278,6 +278,8 @@ MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ +#if defined(MBEDTLS_SELF_TEST) + /** * \brief The SHA-224 and SHA-256 checkup routine. * @@ -286,6 +288,8 @@ MBEDTLS_DEPRECATED void mbedtls_sha256( const unsigned char *input, */ int mbedtls_sha256_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/include/mbedtls/sha512.h b/thirdparty/mbedtls/include/mbedtls/sha512.h index 7b26cf5cc3..c06ceed1d1 100644 --- a/thirdparty/mbedtls/include/mbedtls/sha512.h +++ b/thirdparty/mbedtls/include/mbedtls/sha512.h @@ -253,6 +253,7 @@ int mbedtls_sha512_ret( const unsigned char *input, #else #define MBEDTLS_DEPRECATED #endif + /** * \brief This function calculates the SHA-512 or SHA-384 * checksum of a buffer. @@ -280,6 +281,9 @@ MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input, #undef MBEDTLS_DEPRECATED #endif /* !MBEDTLS_DEPRECATED_REMOVED */ + +#if defined(MBEDTLS_SELF_TEST) + /** * \brief The SHA-384 or SHA-512 checkup routine. * @@ -287,6 +291,7 @@ MBEDTLS_DEPRECATED void mbedtls_sha512( const unsigned char *input, * \return \c 1 on failure. */ int mbedtls_sha512_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ #ifdef __cplusplus } diff --git a/thirdparty/mbedtls/include/mbedtls/ssl.h b/thirdparty/mbedtls/include/mbedtls/ssl.h index 8106bb4ab0..d31f6cdd56 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl.h @@ -2532,22 +2532,28 @@ void mbedtls_ssl_conf_cert_req_ca_list( mbedtls_ssl_config *conf, #if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) /** - * \brief Set the maximum fragment length to emit and/or negotiate - * (Default: the smaller of MBEDTLS_SSL_IN_CONTENT_LEN and - * MBEDTLS_SSL_OUT_CONTENT_LEN, usually 2^14 bytes) + * \brief Set the maximum fragment length to emit and/or negotiate. + * (Typical: the smaller of #MBEDTLS_SSL_IN_CONTENT_LEN and + * #MBEDTLS_SSL_OUT_CONTENT_LEN, usually `2^14` bytes) * (Server: set maximum fragment length to emit, - * usually negotiated by the client during handshake + * usually negotiated by the client during handshake) * (Client: set maximum fragment length to emit *and* * negotiate with the server during handshake) + * (Default: #MBEDTLS_SSL_MAX_FRAG_LEN_NONE) * - * \note With TLS, this currently only affects ApplicationData (sent - * with \c mbedtls_ssl_read()), not handshake messages. - * With DTLS, this affects both ApplicationData and handshake. + * \note On the client side, the maximum fragment length extension + * *will not* be used, unless the maximum fragment length has + * been set via this function to a value different than + * #MBEDTLS_SSL_MAX_FRAG_LEN_NONE. * * \note This sets the maximum length for a record's payload, * excluding record overhead that will be added to it, see * \c mbedtls_ssl_get_record_expansion(). * + * \note With TLS, this currently only affects ApplicationData (sent + * with \c mbedtls_ssl_read()), not handshake messages. + * With DTLS, this affects both ApplicationData and handshake. + * * \note For DTLS, it is also possible to set a limit for the total * size of daragrams passed to the transport layer, including * record overhead, see \c mbedtls_ssl_set_mtu(). diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_cache.h b/thirdparty/mbedtls/include/mbedtls/ssl_cache.h index ec081e6d24..52ba0948c5 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_cache.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_cache.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_SSL_CACHE_H #define MBEDTLS_SSL_CACHE_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "ssl.h" #if defined(MBEDTLS_THREADING_C) diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h b/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h index cda8b4835b..71053e5ba7 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_ciphersuites.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_SSL_CIPHERSUITES_H #define MBEDTLS_SSL_CIPHERSUITES_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "pk.h" #include "cipher.h" #include "md.h" diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h b/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h index 6a0ad4fa96..e34760ae85 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_cookie.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_SSL_COOKIE_H #define MBEDTLS_SSL_COOKIE_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "ssl.h" #if defined(MBEDTLS_THREADING_C) diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h index 97abb9f90b..bd5ad94dbf 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_internal.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_internal.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_SSL_INTERNAL_H #define MBEDTLS_SSL_INTERNAL_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + #include "ssl.h" #include "cipher.h" diff --git a/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h b/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h index b2686df09f..a84e7816e4 100644 --- a/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h +++ b/thirdparty/mbedtls/include/mbedtls/ssl_ticket.h @@ -24,6 +24,12 @@ #ifndef MBEDTLS_SSL_TICKET_H #define MBEDTLS_SSL_TICKET_H +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + /* * This implementation of the session ticket callbacks includes key * management, rotating the keys periodically in order to preserve forward diff --git a/thirdparty/mbedtls/include/mbedtls/version.h b/thirdparty/mbedtls/include/mbedtls/version.h index 56e7398a2a..ef8e4c1f4f 100644 --- a/thirdparty/mbedtls/include/mbedtls/version.h +++ b/thirdparty/mbedtls/include/mbedtls/version.h @@ -40,16 +40,16 @@ */ #define MBEDTLS_VERSION_MAJOR 2 #define MBEDTLS_VERSION_MINOR 16 -#define MBEDTLS_VERSION_PATCH 0 +#define MBEDTLS_VERSION_PATCH 2 /** * The single version number has the following structure: * MMNNPP00 * Major version | Minor version | Patch version */ -#define MBEDTLS_VERSION_NUMBER 0x02100000 -#define MBEDTLS_VERSION_STRING "2.16.0" -#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.0" +#define MBEDTLS_VERSION_NUMBER 0x02100200 +#define MBEDTLS_VERSION_STRING "2.16.2" +#define MBEDTLS_VERSION_STRING_FULL "mbed TLS 2.16.2" #if defined(MBEDTLS_VERSION_C) diff --git a/thirdparty/mbedtls/include/mbedtls/x509.h b/thirdparty/mbedtls/include/mbedtls/x509.h index d6db9c6e37..9ae825c183 100644 --- a/thirdparty/mbedtls/include/mbedtls/x509.h +++ b/thirdparty/mbedtls/include/mbedtls/x509.h @@ -269,6 +269,8 @@ int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ); */ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ); +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -276,6 +278,8 @@ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ); */ int mbedtls_x509_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + /* * Internal module functions. You probably do not want to use these unless you * know you do. diff --git a/thirdparty/mbedtls/include/mbedtls/x509_crt.h b/thirdparty/mbedtls/include/mbedtls/x509_crt.h index 3dd5922486..670bd10d89 100644 --- a/thirdparty/mbedtls/include/mbedtls/x509_crt.h +++ b/thirdparty/mbedtls/include/mbedtls/x509_crt.h @@ -98,7 +98,7 @@ mbedtls_x509_crt; * Build flag from an algorithm/curve identifier (pk, md, ecp) * Since 0 is always XXX_NONE, ignore it. */ -#define MBEDTLS_X509_ID_FLAG( id ) ( 1 << ( id - 1 ) ) +#define MBEDTLS_X509_ID_FLAG( id ) ( 1 << ( (id) - 1 ) ) /** * Security profile for certificate verification. diff --git a/thirdparty/mbedtls/include/mbedtls/x509_csr.h b/thirdparty/mbedtls/include/mbedtls/x509_csr.h index 0c6ccad78d..a3c28048e0 100644 --- a/thirdparty/mbedtls/include/mbedtls/x509_csr.h +++ b/thirdparty/mbedtls/include/mbedtls/x509_csr.h @@ -205,6 +205,14 @@ void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_ty * \param key_usage key usage flags to set * * \return 0 if successful, or MBEDTLS_ERR_X509_ALLOC_FAILED + * + * \note The <code>decipherOnly</code> flag from the Key Usage + * extension is represented by bit 8 (i.e. + * <code>0x8000</code>), which cannot typically be represented + * in an unsigned char. Therefore, the flag + * <code>decipherOnly</code> (i.e. + * #MBEDTLS_X509_KU_DECIPHER_ONLY) cannot be set using this + * function. */ int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ); diff --git a/thirdparty/mbedtls/include/mbedtls/xtea.h b/thirdparty/mbedtls/include/mbedtls/xtea.h index 6430c1318a..b47f553508 100644 --- a/thirdparty/mbedtls/include/mbedtls/xtea.h +++ b/thirdparty/mbedtls/include/mbedtls/xtea.h @@ -121,6 +121,8 @@ int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, unsigned char *output); #endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_SELF_TEST) + /** * \brief Checkup routine * @@ -128,6 +130,8 @@ int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, */ int mbedtls_xtea_self_test( int verbose ); +#endif /* MBEDTLS_SELF_TEST */ + #ifdef __cplusplus } #endif diff --git a/thirdparty/mbedtls/library/aes.c b/thirdparty/mbedtls/library/aes.c index 0543cd7817..aff0a9939a 100644 --- a/thirdparty/mbedtls/library/aes.c +++ b/thirdparty/mbedtls/library/aes.c @@ -395,9 +395,9 @@ static uint32_t RCON[10]; /* * Tables generation code */ -#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) -#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) -#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) +#define ROTL8(x) ( ( (x) << 8 ) & 0xFFFFFFFF ) | ( (x) >> 24 ) +#define XTIME(x) ( ( (x) << 1 ) ^ ( ( (x) & 0x80 ) ? 0x1B : 0x00 ) ) +#define MUL(x,y) ( ( (x) && (y) ) ? pow[(log[(x)]+log[(y)]) % 255] : 0 ) static int aes_init_done = 0; @@ -815,51 +815,53 @@ int mbedtls_aes_xts_setkey_dec( mbedtls_aes_xts_context *ctx, #endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ -#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ -{ \ - X0 = *RK++ ^ AES_FT0( ( Y0 ) & 0xFF ) ^ \ - AES_FT1( ( Y1 >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( Y2 >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( Y3 >> 24 ) & 0xFF ); \ - \ - X1 = *RK++ ^ AES_FT0( ( Y1 ) & 0xFF ) ^ \ - AES_FT1( ( Y2 >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( Y3 >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( Y0 >> 24 ) & 0xFF ); \ - \ - X2 = *RK++ ^ AES_FT0( ( Y2 ) & 0xFF ) ^ \ - AES_FT1( ( Y3 >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( Y0 >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( Y1 >> 24 ) & 0xFF ); \ - \ - X3 = *RK++ ^ AES_FT0( ( Y3 ) & 0xFF ) ^ \ - AES_FT1( ( Y0 >> 8 ) & 0xFF ) ^ \ - AES_FT2( ( Y1 >> 16 ) & 0xFF ) ^ \ - AES_FT3( ( Y2 >> 24 ) & 0xFF ); \ -} - -#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ -{ \ - X0 = *RK++ ^ AES_RT0( ( Y0 ) & 0xFF ) ^ \ - AES_RT1( ( Y3 >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( Y2 >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( Y1 >> 24 ) & 0xFF ); \ - \ - X1 = *RK++ ^ AES_RT0( ( Y1 ) & 0xFF ) ^ \ - AES_RT1( ( Y0 >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( Y3 >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( Y2 >> 24 ) & 0xFF ); \ - \ - X2 = *RK++ ^ AES_RT0( ( Y2 ) & 0xFF ) ^ \ - AES_RT1( ( Y1 >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( Y0 >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( Y3 >> 24 ) & 0xFF ); \ - \ - X3 = *RK++ ^ AES_RT0( ( Y3 ) & 0xFF ) ^ \ - AES_RT1( ( Y2 >> 8 ) & 0xFF ) ^ \ - AES_RT2( ( Y1 >> 16 ) & 0xFF ) ^ \ - AES_RT3( ( Y0 >> 24 ) & 0xFF ); \ -} +#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ + do \ + { \ + (X0) = *RK++ ^ AES_FT0( ( (Y0) ) & 0xFF ) ^ \ + AES_FT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ + AES_FT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ + AES_FT3( ( (Y3) >> 24 ) & 0xFF ); \ + \ + (X1) = *RK++ ^ AES_FT0( ( (Y1) ) & 0xFF ) ^ \ + AES_FT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ + AES_FT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ + AES_FT3( ( (Y0) >> 24 ) & 0xFF ); \ + \ + (X2) = *RK++ ^ AES_FT0( ( (Y2) ) & 0xFF ) ^ \ + AES_FT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ + AES_FT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ + AES_FT3( ( (Y1) >> 24 ) & 0xFF ); \ + \ + (X3) = *RK++ ^ AES_FT0( ( (Y3) ) & 0xFF ) ^ \ + AES_FT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ + AES_FT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ + AES_FT3( ( (Y2) >> 24 ) & 0xFF ); \ + } while( 0 ) + +#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ + do \ + { \ + (X0) = *RK++ ^ AES_RT0( ( (Y0) ) & 0xFF ) ^ \ + AES_RT1( ( (Y3) >> 8 ) & 0xFF ) ^ \ + AES_RT2( ( (Y2) >> 16 ) & 0xFF ) ^ \ + AES_RT3( ( (Y1) >> 24 ) & 0xFF ); \ + \ + (X1) = *RK++ ^ AES_RT0( ( (Y1) ) & 0xFF ) ^ \ + AES_RT1( ( (Y0) >> 8 ) & 0xFF ) ^ \ + AES_RT2( ( (Y3) >> 16 ) & 0xFF ) ^ \ + AES_RT3( ( (Y2) >> 24 ) & 0xFF ); \ + \ + (X2) = *RK++ ^ AES_RT0( ( (Y2) ) & 0xFF ) ^ \ + AES_RT1( ( (Y1) >> 8 ) & 0xFF ) ^ \ + AES_RT2( ( (Y0) >> 16 ) & 0xFF ) ^ \ + AES_RT3( ( (Y3) >> 24 ) & 0xFF ); \ + \ + (X3) = *RK++ ^ AES_RT0( ( (Y3) ) & 0xFF ) ^ \ + AES_RT1( ( (Y2) >> 8 ) & 0xFF ) ^ \ + AES_RT2( ( (Y1) >> 16 ) & 0xFF ) ^ \ + AES_RT3( ( (Y0) >> 24 ) & 0xFF ); \ + } while( 0 ) /* * AES-ECB block encryption diff --git a/thirdparty/mbedtls/library/asn1write.c b/thirdparty/mbedtls/library/asn1write.c index a4d23f6196..c0b4622d58 100644 --- a/thirdparty/mbedtls/library/asn1write.c +++ b/thirdparty/mbedtls/library/asn1write.c @@ -294,22 +294,28 @@ int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, const unsigned char *buf, size_t bits ) { int ret; - size_t len = 0, size; + size_t len = 0; + size_t unused_bits, byte_len; - size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 ); + byte_len = ( bits + 7 ) / 8; + unused_bits = ( byte_len * 8 ) - bits; - // Calculate byte length - // - if( *p < start || (size_t)( *p - start ) < size + 1 ) + if( *p < start || (size_t)( *p - start ) < byte_len + 1 ) return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); - len = size + 1; - (*p) -= size; - memcpy( *p, buf, size ); + len = byte_len + 1; - // Write unused bits - // - *--(*p) = (unsigned char) (size * 8 - bits); + /* Write the bitstring. Ensure the unused bits are zeroed */ + if( byte_len > 0 ) + { + byte_len--; + *--( *p ) = buf[byte_len] & ~( ( 0x1 << unused_bits ) - 1 ); + ( *p ) -= byte_len; + memcpy( *p, buf, byte_len ); + } + + /* Write unused bits */ + *--( *p ) = (unsigned char)unused_bits; MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); diff --git a/thirdparty/mbedtls/library/bignum.c b/thirdparty/mbedtls/library/bignum.c index f968a0ad7d..41946183c5 100644 --- a/thirdparty/mbedtls/library/bignum.c +++ b/thirdparty/mbedtls/library/bignum.c @@ -527,26 +527,38 @@ cleanup: } /* - * Helper to write the digits high-order first + * Helper to write the digits high-order first. */ -static int mpi_write_hlp( mbedtls_mpi *X, int radix, char **p ) +static int mpi_write_hlp( mbedtls_mpi *X, int radix, + char **p, const size_t buflen ) { int ret; mbedtls_mpi_uint r; + size_t length = 0; + char *p_end = *p + buflen; - if( radix < 2 || radix > 16 ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + do + { + if( length >= buflen ) + { + return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); + } - MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) ); + /* + * Write the residue in the current position, as an ASCII character. + */ + if( r < 0xA ) + *(--p_end) = (char)( '0' + r ); + else + *(--p_end) = (char)( 'A' + ( r - 0xA ) ); - if( mbedtls_mpi_cmp_int( X, 0 ) != 0 ) - MBEDTLS_MPI_CHK( mpi_write_hlp( X, radix, p ) ); + length++; + } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 ); - if( r < 10 ) - *(*p)++ = (char)( r + 0x30 ); - else - *(*p)++ = (char)( r + 0x37 ); + memmove( *p, p_end, length ); + *p += length; cleanup: @@ -570,15 +582,20 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, if( radix < 2 || radix > 16 ) return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); - n = mbedtls_mpi_bitlen( X ); - if( radix >= 4 ) n >>= 1; - if( radix >= 16 ) n >>= 1; - /* - * Round up the buffer length to an even value to ensure that there is - * enough room for hexadecimal values that can be represented in an odd - * number of digits. - */ - n += 3 + ( ( n + 1 ) & 1 ); + n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */ + if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present + * `n`. If radix > 4, this might be a strict + * overapproximation of the number of + * radix-adic digits needed to present `n`. */ + if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to + * present `n`. */ + + n += 1; /* Terminating null byte */ + n += 1; /* Compensate for the divisions above, which round down `n` + * in case it's not even. */ + n += 1; /* Potential '-'-sign. */ + n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing, + * which always uses an even number of hex-digits. */ if( buflen < n ) { @@ -590,7 +607,10 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, mbedtls_mpi_init( &T ); if( X->s == -1 ) + { *p++ = '-'; + buflen--; + } if( radix == 16 ) { @@ -619,7 +639,7 @@ int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, if( T.s == -1 ) T.s = 1; - MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p ) ); + MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) ); } *p++ = '\0'; @@ -715,14 +735,101 @@ cleanup: } #endif /* MBEDTLS_FS_IO */ + +/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint + * into the storage form used by mbedtls_mpi. */ + +static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x ) +{ + uint8_t i; + mbedtls_mpi_uint tmp = 0; + /* This works regardless of the endianness. */ + for( i = 0; i < ciL; i++, x >>= 8 ) + tmp |= ( x & 0xFF ) << ( ( ciL - 1 - i ) << 3 ); + return( tmp ); +} + +static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x ) +{ +#if defined(__BYTE_ORDER__) + +/* Nothing to do on bigendian systems. */ +#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ) + return( x ); +#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */ + +#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ ) + +/* For GCC and Clang, have builtins for byte swapping. */ +#if defined(__GNUC__) && defined(__GNUC_PREREQ) +#if __GNUC_PREREQ(4,3) +#define have_bswap +#endif +#endif + +#if defined(__clang__) && defined(__has_builtin) +#if __has_builtin(__builtin_bswap32) && \ + __has_builtin(__builtin_bswap64) +#define have_bswap +#endif +#endif + +#if defined(have_bswap) + /* The compiler is hopefully able to statically evaluate this! */ + switch( sizeof(mbedtls_mpi_uint) ) + { + case 4: + return( __builtin_bswap32(x) ); + case 8: + return( __builtin_bswap64(x) ); + } +#endif +#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */ +#endif /* __BYTE_ORDER__ */ + + /* Fall back to C-based reordering if we don't know the byte order + * or we couldn't use a compiler-specific builtin. */ + return( mpi_uint_bigendian_to_host_c( x ) ); +} + +static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs ) +{ + mbedtls_mpi_uint *cur_limb_left; + mbedtls_mpi_uint *cur_limb_right; + if( limbs == 0 ) + return; + + /* + * Traverse limbs and + * - adapt byte-order in each limb + * - swap the limbs themselves. + * For that, simultaneously traverse the limbs from left to right + * and from right to left, as long as the left index is not bigger + * than the right index (it's not a problem if limbs is odd and the + * indices coincide in the last iteration). + */ + for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 ); + cur_limb_left <= cur_limb_right; + cur_limb_left++, cur_limb_right-- ) + { + mbedtls_mpi_uint tmp; + /* Note that if cur_limb_left == cur_limb_right, + * this code effectively swaps the bytes only once. */ + tmp = mpi_uint_bigendian_to_host( *cur_limb_left ); + *cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right ); + *cur_limb_right = tmp; + } +} + /* * Import X from unsigned binary data, big endian */ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ) { int ret; - size_t i, j; - size_t const limbs = CHARS_TO_LIMBS( buflen ); + size_t const limbs = CHARS_TO_LIMBS( buflen ); + size_t const overhead = ( limbs * ciL ) - buflen; + unsigned char *Xp; MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( buflen == 0 || buf != NULL ); @@ -734,11 +841,17 @@ int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t bu mbedtls_mpi_init( X ); MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); } - MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); - for( i = buflen, j = 0; i > 0; i--, j++ ) - X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3); + /* Avoid calling `memcpy` with NULL source argument, + * even if buflen is 0. */ + if( buf != NULL ) + { + Xp = (unsigned char*) X->p; + memcpy( Xp + overhead, buf, buflen ); + + mpi_bigendian_to_host( X->p, limbs ); + } cleanup: @@ -1764,8 +1877,10 @@ int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; +#if( MBEDTLS_MPI_WINDOW_SIZE < 6 ) if( wsize > MBEDTLS_MPI_WINDOW_SIZE ) wsize = MBEDTLS_MPI_WINDOW_SIZE; +#endif j = N->n + 1; MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); @@ -2008,18 +2123,28 @@ int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, void *p_rng ) { int ret; - unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; + size_t const limbs = CHARS_TO_LIMBS( size ); + size_t const overhead = ( limbs * ciL ) - size; + unsigned char *Xp; + MPI_VALIDATE_RET( X != NULL ); MPI_VALIDATE_RET( f_rng != NULL ); - if( size > MBEDTLS_MPI_MAX_SIZE ) - return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + /* Ensure that target MPI has exactly the necessary number of limbs */ + if( X->n != limbs ) + { + mbedtls_mpi_free( X ); + mbedtls_mpi_init( X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) ); + } + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); + + Xp = (unsigned char*) X->p; + f_rng( p_rng, Xp + overhead, size ); - MBEDTLS_MPI_CHK( f_rng( p_rng, buf, size ) ); - MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) ); + mpi_bigendian_to_host( X->p, limbs ); cleanup: - mbedtls_platform_zeroize( buf, sizeof( buf ) ); return( ret ); } diff --git a/thirdparty/mbedtls/library/ccm.c b/thirdparty/mbedtls/library/ccm.c index 01e58b0436..c6211ee773 100644 --- a/thirdparty/mbedtls/library/ccm.c +++ b/thirdparty/mbedtls/library/ccm.c @@ -134,11 +134,17 @@ void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) * This avoids allocating one more 16 bytes buffer while allowing src == dst. */ #define CTR_CRYPT( dst, src, len ) \ - if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \ - return( ret ); \ - \ - for( i = 0; i < len; i++ ) \ - dst[i] = src[i] ^ b[i]; + do \ + { \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, \ + 16, b, &olen ) ) != 0 ) \ + { \ + return( ret ); \ + } \ + \ + for( i = 0; i < (len); i++ ) \ + (dst)[i] = (src)[i] ^ b[i]; \ + } while( 0 ) /* * Authenticated encryption or decryption diff --git a/thirdparty/mbedtls/library/certs.c b/thirdparty/mbedtls/library/certs.c index ff0f11e923..b07fd8a3a1 100644 --- a/thirdparty/mbedtls/library/certs.c +++ b/thirdparty/mbedtls/library/certs.c @@ -29,328 +29,1673 @@ #if defined(MBEDTLS_CERTS_C) -#if defined(MBEDTLS_ECDSA_C) -#define TEST_CA_CRT_EC \ -"-----BEGIN CERTIFICATE-----\r\n" \ -"MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT\r\n" \ -"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ -"QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT\r\n" \ -"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ -"QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu\r\n" \ -"ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy\r\n" \ -"aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g\r\n" \ -"JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7\r\n" \ -"NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE\r\n" \ -"AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w\r\n" \ -"CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56\r\n" \ -"t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv\r\n" \ -"uCjn8pwUOkABXK8Mss90fzCfCEOtIA==\r\n" \ -"-----END CERTIFICATE-----\r\n" -const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC; -const size_t mbedtls_test_ca_crt_ec_len = sizeof( mbedtls_test_ca_crt_ec ); - -const char mbedtls_test_ca_key_ec[] = -"-----BEGIN EC PRIVATE KEY-----\r\n" -"Proc-Type: 4,ENCRYPTED\r\n" -"DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n" -"\r\n" -"IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n" -"ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n" -"UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n" -"a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n" -"-----END EC PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_ca_key_ec_len = sizeof( mbedtls_test_ca_key_ec ); - -const char mbedtls_test_ca_pwd_ec[] = "PolarSSLTest"; -const size_t mbedtls_test_ca_pwd_ec_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1; - -const char mbedtls_test_srv_crt_ec[] = -"-----BEGIN CERTIFICATE-----\r\n" -"MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" -"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" -"CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" -"2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" -"BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" -"PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" -"clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" -"CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" -"C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" -"fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" -"-----END CERTIFICATE-----\r\n"; -const size_t mbedtls_test_srv_crt_ec_len = sizeof( mbedtls_test_srv_crt_ec ); - -const char mbedtls_test_srv_key_ec[] = -"-----BEGIN EC PRIVATE KEY-----\r\n" -"MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" -"AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" -"6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" -"-----END EC PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_srv_key_ec_len = sizeof( mbedtls_test_srv_key_ec ); - -const char mbedtls_test_cli_crt_ec[] = -"-----BEGIN CERTIFICATE-----\r\n" -"MIICLDCCAbKgAwIBAgIBDTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" -"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjBBMQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UEChMIUG9sYXJTU0wxHzAdBgNVBAMTFlBvbGFyU1NMIFRlc3QgQ2xpZW50IDIw\r\n" -"WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARX5a6xc9/TrLuTuIH/Eq7u5lOszlVT\r\n" -"9jQOzC7jYyUL35ji81xgNpbA1RgUcOV/n9VLRRjlsGzVXPiWj4dwo+THo4GdMIGa\r\n" -"MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMG4GA1Ud\r\n" -"IwRnMGWAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8oUKkQDA+MQswCQYDVQQGEwJOTDER\r\n" -"MA8GA1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0GC\r\n" -"CQDBQ+J+YkPM6DAKBggqhkjOPQQDAgNoADBlAjBKZQ17IIOimbmoD/yN7o89u3BM\r\n" -"lgOsjnhw3fIOoLIWy2WOGsk/LGF++DzvrRzuNiACMQCd8iem1XS4JK7haj8xocpU\r\n" -"LwjQje5PDGHfd3h9tP38Qknu5bJqws0md2KOKHyeV0U=\r\n" -"-----END CERTIFICATE-----\r\n"; -const size_t mbedtls_test_cli_crt_ec_len = sizeof( mbedtls_test_cli_crt_ec ); - -const char mbedtls_test_cli_key_ec[] = -"-----BEGIN EC PRIVATE KEY-----\r\n" -"MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n" -"AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n" -"wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n" -"-----END EC PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_cli_key_ec_len = sizeof( mbedtls_test_cli_key_ec ); -#endif /* MBEDTLS_ECDSA_C */ +/* + * Test CA Certificates + * + * We define test CA certificates for each choice of the following parameters: + * - PEM or DER encoding + * - SHA-1 or SHA-256 hash + * - RSA or EC key + * + * Things to add: + * - multiple EC curve types + * + */ -#if defined(MBEDTLS_RSA_C) +/* This is taken from tests/data_files/test-ca2.crt */ +/* BEGIN FILE string macro TEST_CA_CRT_EC_PEM tests/data_files/test-ca2.crt */ +#define TEST_CA_CRT_EC_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT\r\n" \ + "Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ + "QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT\r\n" \ + "Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ + "QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu\r\n" \ + "ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy\r\n" \ + "aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g\r\n" \ + "JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7\r\n" \ + "NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE\r\n" \ + "AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w\r\n" \ + "CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56\r\n" \ + "t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv\r\n" \ + "uCjn8pwUOkABXK8Mss90fzCfCEOtIA==\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +/* This is generated from tests/data_files/test-ca2.crt.der using `xxd -i`. */ +/* BEGIN FILE binary macro TEST_CA_CRT_EC_DER tests/data_files/test-ca2.crt.der */ +#define TEST_CA_CRT_EC_DER { \ + 0x30, 0x82, 0x02, 0x52, 0x30, 0x82, 0x01, 0xd7, 0xa0, 0x03, 0x02, 0x01, \ + 0x02, 0x02, 0x09, 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, \ + 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, \ + 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, \ + 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, \ + 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, \ + 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c, \ + 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, \ + 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x33, 0x30, 0x39, \ + 0x32, 0x34, 0x31, 0x35, 0x34, 0x39, 0x34, 0x38, 0x5a, 0x17, 0x0d, 0x32, \ + 0x33, 0x30, 0x39, 0x32, 0x32, 0x31, 0x35, 0x34, 0x39, 0x34, 0x38, 0x5a, \ + 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, \ + 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, \ + 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, \ + 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c, \ + 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, \ + 0x43, 0x20, 0x43, 0x41, 0x30, 0x76, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, \ + 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, \ + 0x03, 0x62, 0x00, 0x04, 0xc3, 0xda, 0x2b, 0x34, 0x41, 0x37, 0x58, 0x2f, \ + 0x87, 0x56, 0xfe, 0xfc, 0x89, 0xba, 0x29, 0x43, 0x4b, 0x4e, 0xe0, 0x6e, \ + 0xc3, 0x0e, 0x57, 0x53, 0x33, 0x39, 0x58, 0xd4, 0x52, 0xb4, 0x91, 0x95, \ + 0x39, 0x0b, 0x23, 0xdf, 0x5f, 0x17, 0x24, 0x62, 0x48, 0xfc, 0x1a, 0x95, \ + 0x29, 0xce, 0x2c, 0x2d, 0x87, 0xc2, 0x88, 0x52, 0x80, 0xaf, 0xd6, 0x6a, \ + 0xab, 0x21, 0xdd, 0xb8, 0xd3, 0x1c, 0x6e, 0x58, 0xb8, 0xca, 0xe8, 0xb2, \ + 0x69, 0x8e, 0xf3, 0x41, 0xad, 0x29, 0xc3, 0xb4, 0x5f, 0x75, 0xa7, 0x47, \ + 0x6f, 0xd5, 0x19, 0x29, 0x55, 0x69, 0x9a, 0x53, 0x3b, 0x20, 0xb4, 0x66, \ + 0x16, 0x60, 0x33, 0x1e, 0xa3, 0x81, 0xa0, 0x30, 0x81, 0x9d, 0x30, 0x1d, \ + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x9d, 0x6d, 0x20, \ + 0x24, 0x49, 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, \ + 0xc9, 0xdb, 0xfb, 0x36, 0x7c, 0x30, 0x6e, 0x06, 0x03, 0x55, 0x1d, 0x23, \ + 0x04, 0x67, 0x30, 0x65, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, 0x01, \ + 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, 0xfb, \ + 0x36, 0x7c, 0xa1, 0x42, 0xa4, 0x40, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \ + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ + 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \ + 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, \ + 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x82, 0x09, \ + 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, 0x30, 0x0c, 0x06, \ + 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, \ + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, \ + 0x69, 0x00, 0x30, 0x66, 0x02, 0x31, 0x00, 0xc3, 0xb4, 0x62, 0x73, 0x56, \ + 0x28, 0x95, 0x00, 0x7d, 0x78, 0x12, 0x26, 0xd2, 0x71, 0x7b, 0x19, 0xf8, \ + 0x8a, 0x98, 0x3e, 0x92, 0xfe, 0x33, 0x9e, 0xe4, 0x79, 0xd2, 0xfe, 0x7a, \ + 0xb7, 0x87, 0x74, 0x3c, 0x2b, 0xb8, 0xd7, 0x69, 0x94, 0x0b, 0xa3, 0x67, \ + 0x77, 0xb8, 0xb3, 0xbe, 0xd1, 0x36, 0x32, 0x02, 0x31, 0x00, 0xfd, 0x67, \ + 0x9c, 0x94, 0x23, 0x67, 0xc0, 0x56, 0xba, 0x4b, 0x33, 0x15, 0x00, 0xc6, \ + 0xe3, 0xcc, 0x31, 0x08, 0x2c, 0x9c, 0x8b, 0xda, 0xa9, 0x75, 0x23, 0x2f, \ + 0xb8, 0x28, 0xe7, 0xf2, 0x9c, 0x14, 0x3a, 0x40, 0x01, 0x5c, 0xaf, 0x0c, \ + 0xb2, 0xcf, 0x74, 0x7f, 0x30, 0x9f, 0x08, 0x43, 0xad, 0x20 \ +} +/* END FILE */ + +/* This is taken from tests/data_files/test-ca2.key.enc */ +/* BEGIN FILE string macro TEST_CA_KEY_EC_PEM tests/data_files/test-ca2.key.enc */ +#define TEST_CA_KEY_EC_PEM \ + "-----BEGIN EC PRIVATE KEY-----\r\n" \ + "Proc-Type: 4,ENCRYPTED\r\n" \ + "DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n" \ + "\r\n" \ + "IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n" \ + "ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n" \ + "UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n" \ + "a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n" \ + "-----END EC PRIVATE KEY-----\r\n" +/* END FILE */ + +#define TEST_CA_PWD_EC_PEM "PolarSSLTest" + +/* This is generated from tests/data_files/test-ca2.key.der using `xxd -i`. */ +/* BEGIN FILE binary macro TEST_CA_KEY_EC_DER tests/data_files/test-ca2.key.der */ +#define TEST_CA_KEY_EC_DER { \ + 0x30, 0x81, 0xa4, 0x02, 0x01, 0x01, 0x04, 0x30, 0x83, 0xd9, 0x15, 0x0e, \ + 0xa0, 0x71, 0xf0, 0x57, 0x10, 0x33, 0xa3, 0x38, 0xb8, 0x86, 0xc1, 0xa6, \ + 0x11, 0x5d, 0x6d, 0xb4, 0x03, 0xe1, 0x29, 0x76, 0x45, 0xd7, 0x87, 0x6f, \ + 0x23, 0xab, 0x44, 0x20, 0xea, 0x64, 0x7b, 0x85, 0xb1, 0x76, 0xe7, 0x85, \ + 0x95, 0xaa, 0x74, 0xd6, 0xd1, 0xa4, 0x5e, 0xea, 0xa0, 0x07, 0x06, 0x05, \ + 0x2b, 0x81, 0x04, 0x00, 0x22, 0xa1, 0x64, 0x03, 0x62, 0x00, 0x04, 0xc3, \ + 0xda, 0x2b, 0x34, 0x41, 0x37, 0x58, 0x2f, 0x87, 0x56, 0xfe, 0xfc, 0x89, \ + 0xba, 0x29, 0x43, 0x4b, 0x4e, 0xe0, 0x6e, 0xc3, 0x0e, 0x57, 0x53, 0x33, \ + 0x39, 0x58, 0xd4, 0x52, 0xb4, 0x91, 0x95, 0x39, 0x0b, 0x23, 0xdf, 0x5f, \ + 0x17, 0x24, 0x62, 0x48, 0xfc, 0x1a, 0x95, 0x29, 0xce, 0x2c, 0x2d, 0x87, \ + 0xc2, 0x88, 0x52, 0x80, 0xaf, 0xd6, 0x6a, 0xab, 0x21, 0xdd, 0xb8, 0xd3, \ + 0x1c, 0x6e, 0x58, 0xb8, 0xca, 0xe8, 0xb2, 0x69, 0x8e, 0xf3, 0x41, 0xad, \ + 0x29, 0xc3, 0xb4, 0x5f, 0x75, 0xa7, 0x47, 0x6f, 0xd5, 0x19, 0x29, 0x55, \ + 0x69, 0x9a, 0x53, 0x3b, 0x20, 0xb4, 0x66, 0x16, 0x60, 0x33, 0x1e \ +} +/* END FILE */ + +/* This is taken from tests/data_files/test-ca-sha256.crt. */ +/* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA256_PEM tests/data_files/test-ca-sha256.crt */ +#define TEST_CA_CRT_RSA_SHA256_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ + "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ + "MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ + "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ + "mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ + "50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ + "YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ + "R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ + "KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ + "UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \ + "MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBCwUA\r\n" \ + "A4IBAQB2W2dIy4q4KysbrTL4HIaOqu62RceGuQ/KhyiI6O0ndCtQ/PgCBqHHTP8u\r\n" \ + "8F1X2ivb60ynHV6baMLPI4Kf1k4MONtLSf/++1qh0Gdycd3A8IDAfy0YnC1F3OPK\r\n" \ + "vWO/cZGitKoTbEpP4y4Rng3sFCDndRCWIRIDOEEW/H3lCcfL7sOQojdLl85ajFkh\r\n" \ + "YvcDqjmnTcspUnuq9Y00C7porXJthZwz1S18qVjcFNk0zEhVMUbupSrdXVmKtOJW\r\n" \ + "MWZjgcA+OXzcnb2hSKWbhjykH/u6/PqkuHPkD723rwXbmHdxRVS9CW57kDkn5ezJ\r\n" \ + "5pE6Sam4qFsCNFJNBV9FRf3ZBMFi\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +/* This is generated from tests/data_files/test-ca-sha256.crt.der + * using `xxd -i`. */ +/* BEGIN FILE binary macro TEST_CA_CRT_RSA_SHA256_DER tests/data_files/test-ca-sha256.crt.der */ +#define TEST_CA_CRT_RSA_SHA256_DER { \ + 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \ + 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ + 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ + 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ + 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ + 0x31, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \ + 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, \ + 0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ + 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ + 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \ + 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \ + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \ + 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \ + 0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \ + 0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \ + 0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \ + 0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \ + 0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \ + 0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \ + 0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \ + 0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \ + 0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \ + 0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \ + 0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \ + 0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \ + 0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \ + 0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \ + 0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \ + 0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \ + 0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \ + 0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \ + 0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \ + 0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \ + 0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \ + 0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \ + 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \ + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \ + 0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \ + 0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \ + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \ + 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \ + 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \ + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, \ + 0x03, 0x82, 0x01, 0x01, 0x00, 0x76, 0x5b, 0x67, 0x48, 0xcb, 0x8a, 0xb8, \ + 0x2b, 0x2b, 0x1b, 0xad, 0x32, 0xf8, 0x1c, 0x86, 0x8e, 0xaa, 0xee, 0xb6, \ + 0x45, 0xc7, 0x86, 0xb9, 0x0f, 0xca, 0x87, 0x28, 0x88, 0xe8, 0xed, 0x27, \ + 0x74, 0x2b, 0x50, 0xfc, 0xf8, 0x02, 0x06, 0xa1, 0xc7, 0x4c, 0xff, 0x2e, \ + 0xf0, 0x5d, 0x57, 0xda, 0x2b, 0xdb, 0xeb, 0x4c, 0xa7, 0x1d, 0x5e, 0x9b, \ + 0x68, 0xc2, 0xcf, 0x23, 0x82, 0x9f, 0xd6, 0x4e, 0x0c, 0x38, 0xdb, 0x4b, \ + 0x49, 0xff, 0xfe, 0xfb, 0x5a, 0xa1, 0xd0, 0x67, 0x72, 0x71, 0xdd, 0xc0, \ + 0xf0, 0x80, 0xc0, 0x7f, 0x2d, 0x18, 0x9c, 0x2d, 0x45, 0xdc, 0xe3, 0xca, \ + 0xbd, 0x63, 0xbf, 0x71, 0x91, 0xa2, 0xb4, 0xaa, 0x13, 0x6c, 0x4a, 0x4f, \ + 0xe3, 0x2e, 0x11, 0x9e, 0x0d, 0xec, 0x14, 0x20, 0xe7, 0x75, 0x10, 0x96, \ + 0x21, 0x12, 0x03, 0x38, 0x41, 0x16, 0xfc, 0x7d, 0xe5, 0x09, 0xc7, 0xcb, \ + 0xee, 0xc3, 0x90, 0xa2, 0x37, 0x4b, 0x97, 0xce, 0x5a, 0x8c, 0x59, 0x21, \ + 0x62, 0xf7, 0x03, 0xaa, 0x39, 0xa7, 0x4d, 0xcb, 0x29, 0x52, 0x7b, 0xaa, \ + 0xf5, 0x8d, 0x34, 0x0b, 0xba, 0x68, 0xad, 0x72, 0x6d, 0x85, 0x9c, 0x33, \ + 0xd5, 0x2d, 0x7c, 0xa9, 0x58, 0xdc, 0x14, 0xd9, 0x34, 0xcc, 0x48, 0x55, \ + 0x31, 0x46, 0xee, 0xa5, 0x2a, 0xdd, 0x5d, 0x59, 0x8a, 0xb4, 0xe2, 0x56, \ + 0x31, 0x66, 0x63, 0x81, 0xc0, 0x3e, 0x39, 0x7c, 0xdc, 0x9d, 0xbd, 0xa1, \ + 0x48, 0xa5, 0x9b, 0x86, 0x3c, 0xa4, 0x1f, 0xfb, 0xba, 0xfc, 0xfa, 0xa4, \ + 0xb8, 0x73, 0xe4, 0x0f, 0xbd, 0xb7, 0xaf, 0x05, 0xdb, 0x98, 0x77, 0x71, \ + 0x45, 0x54, 0xbd, 0x09, 0x6e, 0x7b, 0x90, 0x39, 0x27, 0xe5, 0xec, 0xc9, \ + 0xe6, 0x91, 0x3a, 0x49, 0xa9, 0xb8, 0xa8, 0x5b, 0x02, 0x34, 0x52, 0x4d, \ + 0x05, 0x5f, 0x45, 0x45, 0xfd, 0xd9, 0x04, 0xc1, 0x62 \ +} +/* END FILE */ + +/* This is taken from tests/data_files/test-ca-sha1.crt. */ +/* BEGIN FILE string macro TEST_CA_CRT_RSA_SHA1_PEM tests/data_files/test-ca-sha1.crt */ +#define TEST_CA_CRT_RSA_SHA1_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIDQTCCAimgAwIBAgIBAzANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ + "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ + "MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ + "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ + "mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ + "50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ + "YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ + "R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ + "KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ + "UDBOMAwGA1UdEwQFMAMBAf8wHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/\r\n" \ + "MB8GA1UdIwQYMBaAFLRa5KWz3tJS9rnVppUP6z68x/3/MA0GCSqGSIb3DQEBBQUA\r\n" \ + "A4IBAQABE3OEPfEd/bcJW5ZdU3/VgPNS4tMzh8gnJP/V2FcvFtGylMpQq6YnEBYI\r\n" \ + "yBHAL4DRvlMY5rnXGBp3ODR8MpqHC6AquRTCLzjS57iYff//4QFQqW9n92zctspv\r\n" \ + "czkaPKgjqo1No3Uq0Xaz10rcxyTUPrf5wNVRZ2V0KvllvAAVSzbI4mpdUXztjhST\r\n" \ + "S5A2BeWQAAOr0zq1F7TSRVJpJs7jmB2ai/igkh1IAjcuwV6VwlP+sbw0gjQ0NpGM\r\n" \ + "iHpnlzRAi/tIbtOvMIGOBU2TIfax/5jq1agUx5aPmT5TWAiJPOOP6l5xXnDwxeYS\r\n" \ + "NWqiX9GyusBZjezaCaHabjDLU0qQ\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +/* This is taken from tests/data_files/test-ca-sha1.crt.der. */ +/* BEGIN FILE binary macro TEST_CA_CRT_RSA_SHA1_DER tests/data_files/test-ca-sha1.crt.der */ +#define TEST_CA_CRT_RSA_SHA1_DER { \ + 0x30, 0x82, 0x03, 0x41, 0x30, 0x82, 0x02, 0x29, 0xa0, 0x03, 0x02, 0x01, \ + 0x02, 0x02, 0x01, 0x03, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ + 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ + 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ + 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ + 0x31, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, 0x34, 0x30, 0x30, \ + 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, \ + 0x34, 0x30, 0x30, 0x5a, 0x30, 0x3b, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ + 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ + 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \ + 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, \ + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, \ + 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, \ + 0x01, 0x00, 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, \ + 0x86, 0xde, 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, \ + 0x99, 0xd4, 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, \ + 0x9b, 0xc5, 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, \ + 0xc0, 0x8d, 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, \ + 0x93, 0xe8, 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, \ + 0xe7, 0x40, 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, \ + 0xf9, 0x3e, 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, \ + 0x29, 0x00, 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, \ + 0xbd, 0x83, 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, \ + 0x60, 0xc3, 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, \ + 0x32, 0xbe, 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, \ + 0xfb, 0xf5, 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, \ + 0xee, 0xe2, 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, \ + 0x47, 0xb1, 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, \ + 0xf1, 0x79, 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, \ + 0x6f, 0x27, 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, \ + 0xa1, 0x30, 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, \ + 0x28, 0xd1, 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, \ + 0x09, 0xea, 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, \ + 0xc9, 0xab, 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, \ + 0x9e, 0x99, 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, \ + 0x50, 0x30, 0x4e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, \ + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, \ + 0x04, 0x16, 0x04, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, \ + 0xf6, 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, \ + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, \ + 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, \ + 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, \ + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, \ + 0x03, 0x82, 0x01, 0x01, 0x00, 0x01, 0x13, 0x73, 0x84, 0x3d, 0xf1, 0x1d, \ + 0xfd, 0xb7, 0x09, 0x5b, 0x96, 0x5d, 0x53, 0x7f, 0xd5, 0x80, 0xf3, 0x52, \ + 0xe2, 0xd3, 0x33, 0x87, 0xc8, 0x27, 0x24, 0xff, 0xd5, 0xd8, 0x57, 0x2f, \ + 0x16, 0xd1, 0xb2, 0x94, 0xca, 0x50, 0xab, 0xa6, 0x27, 0x10, 0x16, 0x08, \ + 0xc8, 0x11, 0xc0, 0x2f, 0x80, 0xd1, 0xbe, 0x53, 0x18, 0xe6, 0xb9, 0xd7, \ + 0x18, 0x1a, 0x77, 0x38, 0x34, 0x7c, 0x32, 0x9a, 0x87, 0x0b, 0xa0, 0x2a, \ + 0xb9, 0x14, 0xc2, 0x2f, 0x38, 0xd2, 0xe7, 0xb8, 0x98, 0x7d, 0xff, 0xff, \ + 0xe1, 0x01, 0x50, 0xa9, 0x6f, 0x67, 0xf7, 0x6c, 0xdc, 0xb6, 0xca, 0x6f, \ + 0x73, 0x39, 0x1a, 0x3c, 0xa8, 0x23, 0xaa, 0x8d, 0x4d, 0xa3, 0x75, 0x2a, \ + 0xd1, 0x76, 0xb3, 0xd7, 0x4a, 0xdc, 0xc7, 0x24, 0xd4, 0x3e, 0xb7, 0xf9, \ + 0xc0, 0xd5, 0x51, 0x67, 0x65, 0x74, 0x2a, 0xf9, 0x65, 0xbc, 0x00, 0x15, \ + 0x4b, 0x36, 0xc8, 0xe2, 0x6a, 0x5d, 0x51, 0x7c, 0xed, 0x8e, 0x14, 0x93, \ + 0x4b, 0x90, 0x36, 0x05, 0xe5, 0x90, 0x00, 0x03, 0xab, 0xd3, 0x3a, 0xb5, \ + 0x17, 0xb4, 0xd2, 0x45, 0x52, 0x69, 0x26, 0xce, 0xe3, 0x98, 0x1d, 0x9a, \ + 0x8b, 0xf8, 0xa0, 0x92, 0x1d, 0x48, 0x02, 0x37, 0x2e, 0xc1, 0x5e, 0x95, \ + 0xc2, 0x53, 0xfe, 0xb1, 0xbc, 0x34, 0x82, 0x34, 0x34, 0x36, 0x91, 0x8c, \ + 0x88, 0x7a, 0x67, 0x97, 0x34, 0x40, 0x8b, 0xfb, 0x48, 0x6e, 0xd3, 0xaf, \ + 0x30, 0x81, 0x8e, 0x05, 0x4d, 0x93, 0x21, 0xf6, 0xb1, 0xff, 0x98, 0xea, \ + 0xd5, 0xa8, 0x14, 0xc7, 0x96, 0x8f, 0x99, 0x3e, 0x53, 0x58, 0x08, 0x89, \ + 0x3c, 0xe3, 0x8f, 0xea, 0x5e, 0x71, 0x5e, 0x70, 0xf0, 0xc5, 0xe6, 0x12, \ + 0x35, 0x6a, 0xa2, 0x5f, 0xd1, 0xb2, 0xba, 0xc0, 0x59, 0x8d, 0xec, 0xda, \ + 0x09, 0xa1, 0xda, 0x6e, 0x30, 0xcb, 0x53, 0x4a, 0x90 \ +} +/* END FILE */ + +/* This is taken from tests/data_files/test-ca.key */ +/* BEGIN FILE string macro TEST_CA_KEY_RSA_PEM tests/data_files/test-ca.key */ +#define TEST_CA_KEY_RSA_PEM \ + "-----BEGIN RSA PRIVATE KEY-----\r\n" \ + "Proc-Type: 4,ENCRYPTED\r\n" \ + "DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n" \ + "\r\n" \ + "9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n" \ + "7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n" \ + "Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n" \ + "PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n" \ + "GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n" \ + "gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n" \ + "QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n" \ + "PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n" \ + "vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n" \ + "WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n" \ + "JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n" \ + "KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n" \ + "Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n" \ + "9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n" \ + "iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n" \ + "tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n" \ + "P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n" \ + "1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n" \ + "nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n" \ + "X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n" \ + "rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n" \ + "L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n" \ + "I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n" \ + "wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n" \ + "P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n" \ + "-----END RSA PRIVATE KEY-----\r\n" +/* END FILE */ + +#define TEST_CA_PWD_RSA_PEM "PolarSSLTest" + +/* This was generated from test-ca.key.der using `xxd -i`. */ +/* BEGIN FILE binary macro TEST_CA_KEY_RSA_DER tests/data_files/test-ca.key.der */ +#define TEST_CA_KEY_RSA_DER { \ + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ + 0xc0, 0xdf, 0x37, 0xfc, 0x17, 0xbb, 0xe0, 0x96, 0x9d, 0x3f, 0x86, 0xde, \ + 0x96, 0x32, 0x7d, 0x44, 0xa5, 0x16, 0xa0, 0xcd, 0x21, 0xf1, 0x99, 0xd4, \ + 0xec, 0xea, 0xcb, 0x7c, 0x18, 0x58, 0x08, 0x94, 0xa5, 0xec, 0x9b, 0xc5, \ + 0x8b, 0xdf, 0x1a, 0x1e, 0x99, 0x38, 0x99, 0x87, 0x1e, 0x7b, 0xc0, 0x8d, \ + 0x39, 0xdf, 0x38, 0x5d, 0x70, 0x78, 0x07, 0xd3, 0x9e, 0xd9, 0x93, 0xe8, \ + 0xb9, 0x72, 0x51, 0xc5, 0xce, 0xa3, 0x30, 0x52, 0xa9, 0xf2, 0xe7, 0x40, \ + 0x70, 0x14, 0xcb, 0x44, 0xa2, 0x72, 0x0b, 0xc2, 0xe5, 0x40, 0xf9, 0x3e, \ + 0xe5, 0xa6, 0x0e, 0xb3, 0xf9, 0xec, 0x4a, 0x63, 0xc0, 0xb8, 0x29, 0x00, \ + 0x74, 0x9c, 0x57, 0x3b, 0xa8, 0xa5, 0x04, 0x90, 0x71, 0xf1, 0xbd, 0x83, \ + 0xd9, 0x3f, 0xd6, 0xa5, 0xe2, 0x3c, 0x2a, 0x8f, 0xef, 0x27, 0x60, 0xc3, \ + 0xc6, 0x9f, 0xcb, 0xba, 0xec, 0x60, 0x7d, 0xb7, 0xe6, 0x84, 0x32, 0xbe, \ + 0x4f, 0xfb, 0x58, 0x26, 0x22, 0x03, 0x5b, 0xd4, 0xb4, 0xd5, 0xfb, 0xf5, \ + 0xe3, 0x96, 0x2e, 0x70, 0xc0, 0xe4, 0x2e, 0xbd, 0xfc, 0x2e, 0xee, 0xe2, \ + 0x41, 0x55, 0xc0, 0x34, 0x2e, 0x7d, 0x24, 0x72, 0x69, 0xcb, 0x47, 0xb1, \ + 0x14, 0x40, 0x83, 0x7d, 0x67, 0xf4, 0x86, 0xf6, 0x31, 0xab, 0xf1, 0x79, \ + 0xa4, 0xb2, 0xb5, 0x2e, 0x12, 0xf9, 0x84, 0x17, 0xf0, 0x62, 0x6f, 0x27, \ + 0x3e, 0x13, 0x58, 0xb1, 0x54, 0x0d, 0x21, 0x9a, 0x73, 0x37, 0xa1, 0x30, \ + 0xcf, 0x6f, 0x92, 0xdc, 0xf6, 0xe9, 0xfc, 0xac, 0xdb, 0x2e, 0x28, 0xd1, \ + 0x7e, 0x02, 0x4b, 0x23, 0xa0, 0x15, 0xf2, 0x38, 0x65, 0x64, 0x09, 0xea, \ + 0x0c, 0x6e, 0x8e, 0x1b, 0x17, 0xa0, 0x71, 0xc8, 0xb3, 0x9b, 0xc9, 0xab, \ + 0xe9, 0xc3, 0xf2, 0xcf, 0x87, 0x96, 0x8f, 0x80, 0x02, 0x32, 0x9e, 0x99, \ + 0x58, 0x6f, 0xa2, 0xd5, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ + 0x00, 0x3f, 0xf7, 0x07, 0xd3, 0x34, 0x6f, 0xdb, 0xc9, 0x37, 0xb7, 0x84, \ + 0xdc, 0x37, 0x45, 0xe1, 0x63, 0xad, 0xb8, 0xb6, 0x75, 0xb1, 0xc7, 0x35, \ + 0xb4, 0x77, 0x2a, 0x5b, 0x77, 0xf9, 0x7e, 0xe0, 0xc1, 0xa3, 0xd1, 0xb7, \ + 0xcb, 0xa9, 0x5a, 0xc1, 0x87, 0xda, 0x5a, 0xfa, 0x17, 0xe4, 0xd5, 0x38, \ + 0x03, 0xde, 0x68, 0x98, 0x81, 0xec, 0xb5, 0xf2, 0x2a, 0x8d, 0xe9, 0x2c, \ + 0xf3, 0xa6, 0xe5, 0x32, 0x17, 0x7f, 0x33, 0x81, 0xe8, 0x38, 0x72, 0xd5, \ + 0x9c, 0xfa, 0x4e, 0xfb, 0x26, 0xf5, 0x15, 0x0b, 0xaf, 0x84, 0x66, 0xab, \ + 0x02, 0xe0, 0x18, 0xd5, 0x91, 0x7c, 0xd6, 0x8f, 0xc9, 0x4b, 0x76, 0x08, \ + 0x2b, 0x1d, 0x81, 0x68, 0x30, 0xe1, 0xfa, 0x70, 0x6c, 0x13, 0x4e, 0x10, \ + 0x03, 0x35, 0x3e, 0xc5, 0xca, 0x58, 0x20, 0x8a, 0x21, 0x18, 0x38, 0xa0, \ + 0x0f, 0xed, 0xc4, 0xbb, 0x45, 0x6f, 0xf5, 0x84, 0x5b, 0xb0, 0xcf, 0x4e, \ + 0x9d, 0x58, 0x13, 0x6b, 0x35, 0x35, 0x69, 0xa1, 0xd2, 0xc4, 0xf2, 0xc1, \ + 0x48, 0x04, 0x20, 0x51, 0xb9, 0x6b, 0xa4, 0x5d, 0xa5, 0x4b, 0x84, 0x88, \ + 0x43, 0x48, 0x99, 0x2c, 0xbb, 0xa4, 0x97, 0xd6, 0xd6, 0x18, 0xf6, 0xec, \ + 0x5c, 0xd1, 0x31, 0x49, 0xc9, 0xf2, 0x8f, 0x0b, 0x4d, 0xef, 0x09, 0x02, \ + 0xfe, 0x7d, 0xfd, 0xbb, 0xaf, 0x2b, 0x83, 0x94, 0x22, 0xc4, 0xa7, 0x3e, \ + 0x66, 0xf5, 0xe0, 0x57, 0xdc, 0xf2, 0xed, 0x2c, 0x3e, 0x81, 0x74, 0x76, \ + 0x1e, 0x96, 0x6f, 0x74, 0x1e, 0x32, 0x0e, 0x14, 0x31, 0xd0, 0x74, 0xf0, \ + 0xf4, 0x07, 0xbd, 0xc3, 0xd1, 0x22, 0xc2, 0xa8, 0x95, 0x92, 0x06, 0x7f, \ + 0x43, 0x02, 0x91, 0xbc, 0xdd, 0x23, 0x01, 0x89, 0x94, 0x20, 0x44, 0x64, \ + 0xf5, 0x1d, 0x67, 0xd2, 0x8f, 0xe8, 0x69, 0xa5, 0x29, 0x25, 0xe6, 0x50, \ + 0x9c, 0xe3, 0xe9, 0xcb, 0x75, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x29, 0x3e, \ + 0xaa, 0x6b, 0xd5, 0x59, 0x1e, 0x9c, 0xe6, 0x47, 0xd5, 0xb6, 0xd7, 0xe3, \ + 0xf1, 0x8e, 0x9e, 0xe9, 0x83, 0x5f, 0x10, 0x9f, 0x63, 0xec, 0x04, 0x44, \ + 0xcc, 0x3f, 0xf8, 0xd9, 0x3a, 0x17, 0xe0, 0x4f, 0xfe, 0xd8, 0x4d, 0xcd, \ + 0x46, 0x54, 0x74, 0xbf, 0x0a, 0xc4, 0x67, 0x9c, 0xa7, 0xd8, 0x89, 0x65, \ + 0x4c, 0xfd, 0x58, 0x2a, 0x47, 0x0f, 0xf4, 0x37, 0xb6, 0x55, 0xb0, 0x1d, \ + 0xed, 0xa7, 0x39, 0xfc, 0x4f, 0xa3, 0xc4, 0x75, 0x3a, 0xa3, 0x98, 0xa7, \ + 0x45, 0xf5, 0x66, 0xcb, 0x7c, 0x65, 0xfb, 0x80, 0x23, 0xe6, 0xff, 0xfd, \ + 0x99, 0x1f, 0x8e, 0x6b, 0xff, 0x5e, 0x93, 0x66, 0xdf, 0x6c, 0x6f, 0xc3, \ + 0xf6, 0x38, 0x2e, 0xff, 0x69, 0xb5, 0xac, 0xae, 0xbb, 0xc6, 0x71, 0x16, \ + 0x6b, 0xd0, 0xf8, 0x22, 0xd9, 0xf8, 0xa2, 0x72, 0x20, 0xd2, 0xe2, 0x3a, \ + 0x70, 0x4b, 0xde, 0xab, 0x2f, 0x02, 0x81, 0x81, 0x00, 0xda, 0x51, 0x9b, \ + 0xb8, 0xb2, 0x2a, 0x14, 0x75, 0x58, 0x40, 0x8d, 0x27, 0x70, 0xfa, 0x31, \ + 0x48, 0xb0, 0x20, 0x21, 0x34, 0xfa, 0x4c, 0x57, 0xa8, 0x11, 0x88, 0xf3, \ + 0xa7, 0xae, 0x21, 0xe9, 0xb6, 0x2b, 0xd1, 0xcd, 0xa7, 0xf8, 0xd8, 0x0c, \ + 0x8a, 0x76, 0x22, 0x35, 0x44, 0xce, 0x3f, 0x25, 0x29, 0x83, 0x7d, 0x79, \ + 0xa7, 0x31, 0xd6, 0xec, 0xb2, 0xbf, 0xda, 0x34, 0xb6, 0xf6, 0xb2, 0x3b, \ + 0xf3, 0x78, 0x5a, 0x04, 0x83, 0x33, 0x3e, 0xa2, 0xe2, 0x81, 0x82, 0x13, \ + 0xd4, 0x35, 0x17, 0x63, 0x9b, 0x9e, 0xc4, 0x8d, 0x91, 0x4c, 0x03, 0x77, \ + 0xc7, 0x71, 0x5b, 0xee, 0x83, 0x6d, 0xd5, 0x78, 0x88, 0xf6, 0x2c, 0x79, \ + 0xc2, 0x4a, 0xb4, 0x79, 0x90, 0x70, 0xbf, 0xdf, 0x34, 0x56, 0x96, 0x71, \ + 0xe3, 0x0e, 0x68, 0x91, 0xbc, 0xea, 0xcb, 0x33, 0xc0, 0xbe, 0x45, 0xd7, \ + 0xfc, 0x30, 0xfd, 0x01, 0x3b, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x9f, 0x2a, \ + 0xb7, 0x38, 0x19, 0xc7, 0x17, 0x95, 0x73, 0x78, 0xae, 0xf5, 0xcb, 0x75, \ + 0x83, 0x7f, 0x19, 0x4b, 0xcb, 0x86, 0xfb, 0x4a, 0x15, 0x9a, 0xb6, 0x17, \ + 0x04, 0x49, 0x07, 0x8d, 0xf6, 0x66, 0x4a, 0x06, 0xf6, 0x05, 0xa7, 0xdf, \ + 0x66, 0x82, 0x3c, 0xff, 0xb6, 0x1d, 0x57, 0x89, 0x33, 0x5f, 0x9c, 0x05, \ + 0x75, 0x7f, 0xf3, 0x5d, 0xdc, 0x34, 0x65, 0x72, 0x85, 0x22, 0xa4, 0x14, \ + 0x1b, 0x41, 0xc3, 0xe4, 0xd0, 0x9e, 0x69, 0xd5, 0xeb, 0x38, 0x74, 0x70, \ + 0x43, 0xdc, 0xd9, 0x50, 0xe4, 0x97, 0x6d, 0x73, 0xd6, 0xfb, 0xc8, 0xa7, \ + 0xfa, 0xb4, 0xc2, 0xc4, 0x9d, 0x5d, 0x0c, 0xd5, 0x9f, 0x79, 0xb3, 0x54, \ + 0xc2, 0xb7, 0x6c, 0x3d, 0x7d, 0xcb, 0x2d, 0xf8, 0xc4, 0xf3, 0x78, 0x5a, \ + 0x33, 0x2a, 0xb8, 0x0c, 0x6d, 0x06, 0xfa, 0xf2, 0x62, 0xd3, 0x42, 0xd0, \ + 0xbd, 0xc8, 0x4a, 0xa5, 0x0d, 0x02, 0x81, 0x81, 0x00, 0xd4, 0xa9, 0x90, \ + 0x15, 0xde, 0xbf, 0x2c, 0xc4, 0x8d, 0x9d, 0xfb, 0xa1, 0xc2, 0xe4, 0x83, \ + 0xe3, 0x79, 0x65, 0x22, 0xd3, 0xb7, 0x49, 0x6c, 0x4d, 0x94, 0x1f, 0x22, \ + 0xb1, 0x60, 0xe7, 0x3a, 0x00, 0xb1, 0x38, 0xa2, 0xab, 0x0f, 0xb4, 0x6c, \ + 0xaa, 0xe7, 0x9e, 0x34, 0xe3, 0x7c, 0x40, 0x78, 0x53, 0xb2, 0xf9, 0x23, \ + 0xea, 0xa0, 0x9a, 0xea, 0x60, 0xc8, 0x8f, 0xa6, 0xaf, 0xdf, 0x29, 0x09, \ + 0x4b, 0x06, 0x1e, 0x31, 0xad, 0x17, 0xda, 0xd8, 0xd1, 0xe9, 0x33, 0xab, \ + 0x5b, 0x18, 0x08, 0x5b, 0x87, 0xf8, 0xa5, 0x1f, 0xfd, 0xbb, 0xdc, 0xd8, \ + 0xed, 0x97, 0x57, 0xe4, 0xc3, 0x73, 0xd6, 0xf0, 0x9e, 0x01, 0xa6, 0x9b, \ + 0x48, 0x8e, 0x7a, 0xb4, 0xbb, 0xe5, 0x88, 0x91, 0xc5, 0x2a, 0xdf, 0x4b, \ + 0xba, 0xd0, 0x8b, 0x3e, 0x03, 0x97, 0x77, 0x2f, 0x47, 0x7e, 0x51, 0x0c, \ + 0xae, 0x65, 0x8d, 0xde, 0x87, 0x02, 0x81, 0x80, 0x20, 0x24, 0x0f, 0xd2, \ + 0xaf, 0xc2, 0x28, 0x3b, 0x97, 0x20, 0xb2, 0x92, 0x49, 0xeb, 0x09, 0x68, \ + 0x40, 0xb2, 0xbe, 0xd1, 0xc3, 0x83, 0x94, 0x34, 0x38, 0xd6, 0xc9, 0xec, \ + 0x34, 0x09, 0xf9, 0x41, 0x6d, 0x5c, 0x42, 0x94, 0xf7, 0x04, 0xfc, 0x32, \ + 0x39, 0x69, 0xbc, 0x1c, 0xfb, 0x3e, 0x61, 0x98, 0xc0, 0x80, 0xd8, 0x36, \ + 0x47, 0xc3, 0x6d, 0xc2, 0x2e, 0xe7, 0x81, 0x2a, 0x17, 0x34, 0x64, 0x30, \ + 0x4e, 0x96, 0xbb, 0x26, 0x16, 0xb9, 0x41, 0x36, 0xfe, 0x8a, 0xd6, 0x53, \ + 0x7c, 0xaa, 0xec, 0x39, 0x42, 0x50, 0xef, 0xe3, 0xb3, 0x01, 0x28, 0x32, \ + 0xca, 0x6d, 0xf5, 0x9a, 0x1e, 0x9f, 0x37, 0xbe, 0xfe, 0x38, 0x20, 0x22, \ + 0x91, 0x8c, 0xcd, 0x95, 0x02, 0xf2, 0x4d, 0x6f, 0x1a, 0xb4, 0x43, 0xf0, \ + 0x19, 0xdf, 0x65, 0xc0, 0x92, 0xe7, 0x9d, 0x2f, 0x09, 0xe7, 0xec, 0x69, \ + 0xa8, 0xc2, 0x8f, 0x0d \ +} +/* END FILE */ + +/* + * Test server Certificates + * + * Test server certificates are defined for each choice + * of the following parameters: + * - PEM or DER encoding + * - SHA-1 or SHA-256 hash + * - RSA or EC key + * + * Things to add: + * - multiple EC curve types + */ + +/* This is taken from tests/data_files/server5.crt. */ +/* BEGIN FILE string macro TEST_SRV_CRT_EC_PEM tests/data_files/server5.crt */ +#define TEST_SRV_CRT_EC_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" \ + "MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" \ + "CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" \ + "2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" \ + "BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" \ + "PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" \ + "clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" \ + "CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" \ + "C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" \ + "fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +/* This is generated from tests/data_files/server5.crt.der using `xxd -i`. */ +/* BEGIN FILE binary macro TEST_SRV_CRT_EC_DER tests/data_files/server5.crt.der */ +#define TEST_SRV_CRT_EC_DER { \ + 0x30, 0x82, 0x02, 0x1f, 0x30, 0x82, 0x01, 0xa5, 0xa0, 0x03, 0x02, 0x01, \ + 0x02, 0x02, 0x01, 0x09, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ + 0x3d, 0x04, 0x03, 0x02, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ + 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, \ + 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, \ + 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ + 0x31, 0x33, 0x30, 0x39, 0x32, 0x34, 0x31, 0x35, 0x35, 0x32, 0x30, 0x34, \ + 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x39, 0x32, 0x32, 0x31, 0x35, 0x35, \ + 0x32, 0x30, 0x34, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ + 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, \ + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x59, \ + 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, \ + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, \ + 0x04, 0x37, 0xcc, 0x56, 0xd9, 0x76, 0x09, 0x1e, 0x5a, 0x72, 0x3e, 0xc7, \ + 0x59, 0x2d, 0xff, 0x20, 0x6e, 0xee, 0x7c, 0xf9, 0x06, 0x91, 0x74, 0xd0, \ + 0xad, 0x14, 0xb5, 0xf7, 0x68, 0x22, 0x59, 0x62, 0x92, 0x4e, 0xe5, 0x00, \ + 0xd8, 0x23, 0x11, 0xff, 0xea, 0x2f, 0xd2, 0x34, 0x5d, 0x5d, 0x16, 0xbd, \ + 0x8a, 0x88, 0xc2, 0x6b, 0x77, 0x0d, 0x55, 0xcd, 0x8a, 0x2a, 0x0e, 0xfa, \ + 0x01, 0xc8, 0xb4, 0xed, 0xff, 0xa3, 0x81, 0x9d, 0x30, 0x81, 0x9a, 0x30, \ + 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, \ + 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x50, 0x61, 0xa5, \ + 0x8f, 0xd4, 0x07, 0xd9, 0xd7, 0x82, 0x01, 0x0c, 0xe5, 0x65, 0x7f, 0x8c, \ + 0x63, 0x46, 0xa7, 0x13, 0xbe, 0x30, 0x6e, 0x06, 0x03, 0x55, 0x1d, 0x23, \ + 0x04, 0x67, 0x30, 0x65, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, 0x01, \ + 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, 0xfb, \ + 0x36, 0x7c, 0xa1, 0x42, 0xa4, 0x40, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, \ + 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, \ + 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, \ + 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, \ + 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, \ + 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x82, 0x09, \ + 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, 0x30, 0x0a, 0x06, \ + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x68, 0x00, \ + 0x30, 0x65, 0x02, 0x31, 0x00, 0x9a, 0x2c, 0x5c, 0xd7, 0xa6, 0xdb, 0xa2, \ + 0xe5, 0x64, 0x0d, 0xf0, 0xb9, 0x4e, 0xdd, 0xd7, 0x61, 0xd6, 0x13, 0x31, \ + 0xc7, 0xab, 0x73, 0x80, 0xbb, 0xd3, 0xd3, 0x73, 0x13, 0x54, 0xad, 0x92, \ + 0x0b, 0x5d, 0xab, 0xd0, 0xbc, 0xf7, 0xae, 0x2f, 0xe6, 0xa1, 0x21, 0x29, \ + 0x35, 0x95, 0xaa, 0x3e, 0x39, 0x02, 0x30, 0x21, 0x36, 0x7f, 0x9d, 0xc6, \ + 0x5d, 0xc6, 0x0b, 0xab, 0x27, 0xf2, 0x25, 0x1d, 0x3b, 0xf1, 0xcf, 0xf1, \ + 0x35, 0x25, 0x14, 0xe7, 0xe5, 0xf1, 0x97, 0xb5, 0x59, 0xe3, 0x5e, 0x15, \ + 0x7c, 0x66, 0xb9, 0x90, 0x7b, 0xc7, 0x01, 0x10, 0x4f, 0x73, 0xc6, 0x00, \ + 0x21, 0x52, 0x2a, 0x0e, 0xf1, 0xc7, 0xd5 \ +} +/* END FILE */ + +/* This is taken from tests/data_files/server5.key. */ +/* BEGIN FILE string macro TEST_SRV_KEY_EC_PEM tests/data_files/server5.key */ +#define TEST_SRV_KEY_EC_PEM \ + "-----BEGIN EC PRIVATE KEY-----\r\n" \ + "MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" \ + "AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" \ + "6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" \ + "-----END EC PRIVATE KEY-----\r\n" +/* END FILE */ + +/* This is generated from tests/data_files/server5.key.der using `xxd -i`. */ +/* BEGIN FILE binary macro TEST_SRV_KEY_EC_DER tests/data_files/server5.key.der */ +#define TEST_SRV_KEY_EC_DER { \ + 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xf1, 0x2a, 0x13, 0x20, 0x76, \ + 0x02, 0x70, 0xa8, 0x3c, 0xbf, 0xfd, 0x53, 0xf6, 0x03, 0x1e, 0xf7, 0x6a, \ + 0x5d, 0x86, 0xc8, 0xa2, 0x04, 0xf2, 0xc3, 0x0c, 0xa9, 0xeb, 0xf5, 0x1f, \ + 0x0f, 0x0e, 0xa7, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ + 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x37, 0xcc, 0x56, \ + 0xd9, 0x76, 0x09, 0x1e, 0x5a, 0x72, 0x3e, 0xc7, 0x59, 0x2d, 0xff, 0x20, \ + 0x6e, 0xee, 0x7c, 0xf9, 0x06, 0x91, 0x74, 0xd0, 0xad, 0x14, 0xb5, 0xf7, \ + 0x68, 0x22, 0x59, 0x62, 0x92, 0x4e, 0xe5, 0x00, 0xd8, 0x23, 0x11, 0xff, \ + 0xea, 0x2f, 0xd2, 0x34, 0x5d, 0x5d, 0x16, 0xbd, 0x8a, 0x88, 0xc2, 0x6b, \ + 0x77, 0x0d, 0x55, 0xcd, 0x8a, 0x2a, 0x0e, 0xfa, 0x01, 0xc8, 0xb4, 0xed, \ + 0xff \ +} +/* END FILE */ + +/* This is taken from tests/data_files/server2-sha256.crt. */ +/* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA256_PEM tests/data_files/server2-sha256.crt */ +#define TEST_SRV_CRT_RSA_SHA256_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ + "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ + "MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \ + "AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \ + "owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \ + "NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \ + "tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \ + "hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \ + "HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \ + "VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \ + "FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQELBQADggEBAGGEshT5\r\n" \ + "kvnRmLVScVeUEdwIrvW7ezbGbUvJ8VxeJ79/HSjlLiGbMc4uUathwtzEdi9R/4C5\r\n" \ + "DXBNeEPTkbB+fhG1W06iHYj/Dp8+aaG7fuDxKVKHVZSqBnmQLn73ymyclZNHii5A\r\n" \ + "3nTS8WUaHAzxN/rajOtoM7aH1P9tULpHrl+7HOeLMpxUnwI12ZqZaLIzxbcdJVcr\r\n" \ + "ra2F00aXCGkYVLvyvbZIq7LC+yVysej5gCeQYD7VFOEks0jhFjrS06gP0/XnWv6v\r\n" \ + "eBoPez9d+CCjkrhseiWzXOiriIMICX48EloO/DrsMRAtvlwq7EDz4QhILz6ffndm\r\n" \ + "e4K1cVANRPN2o9Y=\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +/* This is taken from tests/data_files/server2-sha256.crt.der. */ +/* BEGIN FILE binary macro TEST_SRV_CRT_RSA_SHA256_DER tests/data_files/server2-sha256.crt.der */ +#define TEST_SRV_CRT_RSA_SHA256_DER { \ + 0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \ + 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ + 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ + 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ + 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ + 0x31, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ + 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, \ + 0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ + 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \ + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \ + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \ + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \ + 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \ + 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \ + 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \ + 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \ + 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \ + 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \ + 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \ + 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \ + 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \ + 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \ + 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \ + 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \ + 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \ + 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \ + 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \ + 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \ + 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \ + 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \ + 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \ + 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \ + 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \ + 0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \ + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \ + 0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \ + 0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \ + 0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \ + 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \ + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, \ + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x61, 0x84, 0xb2, 0x14, 0xf9, \ + 0x92, 0xf9, 0xd1, 0x98, 0xb5, 0x52, 0x71, 0x57, 0x94, 0x11, 0xdc, 0x08, \ + 0xae, 0xf5, 0xbb, 0x7b, 0x36, 0xc6, 0x6d, 0x4b, 0xc9, 0xf1, 0x5c, 0x5e, \ + 0x27, 0xbf, 0x7f, 0x1d, 0x28, 0xe5, 0x2e, 0x21, 0x9b, 0x31, 0xce, 0x2e, \ + 0x51, 0xab, 0x61, 0xc2, 0xdc, 0xc4, 0x76, 0x2f, 0x51, 0xff, 0x80, 0xb9, \ + 0x0d, 0x70, 0x4d, 0x78, 0x43, 0xd3, 0x91, 0xb0, 0x7e, 0x7e, 0x11, 0xb5, \ + 0x5b, 0x4e, 0xa2, 0x1d, 0x88, 0xff, 0x0e, 0x9f, 0x3e, 0x69, 0xa1, 0xbb, \ + 0x7e, 0xe0, 0xf1, 0x29, 0x52, 0x87, 0x55, 0x94, 0xaa, 0x06, 0x79, 0x90, \ + 0x2e, 0x7e, 0xf7, 0xca, 0x6c, 0x9c, 0x95, 0x93, 0x47, 0x8a, 0x2e, 0x40, \ + 0xde, 0x74, 0xd2, 0xf1, 0x65, 0x1a, 0x1c, 0x0c, 0xf1, 0x37, 0xfa, 0xda, \ + 0x8c, 0xeb, 0x68, 0x33, 0xb6, 0x87, 0xd4, 0xff, 0x6d, 0x50, 0xba, 0x47, \ + 0xae, 0x5f, 0xbb, 0x1c, 0xe7, 0x8b, 0x32, 0x9c, 0x54, 0x9f, 0x02, 0x35, \ + 0xd9, 0x9a, 0x99, 0x68, 0xb2, 0x33, 0xc5, 0xb7, 0x1d, 0x25, 0x57, 0x2b, \ + 0xad, 0xad, 0x85, 0xd3, 0x46, 0x97, 0x08, 0x69, 0x18, 0x54, 0xbb, 0xf2, \ + 0xbd, 0xb6, 0x48, 0xab, 0xb2, 0xc2, 0xfb, 0x25, 0x72, 0xb1, 0xe8, 0xf9, \ + 0x80, 0x27, 0x90, 0x60, 0x3e, 0xd5, 0x14, 0xe1, 0x24, 0xb3, 0x48, 0xe1, \ + 0x16, 0x3a, 0xd2, 0xd3, 0xa8, 0x0f, 0xd3, 0xf5, 0xe7, 0x5a, 0xfe, 0xaf, \ + 0x78, 0x1a, 0x0f, 0x7b, 0x3f, 0x5d, 0xf8, 0x20, 0xa3, 0x92, 0xb8, 0x6c, \ + 0x7a, 0x25, 0xb3, 0x5c, 0xe8, 0xab, 0x88, 0x83, 0x08, 0x09, 0x7e, 0x3c, \ + 0x12, 0x5a, 0x0e, 0xfc, 0x3a, 0xec, 0x31, 0x10, 0x2d, 0xbe, 0x5c, 0x2a, \ + 0xec, 0x40, 0xf3, 0xe1, 0x08, 0x48, 0x2f, 0x3e, 0x9f, 0x7e, 0x77, 0x66, \ + 0x7b, 0x82, 0xb5, 0x71, 0x50, 0x0d, 0x44, 0xf3, 0x76, 0xa3, 0xd6 \ +} +/* END FILE */ + +/* This is taken from tests/data_files/server2.crt. */ +/* BEGIN FILE string macro TEST_SRV_CRT_RSA_SHA1_PEM tests/data_files/server2.crt */ +#define TEST_SRV_CRT_RSA_SHA1_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ + "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ + "MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" \ + "AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" \ + "owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" \ + "NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" \ + "tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" \ + "hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" \ + "HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" \ + "VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" \ + "FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAAFzC0rF\r\n" \ + "y6De8WMcdgQrEw3AhBHFjzqnxZw1ene4IBSC7lTw8rBSy3jOWQdPUWn+0y/pCeeF\r\n" \ + "kti6sevFdl1hLemGtd4q+T9TKEKGg3ND4ARfB5AUZZ9uEHq8WBkiwus5clGS17Qd\r\n" \ + "dS/TOisB59tQruLx1E1bPLtBKyqk4koC5WAULJwfpswGSyWJTpYwIpxcWE3D2tBu\r\n" \ + "UB6MZfXZFzWmWEOyKbeoXjXe8GBCGgHLywvYDsGQ36HSGtEsAvR2QaTLSxWYcfk1\r\n" \ + "fbDn4jSWkb4yZy1r01UEigFQtONieGwRFaUqEcFJHJvEEGVgh9keaVlOj2vrwf5r\r\n" \ + "4mN4lW7gLdenN6g=\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +/* This is taken from tests/data_files/server2.crt.der. */ +/* BEGIN FILE binary macro TEST_SRV_CRT_RSA_SHA1_DER tests/data_files/server2.crt.der */ +#define TEST_SRV_CRT_RSA_SHA1_DER { \ + 0x30, 0x82, 0x03, 0x37, 0x30, 0x82, 0x02, 0x1f, 0xa0, 0x03, 0x02, 0x01, \ + 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ + 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ + 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ + 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ + 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ + 0x31, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ + 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, \ + 0x34, 0x30, 0x36, 0x5a, 0x30, 0x34, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ + 0x53, 0x4c, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ + 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x30, 0x82, \ + 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, \ + 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, \ + 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, \ + 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, 0xb8, 0x99, 0xac, 0x0e, 0x78, \ + 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, 0x16, 0xd0, 0x5a, 0xe4, 0xcd, \ + 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, 0x96, 0xa7, 0x52, 0xb4, 0x90, \ + 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, 0xfc, 0xb6, 0x34, 0xac, 0x24, \ + 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, 0xb0, 0x28, 0x7d, 0xa1, 0xda, \ + 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, 0xfe, 0xc1, 0x04, 0x52, 0xb3, \ + 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, 0xd8, 0x90, 0xc1, 0x61, 0xb4, \ + 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, 0xab, 0x74, 0x5e, 0x07, 0x7d, \ + 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, 0xd9, 0x0d, 0x1c, 0x2d, 0x49, \ + 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, 0x0b, 0x8a, 0x4f, 0x69, 0x0c, \ + 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, 0x66, 0x7d, 0xae, 0x54, 0x2b, \ + 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, 0xc3, 0xcd, 0x40, 0x49, 0x08, \ + 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, 0x46, 0xbf, 0xd0, 0xb8, 0xaa, \ + 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, 0x1e, 0x44, 0x18, 0x0f, 0x0f, \ + 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, 0x18, 0xc6, 0x62, 0x2f, 0xc7, \ + 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, 0x27, 0x89, 0x29, 0x01, 0xc5, \ + 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, 0x4a, 0x0e, 0xef, 0xd6, 0xde, \ + 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, 0x7a, 0xc4, 0x02, 0x3c, 0x9a, \ + 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, 0xcb, 0x73, 0x4b, 0x52, 0x96, \ + 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, 0x39, 0x5a, 0xd3, 0x0f, 0xb0, \ + 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, 0x12, 0x01, 0x30, 0x97, 0x02, \ + 0x03, 0x01, 0x00, 0x01, 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, \ + 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0xa5, 0x05, 0xe8, 0x64, 0xb8, 0xdc, \ + 0xdf, 0x60, 0x0f, 0x50, 0x12, 0x4d, 0x60, 0xa8, 0x64, 0xaf, 0x4d, 0x8b, \ + 0x43, 0x93, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, \ + 0x16, 0x80, 0x14, 0xb4, 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, \ + 0xb9, 0xd5, 0xa6, 0x95, 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, \ + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, \ + 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x01, 0x73, 0x0b, 0x4a, 0xc5, \ + 0xcb, 0xa0, 0xde, 0xf1, 0x63, 0x1c, 0x76, 0x04, 0x2b, 0x13, 0x0d, 0xc0, \ + 0x84, 0x11, 0xc5, 0x8f, 0x3a, 0xa7, 0xc5, 0x9c, 0x35, 0x7a, 0x77, 0xb8, \ + 0x20, 0x14, 0x82, 0xee, 0x54, 0xf0, 0xf2, 0xb0, 0x52, 0xcb, 0x78, 0xce, \ + 0x59, 0x07, 0x4f, 0x51, 0x69, 0xfe, 0xd3, 0x2f, 0xe9, 0x09, 0xe7, 0x85, \ + 0x92, 0xd8, 0xba, 0xb1, 0xeb, 0xc5, 0x76, 0x5d, 0x61, 0x2d, 0xe9, 0x86, \ + 0xb5, 0xde, 0x2a, 0xf9, 0x3f, 0x53, 0x28, 0x42, 0x86, 0x83, 0x73, 0x43, \ + 0xe0, 0x04, 0x5f, 0x07, 0x90, 0x14, 0x65, 0x9f, 0x6e, 0x10, 0x7a, 0xbc, \ + 0x58, 0x19, 0x22, 0xc2, 0xeb, 0x39, 0x72, 0x51, 0x92, 0xd7, 0xb4, 0x1d, \ + 0x75, 0x2f, 0xd3, 0x3a, 0x2b, 0x01, 0xe7, 0xdb, 0x50, 0xae, 0xe2, 0xf1, \ + 0xd4, 0x4d, 0x5b, 0x3c, 0xbb, 0x41, 0x2b, 0x2a, 0xa4, 0xe2, 0x4a, 0x02, \ + 0xe5, 0x60, 0x14, 0x2c, 0x9c, 0x1f, 0xa6, 0xcc, 0x06, 0x4b, 0x25, 0x89, \ + 0x4e, 0x96, 0x30, 0x22, 0x9c, 0x5c, 0x58, 0x4d, 0xc3, 0xda, 0xd0, 0x6e, \ + 0x50, 0x1e, 0x8c, 0x65, 0xf5, 0xd9, 0x17, 0x35, 0xa6, 0x58, 0x43, 0xb2, \ + 0x29, 0xb7, 0xa8, 0x5e, 0x35, 0xde, 0xf0, 0x60, 0x42, 0x1a, 0x01, 0xcb, \ + 0xcb, 0x0b, 0xd8, 0x0e, 0xc1, 0x90, 0xdf, 0xa1, 0xd2, 0x1a, 0xd1, 0x2c, \ + 0x02, 0xf4, 0x76, 0x41, 0xa4, 0xcb, 0x4b, 0x15, 0x98, 0x71, 0xf9, 0x35, \ + 0x7d, 0xb0, 0xe7, 0xe2, 0x34, 0x96, 0x91, 0xbe, 0x32, 0x67, 0x2d, 0x6b, \ + 0xd3, 0x55, 0x04, 0x8a, 0x01, 0x50, 0xb4, 0xe3, 0x62, 0x78, 0x6c, 0x11, \ + 0x15, 0xa5, 0x2a, 0x11, 0xc1, 0x49, 0x1c, 0x9b, 0xc4, 0x10, 0x65, 0x60, \ + 0x87, 0xd9, 0x1e, 0x69, 0x59, 0x4e, 0x8f, 0x6b, 0xeb, 0xc1, 0xfe, 0x6b, \ + 0xe2, 0x63, 0x78, 0x95, 0x6e, 0xe0, 0x2d, 0xd7, 0xa7, 0x37, 0xa8 \ +} +/* END FILE */ + +/* This is taken from tests/data_files/server2.key. */ +/* BEGIN FILE string macro TEST_SRV_KEY_RSA_PEM tests/data_files/server2.key */ +#define TEST_SRV_KEY_RSA_PEM \ + "-----BEGIN RSA PRIVATE KEY-----\r\n" \ + "MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n" \ + "lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n" \ + "2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n" \ + "Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n" \ + "GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n" \ + "y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n" \ + "++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n" \ + "Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n" \ + "/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n" \ + "WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n" \ + "GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n" \ + "TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n" \ + "CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" \ + "nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" \ + "AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" \ + "sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" \ + "mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" \ + "BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" \ + "whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" \ + "vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" \ + "3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" \ + "3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" \ + "ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" \ + "4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" \ + "TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" \ + "-----END RSA PRIVATE KEY-----\r\n" +/* END FILE */ + +/* This was generated from tests/data_files/server2.key.der using `xxd -i`. */ +/* BEGIN FILE binary macro TEST_SRV_KEY_RSA_DER tests/data_files/server2.key.der */ +#define TEST_SRV_KEY_RSA_DER { \ + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ + 0xc1, 0x4d, 0xa3, 0xdd, 0xe7, 0xcd, 0x1d, 0xd1, 0x04, 0xd7, 0x49, 0x72, \ + 0xb8, 0x99, 0xac, 0x0e, 0x78, 0xe4, 0x3a, 0x3c, 0x4a, 0xcf, 0x3a, 0x13, \ + 0x16, 0xd0, 0x5a, 0xe4, 0xcd, 0xa3, 0x00, 0x88, 0xa7, 0xee, 0x1e, 0x6b, \ + 0x96, 0xa7, 0x52, 0xb4, 0x90, 0xef, 0x2d, 0x72, 0x7a, 0x3e, 0x24, 0x9a, \ + 0xfc, 0xb6, 0x34, 0xac, 0x24, 0xf5, 0x77, 0xe0, 0x26, 0x64, 0x8c, 0x9c, \ + 0xb0, 0x28, 0x7d, 0xa1, 0xda, 0xea, 0x8c, 0xe6, 0xc9, 0x1c, 0x96, 0xbc, \ + 0xfe, 0xc1, 0x04, 0x52, 0xb3, 0x36, 0xd4, 0xa3, 0xfa, 0xe1, 0xb1, 0x76, \ + 0xd8, 0x90, 0xc1, 0x61, 0xb4, 0x66, 0x52, 0x36, 0xa2, 0x26, 0x53, 0xaa, \ + 0xab, 0x74, 0x5e, 0x07, 0x7d, 0x19, 0x82, 0xdb, 0x2a, 0xd8, 0x1f, 0xa0, \ + 0xd9, 0x0d, 0x1c, 0x2d, 0x49, 0x66, 0xf7, 0x5b, 0x25, 0x73, 0x46, 0xe8, \ + 0x0b, 0x8a, 0x4f, 0x69, 0x0c, 0xb5, 0x00, 0x90, 0xe1, 0xda, 0x82, 0x10, \ + 0x66, 0x7d, 0xae, 0x54, 0x2b, 0x8b, 0x65, 0x79, 0x91, 0xa1, 0xe2, 0x61, \ + 0xc3, 0xcd, 0x40, 0x49, 0x08, 0xee, 0x68, 0x0c, 0xf1, 0x8b, 0x86, 0xd2, \ + 0x46, 0xbf, 0xd0, 0xb8, 0xaa, 0x11, 0x03, 0x1e, 0x7f, 0x56, 0xa8, 0x1a, \ + 0x1e, 0x44, 0x18, 0x0f, 0x0f, 0x85, 0x8b, 0xda, 0x8b, 0x44, 0x5e, 0xe2, \ + 0x18, 0xc6, 0x62, 0x2f, 0xc7, 0x66, 0x8d, 0xfa, 0x5d, 0xd8, 0x7d, 0xf3, \ + 0x27, 0x89, 0x29, 0x01, 0xc5, 0x90, 0x0e, 0x3f, 0x27, 0xf1, 0x30, 0xc8, \ + 0x4a, 0x0e, 0xef, 0xd6, 0xde, 0xc7, 0xc7, 0x27, 0x6b, 0xc7, 0x05, 0x3d, \ + 0x7a, 0xc4, 0x02, 0x3c, 0x9a, 0x1d, 0x3e, 0x0f, 0xe8, 0x34, 0x98, 0x5b, \ + 0xcb, 0x73, 0x4b, 0x52, 0x96, 0xd8, 0x11, 0xa2, 0x2c, 0x80, 0x88, 0x69, \ + 0x39, 0x5a, 0xd3, 0x0f, 0xb0, 0xde, 0x59, 0x2f, 0x11, 0xc7, 0xf7, 0xea, \ + 0x12, 0x01, 0x30, 0x97, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ + 0x01, 0x00, 0x97, 0x47, 0x44, 0xbc, 0x10, 0x81, 0xc5, 0x18, 0xe4, 0x59, \ + 0xfb, 0xe0, 0x2d, 0x3a, 0x0e, 0x9e, 0x10, 0xdc, 0x43, 0xfb, 0x15, 0x6c, \ + 0xd1, 0xfd, 0x48, 0x78, 0x6c, 0xf9, 0xed, 0x38, 0xe8, 0xdd, 0x09, 0xd7, \ + 0x5f, 0xb5, 0x41, 0x64, 0xd7, 0x63, 0xfa, 0x9d, 0x44, 0x0a, 0xf8, 0x42, \ + 0x13, 0xf1, 0xbb, 0x5e, 0x79, 0x20, 0x53, 0x98, 0x4b, 0x65, 0x7f, 0x86, \ + 0x67, 0x48, 0xe4, 0xcf, 0xfb, 0x6a, 0x24, 0xe2, 0x34, 0xbd, 0x14, 0x9d, \ + 0x2c, 0x16, 0xe2, 0xa4, 0x79, 0xd6, 0xa2, 0xec, 0x81, 0x43, 0x87, 0xbf, \ + 0x03, 0x5c, 0x88, 0x25, 0xd9, 0x41, 0xb6, 0xa5, 0xf1, 0x27, 0x52, 0x84, \ + 0xfe, 0x2b, 0x6e, 0x1d, 0x16, 0xcd, 0x73, 0x88, 0xf8, 0x90, 0xbf, 0x19, \ + 0xfe, 0xbe, 0xa9, 0xbf, 0x09, 0xd3, 0x23, 0x43, 0xd2, 0xc7, 0x61, 0x2a, \ + 0xb3, 0x4e, 0x3c, 0x61, 0xd4, 0xbd, 0xd8, 0xb4, 0xfa, 0xa8, 0x0b, 0xf8, \ + 0x7e, 0x56, 0xcd, 0x0f, 0x13, 0x27, 0xda, 0xe6, 0x3b, 0xb3, 0x8c, 0x9c, \ + 0x4b, 0x84, 0x3c, 0xc3, 0x52, 0x57, 0x9c, 0x27, 0x9a, 0x02, 0x76, 0x26, \ + 0x59, 0x82, 0x39, 0xc3, 0x13, 0xbe, 0x6e, 0xf4, 0x44, 0x2d, 0x1d, 0x8c, \ + 0x73, 0x3e, 0x43, 0x99, 0x59, 0xcb, 0xf2, 0x34, 0x72, 0x9a, 0x5e, 0xa5, \ + 0xeb, 0x9f, 0x36, 0x6d, 0x2b, 0xf9, 0xa2, 0xe7, 0xd1, 0x78, 0x52, 0x1b, \ + 0xc8, 0xf6, 0x5b, 0x41, 0x69, 0x57, 0x81, 0x89, 0xe9, 0xbb, 0xa1, 0xde, \ + 0x19, 0x37, 0x3b, 0x13, 0x5c, 0xca, 0x61, 0x01, 0x86, 0xff, 0xdf, 0x83, \ + 0x41, 0x49, 0x7f, 0xd6, 0xf4, 0x2e, 0x08, 0xfa, 0x90, 0xc2, 0x7c, 0xb4, \ + 0xb5, 0x0a, 0x17, 0xdb, 0x0e, 0x6d, 0x75, 0x8a, 0x5d, 0x31, 0xd5, 0x66, \ + 0xfb, 0x39, 0x0b, 0xb5, 0xb6, 0xa3, 0xcd, 0xd4, 0xef, 0x88, 0x92, 0x5a, \ + 0x4d, 0x6c, 0xcb, 0xea, 0x5b, 0x79, 0x02, 0x81, 0x81, 0x00, 0xdf, 0x3a, \ + 0xf9, 0x25, 0x5e, 0x24, 0x37, 0x26, 0x40, 0x97, 0x2f, 0xe0, 0x4a, 0xba, \ + 0x52, 0x1b, 0x51, 0xaf, 0x84, 0x06, 0x32, 0x24, 0x0c, 0xcf, 0x44, 0xa8, \ + 0x77, 0xa7, 0xad, 0xb5, 0x8c, 0x58, 0xcc, 0xc8, 0x31, 0xb7, 0x0d, 0xbc, \ + 0x08, 0x8a, 0xe0, 0xa6, 0x8c, 0xc2, 0x73, 0xe5, 0x1a, 0x64, 0x92, 0xe8, \ + 0xed, 0x4c, 0x6f, 0x0b, 0xa6, 0xa7, 0xf3, 0x9a, 0xf5, 0x6f, 0x69, 0xca, \ + 0x3c, 0x22, 0xd0, 0x15, 0xa8, 0x20, 0x27, 0x41, 0xf8, 0x43, 0x42, 0x7f, \ + 0xb1, 0x93, 0xa1, 0x04, 0x85, 0xda, 0xa0, 0x1c, 0xd6, 0xc6, 0xf7, 0x8a, \ + 0x9e, 0xea, 0x5c, 0x78, 0xa7, 0x55, 0xc4, 0x6b, 0x05, 0x8b, 0xc0, 0x83, \ + 0xcb, 0xce, 0x83, 0x05, 0xf8, 0xb2, 0x16, 0x2b, 0xdf, 0x06, 0x3f, 0xb8, \ + 0xec, 0x16, 0xda, 0x43, 0x33, 0xc1, 0x8f, 0xb0, 0xb8, 0xac, 0xae, 0xd4, \ + 0x94, 0xb8, 0xda, 0x6f, 0x6a, 0xc3, 0x02, 0x81, 0x81, 0x00, 0xdd, 0xae, \ + 0x00, 0xcd, 0xa0, 0x72, 0x1a, 0x05, 0x8a, 0xee, 0x2f, 0xd4, 0x71, 0x4b, \ + 0xf0, 0x3e, 0xe5, 0xc1, 0xe1, 0x29, 0x8b, 0xa6, 0x67, 0x30, 0x98, 0xe7, \ + 0x12, 0xef, 0xdd, 0x12, 0x01, 0x90, 0x24, 0x58, 0xf0, 0x76, 0x92, 0xe7, \ + 0x3d, 0xbb, 0x23, 0xe1, 0xce, 0xf9, 0xa1, 0xd4, 0x38, 0x1b, 0x3f, 0x20, \ + 0xb3, 0x0f, 0x65, 0x6a, 0x8f, 0x55, 0x57, 0x36, 0xee, 0xb2, 0x84, 0x44, \ + 0xfc, 0x91, 0x88, 0xe1, 0xa4, 0xdd, 0x3b, 0x4a, 0x40, 0x4d, 0x7c, 0x86, \ + 0xed, 0xe1, 0xb5, 0x42, 0xef, 0xb9, 0x61, 0xcd, 0x58, 0x19, 0x77, 0x02, \ + 0xae, 0x58, 0x80, 0xdb, 0x13, 0x3d, 0xc7, 0x1f, 0x9d, 0xed, 0xff, 0xac, \ + 0x98, 0xfc, 0xcd, 0xf9, 0x62, 0x04, 0x83, 0x91, 0x89, 0x0d, 0x86, 0x43, \ + 0x8c, 0x0c, 0xc7, 0x1b, 0x90, 0x4d, 0xbe, 0x2f, 0xc5, 0x7c, 0xcd, 0x42, \ + 0xf5, 0xd3, 0xad, 0x8e, 0xfd, 0x9d, 0x02, 0x81, 0x80, 0x17, 0x4b, 0x79, \ + 0x2a, 0x6c, 0x1b, 0x8d, 0x61, 0xc1, 0x85, 0xc5, 0x6a, 0x3b, 0x82, 0x1c, \ + 0x05, 0x5b, 0xcd, 0xdc, 0x12, 0x25, 0x73, 0x5b, 0x9e, 0xd9, 0x84, 0x57, \ + 0x10, 0x39, 0x71, 0x63, 0x96, 0xf4, 0xaf, 0xc3, 0x78, 0x5d, 0xc7, 0x8c, \ + 0x80, 0xa9, 0x96, 0xd7, 0xc3, 0x87, 0x02, 0x96, 0x71, 0x7e, 0x5f, 0x2e, \ + 0x3c, 0x36, 0xae, 0x59, 0x92, 0xd7, 0x3a, 0x09, 0x78, 0xb9, 0xea, 0x6f, \ + 0xc2, 0x16, 0x42, 0xdc, 0x4b, 0x96, 0xad, 0x2c, 0xb2, 0x20, 0x23, 0x61, \ + 0x2d, 0x8d, 0xb5, 0x02, 0x1e, 0xe1, 0x6c, 0x81, 0x01, 0x3c, 0x5d, 0xcb, \ + 0xdd, 0x9b, 0x0e, 0xc0, 0x2f, 0x94, 0x12, 0xb2, 0xfe, 0x75, 0x75, 0x8b, \ + 0x74, 0x1e, 0x7a, 0x26, 0x0c, 0xb7, 0x81, 0x96, 0x81, 0x79, 0x6e, 0xdb, \ + 0xbc, 0x3a, 0xc4, 0x9e, 0x87, 0x09, 0x6e, 0xa0, 0xa6, 0xec, 0x8b, 0xa4, \ + 0x85, 0x71, 0xce, 0x04, 0xaf, 0x02, 0x81, 0x81, 0x00, 0xc2, 0xa7, 0x47, \ + 0x07, 0x48, 0x6a, 0xc8, 0xd4, 0xb3, 0x20, 0xe1, 0x98, 0xee, 0xff, 0x5a, \ + 0x6f, 0x30, 0x7a, 0xa5, 0x47, 0x40, 0xdc, 0x16, 0x62, 0x42, 0xf1, 0x2c, \ + 0xdc, 0xb8, 0xc7, 0x55, 0xde, 0x07, 0x3c, 0x9d, 0xb1, 0xd0, 0xdf, 0x02, \ + 0x82, 0xb0, 0x48, 0x58, 0xe1, 0x34, 0xab, 0xcf, 0xb4, 0x85, 0x23, 0x26, \ + 0x78, 0x4f, 0x7a, 0x59, 0x6f, 0xfb, 0x8c, 0x3d, 0xdf, 0x3d, 0x6c, 0x02, \ + 0x47, 0x9c, 0xe5, 0x5e, 0x49, 0xf1, 0x05, 0x0b, 0x1f, 0xbf, 0x48, 0x0f, \ + 0xdc, 0x10, 0xb9, 0x3d, 0x1d, 0x10, 0x77, 0x2a, 0x73, 0xf9, 0xdf, 0xbd, \ + 0xcd, 0xf3, 0x1f, 0xeb, 0x6e, 0x64, 0xca, 0x2b, 0x78, 0x4f, 0xf8, 0x73, \ + 0xc2, 0x10, 0xef, 0x79, 0x95, 0x33, 0x1e, 0x79, 0x35, 0x09, 0xff, 0x88, \ + 0x1b, 0xb4, 0x3e, 0x4c, 0xe1, 0x27, 0x2e, 0x75, 0x80, 0x58, 0x11, 0x03, \ + 0x21, 0x23, 0x96, 0x9a, 0xb5, 0x02, 0x81, 0x80, 0x05, 0x12, 0x64, 0x71, \ + 0x83, 0x00, 0x1c, 0xfe, 0xef, 0x83, 0xea, 0xdd, 0x2c, 0xc8, 0x2c, 0x00, \ + 0x62, 0x1e, 0x8f, 0x3a, 0xdb, 0x1c, 0xab, 0xd6, 0x34, 0x8b, 0xd1, 0xb2, \ + 0x5a, 0x4f, 0x3d, 0x37, 0x38, 0x02, 0xe0, 0xd7, 0x70, 0xc1, 0xb0, 0x47, \ + 0xe0, 0x08, 0x1a, 0x84, 0xec, 0x48, 0xc5, 0x7c, 0x76, 0x83, 0x12, 0x67, \ + 0xab, 0x7c, 0x9f, 0x90, 0x97, 0xc8, 0x8f, 0x07, 0xf4, 0xb3, 0x60, 0xf2, \ + 0x3f, 0x49, 0x18, 0xdb, 0x2e, 0x94, 0x6b, 0x53, 0x9e, 0xa2, 0x63, 0xde, \ + 0x63, 0xd9, 0xab, 0x21, 0x2e, 0x2d, 0x0a, 0xe0, 0xd0, 0xe8, 0xba, 0xc4, \ + 0x4c, 0x1e, 0xa5, 0xf5, 0x51, 0xa8, 0xc4, 0x92, 0xf8, 0x7f, 0x21, 0xe7, \ + 0x65, 0xbf, 0x0b, 0xe6, 0x01, 0xaf, 0x9c, 0x1d, 0x5b, 0x6c, 0x3f, 0x1c, \ + 0x2f, 0xa6, 0x0f, 0x68, 0x38, 0x8e, 0x85, 0xc4, 0x6c, 0x78, 0x2f, 0x6f, \ + 0x06, 0x21, 0x2e, 0x56 \ +} +/* END FILE */ + +/* + * Test client Certificates + * + * Test client certificates are defined for each choice + * of the following parameters: + * - PEM or DER encoding + * - RSA or EC key + * + * Things to add: + * - hash type + * - multiple EC curve types + */ + +/* This is taken from tests/data_files/cli2.crt. */ +/* BEGIN FILE string macro TEST_CLI_CRT_EC_PEM tests/data_files/cli2.crt */ +#define TEST_CLI_CRT_EC_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIICLDCCAbKgAwIBAgIBDTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" \ + "MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjBBMQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UEChMIUG9sYXJTU0wxHzAdBgNVBAMTFlBvbGFyU1NMIFRlc3QgQ2xpZW50IDIw\r\n" \ + "WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARX5a6xc9/TrLuTuIH/Eq7u5lOszlVT\r\n" \ + "9jQOzC7jYyUL35ji81xgNpbA1RgUcOV/n9VLRRjlsGzVXPiWj4dwo+THo4GdMIGa\r\n" \ + "MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMG4GA1Ud\r\n" \ + "IwRnMGWAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8oUKkQDA+MQswCQYDVQQGEwJOTDER\r\n" \ + "MA8GA1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0GC\r\n" \ + "CQDBQ+J+YkPM6DAKBggqhkjOPQQDAgNoADBlAjBKZQ17IIOimbmoD/yN7o89u3BM\r\n" \ + "lgOsjnhw3fIOoLIWy2WOGsk/LGF++DzvrRzuNiACMQCd8iem1XS4JK7haj8xocpU\r\n" \ + "LwjQje5PDGHfd3h9tP38Qknu5bJqws0md2KOKHyeV0U=\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +/* This is generated from tests/data_files/cli2.crt.der using `xxd -i`. */ +/* BEGIN FILE binary macro TEST_CLI_CRT_EC_DER tests/data_files/cli2.crt.der */ +#define TEST_CLI_CRT_EC_DER { \ + 0x30, 0x82, 0x02, 0x2c, 0x30, 0x82, 0x01, 0xb2, 0xa0, 0x03, 0x02, 0x01, \ + 0x02, 0x02, 0x01, 0x0d, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, \ + 0x3d, 0x04, 0x03, 0x02, 0x30, 0x3e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ + 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, \ + 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, 0x20, 0x54, 0x65, \ + 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ + 0x31, 0x33, 0x30, 0x39, 0x32, 0x34, 0x31, 0x35, 0x35, 0x32, 0x30, 0x34, \ + 0x5a, 0x17, 0x0d, 0x32, 0x33, 0x30, 0x39, 0x32, 0x32, 0x31, 0x35, 0x35, \ + 0x32, 0x30, 0x34, 0x5a, 0x30, 0x41, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ + 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ + 0x53, 0x4c, 0x31, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, \ + 0x16, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x54, 0x65, \ + 0x73, 0x74, 0x20, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, 0x32, 0x30, \ + 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, \ + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, \ + 0x00, 0x04, 0x57, 0xe5, 0xae, 0xb1, 0x73, 0xdf, 0xd3, 0xac, 0xbb, 0x93, \ + 0xb8, 0x81, 0xff, 0x12, 0xae, 0xee, 0xe6, 0x53, 0xac, 0xce, 0x55, 0x53, \ + 0xf6, 0x34, 0x0e, 0xcc, 0x2e, 0xe3, 0x63, 0x25, 0x0b, 0xdf, 0x98, 0xe2, \ + 0xf3, 0x5c, 0x60, 0x36, 0x96, 0xc0, 0xd5, 0x18, 0x14, 0x70, 0xe5, 0x7f, \ + 0x9f, 0xd5, 0x4b, 0x45, 0x18, 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, 0xf8, 0x96, \ + 0x8f, 0x87, 0x70, 0xa3, 0xe4, 0xc7, 0xa3, 0x81, 0x9d, 0x30, 0x81, 0x9a, \ + 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, \ + 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7a, 0x00, \ + 0x5f, 0x86, 0x64, 0xfc, 0xe0, 0x5d, 0xe5, 0x11, 0x10, 0x3b, 0xb2, 0xe6, \ + 0x3b, 0xc4, 0x26, 0x3f, 0xcf, 0xe2, 0x30, 0x6e, 0x06, 0x03, 0x55, 0x1d, \ + 0x23, 0x04, 0x67, 0x30, 0x65, 0x80, 0x14, 0x9d, 0x6d, 0x20, 0x24, 0x49, \ + 0x01, 0x3f, 0x2b, 0xcb, 0x78, 0xb5, 0x19, 0xbc, 0x7e, 0x24, 0xc9, 0xdb, \ + 0xfb, 0x36, 0x7c, 0xa1, 0x42, 0xa4, 0x40, 0x30, 0x3e, 0x31, 0x0b, 0x30, \ + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x50, 0x6f, 0x6c, \ + 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, \ + 0x04, 0x03, 0x13, 0x13, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x73, 0x73, 0x6c, \ + 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x45, 0x43, 0x20, 0x43, 0x41, 0x82, \ + 0x09, 0x00, 0xc1, 0x43, 0xe2, 0x7e, 0x62, 0x43, 0xcc, 0xe8, 0x30, 0x0a, \ + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x68, \ + 0x00, 0x30, 0x65, 0x02, 0x30, 0x4a, 0x65, 0x0d, 0x7b, 0x20, 0x83, 0xa2, \ + 0x99, 0xb9, 0xa8, 0x0f, 0xfc, 0x8d, 0xee, 0x8f, 0x3d, 0xbb, 0x70, 0x4c, \ + 0x96, 0x03, 0xac, 0x8e, 0x78, 0x70, 0xdd, 0xf2, 0x0e, 0xa0, 0xb2, 0x16, \ + 0xcb, 0x65, 0x8e, 0x1a, 0xc9, 0x3f, 0x2c, 0x61, 0x7e, 0xf8, 0x3c, 0xef, \ + 0xad, 0x1c, 0xee, 0x36, 0x20, 0x02, 0x31, 0x00, 0x9d, 0xf2, 0x27, 0xa6, \ + 0xd5, 0x74, 0xb8, 0x24, 0xae, 0xe1, 0x6a, 0x3f, 0x31, 0xa1, 0xca, 0x54, \ + 0x2f, 0x08, 0xd0, 0x8d, 0xee, 0x4f, 0x0c, 0x61, 0xdf, 0x77, 0x78, 0x7d, \ + 0xb4, 0xfd, 0xfc, 0x42, 0x49, 0xee, 0xe5, 0xb2, 0x6a, 0xc2, 0xcd, 0x26, \ + 0x77, 0x62, 0x8e, 0x28, 0x7c, 0x9e, 0x57, 0x45 \ +} +/* END FILE */ + +/* This is taken from tests/data_files/cli2.key. */ +/* BEGIN FILE string macro TEST_CLI_KEY_EC_PEM tests/data_files/cli2.key */ +#define TEST_CLI_KEY_EC_PEM \ + "-----BEGIN EC PRIVATE KEY-----\r\n" \ + "MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n" \ + "AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n" \ + "wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n" \ + "-----END EC PRIVATE KEY-----\r\n" +/* END FILE */ + +/* This is generated from tests/data_files/cli2.key.der using `xxd -i`. */ +/* BEGIN FILE binary macro TEST_CLI_KEY_EC_DER tests/data_files/cli2.key.der */ +#define TEST_CLI_KEY_EC_DER { \ + 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0xf6, 0xf7, 0x86, 0x64, 0xf1, \ + 0x67, 0x7f, 0xe6, 0x64, 0x8d, 0xef, 0xca, 0x4e, 0xe9, 0xdd, 0x4d, 0xf0, \ + 0x05, 0xff, 0x96, 0x22, 0x8a, 0x7a, 0x84, 0x38, 0x64, 0x17, 0x32, 0x61, \ + 0x98, 0xb7, 0x2a, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, \ + 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0x57, 0xe5, 0xae, \ + 0xb1, 0x73, 0xdf, 0xd3, 0xac, 0xbb, 0x93, 0xb8, 0x81, 0xff, 0x12, 0xae, \ + 0xee, 0xe6, 0x53, 0xac, 0xce, 0x55, 0x53, 0xf6, 0x34, 0x0e, 0xcc, 0x2e, \ + 0xe3, 0x63, 0x25, 0x0b, 0xdf, 0x98, 0xe2, 0xf3, 0x5c, 0x60, 0x36, 0x96, \ + 0xc0, 0xd5, 0x18, 0x14, 0x70, 0xe5, 0x7f, 0x9f, 0xd5, 0x4b, 0x45, 0x18, \ + 0xe5, 0xb0, 0x6c, 0xd5, 0x5c, 0xf8, 0x96, 0x8f, 0x87, 0x70, 0xa3, 0xe4, \ + 0xc7 \ +} +/* END FILE */ + +/* This is taken from tests/data_files/cli-rsa-sha256.crt. */ +/* BEGIN FILE string macro TEST_CLI_CRT_RSA_PEM tests/data_files/cli-rsa-sha256.crt */ +#define TEST_CLI_CRT_RSA_PEM \ + "-----BEGIN CERTIFICATE-----\r\n" \ + "MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ + "MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ + "MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" \ + "A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" \ + "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n" \ + "M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n" \ + "1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n" \ + "MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n" \ + "4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n" \ + "/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n" \ + "o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n" \ + "BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQsFAAOC\r\n" \ + "AQEAlHabem2Tu69VUN7EipwnQn1dIHdgvT5i+iQHpSxY1crPnBbAeSdAXwsVEqLQ\r\n" \ + "gOOIAQD5VIITNuoGgo4i+4OpNh9u7ZkpRHla+/swsfrFWRRbBNP5Bcu74AGLstwU\r\n" \ + "zM8gIkBiyfM1Q1qDQISV9trlCG6O8vh8dp/rbI3rfzo99BOHXgFCrzXjCuW4vDsF\r\n" \ + "r+Dao26bX3sJ6UnEWg1H3o2x6PpUcvQ36h71/bz4TEbbUUEpe02V4QWuL+wrhHJL\r\n" \ + "U7o3SVE3Og7jPF8sat0a50YUWhwEFI256m02KAXLg89ueUyYKEr6rNwhcvXJpvU9\r\n" \ + "giIVvd0Sbjjnn7NC4VDbcXV8vw==\r\n" \ + "-----END CERTIFICATE-----\r\n" +/* END FILE */ + +/* This was generated from tests/data_files/cli-rsa-sha256.crt.der + using `xxd -i.` */ +/* BEGIN FILE binary macro TEST_CLI_CRT_RSA_DER tests/data_files/cli-rsa-sha256.crt.der */ +#define TEST_CLI_CRT_RSA_DER { \ + 0x30, 0x82, 0x03, 0x3f, 0x30, 0x82, 0x02, 0x27, 0xa0, 0x03, 0x02, 0x01, \ + 0x02, 0x02, 0x01, 0x04, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, \ + 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x3b, 0x31, 0x0b, 0x30, \ + 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, \ + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, \ + 0x61, 0x72, 0x53, 0x53, 0x4c, 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, \ + 0x04, 0x03, 0x0c, 0x10, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, \ + 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, \ + 0x31, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, 0x34, 0x30, 0x36, \ + 0x5a, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, 0x31, 0x32, 0x31, 0x34, 0x34, \ + 0x34, 0x30, 0x36, 0x5a, 0x30, 0x3c, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, \ + 0x55, 0x04, 0x06, 0x13, 0x02, 0x4e, 0x4c, 0x31, 0x11, 0x30, 0x0f, 0x06, \ + 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x08, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, \ + 0x53, 0x4c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, \ + 0x11, 0x50, 0x6f, 0x6c, 0x61, 0x72, 0x53, 0x53, 0x4c, 0x20, 0x43, 0x6c, \ + 0x69, 0x65, 0x6e, 0x74, 0x20, 0x32, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, \ + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, \ + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, \ + 0x01, 0x01, 0x00, 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, \ + 0x45, 0xd9, 0x14, 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, \ + 0x33, 0xad, 0x0d, 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, \ + 0xcc, 0x66, 0x85, 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, \ + 0x9e, 0x0a, 0x6e, 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, \ + 0x93, 0x86, 0x49, 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, \ + 0xd4, 0x2f, 0x77, 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, \ + 0x48, 0x70, 0xf5, 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, \ + 0xe6, 0x43, 0xea, 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, \ + 0x57, 0x4e, 0xa9, 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, \ + 0x32, 0x30, 0xd5, 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, \ + 0x5f, 0xf9, 0x3d, 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, \ + 0xfb, 0xe5, 0x0c, 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, \ + 0x7f, 0xca, 0xad, 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, \ + 0xe0, 0x9b, 0xf8, 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, \ + 0x04, 0x66, 0xc7, 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, \ + 0x06, 0x67, 0xf4, 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, \ + 0x3c, 0x8b, 0x35, 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, \ + 0xfc, 0x36, 0x6b, 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, \ + 0x00, 0xcf, 0xaf, 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, \ + 0xe7, 0x50, 0x71, 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, \ + 0xe4, 0xc4, 0xfd, 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, \ + 0xa3, 0x4d, 0x30, 0x4b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, \ + 0x02, 0x30, 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, \ + 0x04, 0x14, 0x71, 0xa1, 0x00, 0x73, 0x72, 0x40, 0x2f, 0x54, 0x76, 0x5e, \ + 0x33, 0xfc, 0x52, 0x8f, 0xbc, 0xf1, 0xdd, 0x6b, 0x46, 0x21, 0x30, 0x1f, \ + 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xb4, \ + 0x5a, 0xe4, 0xa5, 0xb3, 0xde, 0xd2, 0x52, 0xf6, 0xb9, 0xd5, 0xa6, 0x95, \ + 0x0f, 0xeb, 0x3e, 0xbc, 0xc7, 0xfd, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, \ + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, \ + 0x01, 0x01, 0x00, 0x94, 0x76, 0x9b, 0x7a, 0x6d, 0x93, 0xbb, 0xaf, 0x55, \ + 0x50, 0xde, 0xc4, 0x8a, 0x9c, 0x27, 0x42, 0x7d, 0x5d, 0x20, 0x77, 0x60, \ + 0xbd, 0x3e, 0x62, 0xfa, 0x24, 0x07, 0xa5, 0x2c, 0x58, 0xd5, 0xca, 0xcf, \ + 0x9c, 0x16, 0xc0, 0x79, 0x27, 0x40, 0x5f, 0x0b, 0x15, 0x12, 0xa2, 0xd0, \ + 0x80, 0xe3, 0x88, 0x01, 0x00, 0xf9, 0x54, 0x82, 0x13, 0x36, 0xea, 0x06, \ + 0x82, 0x8e, 0x22, 0xfb, 0x83, 0xa9, 0x36, 0x1f, 0x6e, 0xed, 0x99, 0x29, \ + 0x44, 0x79, 0x5a, 0xfb, 0xfb, 0x30, 0xb1, 0xfa, 0xc5, 0x59, 0x14, 0x5b, \ + 0x04, 0xd3, 0xf9, 0x05, 0xcb, 0xbb, 0xe0, 0x01, 0x8b, 0xb2, 0xdc, 0x14, \ + 0xcc, 0xcf, 0x20, 0x22, 0x40, 0x62, 0xc9, 0xf3, 0x35, 0x43, 0x5a, 0x83, \ + 0x40, 0x84, 0x95, 0xf6, 0xda, 0xe5, 0x08, 0x6e, 0x8e, 0xf2, 0xf8, 0x7c, \ + 0x76, 0x9f, 0xeb, 0x6c, 0x8d, 0xeb, 0x7f, 0x3a, 0x3d, 0xf4, 0x13, 0x87, \ + 0x5e, 0x01, 0x42, 0xaf, 0x35, 0xe3, 0x0a, 0xe5, 0xb8, 0xbc, 0x3b, 0x05, \ + 0xaf, 0xe0, 0xda, 0xa3, 0x6e, 0x9b, 0x5f, 0x7b, 0x09, 0xe9, 0x49, 0xc4, \ + 0x5a, 0x0d, 0x47, 0xde, 0x8d, 0xb1, 0xe8, 0xfa, 0x54, 0x72, 0xf4, 0x37, \ + 0xea, 0x1e, 0xf5, 0xfd, 0xbc, 0xf8, 0x4c, 0x46, 0xdb, 0x51, 0x41, 0x29, \ + 0x7b, 0x4d, 0x95, 0xe1, 0x05, 0xae, 0x2f, 0xec, 0x2b, 0x84, 0x72, 0x4b, \ + 0x53, 0xba, 0x37, 0x49, 0x51, 0x37, 0x3a, 0x0e, 0xe3, 0x3c, 0x5f, 0x2c, \ + 0x6a, 0xdd, 0x1a, 0xe7, 0x46, 0x14, 0x5a, 0x1c, 0x04, 0x14, 0x8d, 0xb9, \ + 0xea, 0x6d, 0x36, 0x28, 0x05, 0xcb, 0x83, 0xcf, 0x6e, 0x79, 0x4c, 0x98, \ + 0x28, 0x4a, 0xfa, 0xac, 0xdc, 0x21, 0x72, 0xf5, 0xc9, 0xa6, 0xf5, 0x3d, \ + 0x82, 0x22, 0x15, 0xbd, 0xdd, 0x12, 0x6e, 0x38, 0xe7, 0x9f, 0xb3, 0x42, \ + 0xe1, 0x50, 0xdb, 0x71, 0x75, 0x7c, 0xbf \ +} +/* END FILE */ + +/* This is taken from tests/data_files/cli-rsa.key. */ +/* BEGIN FILE string macro TEST_CLI_KEY_RSA_PEM tests/data_files/cli-rsa.key */ +#define TEST_CLI_KEY_RSA_PEM \ + "-----BEGIN RSA PRIVATE KEY-----\r\n" \ + "MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n" \ + "B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n" \ + "bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n" \ + "Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n" \ + "7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n" \ + "dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n" \ + "yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n" \ + "4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n" \ + "ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n" \ + "zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n" \ + "l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n" \ + "DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n" \ + "VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n" \ + "Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n" \ + "wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n" \ + "c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n" \ + "33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n" \ + "ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n" \ + "BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n" \ + "KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n" \ + "UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n" \ + "7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n" \ + "gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n" \ + "bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" \ + "8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" \ + "-----END RSA PRIVATE KEY-----\r\n"/* END FILE */ + +/* This was generated from tests/data_files/cli-rsa.key.der using `xxd -i`. */ +/* BEGIN FILE binary macro TEST_CLI_KEY_RSA_DER tests/data_files/cli-rsa.key.der */ +#define TEST_CLI_KEY_RSA_DER { \ + 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, \ + 0xc8, 0x74, 0xc4, 0xcc, 0xb9, 0xf9, 0xb5, 0x79, 0xe9, 0x45, 0xd9, 0x14, \ + 0x60, 0xb0, 0x7d, 0xbb, 0x93, 0xf2, 0x6b, 0x1e, 0x9f, 0x33, 0xad, 0x0d, \ + 0x8f, 0x8a, 0x3c, 0x56, 0x65, 0xe5, 0xdc, 0x44, 0xd9, 0xcc, 0x66, 0x85, \ + 0x07, 0xd5, 0xf8, 0x27, 0xb0, 0x4a, 0x35, 0xd0, 0x63, 0x9e, 0x0a, 0x6e, \ + 0x1b, 0xb7, 0xda, 0xf0, 0x7e, 0xab, 0xee, 0x0c, 0x10, 0x93, 0x86, 0x49, \ + 0x18, 0x34, 0xf3, 0xa8, 0x2a, 0xd2, 0x57, 0xf5, 0x2e, 0xd4, 0x2f, 0x77, \ + 0x29, 0x84, 0x61, 0x4d, 0x82, 0x50, 0x8f, 0xa7, 0x95, 0x48, 0x70, 0xf5, \ + 0x6e, 0x4d, 0xb2, 0xd5, 0x13, 0xc3, 0xd2, 0x1a, 0xed, 0xe6, 0x43, 0xea, \ + 0x42, 0x14, 0xeb, 0x74, 0xea, 0xc0, 0xed, 0x1f, 0xd4, 0x57, 0x4e, 0xa9, \ + 0xf3, 0xa8, 0xed, 0xd2, 0xe0, 0xc1, 0x30, 0x71, 0x30, 0x32, 0x30, 0xd5, \ + 0xd3, 0xf6, 0x08, 0xd0, 0x56, 0x4f, 0x46, 0x8e, 0xf2, 0x5f, 0xf9, 0x3d, \ + 0x67, 0x91, 0x88, 0x30, 0x2e, 0x42, 0xb2, 0xdf, 0x7d, 0xfb, 0xe5, 0x0c, \ + 0x77, 0xff, 0xec, 0x31, 0xc0, 0x78, 0x8f, 0xbf, 0xc2, 0x7f, 0xca, 0xad, \ + 0x6c, 0x21, 0xd6, 0x8d, 0xd9, 0x8b, 0x6a, 0x8e, 0x6f, 0xe0, 0x9b, 0xf8, \ + 0x10, 0x56, 0xcc, 0xb3, 0x8e, 0x13, 0x15, 0xe6, 0x34, 0x04, 0x66, 0xc7, \ + 0xee, 0xf9, 0x36, 0x0e, 0x6a, 0x95, 0xf6, 0x09, 0x9a, 0x06, 0x67, 0xf4, \ + 0x65, 0x71, 0xf8, 0xca, 0xa4, 0xb1, 0x25, 0xe0, 0xfe, 0x3c, 0x8b, 0x35, \ + 0x04, 0x67, 0xba, 0xe0, 0x4f, 0x76, 0x85, 0xfc, 0x7f, 0xfc, 0x36, 0x6b, \ + 0xb5, 0xe9, 0xcd, 0x2d, 0x03, 0x62, 0x4e, 0xb3, 0x3d, 0x00, 0xcf, 0xaf, \ + 0x76, 0xa0, 0x69, 0x56, 0x83, 0x6a, 0xd2, 0xa8, 0xd4, 0xe7, 0x50, 0x71, \ + 0xe6, 0xb5, 0x36, 0x05, 0x77, 0x05, 0x6d, 0x7b, 0xc8, 0xe4, 0xc4, 0xfd, \ + 0x4c, 0xd5, 0x21, 0x5f, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01, \ + 0x00, 0x67, 0x4d, 0xb5, 0xf6, 0x03, 0x89, 0xaa, 0x7a, 0x6f, 0x3b, 0x2d, \ + 0xca, 0x10, 0xa2, 0x23, 0xc9, 0xbd, 0x4e, 0xda, 0xe1, 0x67, 0x0e, 0x0c, \ + 0x8a, 0xc6, 0x84, 0x68, 0xdf, 0xe5, 0x97, 0x75, 0xd2, 0x8d, 0xa3, 0x86, \ + 0xd9, 0xdb, 0xd5, 0xeb, 0x13, 0x19, 0x08, 0xc5, 0x7e, 0xe5, 0x37, 0x97, \ + 0x0c, 0x73, 0x80, 0x66, 0x76, 0x35, 0xf1, 0x88, 0xb5, 0xf2, 0xfc, 0xf3, \ + 0xe1, 0x4b, 0x76, 0x4e, 0x73, 0x45, 0xce, 0x2c, 0xc2, 0x10, 0x26, 0x0d, \ + 0x68, 0x0d, 0x9f, 0x49, 0x3d, 0xd6, 0x80, 0x89, 0xe7, 0xc5, 0x49, 0x15, \ + 0xdd, 0x85, 0xc0, 0xc8, 0xfe, 0x82, 0x37, 0x12, 0x5a, 0x0a, 0x6b, 0xf6, \ + 0x68, 0x0d, 0x32, 0x16, 0xbd, 0xa4, 0x15, 0x54, 0x9e, 0x68, 0xa1, 0xad, \ + 0xca, 0x6b, 0xe5, 0x8c, 0xda, 0x76, 0x35, 0x59, 0x2f, 0x9b, 0xb4, 0xe1, \ + 0xf1, 0xf0, 0x50, 0x04, 0xee, 0xc8, 0xec, 0x05, 0xe1, 0xcf, 0x8d, 0xe4, \ + 0xd2, 0x64, 0x7b, 0x5e, 0x63, 0xe0, 0x7b, 0x07, 0xbc, 0x02, 0x96, 0x4e, \ + 0x1b, 0x78, 0x6c, 0xb6, 0x43, 0x9a, 0x32, 0xf6, 0xd6, 0x02, 0xf5, 0x80, \ + 0xcc, 0x26, 0x6e, 0xa5, 0xd0, 0xe3, 0x65, 0x88, 0xce, 0x26, 0xa9, 0x40, \ + 0xe1, 0xe1, 0x00, 0xe0, 0x7f, 0x3f, 0xc3, 0xb1, 0x7c, 0xde, 0xbe, 0x42, \ + 0xba, 0x07, 0x81, 0x13, 0xc2, 0xe0, 0x11, 0x11, 0x23, 0x2c, 0xf8, 0xb2, \ + 0x7a, 0x3a, 0xd4, 0xe4, 0x7d, 0x5f, 0xb9, 0xb1, 0x18, 0xfa, 0x1d, 0x1d, \ + 0x97, 0x91, 0xd9, 0x04, 0x9e, 0xbc, 0xc9, 0xb4, 0xd7, 0x7d, 0x0e, 0x54, \ + 0xf6, 0x8f, 0xd0, 0x28, 0x0d, 0xdd, 0x77, 0x4b, 0x68, 0x04, 0x48, 0x61, \ + 0x75, 0x15, 0x03, 0x1b, 0x35, 0xad, 0x8e, 0xfc, 0x24, 0x11, 0x07, 0xea, \ + 0x17, 0x5a, 0xde, 0x19, 0x68, 0xff, 0xb6, 0x87, 0x7f, 0x80, 0x2a, 0x5f, \ + 0x0c, 0x58, 0xba, 0x5f, 0x41, 0x02, 0x81, 0x81, 0x00, 0xe3, 0x03, 0xaf, \ + 0xfe, 0x98, 0xd2, 0x0b, 0x7b, 0x72, 0xe9, 0x3b, 0x8e, 0xbc, 0xa5, 0xf6, \ + 0xac, 0xe5, 0x22, 0x06, 0xb2, 0xd7, 0x5e, 0xfd, 0x89, 0x4b, 0x16, 0x67, \ + 0x32, 0x83, 0x22, 0x58, 0x8e, 0x62, 0xa4, 0xb4, 0x2d, 0xf9, 0x16, 0x13, \ + 0x54, 0xf6, 0x9f, 0x2f, 0xf9, 0xbb, 0x0e, 0x7e, 0x8c, 0x6f, 0x08, 0xda, \ + 0xc8, 0xe9, 0x1c, 0x66, 0x10, 0x70, 0x93, 0x90, 0x8d, 0xcf, 0x90, 0x3a, \ + 0x43, 0x89, 0x49, 0xeb, 0x83, 0x2a, 0xfe, 0x5a, 0x87, 0xce, 0x74, 0x42, \ + 0x41, 0x0d, 0x8c, 0x73, 0x51, 0xbc, 0x7b, 0x20, 0xc5, 0xfd, 0xf6, 0x0b, \ + 0x65, 0xed, 0xa9, 0x2e, 0xfc, 0x0f, 0xf5, 0x50, 0xf9, 0x8d, 0x37, 0x36, \ + 0x9a, 0x20, 0xdf, 0xc3, 0xe3, 0x27, 0xbc, 0x98, 0x72, 0xc1, 0x14, 0x4b, \ + 0x71, 0xe9, 0x83, 0x14, 0xff, 0x24, 0xe2, 0x14, 0x15, 0xb6, 0x6f, 0x0f, \ + 0x32, 0x9d, 0xd9, 0x98, 0xd1, 0x02, 0x81, 0x81, 0x00, 0xe2, 0x0c, 0xfb, \ + 0xc3, 0x33, 0x9b, 0x47, 0x88, 0x27, 0xf2, 0x26, 0xde, 0xeb, 0x5e, 0xee, \ + 0x40, 0xf6, 0x63, 0x5b, 0x35, 0x23, 0xf5, 0xd5, 0x07, 0x61, 0xdf, 0xa2, \ + 0x9f, 0x58, 0x30, 0x04, 0x22, 0x2b, 0xb4, 0xd9, 0xda, 0x46, 0x7f, 0x48, \ + 0xf5, 0x4f, 0xd0, 0xea, 0xd7, 0xa0, 0x45, 0x8a, 0x62, 0x8b, 0x8c, 0xac, \ + 0x73, 0x5e, 0xfa, 0x36, 0x65, 0x3e, 0xba, 0x6c, 0xba, 0x5e, 0x6b, 0x92, \ + 0x29, 0x5e, 0x6a, 0x0f, 0xd6, 0xd2, 0xa5, 0x95, 0x86, 0xda, 0x72, 0xc5, \ + 0x9e, 0xc9, 0x6b, 0x37, 0x5e, 0x4b, 0x9b, 0x77, 0xe1, 0x67, 0x1a, 0x1e, \ + 0x30, 0xd8, 0x41, 0x68, 0x40, 0xd3, 0x9c, 0xb4, 0xf6, 0xeb, 0x2a, 0x22, \ + 0xdf, 0x78, 0x29, 0xd2, 0x64, 0x92, 0x5b, 0x2f, 0x78, 0x64, 0x4a, 0xa2, \ + 0xa6, 0x6b, 0x3e, 0x50, 0xb1, 0x7a, 0xb1, 0x8d, 0x59, 0xb4, 0x55, 0xba, \ + 0xb6, 0x91, 0x85, 0xa3, 0x2f, 0x02, 0x81, 0x80, 0x10, 0x1e, 0x19, 0xe7, \ + 0xbc, 0x97, 0xe5, 0x22, 0xcd, 0xa4, 0xcb, 0x8a, 0xb5, 0xd0, 0x1e, 0xb4, \ + 0x65, 0xcc, 0x45, 0xa7, 0x7a, 0xed, 0x0e, 0x99, 0x29, 0xd0, 0x9c, 0x61, \ + 0x14, 0xb8, 0x62, 0x8b, 0x31, 0x6b, 0xba, 0x33, 0x2d, 0x65, 0x28, 0xd8, \ + 0x36, 0x6e, 0x54, 0xec, 0xa9, 0x20, 0x3d, 0x51, 0xe1, 0x2c, 0x42, 0xc4, \ + 0x52, 0xf0, 0xa6, 0x3a, 0x72, 0x93, 0xb7, 0x86, 0xa9, 0xfe, 0xf6, 0x74, \ + 0x07, 0x12, 0x4d, 0x7b, 0x51, 0x99, 0x1f, 0x7a, 0x56, 0xe9, 0x20, 0x2f, \ + 0x18, 0x34, 0x29, 0x97, 0xdb, 0x06, 0xee, 0xeb, 0xbf, 0xbd, 0x31, 0x4f, \ + 0xfa, 0x50, 0xb1, 0xba, 0x49, 0xb3, 0xc4, 0x1d, 0x03, 0xae, 0xb0, 0xdc, \ + 0xbe, 0x8a, 0xc4, 0x90, 0xa3, 0x28, 0x9b, 0xb6, 0x42, 0x09, 0x1b, 0xd6, \ + 0x29, 0x9b, 0x19, 0xe9, 0x87, 0x87, 0xd9, 0x9f, 0x35, 0x05, 0xab, 0x91, \ + 0x8f, 0x6d, 0x7c, 0x91, 0x02, 0x81, 0x81, 0x00, 0x94, 0x57, 0xf0, 0xe0, \ + 0x28, 0xfd, 0xbd, 0xf3, 0x9c, 0x43, 0x4d, 0x3e, 0xfd, 0x37, 0x4f, 0x23, \ + 0x52, 0x8d, 0xe1, 0x4c, 0xfe, 0x4c, 0x55, 0x80, 0x82, 0xba, 0x3f, 0xfe, \ + 0x51, 0xe1, 0x30, 0xd5, 0x3b, 0xd9, 0x73, 0x1d, 0xcb, 0x25, 0xbc, 0xbb, \ + 0x3f, 0xa5, 0xda, 0x77, 0xa6, 0xb5, 0xfc, 0x1a, 0xaf, 0x79, 0xa1, 0xb2, \ + 0x14, 0xa2, 0x1f, 0x10, 0x52, 0x1a, 0x05, 0x40, 0x48, 0xb6, 0x4f, 0x34, \ + 0xd6, 0xc0, 0xc3, 0xa4, 0x36, 0x98, 0x73, 0x88, 0x0b, 0xd3, 0x45, 0xdc, \ + 0xee, 0x51, 0x6e, 0x04, 0x73, 0x99, 0x93, 0x12, 0x58, 0x96, 0xcb, 0x39, \ + 0x42, 0xb1, 0xa9, 0xb8, 0xe1, 0x25, 0xf5, 0x9c, 0x14, 0xb7, 0x92, 0x2b, \ + 0x14, 0xb0, 0x5d, 0x61, 0xa2, 0xaa, 0x34, 0x7c, 0xcd, 0x54, 0x2d, 0x69, \ + 0x08, 0xf7, 0xdb, 0xfc, 0x9c, 0x87, 0xe8, 0x3a, 0xf6, 0x1d, 0x4c, 0x6a, \ + 0x83, 0x15, 0x30, 0x01, 0x02, 0x81, 0x81, 0x00, 0x9c, 0x53, 0xa1, 0xb6, \ + 0x2f, 0xc0, 0x06, 0xf5, 0xdf, 0x5c, 0xd1, 0x4a, 0x4e, 0xc8, 0xbd, 0x6d, \ + 0x32, 0xf1, 0x5e, 0xe5, 0x3b, 0x70, 0xd0, 0xa8, 0xe5, 0x41, 0x57, 0x6c, \ + 0x87, 0x53, 0x0f, 0xeb, 0x28, 0xa0, 0x62, 0x8f, 0x43, 0x62, 0xec, 0x2e, \ + 0x6c, 0x71, 0x55, 0x5b, 0x6a, 0xf4, 0x74, 0x14, 0xea, 0x7a, 0x03, 0xf6, \ + 0xfc, 0xa4, 0xce, 0xc4, 0xac, 0xda, 0x1d, 0xf0, 0xb5, 0xa9, 0xfd, 0x11, \ + 0x18, 0x3b, 0x14, 0xa0, 0x90, 0x8d, 0x26, 0xb7, 0x75, 0x73, 0x0a, 0x02, \ + 0x2c, 0x6f, 0x0f, 0xd8, 0x41, 0x78, 0xc3, 0x73, 0x81, 0xac, 0xaa, 0xaf, \ + 0xf2, 0xee, 0x32, 0xb5, 0x8d, 0x05, 0xf9, 0x59, 0x5a, 0x9e, 0x3e, 0x65, \ + 0x9b, 0x74, 0xda, 0xa0, 0x74, 0x95, 0x17, 0x5f, 0x8d, 0x58, 0xfc, 0x8e, \ + 0x4e, 0x2c, 0x1e, 0xbc, 0x81, 0x02, 0x18, 0xac, 0x12, 0xc6, 0xf9, 0x64, \ + 0x8b, 0x87, 0xc3, 0x00 \ +} +/* END FILE */ + +/* + * + * Test certificates and keys as C variables + * + */ + +/* + * CA + */ + +const char mbedtls_test_ca_crt_ec_pem[] = TEST_CA_CRT_EC_PEM; +const char mbedtls_test_ca_key_ec_pem[] = TEST_CA_KEY_EC_PEM; +const char mbedtls_test_ca_pwd_ec_pem[] = TEST_CA_PWD_EC_PEM; +const char mbedtls_test_ca_key_rsa_pem[] = TEST_CA_KEY_RSA_PEM; +const char mbedtls_test_ca_pwd_rsa_pem[] = TEST_CA_PWD_RSA_PEM; +const char mbedtls_test_ca_crt_rsa_sha1_pem[] = TEST_CA_CRT_RSA_SHA1_PEM; +const char mbedtls_test_ca_crt_rsa_sha256_pem[] = TEST_CA_CRT_RSA_SHA256_PEM; + +const unsigned char mbedtls_test_ca_crt_ec_der[] = TEST_CA_CRT_EC_DER; +const unsigned char mbedtls_test_ca_key_ec_der[] = TEST_CA_KEY_EC_DER; +const unsigned char mbedtls_test_ca_key_rsa_der[] = TEST_CA_KEY_RSA_DER; +const unsigned char mbedtls_test_ca_crt_rsa_sha1_der[] = + TEST_CA_CRT_RSA_SHA1_DER; +const unsigned char mbedtls_test_ca_crt_rsa_sha256_der[] = + TEST_CA_CRT_RSA_SHA256_DER; + +const size_t mbedtls_test_ca_crt_ec_pem_len = + sizeof( mbedtls_test_ca_crt_ec_pem ); +const size_t mbedtls_test_ca_key_ec_pem_len = + sizeof( mbedtls_test_ca_key_ec_pem ); +const size_t mbedtls_test_ca_pwd_ec_pem_len = + sizeof( mbedtls_test_ca_pwd_ec_pem ) - 1; +const size_t mbedtls_test_ca_key_rsa_pem_len = + sizeof( mbedtls_test_ca_key_rsa_pem ); +const size_t mbedtls_test_ca_pwd_rsa_pem_len = + sizeof( mbedtls_test_ca_pwd_rsa_pem ) - 1; +const size_t mbedtls_test_ca_crt_rsa_sha1_pem_len = + sizeof( mbedtls_test_ca_crt_rsa_sha1_pem ); +const size_t mbedtls_test_ca_crt_rsa_sha256_pem_len = + sizeof( mbedtls_test_ca_crt_rsa_sha256_pem ); + +const size_t mbedtls_test_ca_crt_ec_der_len = + sizeof( mbedtls_test_ca_crt_ec_der ); +const size_t mbedtls_test_ca_key_ec_der_len = + sizeof( mbedtls_test_ca_key_ec_der ); +const size_t mbedtls_test_ca_pwd_ec_der_len = 0; +const size_t mbedtls_test_ca_key_rsa_der_len = + sizeof( mbedtls_test_ca_key_rsa_der ); +const size_t mbedtls_test_ca_pwd_rsa_der_len = 0; +const size_t mbedtls_test_ca_crt_rsa_sha1_der_len = + sizeof( mbedtls_test_ca_crt_rsa_sha1_der ); +const size_t mbedtls_test_ca_crt_rsa_sha256_der_len = + sizeof( mbedtls_test_ca_crt_rsa_sha256_der ); + +/* + * Server + */ + +const char mbedtls_test_srv_crt_ec_pem[] = TEST_SRV_CRT_EC_PEM; +const char mbedtls_test_srv_key_ec_pem[] = TEST_SRV_KEY_EC_PEM; +const char mbedtls_test_srv_pwd_ec_pem[] = ""; +const char mbedtls_test_srv_key_rsa_pem[] = TEST_SRV_KEY_RSA_PEM; +const char mbedtls_test_srv_pwd_rsa_pem[] = ""; +const char mbedtls_test_srv_crt_rsa_sha1_pem[] = TEST_SRV_CRT_RSA_SHA1_PEM; +const char mbedtls_test_srv_crt_rsa_sha256_pem[] = TEST_SRV_CRT_RSA_SHA256_PEM; + +const unsigned char mbedtls_test_srv_crt_ec_der[] = TEST_SRV_CRT_EC_DER; +const unsigned char mbedtls_test_srv_key_ec_der[] = TEST_SRV_KEY_EC_DER; +const unsigned char mbedtls_test_srv_key_rsa_der[] = TEST_SRV_KEY_RSA_DER; +const unsigned char mbedtls_test_srv_crt_rsa_sha1_der[] = + TEST_SRV_CRT_RSA_SHA1_DER; +const unsigned char mbedtls_test_srv_crt_rsa_sha256_der[] = + TEST_SRV_CRT_RSA_SHA256_DER; + +const size_t mbedtls_test_srv_crt_ec_pem_len = + sizeof( mbedtls_test_srv_crt_ec_pem ); +const size_t mbedtls_test_srv_key_ec_pem_len = + sizeof( mbedtls_test_srv_key_ec_pem ); +const size_t mbedtls_test_srv_pwd_ec_pem_len = + sizeof( mbedtls_test_srv_pwd_ec_pem ) - 1; +const size_t mbedtls_test_srv_key_rsa_pem_len = + sizeof( mbedtls_test_srv_key_rsa_pem ); +const size_t mbedtls_test_srv_pwd_rsa_pem_len = + sizeof( mbedtls_test_srv_pwd_rsa_pem ) - 1; +const size_t mbedtls_test_srv_crt_rsa_sha1_pem_len = + sizeof( mbedtls_test_srv_crt_rsa_sha1_pem ); +const size_t mbedtls_test_srv_crt_rsa_sha256_pem_len = + sizeof( mbedtls_test_srv_crt_rsa_sha256_pem ); + +const size_t mbedtls_test_srv_crt_ec_der_len = + sizeof( mbedtls_test_srv_crt_ec_der ); +const size_t mbedtls_test_srv_key_ec_der_len = + sizeof( mbedtls_test_srv_key_ec_der ); +const size_t mbedtls_test_srv_pwd_ec_der_len = 0; +const size_t mbedtls_test_srv_key_rsa_der_len = + sizeof( mbedtls_test_srv_key_rsa_der ); +const size_t mbedtls_test_srv_pwd_rsa_der_len = 0; +const size_t mbedtls_test_srv_crt_rsa_sha1_der_len = + sizeof( mbedtls_test_srv_crt_rsa_sha1_der ); +const size_t mbedtls_test_srv_crt_rsa_sha256_der_len = + sizeof( mbedtls_test_srv_crt_rsa_sha256_der ); + +/* + * Client + */ + +const char mbedtls_test_cli_crt_ec_pem[] = TEST_CLI_CRT_EC_PEM; +const char mbedtls_test_cli_key_ec_pem[] = TEST_CLI_KEY_EC_PEM; +const char mbedtls_test_cli_pwd_ec_pem[] = ""; +const char mbedtls_test_cli_key_rsa_pem[] = TEST_CLI_KEY_RSA_PEM; +const char mbedtls_test_cli_pwd_rsa_pem[] = ""; +const char mbedtls_test_cli_crt_rsa_pem[] = TEST_CLI_CRT_RSA_PEM; + +const unsigned char mbedtls_test_cli_crt_ec_der[] = TEST_CLI_CRT_EC_DER; +const unsigned char mbedtls_test_cli_key_ec_der[] = TEST_CLI_KEY_EC_DER; +const unsigned char mbedtls_test_cli_key_rsa_der[] = TEST_CLI_KEY_RSA_DER; +const unsigned char mbedtls_test_cli_crt_rsa_der[] = TEST_CLI_CRT_RSA_DER; + +const size_t mbedtls_test_cli_crt_ec_pem_len = + sizeof( mbedtls_test_cli_crt_ec_pem ); +const size_t mbedtls_test_cli_key_ec_pem_len = + sizeof( mbedtls_test_cli_key_ec_pem ); +const size_t mbedtls_test_cli_pwd_ec_pem_len = + sizeof( mbedtls_test_cli_pwd_ec_pem ) - 1; +const size_t mbedtls_test_cli_key_rsa_pem_len = + sizeof( mbedtls_test_cli_key_rsa_pem ); +const size_t mbedtls_test_cli_pwd_rsa_pem_len = + sizeof( mbedtls_test_cli_pwd_rsa_pem ) - 1; +const size_t mbedtls_test_cli_crt_rsa_pem_len = + sizeof( mbedtls_test_cli_crt_rsa_pem ); + +const size_t mbedtls_test_cli_crt_ec_der_len = + sizeof( mbedtls_test_cli_crt_ec_der ); +const size_t mbedtls_test_cli_key_ec_der_len = + sizeof( mbedtls_test_cli_key_ec_der ); +const size_t mbedtls_test_cli_key_rsa_der_len = + sizeof( mbedtls_test_cli_key_rsa_der ); +const size_t mbedtls_test_cli_crt_rsa_der_len = + sizeof( mbedtls_test_cli_crt_rsa_der ); + +/* + * + * Definitions of test CRTs without specification of all parameters, choosing + * them automatically according to the config. For example, mbedtls_test_ca_crt + * is one of mbedtls_test_ca_crt_{rsa|ec}_{sha1|sha256}_{pem|der}. + * + */ + +/* + * Dispatch between PEM and DER according to config + */ + +#if defined(MBEDTLS_PEM_PARSE_C) + +/* PEM encoded test CA certificates and keys */ + +#define TEST_CA_KEY_RSA TEST_CA_KEY_RSA_PEM +#define TEST_CA_PWD_RSA TEST_CA_PWD_RSA_PEM +#define TEST_CA_CRT_RSA_SHA256 TEST_CA_CRT_RSA_SHA256_PEM +#define TEST_CA_CRT_RSA_SHA1 TEST_CA_CRT_RSA_SHA1_PEM +#define TEST_CA_KEY_EC TEST_CA_KEY_EC_PEM +#define TEST_CA_PWD_EC TEST_CA_PWD_EC_PEM +#define TEST_CA_CRT_EC TEST_CA_CRT_EC_PEM + +/* PEM encoded test server certificates and keys */ + +#define TEST_SRV_KEY_RSA TEST_SRV_KEY_RSA_PEM +#define TEST_SRV_PWD_RSA "" +#define TEST_SRV_CRT_RSA_SHA256 TEST_SRV_CRT_RSA_SHA256_PEM +#define TEST_SRV_CRT_RSA_SHA1 TEST_SRV_CRT_RSA_SHA1_PEM +#define TEST_SRV_KEY_EC TEST_SRV_KEY_EC_PEM +#define TEST_SRV_PWD_EC "" +#define TEST_SRV_CRT_EC TEST_SRV_CRT_EC_PEM + +/* PEM encoded test client certificates and keys */ + +#define TEST_CLI_KEY_RSA TEST_CLI_KEY_RSA_PEM +#define TEST_CLI_PWD_RSA "" +#define TEST_CLI_CRT_RSA TEST_CLI_CRT_RSA_PEM +#define TEST_CLI_KEY_EC TEST_CLI_KEY_EC_PEM +#define TEST_CLI_PWD_EC "" +#define TEST_CLI_CRT_EC TEST_CLI_CRT_EC_PEM + +#else /* MBEDTLS_PEM_PARSE_C */ + +/* DER encoded test CA certificates and keys */ + +#define TEST_CA_KEY_RSA TEST_CA_KEY_RSA_DER +#define TEST_CA_PWD_RSA "" +#define TEST_CA_CRT_RSA_SHA256 TEST_CA_CRT_RSA_SHA256_DER +#define TEST_CA_CRT_RSA_SHA1 TEST_CA_CRT_RSA_SHA1_DER +#define TEST_CA_KEY_EC TEST_CA_KEY_EC_DER +#define TEST_CA_PWD_EC "" +#define TEST_CA_CRT_EC TEST_CA_CRT_EC_DER + +/* DER encoded test server certificates and keys */ + +#define TEST_SRV_KEY_RSA TEST_SRV_KEY_RSA_DER +#define TEST_SRV_PWD_RSA "" +#define TEST_SRV_CRT_RSA_SHA256 TEST_SRV_CRT_RSA_SHA256_DER +#define TEST_SRV_CRT_RSA_SHA1 TEST_SRV_CRT_RSA_SHA1_DER +#define TEST_SRV_KEY_EC TEST_SRV_KEY_EC_DER +#define TEST_SRV_PWD_EC "" +#define TEST_SRV_CRT_EC TEST_SRV_CRT_EC_DER + +/* DER encoded test client certificates and keys */ + +#define TEST_CLI_KEY_RSA TEST_CLI_KEY_RSA_DER +#define TEST_CLI_PWD_RSA "" +#define TEST_CLI_CRT_RSA TEST_CLI_CRT_RSA_DER +#define TEST_CLI_KEY_EC TEST_CLI_KEY_EC_DER +#define TEST_CLI_PWD_EC "" +#define TEST_CLI_CRT_EC TEST_CLI_CRT_EC_DER + +#endif /* MBEDTLS_PEM_PARSE_C */ + +const char mbedtls_test_ca_key_rsa[] = TEST_CA_KEY_RSA; +const char mbedtls_test_ca_pwd_rsa[] = TEST_CA_PWD_RSA; +const char mbedtls_test_ca_crt_rsa_sha256[] = TEST_CA_CRT_RSA_SHA256; +const char mbedtls_test_ca_crt_rsa_sha1[] = TEST_CA_CRT_RSA_SHA1; +const char mbedtls_test_ca_key_ec[] = TEST_CA_KEY_EC; +const char mbedtls_test_ca_pwd_ec[] = TEST_CA_PWD_EC; +const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC; + +const char mbedtls_test_srv_key_rsa[] = TEST_SRV_KEY_RSA; +const char mbedtls_test_srv_pwd_rsa[] = TEST_SRV_PWD_RSA; +const char mbedtls_test_srv_crt_rsa_sha256[] = TEST_SRV_CRT_RSA_SHA256; +const char mbedtls_test_srv_crt_rsa_sha1[] = TEST_SRV_CRT_RSA_SHA1; +const char mbedtls_test_srv_key_ec[] = TEST_SRV_KEY_EC; +const char mbedtls_test_srv_pwd_ec[] = TEST_SRV_PWD_EC; +const char mbedtls_test_srv_crt_ec[] = TEST_SRV_CRT_EC; + +const char mbedtls_test_cli_key_rsa[] = TEST_CLI_KEY_RSA; +const char mbedtls_test_cli_pwd_rsa[] = TEST_CLI_PWD_RSA; +const char mbedtls_test_cli_crt_rsa[] = TEST_CLI_CRT_RSA; +const char mbedtls_test_cli_key_ec[] = TEST_CLI_KEY_EC; +const char mbedtls_test_cli_pwd_ec[] = TEST_CLI_PWD_EC; +const char mbedtls_test_cli_crt_ec[] = TEST_CLI_CRT_EC; + +const size_t mbedtls_test_ca_key_rsa_len = + sizeof( mbedtls_test_ca_key_rsa ); +const size_t mbedtls_test_ca_pwd_rsa_len = + sizeof( mbedtls_test_ca_pwd_rsa ) - 1; +const size_t mbedtls_test_ca_crt_rsa_sha256_len = + sizeof( mbedtls_test_ca_crt_rsa_sha256 ); +const size_t mbedtls_test_ca_crt_rsa_sha1_len = + sizeof( mbedtls_test_ca_crt_rsa_sha1 ); +const size_t mbedtls_test_ca_key_ec_len = + sizeof( mbedtls_test_ca_key_ec ); +const size_t mbedtls_test_ca_pwd_ec_len = + sizeof( mbedtls_test_ca_pwd_ec ) - 1; +const size_t mbedtls_test_ca_crt_ec_len = + sizeof( mbedtls_test_ca_crt_ec ); + +const size_t mbedtls_test_srv_key_rsa_len = + sizeof( mbedtls_test_srv_key_rsa ); +const size_t mbedtls_test_srv_pwd_rsa_len = + sizeof( mbedtls_test_srv_pwd_rsa ) -1; +const size_t mbedtls_test_srv_crt_rsa_sha256_len = + sizeof( mbedtls_test_srv_crt_rsa_sha256 ); +const size_t mbedtls_test_srv_crt_rsa_sha1_len = + sizeof( mbedtls_test_srv_crt_rsa_sha1 ); +const size_t mbedtls_test_srv_key_ec_len = + sizeof( mbedtls_test_srv_key_ec ); +const size_t mbedtls_test_srv_pwd_ec_len = + sizeof( mbedtls_test_srv_pwd_ec ) - 1; +const size_t mbedtls_test_srv_crt_ec_len = + sizeof( mbedtls_test_srv_crt_ec ); + +const size_t mbedtls_test_cli_key_rsa_len = + sizeof( mbedtls_test_cli_key_rsa ); +const size_t mbedtls_test_cli_pwd_rsa_len = + sizeof( mbedtls_test_cli_pwd_rsa ) - 1; +const size_t mbedtls_test_cli_crt_rsa_len = + sizeof( mbedtls_test_cli_crt_rsa ); +const size_t mbedtls_test_cli_key_ec_len = + sizeof( mbedtls_test_cli_key_ec ); +const size_t mbedtls_test_cli_pwd_ec_len = + sizeof( mbedtls_test_cli_pwd_ec ) - 1; +const size_t mbedtls_test_cli_crt_ec_len = + sizeof( mbedtls_test_cli_crt_ec ); + +/* + * Dispatch between SHA-1 and SHA-256 + */ #if defined(MBEDTLS_SHA256_C) -#define TEST_CA_CRT_RSA_SHA256 \ -"-----BEGIN CERTIFICATE-----\r\n" \ -"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" \ -"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ -"MTcwNTA0MTY1NzAxWhcNMjcwNTA1MTY1NzAxWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ -"A1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ -"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ -"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ -"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ -"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ -"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ -"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ -"gZUwgZIwHQYDVR0OBBYEFLRa5KWz3tJS9rnVppUP6z68x/3/MGMGA1UdIwRcMFqA\r\n" \ -"FLRa5KWz3tJS9rnVppUP6z68x/3/oT+kPTA7MQswCQYDVQQGEwJOTDERMA8GA1UE\r\n" \ -"CgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0GCAQAwDAYDVR0T\r\n" \ -"BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAHK/HHrTZMnnVMpde1io+voAtql7j\r\n" \ -"4sRhLrjD7o3THtwRbDa2diCvpq0Sq23Ng2LMYoXsOxoL/RQK3iN7UKxV3MKPEr0w\r\n" \ -"XQS+kKQqiT2bsfrjnWMVHZtUOMpm6FNqcdGm/Rss3vKda2lcKl8kUnq/ylc1+QbB\r\n" \ -"G6A6tUvQcr2ZyWfVg+mM5XkhTrOOXus2OLikb4WwEtJTJRNE0f+yPODSUz0/vT57\r\n" \ -"ApH0CnB80bYJshYHPHHymOtleAB8KSYtqm75g/YNobjnjB6cm4HkW3OZRVIl6fYY\r\n" \ -"n20NRVA1Vjs6GAROr4NqW4k/+LofY9y0LLDE+p0oIEKXIsIvhPr39swxSA==\r\n" \ -"-----END CERTIFICATE-----\r\n" - -const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA_SHA256; -const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); -#define TEST_CA_CRT_RSA_SOME - -static const char mbedtls_test_ca_crt_rsa_sha256[] = TEST_CA_CRT_RSA_SHA256; +#define TEST_CA_CRT_RSA TEST_CA_CRT_RSA_SHA256 +#define TEST_SRV_CRT_RSA TEST_SRV_CRT_RSA_SHA256 +#else +#define TEST_CA_CRT_RSA TEST_CA_CRT_RSA_SHA1 +#define TEST_SRV_CRT_RSA TEST_SRV_CRT_RSA_SHA1 +#endif /* MBEDTLS_SHA256_C */ -#endif +const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA; +const char mbedtls_test_srv_crt_rsa[] = TEST_SRV_CRT_RSA; -#if !defined(TEST_CA_CRT_RSA_SOME) || defined(MBEDTLS_SHA1_C) -#define TEST_CA_CRT_RSA_SHA1 \ -"-----BEGIN CERTIFICATE-----\r\n" \ -"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ -"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ -"MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ -"A1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ -"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ -"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ -"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ -"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ -"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ -"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ -"gZUwgZIwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUtFrkpbPe0lL2udWmlQ/rPrzH\r\n" \ -"/f8wYwYDVR0jBFwwWoAUtFrkpbPe0lL2udWmlQ/rPrzH/f+hP6Q9MDsxCzAJBgNV\r\n" \ -"BAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEZMBcGA1UEAxMQUG9sYXJTU0wgVGVz\r\n" \ -"dCBDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAuP1U2ABUkIslsCfdlc2i94QHHYeJ\r\n" \ -"SsR4EdgHtdciUI5I62J6Mom+Y0dT/7a+8S6MVMCZP6C5NyNyXw1GWY/YR82XTJ8H\r\n" \ -"DBJiCTok5DbZ6SzaONBzdWHXwWwmi5vg1dxn7YxrM9d0IjxM27WNKs4sDQhZBQkF\r\n" \ -"pjmfs2cb4oPl4Y9T9meTx/lvdkRYEug61Jfn6cA+qHpyPYdTH+UshITnmp5/Ztkf\r\n" \ -"m/UTSLBNFNHesiTZeH31NcxYGdHSme9Nc/gfidRa0FLOCfWxRlFqAI47zG9jAQCZ\r\n" \ -"7Z2mCGDNMhjQc+BYcdnl0lPXjdDK6V0qCg1dVewhUBcW5gZKzV7e9+DpVA==\r\n" \ -"-----END CERTIFICATE-----\r\n" - -#if !defined (TEST_CA_CRT_RSA_SOME) -const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA_SHA1; -const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); -#endif +const size_t mbedtls_test_ca_crt_rsa_len = + sizeof( mbedtls_test_ca_crt_rsa ); +const size_t mbedtls_test_srv_crt_rsa_len = + sizeof( mbedtls_test_srv_crt_rsa ); -static const char mbedtls_test_ca_crt_rsa_sha1[] = TEST_CA_CRT_RSA_SHA1; +/* + * Dispatch between RSA and EC + */ -#endif +#if defined(MBEDTLS_RSA_C) + +#define TEST_CA_KEY TEST_CA_KEY_RSA +#define TEST_CA_PWD TEST_CA_PWD_RSA +#define TEST_CA_CRT TEST_CA_CRT_RSA + +#define TEST_SRV_KEY TEST_SRV_KEY_RSA +#define TEST_SRV_PWD TEST_SRV_PWD_RSA +#define TEST_SRV_CRT TEST_SRV_CRT_RSA + +#define TEST_CLI_KEY TEST_CLI_KEY_RSA +#define TEST_CLI_PWD TEST_CLI_PWD_RSA +#define TEST_CLI_CRT TEST_CLI_CRT_RSA + +#else /* no RSA, so assume ECDSA */ + +#define TEST_CA_KEY TEST_CA_KEY_EC +#define TEST_CA_PWD TEST_CA_PWD_EC +#define TEST_CA_CRT TEST_CA_CRT_EC + +#define TEST_SRV_KEY TEST_SRV_KEY_EC +#define TEST_SRV_PWD TEST_SRV_PWD_EC +#define TEST_SRV_CRT TEST_SRV_CRT_EC + +#define TEST_CLI_KEY TEST_CLI_KEY_EC +#define TEST_CLI_PWD TEST_CLI_PWD_EC +#define TEST_CLI_CRT TEST_CLI_CRT_EC -const char mbedtls_test_ca_key_rsa[] = -"-----BEGIN RSA PRIVATE KEY-----\r\n" -"Proc-Type: 4,ENCRYPTED\r\n" -"DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n" -"\r\n" -"9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n" -"7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n" -"Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n" -"PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n" -"GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n" -"gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n" -"QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n" -"PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n" -"vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n" -"WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n" -"JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n" -"KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n" -"Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n" -"9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n" -"iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n" -"tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n" -"P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n" -"1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n" -"nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n" -"X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n" -"rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n" -"L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n" -"I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n" -"wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n" -"P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n" -"-----END RSA PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_ca_key_rsa_len = sizeof( mbedtls_test_ca_key_rsa ); - -const char mbedtls_test_ca_pwd_rsa[] = "PolarSSLTest"; -const size_t mbedtls_test_ca_pwd_rsa_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1; - -/* tests/data_files/server2.crt */ -const char mbedtls_test_srv_crt_rsa[] = -"-----BEGIN CERTIFICATE-----\r\n" -"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" -"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" -"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UECgwIUG9sYXJTU0wxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" -"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" -"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" -"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" -"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" -"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" -"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" -"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" -"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAAFzC0rF\r\n" -"y6De8WMcdgQrEw3AhBHFjzqnxZw1ene4IBSC7lTw8rBSy3jOWQdPUWn+0y/pCeeF\r\n" -"kti6sevFdl1hLemGtd4q+T9TKEKGg3ND4ARfB5AUZZ9uEHq8WBkiwus5clGS17Qd\r\n" -"dS/TOisB59tQruLx1E1bPLtBKyqk4koC5WAULJwfpswGSyWJTpYwIpxcWE3D2tBu\r\n" -"UB6MZfXZFzWmWEOyKbeoXjXe8GBCGgHLywvYDsGQ36HSGtEsAvR2QaTLSxWYcfk1\r\n" -"fbDn4jSWkb4yZy1r01UEigFQtONieGwRFaUqEcFJHJvEEGVgh9keaVlOj2vrwf5r\r\n" -"4mN4lW7gLdenN6g=\r\n" -"-----END CERTIFICATE-----\r\n"; -const size_t mbedtls_test_srv_crt_rsa_len = sizeof( mbedtls_test_srv_crt_rsa ); - -/* tests/data_files/server2.key */ -const char mbedtls_test_srv_key_rsa[] = -"-----BEGIN RSA PRIVATE KEY-----\r\n" -"MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n" -"lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n" -"2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n" -"Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n" -"GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n" -"y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n" -"++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n" -"Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n" -"/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n" -"WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n" -"GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n" -"TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n" -"CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" -"nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" -"AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" -"sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" -"mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" -"BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" -"whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" -"vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" -"3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" -"3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" -"ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" -"4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" -"TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" -"-----END RSA PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_srv_key_rsa_len = sizeof( mbedtls_test_srv_key_rsa ); - -/* tests/data_files/cli-rsa-sha256.crt */ -const char mbedtls_test_cli_crt_rsa[] = -"-----BEGIN CERTIFICATE-----\r\n" -"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQsFADA7MQswCQYDVQQGEwJOTDER\r\n" -"MA8GA1UECgwIUG9sYXJTU0wxGTAXBgNVBAMMEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" -"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" -"A1UECgwIUG9sYXJTU0wxGjAYBgNVBAMMEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" -"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n" -"M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n" -"1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n" -"MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n" -"4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n" -"/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n" -"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n" -"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQsFAAOC\r\n" -"AQEAlHabem2Tu69VUN7EipwnQn1dIHdgvT5i+iQHpSxY1crPnBbAeSdAXwsVEqLQ\r\n" -"gOOIAQD5VIITNuoGgo4i+4OpNh9u7ZkpRHla+/swsfrFWRRbBNP5Bcu74AGLstwU\r\n" -"zM8gIkBiyfM1Q1qDQISV9trlCG6O8vh8dp/rbI3rfzo99BOHXgFCrzXjCuW4vDsF\r\n" -"r+Dao26bX3sJ6UnEWg1H3o2x6PpUcvQ36h71/bz4TEbbUUEpe02V4QWuL+wrhHJL\r\n" -"U7o3SVE3Og7jPF8sat0a50YUWhwEFI256m02KAXLg89ueUyYKEr6rNwhcvXJpvU9\r\n" -"giIVvd0Sbjjnn7NC4VDbcXV8vw==\r\n" -"-----END CERTIFICATE-----\r\n"; -const size_t mbedtls_test_cli_crt_rsa_len = sizeof( mbedtls_test_cli_crt_rsa ); - -/* tests/data_files/cli-rsa.key */ -const char mbedtls_test_cli_key_rsa[] = -"-----BEGIN RSA PRIVATE KEY-----\r\n" -"MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n" -"B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n" -"bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n" -"Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n" -"7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n" -"dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n" -"yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n" -"4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n" -"ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n" -"zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n" -"l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n" -"DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n" -"VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n" -"Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n" -"wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n" -"c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n" -"33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n" -"ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n" -"BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n" -"KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n" -"UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n" -"7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n" -"gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n" -"bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" -"8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" -"-----END RSA PRIVATE KEY-----\r\n"; -const size_t mbedtls_test_cli_key_rsa_len = sizeof( mbedtls_test_cli_key_rsa ); #endif /* MBEDTLS_RSA_C */ -#if defined(MBEDTLS_PEM_PARSE_C) -/* Concatenation of all available CA certificates */ -const char mbedtls_test_cas_pem[] = -#ifdef TEST_CA_CRT_RSA_SHA1 - TEST_CA_CRT_RSA_SHA1 -#endif -#ifdef TEST_CA_CRT_RSA_SHA256 - TEST_CA_CRT_RSA_SHA256 -#endif -#ifdef TEST_CA_CRT_EC - TEST_CA_CRT_EC -#endif - ""; -const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem ); -#endif +/* API stability forces us to declare + * mbedtls_test_{ca|srv|cli}_{key|pwd|crt} + * as pointers. */ +static const char test_ca_key[] = TEST_CA_KEY; +static const char test_ca_pwd[] = TEST_CA_PWD; +static const char test_ca_crt[] = TEST_CA_CRT; + +static const char test_srv_key[] = TEST_SRV_KEY; +static const char test_srv_pwd[] = TEST_SRV_PWD; +static const char test_srv_crt[] = TEST_SRV_CRT; + +static const char test_cli_key[] = TEST_CLI_KEY; +static const char test_cli_pwd[] = TEST_CLI_PWD; +static const char test_cli_crt[] = TEST_CLI_CRT; + +const char *mbedtls_test_ca_key = test_ca_key; +const char *mbedtls_test_ca_pwd = test_ca_pwd; +const char *mbedtls_test_ca_crt = test_ca_crt; + +const char *mbedtls_test_srv_key = test_srv_key; +const char *mbedtls_test_srv_pwd = test_srv_pwd; +const char *mbedtls_test_srv_crt = test_srv_crt; + +const char *mbedtls_test_cli_key = test_cli_key; +const char *mbedtls_test_cli_pwd = test_cli_pwd; +const char *mbedtls_test_cli_crt = test_cli_crt; + +const size_t mbedtls_test_ca_key_len = + sizeof( test_ca_key ); +const size_t mbedtls_test_ca_pwd_len = + sizeof( test_ca_pwd ) - 1; +const size_t mbedtls_test_ca_crt_len = + sizeof( test_ca_crt ); -/* List of all available CA certificates */ +const size_t mbedtls_test_srv_key_len = + sizeof( test_srv_key ); +const size_t mbedtls_test_srv_pwd_len = + sizeof( test_srv_pwd ) - 1; +const size_t mbedtls_test_srv_crt_len = + sizeof( test_srv_crt ); + +const size_t mbedtls_test_cli_key_len = + sizeof( test_cli_key ); +const size_t mbedtls_test_cli_pwd_len = + sizeof( test_cli_pwd ) - 1; +const size_t mbedtls_test_cli_crt_len = + sizeof( test_cli_crt ); + +/* + * + * Lists of certificates + * + */ + +/* List of CAs in PEM or DER, depending on config */ const char * mbedtls_test_cas[] = { -#if defined(TEST_CA_CRT_RSA_SHA1) +#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA1_C) mbedtls_test_ca_crt_rsa_sha1, #endif -#if defined(TEST_CA_CRT_RSA_SHA256) +#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) mbedtls_test_ca_crt_rsa_sha256, #endif #if defined(MBEDTLS_ECDSA_C) @@ -359,10 +1704,10 @@ const char * mbedtls_test_cas[] = { NULL }; const size_t mbedtls_test_cas_len[] = { -#if defined(TEST_CA_CRT_RSA_SHA1) +#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA1_C) sizeof( mbedtls_test_ca_crt_rsa_sha1 ), #endif -#if defined(TEST_CA_CRT_RSA_SHA256) +#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_SHA256_C) sizeof( mbedtls_test_ca_crt_rsa_sha256 ), #endif #if defined(MBEDTLS_ECDSA_C) @@ -371,36 +1716,53 @@ const size_t mbedtls_test_cas_len[] = { 0 }; +/* List of all available CA certificates in DER format */ +const unsigned char * mbedtls_test_cas_der[] = { #if defined(MBEDTLS_RSA_C) -const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_rsa; /* SHA1 or SHA256 */ -const char *mbedtls_test_ca_key = mbedtls_test_ca_key_rsa; -const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_rsa; -const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_rsa; -const char *mbedtls_test_srv_key = mbedtls_test_srv_key_rsa; -const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_rsa; -const char *mbedtls_test_cli_key = mbedtls_test_cli_key_rsa; -const size_t mbedtls_test_ca_crt_len = sizeof( mbedtls_test_ca_crt_rsa ); -const size_t mbedtls_test_ca_key_len = sizeof( mbedtls_test_ca_key_rsa ); -const size_t mbedtls_test_ca_pwd_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1; -const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_rsa ); -const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_rsa ); -const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_rsa ); -const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_rsa ); -#else /* ! MBEDTLS_RSA_C, so MBEDTLS_ECDSA_C */ -const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_ec; -const char *mbedtls_test_ca_key = mbedtls_test_ca_key_ec; -const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_ec; -const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_ec; -const char *mbedtls_test_srv_key = mbedtls_test_srv_key_ec; -const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_ec; -const char *mbedtls_test_cli_key = mbedtls_test_cli_key_ec; -const size_t mbedtls_test_ca_crt_len = sizeof( mbedtls_test_ca_crt_ec ); -const size_t mbedtls_test_ca_key_len = sizeof( mbedtls_test_ca_key_ec ); -const size_t mbedtls_test_ca_pwd_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1; -const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_ec ); -const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_ec ); -const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_ec ); -const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_ec ); +#if defined(MBEDTLS_SHA256_C) + mbedtls_test_ca_crt_rsa_sha256_der, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA1_C) + mbedtls_test_ca_crt_rsa_sha1_der, +#endif /* MBEDTLS_SHA1_C */ #endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECDSA_C) + mbedtls_test_ca_crt_ec_der, +#endif /* MBEDTLS_ECDSA_C */ + NULL +}; + +const size_t mbedtls_test_cas_der_len[] = { +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_SHA256_C) + sizeof( mbedtls_test_ca_crt_rsa_sha256_der ), +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA1_C) + sizeof( mbedtls_test_ca_crt_rsa_sha1_der ), +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECDSA_C) + sizeof( mbedtls_test_ca_crt_ec_der ), +#endif /* MBEDTLS_ECDSA_C */ + 0 +}; + +/* Concatenation of all available CA certificates in PEM format */ +#if defined(MBEDTLS_PEM_PARSE_C) +const char mbedtls_test_cas_pem[] = +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_SHA256_C) + TEST_CA_CRT_RSA_SHA256_PEM +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA1_C) + TEST_CA_CRT_RSA_SHA1_PEM +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECDSA_C) + TEST_CA_CRT_EC_PEM +#endif /* MBEDTLS_ECDSA_C */ + ""; +const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem ); +#endif /* MBEDTLS_PEM_PARSE_C */ #endif /* MBEDTLS_CERTS_C */ diff --git a/thirdparty/mbedtls/library/chacha20.c b/thirdparty/mbedtls/library/chacha20.c index 0757163e2f..8a3610f0e0 100644 --- a/thirdparty/mbedtls/library/chacha20.c +++ b/thirdparty/mbedtls/library/chacha20.c @@ -60,14 +60,14 @@ MBEDTLS_INTERNAL_VALIDATE( cond ) #define BYTES_TO_U32_LE( data, offset ) \ - ( (uint32_t) data[offset] \ - | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 ) \ - | (uint32_t) ( (uint32_t) data[( offset ) + 2] << 16 ) \ - | (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 ) \ + ( (uint32_t) (data)[offset] \ + | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \ + | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \ + | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \ ) #define ROTL32( value, amount ) \ - ( (uint32_t) ( value << amount ) | ( value >> ( 32 - amount ) ) ) + ( (uint32_t) ( (value) << (amount) ) | ( (value) >> ( 32 - (amount) ) ) ) #define CHACHA20_CTR_INDEX ( 12U ) diff --git a/thirdparty/mbedtls/library/debug.c b/thirdparty/mbedtls/library/debug.c index 824cd0236e..36510cdd56 100644 --- a/thirdparty/mbedtls/library/debug.c +++ b/thirdparty/mbedtls/library/debug.c @@ -86,8 +86,13 @@ void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, char str[DEBUG_BUF_SIZE]; int ret; - if( NULL == ssl || NULL == ssl->conf || NULL == ssl->conf->f_dbg || level > debug_threshold ) + if( NULL == ssl || + NULL == ssl->conf || + NULL == ssl->conf->f_dbg || + level > debug_threshold ) + { return; + } va_start( argp, format ); #if defined(_WIN32) @@ -121,8 +126,13 @@ void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level, { char str[DEBUG_BUF_SIZE]; - if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold ) + if( NULL == ssl || + NULL == ssl->conf || + NULL == ssl->conf->f_dbg || + level > debug_threshold ) + { return; + } /* * With non-blocking I/O and examples that just retry immediately, @@ -146,8 +156,13 @@ void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level, char txt[17]; size_t i, idx = 0; - if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold ) + if( NULL == ssl || + NULL == ssl->conf || + NULL == ssl->conf->f_dbg || + level > debug_threshold ) + { return; + } mbedtls_snprintf( str + idx, sizeof( str ) - idx, "dumping '%s' (%u bytes)\n", text, (unsigned int) len ); @@ -199,8 +214,13 @@ void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, { char str[DEBUG_BUF_SIZE]; - if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold ) + if( NULL == ssl || + NULL == ssl->conf || + NULL == ssl->conf->f_dbg || + level > debug_threshold ) + { return; + } mbedtls_snprintf( str, sizeof( str ), "%s(X)", text ); mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X ); @@ -219,8 +239,14 @@ void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level, int j, k, zeros = 1; size_t i, n, idx = 0; - if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || X == NULL || level > debug_threshold ) + if( NULL == ssl || + NULL == ssl->conf || + NULL == ssl->conf->f_dbg || + NULL == X || + level > debug_threshold ) + { return; + } for( n = X->n - 1; n > 0; n-- ) if( X->p[n] != 0 ) @@ -345,8 +371,14 @@ void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, char str[DEBUG_BUF_SIZE]; int i = 0; - if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || crt == NULL || level > debug_threshold ) + if( NULL == ssl || + NULL == ssl->conf || + NULL == ssl->conf->f_dbg || + NULL == crt || + level > debug_threshold ) + { return; + } while( crt != NULL ) { diff --git a/thirdparty/mbedtls/library/des.c b/thirdparty/mbedtls/library/des.c index ca9e071f32..8a33d82e50 100644 --- a/thirdparty/mbedtls/library/des.c +++ b/thirdparty/mbedtls/library/des.c @@ -257,50 +257,57 @@ static const uint32_t RHs[16] = /* * Initial Permutation macro */ -#define DES_IP(X,Y) \ -{ \ - T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ - T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ - T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ - T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ - Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ - T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ - X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ -} +#define DES_IP(X,Y) \ + do \ + { \ + T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \ + T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \ + T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \ + T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \ + (Y) = (((Y) << 1) | ((Y) >> 31)) & 0xFFFFFFFF; \ + T = ((X) ^ (Y)) & 0xAAAAAAAA; (Y) ^= T; (X) ^= T; \ + (X) = (((X) << 1) | ((X) >> 31)) & 0xFFFFFFFF; \ + } while( 0 ) /* * Final Permutation macro */ -#define DES_FP(X,Y) \ -{ \ - X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ - T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ - Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ - T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ - T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ - T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ - T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ -} +#define DES_FP(X,Y) \ + do \ + { \ + (X) = (((X) << 31) | ((X) >> 1)) & 0xFFFFFFFF; \ + T = ((X) ^ (Y)) & 0xAAAAAAAA; (X) ^= T; (Y) ^= T; \ + (Y) = (((Y) << 31) | ((Y) >> 1)) & 0xFFFFFFFF; \ + T = (((Y) >> 8) ^ (X)) & 0x00FF00FF; (X) ^= T; (Y) ^= (T << 8); \ + T = (((Y) >> 2) ^ (X)) & 0x33333333; (X) ^= T; (Y) ^= (T << 2); \ + T = (((X) >> 16) ^ (Y)) & 0x0000FFFF; (Y) ^= T; (X) ^= (T << 16); \ + T = (((X) >> 4) ^ (Y)) & 0x0F0F0F0F; (Y) ^= T; (X) ^= (T << 4); \ + } while( 0 ) /* * DES round macro */ -#define DES_ROUND(X,Y) \ -{ \ - T = *SK++ ^ X; \ - Y ^= SB8[ (T ) & 0x3F ] ^ \ - SB6[ (T >> 8) & 0x3F ] ^ \ - SB4[ (T >> 16) & 0x3F ] ^ \ - SB2[ (T >> 24) & 0x3F ]; \ - \ - T = *SK++ ^ ((X << 28) | (X >> 4)); \ - Y ^= SB7[ (T ) & 0x3F ] ^ \ - SB5[ (T >> 8) & 0x3F ] ^ \ - SB3[ (T >> 16) & 0x3F ] ^ \ - SB1[ (T >> 24) & 0x3F ]; \ -} - -#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; } +#define DES_ROUND(X,Y) \ + do \ + { \ + T = *SK++ ^ (X); \ + (Y) ^= SB8[ (T ) & 0x3F ] ^ \ + SB6[ (T >> 8) & 0x3F ] ^ \ + SB4[ (T >> 16) & 0x3F ] ^ \ + SB2[ (T >> 24) & 0x3F ]; \ + \ + T = *SK++ ^ (((X) << 28) | ((X) >> 4)); \ + (Y) ^= SB7[ (T ) & 0x3F ] ^ \ + SB5[ (T >> 8) & 0x3F ] ^ \ + SB3[ (T >> 16) & 0x3F ] ^ \ + SB1[ (T >> 24) & 0x3F ]; \ + } while( 0 ) + +#define SWAP(a,b) \ + do \ + { \ + uint32_t t = (a); (a) = (b); (b) = t; t = 0; \ + } while( 0 ) void mbedtls_des_init( mbedtls_des_context *ctx ) { diff --git a/thirdparty/mbedtls/library/dhm.c b/thirdparty/mbedtls/library/dhm.c index fb6937e854..8255632a99 100644 --- a/thirdparty/mbedtls/library/dhm.c +++ b/thirdparty/mbedtls/library/dhm.c @@ -649,12 +649,28 @@ int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ) #if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PEM_PARSE_C) static const char mbedtls_test_dhm_params[] = "-----BEGIN DH PARAMETERS-----\r\n" "MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" "1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" "9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" "-----END DH PARAMETERS-----\r\n"; +#else /* MBEDTLS_PEM_PARSE_C */ +static const char mbedtls_test_dhm_params[] = { + 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0x9e, 0x35, 0xf4, 0x30, 0x44, + 0x3a, 0x09, 0x90, 0x4f, 0x3a, 0x39, 0xa9, 0x79, 0x79, 0x7d, 0x07, 0x0d, + 0xf5, 0x33, 0x78, 0xe7, 0x9c, 0x24, 0x38, 0xbe, 0xf4, 0xe7, 0x61, 0xf3, + 0xc7, 0x14, 0x55, 0x33, 0x28, 0x58, 0x9b, 0x04, 0x1c, 0x80, 0x9b, 0xe1, + 0xd6, 0xc6, 0xb5, 0xf1, 0xfc, 0x9f, 0x47, 0xd3, 0xa2, 0x54, 0x43, 0x18, + 0x82, 0x53, 0xa9, 0x92, 0xa5, 0x68, 0x18, 0xb3, 0x7b, 0xa9, 0xde, 0x5a, + 0x40, 0xd3, 0x62, 0xe5, 0x6e, 0xff, 0x0b, 0xe5, 0x41, 0x74, 0x74, 0xc1, + 0x25, 0xc1, 0x99, 0x27, 0x2c, 0x8f, 0xe4, 0x1d, 0xea, 0x73, 0x3d, 0xf6, + 0xf6, 0x62, 0xc9, 0x2a, 0xe7, 0x65, 0x56, 0xe7, 0x55, 0xd1, 0x0c, 0x64, + 0xe6, 0xa5, 0x09, 0x68, 0xf6, 0x7f, 0xc6, 0xea, 0x73, 0xd0, 0xdc, 0xa8, + 0x56, 0x9b, 0xe2, 0xba, 0x20, 0x4e, 0x23, 0x58, 0x0d, 0x8b, 0xca, 0x2f, + 0x49, 0x75, 0xb3, 0x02, 0x01, 0x02 }; +#endif /* MBEDTLS_PEM_PARSE_C */ static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params ); diff --git a/thirdparty/mbedtls/library/ecdh.c b/thirdparty/mbedtls/library/ecdh.c index da95c60dad..c5726877d5 100644 --- a/thirdparty/mbedtls/library/ecdh.c +++ b/thirdparty/mbedtls/library/ecdh.c @@ -49,6 +49,16 @@ typedef mbedtls_ecdh_context mbedtls_ecdh_context_mbed; #endif +static mbedtls_ecp_group_id mbedtls_ecdh_grp_id( + const mbedtls_ecdh_context *ctx ) +{ +#if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) + return( ctx->grp.id ); +#else + return( ctx->grp_id ); +#endif +} + #if !defined(MBEDTLS_ECDH_GEN_PUBLIC_ALT) /* * Generate public key (restartable version) @@ -442,8 +452,21 @@ int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, ECDH_VALIDATE_RET( side == MBEDTLS_ECDH_OURS || side == MBEDTLS_ECDH_THEIRS ); - if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 ) - return( ret ); + if( mbedtls_ecdh_grp_id( ctx ) == MBEDTLS_ECP_DP_NONE ) + { + /* This is the first call to get_params(). Set up the context + * for use with the group. */ + if( ( ret = mbedtls_ecdh_setup( ctx, key->grp.id ) ) != 0 ) + return( ret ); + } + else + { + /* This is not the first call to get_params(). Check that the + * current key's group is the same as the context's, which was set + * from the first key's group. */ + if( mbedtls_ecdh_grp_id( ctx ) != key->grp.id ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + } #if defined(MBEDTLS_ECDH_LEGACY_CONTEXT) return( ecdh_get_params_internal( ctx, key, side ) ); diff --git a/thirdparty/mbedtls/library/ecdsa.c b/thirdparty/mbedtls/library/ecdsa.c index 1204ef9949..dc19384d61 100644 --- a/thirdparty/mbedtls/library/ecdsa.c +++ b/thirdparty/mbedtls/library/ecdsa.c @@ -800,11 +800,16 @@ cleanup: int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { + int ret = 0; ECDSA_VALIDATE_RET( ctx != NULL ); ECDSA_VALIDATE_RET( f_rng != NULL ); - return( mbedtls_ecp_group_load( &ctx->grp, gid ) || - mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ); + ret = mbedtls_ecp_group_load( &ctx->grp, gid ); + if( ret != 0 ) + return( ret ); + + return( mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, + &ctx->Q, f_rng, p_rng ) ); } #endif /* !MBEDTLS_ECDSA_GENKEY_ALT */ diff --git a/thirdparty/mbedtls/library/ecp.c b/thirdparty/mbedtls/library/ecp.c index ecea5910e0..db36191b9b 100644 --- a/thirdparty/mbedtls/library/ecp.c +++ b/thirdparty/mbedtls/library/ecp.c @@ -1046,25 +1046,29 @@ cleanup: #define INC_MUL_COUNT #endif -#define MOD_MUL( N ) do { MBEDTLS_MPI_CHK( ecp_modp( &N, grp ) ); INC_MUL_COUNT } \ - while( 0 ) +#define MOD_MUL( N ) \ + do \ + { \ + MBEDTLS_MPI_CHK( ecp_modp( &(N), grp ) ); \ + INC_MUL_COUNT \ + } while( 0 ) /* * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi * N->s < 0 is a very fast test, which fails only if N is 0 */ -#define MOD_SUB( N ) \ - while( N.s < 0 && mbedtls_mpi_cmp_int( &N, 0 ) != 0 ) \ - MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &N, &N, &grp->P ) ) +#define MOD_SUB( N ) \ + while( (N).s < 0 && mbedtls_mpi_cmp_int( &(N), 0 ) != 0 ) \ + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &(N), &(N), &grp->P ) ) /* * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int. * We known P, N and the result are positive, so sub_abs is correct, and * a bit faster. */ -#define MOD_ADD( N ) \ - while( mbedtls_mpi_cmp_mpi( &N, &grp->P ) >= 0 ) \ - MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &N, &N, &grp->P ) ) +#define MOD_ADD( N ) \ + while( mbedtls_mpi_cmp_mpi( &(N), &grp->P ) >= 0 ) \ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &(N), &(N), &grp->P ) ) #if defined(ECP_SHORTWEIERSTRASS) /* diff --git a/thirdparty/mbedtls/library/ecp_curves.c b/thirdparty/mbedtls/library/ecp_curves.c index 731621dc3c..282481d053 100644 --- a/thirdparty/mbedtls/library/ecp_curves.c +++ b/thirdparty/mbedtls/library/ecp_curves.c @@ -51,11 +51,11 @@ */ #if defined(MBEDTLS_HAVE_INT32) -#define BYTES_TO_T_UINT_4( a, b, c, d ) \ - ( (mbedtls_mpi_uint) a << 0 ) | \ - ( (mbedtls_mpi_uint) b << 8 ) | \ - ( (mbedtls_mpi_uint) c << 16 ) | \ - ( (mbedtls_mpi_uint) d << 24 ) +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + ( (mbedtls_mpi_uint) (a) << 0 ) | \ + ( (mbedtls_mpi_uint) (b) << 8 ) | \ + ( (mbedtls_mpi_uint) (c) << 16 ) | \ + ( (mbedtls_mpi_uint) (d) << 24 ) #define BYTES_TO_T_UINT_2( a, b ) \ BYTES_TO_T_UINT_4( a, b, 0, 0 ) @@ -67,14 +67,14 @@ #else /* 64-bits */ #define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ - ( (mbedtls_mpi_uint) a << 0 ) | \ - ( (mbedtls_mpi_uint) b << 8 ) | \ - ( (mbedtls_mpi_uint) c << 16 ) | \ - ( (mbedtls_mpi_uint) d << 24 ) | \ - ( (mbedtls_mpi_uint) e << 32 ) | \ - ( (mbedtls_mpi_uint) f << 40 ) | \ - ( (mbedtls_mpi_uint) g << 48 ) | \ - ( (mbedtls_mpi_uint) h << 56 ) + ( (mbedtls_mpi_uint) (a) << 0 ) | \ + ( (mbedtls_mpi_uint) (b) << 8 ) | \ + ( (mbedtls_mpi_uint) (c) << 16 ) | \ + ( (mbedtls_mpi_uint) (d) << 24 ) | \ + ( (mbedtls_mpi_uint) (e) << 32 ) | \ + ( (mbedtls_mpi_uint) (f) << 40 ) | \ + ( (mbedtls_mpi_uint) (g) << 48 ) | \ + ( (mbedtls_mpi_uint) (h) << 56 ) #define BYTES_TO_T_UINT_4( a, b, c, d ) \ BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 ) @@ -890,7 +890,7 @@ static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry ) } #define WIDTH 8 / sizeof( mbedtls_mpi_uint ) -#define A( i ) N->p + i * WIDTH +#define A( i ) N->p + (i) * WIDTH #define ADD( i ) add64( p, A( i ), &c ) #define NEXT p += WIDTH; carry64( p, &c ) #define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 @@ -955,7 +955,8 @@ cleanup: #else /* 64-bit */ #define MAX32 N->n * 2 -#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] ) +#define A( j ) (j) % 2 ? (uint32_t)( N->p[(j)/2] >> 32 ) : \ + (uint32_t)( N->p[(j)/2] ) #define STORE32 \ if( i % 2 ) { \ N->p[i/2] &= 0x00000000FFFFFFFF; \ @@ -989,20 +990,21 @@ static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) * Helpers for the main 'loop' * (see fix_negative for the motivation of C) */ -#define INIT( b ) \ - int ret; \ - signed char c = 0, cc; \ - uint32_t cur; \ - size_t i = 0, bits = b; \ - mbedtls_mpi C; \ - mbedtls_mpi_uint Cp[ b / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \ - \ - C.s = 1; \ - C.n = b / 8 / sizeof( mbedtls_mpi_uint) + 1; \ - C.p = Cp; \ - memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \ - \ - MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, b * 2 / 8 / sizeof( mbedtls_mpi_uint ) ) ); \ +#define INIT( b ) \ + int ret; \ + signed char c = 0, cc; \ + uint32_t cur; \ + size_t i = 0, bits = (b); \ + mbedtls_mpi C; \ + mbedtls_mpi_uint Cp[ (b) / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \ + \ + C.s = 1; \ + C.n = (b) / 8 / sizeof( mbedtls_mpi_uint) + 1; \ + C.p = Cp; \ + memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \ + \ + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, (b) * 2 / 8 / \ + sizeof( mbedtls_mpi_uint ) ) ); \ LOAD32; #define NEXT \ diff --git a/thirdparty/mbedtls/library/entropy_poll.c b/thirdparty/mbedtls/library/entropy_poll.c index ba56b70f77..4556f88a55 100644 --- a/thirdparty/mbedtls/library/entropy_poll.c +++ b/thirdparty/mbedtls/library/entropy_poll.c @@ -61,43 +61,28 @@ #define _WIN32_WINNT 0x0400 #endif #include <windows.h> -#include <bcrypt.h> -#if defined(_MSC_VER) && _MSC_VER <= 1600 -/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and - * <intsafe.h> are included, as they redefine a number of <TYPE>_MAX constants. - * These constants are guaranteed to be the same, though, so we suppress the - * warning when including intsafe.h. - */ -#pragma warning( push ) -#pragma warning( disable : 4005 ) -#endif -#include <intsafe.h> -#if defined(_MSC_VER) && _MSC_VER <= 1600 -#pragma warning( pop ) -#endif +#include <wincrypt.h> int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, size_t *olen ) { - ULONG len_as_ulong = 0; + HCRYPTPROV provider; ((void) data); *olen = 0; - /* - * BCryptGenRandom takes ULONG for size, which is smaller than size_t on - * 64-bit Windows platforms. Ensure len's value can be safely converted into - * a ULONG. - */ - if ( FAILED( SizeTToULong( len, &len_as_ulong ) ) ) + if( CryptAcquireContext( &provider, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) { return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); } - if ( !BCRYPT_SUCCESS( BCryptGenRandom( NULL, output, len_as_ulong, BCRYPT_USE_SYSTEM_PREFERRED_RNG ) ) ) + if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) { + CryptReleaseContext( provider, 0 ); return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); } + CryptReleaseContext( provider, 0 ); *olen = len; return( 0 ); diff --git a/thirdparty/mbedtls/library/godot_core_mbedtls_platform.c b/thirdparty/mbedtls/library/godot_core_mbedtls_platform.c new file mode 100644 index 0000000000..9018726072 --- /dev/null +++ b/thirdparty/mbedtls/library/godot_core_mbedtls_platform.c @@ -0,0 +1,18 @@ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include <stdio.h> +#include <string.h> +#include <stddef.h> + +#ifdef MBEDTLS_PLATFORM_ZEROIZE_ALT +static void *(*const volatile memset_func)(void *, int, size_t) = memset; + +void mbedtls_platform_zeroize(void *buf, size_t len) { + memset_func( buf, 0, len ); +} +#endif + diff --git a/thirdparty/mbedtls/library/havege.c b/thirdparty/mbedtls/library/havege.c index 4dcac02875..54f897c6e7 100644 --- a/thirdparty/mbedtls/library/havege.c +++ b/thirdparty/mbedtls/library/havege.c @@ -54,7 +54,7 @@ * ------------------------------------------------------------------------ */ -#define SWAP(X,Y) { int *T = X; X = Y; Y = T; } +#define SWAP(X,Y) { int *T = (X); (X) = (Y); (Y) = T; } #define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; #define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; diff --git a/thirdparty/mbedtls/library/md4.c b/thirdparty/mbedtls/library/md4.c index 3f8ddff31d..828fd42999 100644 --- a/thirdparty/mbedtls/library/md4.c +++ b/thirdparty/mbedtls/library/md4.c @@ -137,15 +137,21 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, GET_UINT32_LE( X[14], data, 56 ); GET_UINT32_LE( X[15], data, 60 ); -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) +#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) A = ctx->state[0]; B = ctx->state[1]; C = ctx->state[2]; D = ctx->state[3]; -#define F(x, y, z) ((x & y) | ((~x) & z)) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } +#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z))) +#define P(a,b,c,d,x,s) \ + do \ + { \ + (a) += F((b),(c),(d)) + (x); \ + (a) = S((a),(s)); \ + } while( 0 ) + P( A, B, C, D, X[ 0], 3 ); P( D, A, B, C, X[ 1], 7 ); @@ -167,8 +173,13 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, #undef P #undef F -#define F(x,y,z) ((x & y) | (x & z) | (y & z)) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } +#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define P(a,b,c,d,x,s) \ + do \ + { \ + (a) += F((b),(c),(d)) + (x) + 0x5A827999; \ + (a) = S((a),(s)); \ + } while( 0 ) P( A, B, C, D, X[ 0], 3 ); P( D, A, B, C, X[ 4], 5 ); @@ -190,8 +201,13 @@ int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, #undef P #undef F -#define F(x,y,z) (x ^ y ^ z) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } +#define F(x,y,z) ((x) ^ (y) ^ (z)) +#define P(a,b,c,d,x,s) \ + do \ + { \ + (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \ + (a) = S((a),(s)); \ + } while( 0 ) P( A, B, C, D, X[ 0], 3 ); P( D, A, B, C, X[ 8], 9 ); diff --git a/thirdparty/mbedtls/library/md5.c b/thirdparty/mbedtls/library/md5.c index 2a740cda81..a93da8a061 100644 --- a/thirdparty/mbedtls/library/md5.c +++ b/thirdparty/mbedtls/library/md5.c @@ -136,19 +136,22 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, GET_UINT32_LE( X[14], data, 56 ); GET_UINT32_LE( X[15], data, 60 ); -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) +#define S(x,n) \ + ( ( (x) << (n) ) | ( ( (x) & 0xFFFFFFFF) >> ( 32 - (n) ) ) ) -#define P(a,b,c,d,k,s,t) \ -{ \ - a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ -} +#define P(a,b,c,d,k,s,t) \ + do \ + { \ + (a) += F((b),(c),(d)) + X[(k)] + (t); \ + (a) = S((a),(s)) + (b); \ + } while( 0 ) A = ctx->state[0]; B = ctx->state[1]; C = ctx->state[2]; D = ctx->state[3]; -#define F(x,y,z) (z ^ (x & (y ^ z))) +#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) P( A, B, C, D, 0, 7, 0xD76AA478 ); P( D, A, B, C, 1, 12, 0xE8C7B756 ); @@ -169,7 +172,7 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, #undef F -#define F(x,y,z) (y ^ (z & (x ^ y))) +#define F(x,y,z) ((y) ^ ((z) & ((x) ^ (y)))) P( A, B, C, D, 1, 5, 0xF61E2562 ); P( D, A, B, C, 6, 9, 0xC040B340 ); @@ -190,7 +193,7 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, #undef F -#define F(x,y,z) (x ^ y ^ z) +#define F(x,y,z) ((x) ^ (y) ^ (z)) P( A, B, C, D, 5, 4, 0xFFFA3942 ); P( D, A, B, C, 8, 11, 0x8771F681 ); @@ -211,7 +214,7 @@ int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, #undef F -#define F(x,y,z) (y ^ (x | ~z)) +#define F(x,y,z) ((y) ^ ((x) | ~(z))) P( A, B, C, D, 0, 6, 0xF4292244 ); P( D, A, B, C, 7, 10, 0x432AFF97 ); diff --git a/thirdparty/mbedtls/library/oid.c b/thirdparty/mbedtls/library/oid.c index edea950f8f..33f437cbe6 100644 --- a/thirdparty/mbedtls/library/oid.c +++ b/thirdparty/mbedtls/library/oid.c @@ -54,22 +54,24 @@ * Macro to generate an internal function for oid_XXX_from_asn1() (used by * the other functions) */ -#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \ -static const TYPE_T * oid_ ## NAME ## _from_asn1( const mbedtls_asn1_buf *oid ) \ -{ \ - const TYPE_T *p = LIST; \ - const mbedtls_oid_descriptor_t *cur = (const mbedtls_oid_descriptor_t *) p; \ - if( p == NULL || oid == NULL ) return( NULL ); \ - while( cur->asn1 != NULL ) { \ - if( cur->asn1_len == oid->len && \ - memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \ - return( p ); \ - } \ - p++; \ - cur = (const mbedtls_oid_descriptor_t *) p; \ - } \ - return( NULL ); \ -} +#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \ + static const TYPE_T * oid_ ## NAME ## _from_asn1( \ + const mbedtls_asn1_buf *oid ) \ + { \ + const TYPE_T *p = (LIST); \ + const mbedtls_oid_descriptor_t *cur = \ + (const mbedtls_oid_descriptor_t *) p; \ + if( p == NULL || oid == NULL ) return( NULL ); \ + while( cur->asn1 != NULL ) { \ + if( cur->asn1_len == oid->len && \ + memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \ + return( p ); \ + } \ + p++; \ + cur = (const mbedtls_oid_descriptor_t *) p; \ + } \ + return( NULL ); \ + } /* * Macro to generate a function for retrieving a single attribute from the @@ -103,12 +105,13 @@ int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) */ #define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \ ATTR2_TYPE, ATTR2) \ -int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 ) \ +int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, \ + ATTR2_TYPE * ATTR2 ) \ { \ const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ - if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ - *ATTR1 = data->ATTR1; \ - *ATTR2 = data->ATTR2; \ + if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ + *(ATTR1) = data->ATTR1; \ + *(ATTR2) = data->ATTR2; \ return( 0 ); \ } @@ -119,16 +122,16 @@ int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 #define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \ int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \ { \ - const TYPE_T *cur = LIST; \ + const TYPE_T *cur = (LIST); \ while( cur->descriptor.asn1 != NULL ) { \ - if( cur->ATTR1 == ATTR1 ) { \ + if( cur->ATTR1 == (ATTR1) ) { \ *oid = cur->descriptor.asn1; \ *olen = cur->descriptor.asn1_len; \ return( 0 ); \ } \ cur++; \ } \ - return( MBEDTLS_ERR_OID_NOT_FOUND ); \ + return( MBEDTLS_ERR_OID_NOT_FOUND ); \ } /* @@ -140,9 +143,9 @@ int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \ int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \ size_t *olen ) \ { \ - const TYPE_T *cur = LIST; \ + const TYPE_T *cur = (LIST); \ while( cur->descriptor.asn1 != NULL ) { \ - if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) { \ + if( cur->ATTR1 == (ATTR1) && cur->ATTR2 == (ATTR2) ) { \ *oid = cur->descriptor.asn1; \ *olen = cur->descriptor.asn1_len; \ return( 0 ); \ diff --git a/thirdparty/mbedtls/library/poly1305.c b/thirdparty/mbedtls/library/poly1305.c index b274119181..2b56c5f7ef 100644 --- a/thirdparty/mbedtls/library/poly1305.c +++ b/thirdparty/mbedtls/library/poly1305.c @@ -58,10 +58,10 @@ #define POLY1305_BLOCK_SIZE_BYTES ( 16U ) #define BYTES_TO_U32_LE( data, offset ) \ - ( (uint32_t) data[offset] \ - | (uint32_t) ( (uint32_t) data[( offset ) + 1] << 8 ) \ - | (uint32_t) ( (uint32_t) data[( offset ) + 2] << 16 ) \ - | (uint32_t) ( (uint32_t) data[( offset ) + 3] << 24 ) \ + ( (uint32_t) (data)[offset] \ + | (uint32_t) ( (uint32_t) (data)[( offset ) + 1] << 8 ) \ + | (uint32_t) ( (uint32_t) (data)[( offset ) + 2] << 16 ) \ + | (uint32_t) ( (uint32_t) (data)[( offset ) + 3] << 24 ) \ ) /* diff --git a/thirdparty/mbedtls/library/ripemd160.c b/thirdparty/mbedtls/library/ripemd160.c index bd25ada62c..0791ae4cc9 100644 --- a/thirdparty/mbedtls/library/ripemd160.c +++ b/thirdparty/mbedtls/library/ripemd160.c @@ -147,22 +147,29 @@ int mbedtls_internal_ripemd160_process( mbedtls_ripemd160_context *ctx, D = Dp = ctx->state[3]; E = Ep = ctx->state[4]; -#define F1( x, y, z ) ( x ^ y ^ z ) -#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) ) -#define F3( x, y, z ) ( ( x | ~y ) ^ z ) -#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) ) -#define F5( x, y, z ) ( x ^ ( y | ~z ) ) - -#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) ) - -#define P( a, b, c, d, e, r, s, f, k ) \ - a += f( b, c, d ) + X[r] + k; \ - a = S( a, s ) + e; \ - c = S( c, 10 ); - -#define P2( a, b, c, d, e, r, s, rp, sp ) \ - P( a, b, c, d, e, r, s, F, K ); \ - P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp ); +#define F1( x, y, z ) ( (x) ^ (y) ^ (z) ) +#define F2( x, y, z ) ( ( (x) & (y) ) | ( ~(x) & (z) ) ) +#define F3( x, y, z ) ( ( (x) | ~(y) ) ^ (z) ) +#define F4( x, y, z ) ( ( (x) & (z) ) | ( (y) & ~(z) ) ) +#define F5( x, y, z ) ( (x) ^ ( (y) | ~(z) ) ) + +#define S( x, n ) ( ( (x) << (n) ) | ( (x) >> (32 - (n)) ) ) + +#define P( a, b, c, d, e, r, s, f, k ) \ + do \ + { \ + (a) += f( (b), (c), (d) ) + X[r] + (k); \ + (a) = S( (a), (s) ) + (e); \ + (c) = S( (c), 10 ); \ + } while( 0 ) + +#define P2( a, b, c, d, e, r, s, rp, sp ) \ + do \ + { \ + P( (a), (b), (c), (d), (e), (r), (s), F, K ); \ + P( a ## p, b ## p, c ## p, d ## p, e ## p, \ + (rp), (sp), Fp, Kp ); \ + } while( 0 ) #define F F1 #define K 0x00000000 diff --git a/thirdparty/mbedtls/library/sha1.c b/thirdparty/mbedtls/library/sha1.c index e8d4096fbb..355c83d2f7 100644 --- a/thirdparty/mbedtls/library/sha1.c +++ b/thirdparty/mbedtls/library/sha1.c @@ -152,19 +152,21 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, GET_UINT32_BE( W[14], data, 56 ); GET_UINT32_BE( W[15], data, 60 ); -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define R(t) \ -( \ - temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ - W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) - -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} +#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) + +#define R(t) \ + ( \ + temp = W[( (t) - 3 ) & 0x0F] ^ W[( (t) - 8 ) & 0x0F] ^ \ + W[( (t) - 14 ) & 0x0F] ^ W[ (t) & 0x0F], \ + ( W[(t) & 0x0F] = S(temp,1) ) \ + ) + +#define P(a,b,c,d,e,x) \ + do \ + { \ + (e) += S((a),5) + F((b),(c),(d)) + K + (x); \ + (b) = S((b),30); \ + } while( 0 ) A = ctx->state[0]; B = ctx->state[1]; @@ -172,7 +174,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, D = ctx->state[3]; E = ctx->state[4]; -#define F(x,y,z) (z ^ (x & (y ^ z))) +#define F(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) #define K 0x5A827999 P( A, B, C, D, E, W[0] ); @@ -199,7 +201,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, #undef K #undef F -#define F(x,y,z) (x ^ y ^ z) +#define F(x,y,z) ((x) ^ (y) ^ (z)) #define K 0x6ED9EBA1 P( A, B, C, D, E, R(20) ); @@ -226,7 +228,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, #undef K #undef F -#define F(x,y,z) ((x & y) | (z & (x | y))) +#define F(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) #define K 0x8F1BBCDC P( A, B, C, D, E, R(40) ); @@ -253,7 +255,7 @@ int mbedtls_internal_sha1_process( mbedtls_sha1_context *ctx, #undef K #undef F -#define F(x,y,z) (x ^ y ^ z) +#define F(x,y,z) ((x) ^ (y) ^ (z)) #define K 0xCA62C1D6 P( A, B, C, D, E, R(60) ); diff --git a/thirdparty/mbedtls/library/sha256.c b/thirdparty/mbedtls/library/sha256.c index 8a540adfbe..2dc0e1a2c9 100644 --- a/thirdparty/mbedtls/library/sha256.c +++ b/thirdparty/mbedtls/library/sha256.c @@ -172,8 +172,8 @@ static const uint32_t K[] = 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, }; -#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) -#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) +#define SHR(x,n) (((x) & 0xFFFFFFFF) >> (n)) +#define ROTR(x,n) (SHR(x,n) | ((x) << (32 - (n)))) #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) @@ -181,21 +181,22 @@ static const uint32_t K[] = #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) -#define F0(x,y,z) ((x & y) | (z & (x | y))) -#define F1(x,y,z) (z ^ (x & (y ^ z))) +#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) +#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) #define R(t) \ -( \ - W[t] = S1(W[t - 2]) + W[t - 7] + \ - S0(W[t - 15]) + W[t - 16] \ -) - -#define P(a,b,c,d,e,f,g,h,x,K) \ -{ \ - temp1 = h + S3(e) + F1(e,f,g) + K + x; \ - temp2 = S2(a) + F0(a,b,c); \ - d += temp1; h = temp1 + temp2; \ -} + ( \ + W[t] = S1(W[(t) - 2]) + W[(t) - 7] + \ + S0(W[(t) - 15]) + W[(t) - 16] \ + ) + +#define P(a,b,c,d,e,f,g,h,x,K) \ + do \ + { \ + temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ + temp2 = S2(a) + F0((a),(b),(c)); \ + (d) += temp1; (h) = temp1 + temp2; \ + } while( 0 ) int mbedtls_internal_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) diff --git a/thirdparty/mbedtls/library/sha512.c b/thirdparty/mbedtls/library/sha512.c index 941ecda762..bdd20b284a 100644 --- a/thirdparty/mbedtls/library/sha512.c +++ b/thirdparty/mbedtls/library/sha512.c @@ -224,8 +224,8 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, SHA512_VALIDATE_RET( ctx != NULL ); SHA512_VALIDATE_RET( (const unsigned char *)data != NULL ); -#define SHR(x,n) (x >> n) -#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) +#define SHR(x,n) ((x) >> (n)) +#define ROTR(x,n) (SHR((x),(n)) | ((x) << (64 - (n)))) #define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) #define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) @@ -233,15 +233,16 @@ int mbedtls_internal_sha512_process( mbedtls_sha512_context *ctx, #define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) #define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) -#define F0(x,y,z) ((x & y) | (z & (x | y))) -#define F1(x,y,z) (z ^ (x & (y ^ z))) +#define F0(x,y,z) (((x) & (y)) | ((z) & ((x) | (y)))) +#define F1(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) -#define P(a,b,c,d,e,f,g,h,x,K) \ -{ \ - temp1 = h + S3(e) + F1(e,f,g) + K + x; \ - temp2 = S2(a) + F0(a,b,c); \ - d += temp1; h = temp1 + temp2; \ -} +#define P(a,b,c,d,e,f,g,h,x,K) \ + do \ + { \ + temp1 = (h) + S3(e) + F1((e),(f),(g)) + (K) + (x); \ + temp2 = S2(a) + F0((a),(b),(c)); \ + (d) += temp1; (h) = temp1 + temp2; \ + } while( 0 ) for( i = 0; i < 16; i++ ) { diff --git a/thirdparty/mbedtls/library/ssl_ciphersuites.c b/thirdparty/mbedtls/library/ssl_ciphersuites.c index 745474effe..518f7dde00 100644 --- a/thirdparty/mbedtls/library/ssl_ciphersuites.c +++ b/thirdparty/mbedtls/library/ssl_ciphersuites.c @@ -43,11 +43,11 @@ /* * Ordered from most preferred to least preferred in terms of security. * - * Current rule (except rc4, weak and null which come last): + * Current rule (except RC4 and 3DES, weak and null which come last): * 1. By key exchange: * Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK * 2. By key length and cipher: - * ChaCha > AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128 > 3DES + * ChaCha > AES-256 > Camellia-256 > ARIA-256 > AES-128 > Camellia-128 > ARIA-128 * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 * 4. By hash function used when relevant * 5. By key exchange/auth again: EC > non-EC @@ -126,11 +126,6 @@ static const int ciphersuite_preference[] = MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256, MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256, - /* All remaining >= 128-bit ephemeral suites */ - MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, - /* The PSK ephemeral suites */ MBEDTLS_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256, @@ -162,9 +157,6 @@ static const int ciphersuite_preference[] = MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256, MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, - /* The ECJPAKE suite */ MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, @@ -228,11 +220,6 @@ static const int ciphersuite_preference[] = MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256, MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256, - /* All remaining >= 128-bit suites */ - MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, - MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, - /* The RSA PSK suites */ MBEDTLS_TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, @@ -251,8 +238,6 @@ static const int ciphersuite_preference[] = MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256, MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256, - MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, - /* The PSK suites */ MBEDTLS_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, @@ -275,6 +260,16 @@ static const int ciphersuite_preference[] = MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256, MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256, + /* 3DES suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, /* RC4 suites */ @@ -2187,6 +2182,26 @@ const int *mbedtls_ssl_list_ciphersuites( void ) static int supported_ciphersuites[MAX_CIPHERSUITES]; static int supported_init = 0; +static int ciphersuite_is_removed( const mbedtls_ssl_ciphersuite_t *cs_info ) +{ + (void)cs_info; + +#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) + if( cs_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) + return( 1 ); +#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */ + +#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES) + if( cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_ECB || + cs_info->cipher == MBEDTLS_CIPHER_DES_EDE3_CBC ) + { + return( 1 ); + } +#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */ + + return( 0 ); +} + const int *mbedtls_ssl_list_ciphersuites( void ) { /* @@ -2202,14 +2217,12 @@ const int *mbedtls_ssl_list_ciphersuites( void ) *p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1; p++ ) { -#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) const mbedtls_ssl_ciphersuite_t *cs_info; if( ( cs_info = mbedtls_ssl_ciphersuite_from_id( *p ) ) != NULL && - cs_info->cipher != MBEDTLS_CIPHER_ARC4_128 ) -#else - if( mbedtls_ssl_ciphersuite_from_id( *p ) != NULL ) -#endif + !ciphersuite_is_removed( cs_info ) ) + { *(q++) = *p; + } } *q = 0; diff --git a/thirdparty/mbedtls/library/version_features.c b/thirdparty/mbedtls/library/version_features.c index 4c36d3caaa..24143d052c 100644 --- a/thirdparty/mbedtls/library/version_features.c +++ b/thirdparty/mbedtls/library/version_features.c @@ -300,6 +300,9 @@ static const char *features[] = { #if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) "MBEDTLS_REMOVE_ARC4_CIPHERSUITES", #endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */ +#if defined(MBEDTLS_REMOVE_3DES_CIPHERSUITES) + "MBEDTLS_REMOVE_3DES_CIPHERSUITES", +#endif /* MBEDTLS_REMOVE_3DES_CIPHERSUITES */ #if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) "MBEDTLS_ECP_DP_SECP192R1_ENABLED", #endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ diff --git a/thirdparty/mbedtls/library/x509.c b/thirdparty/mbedtls/library/x509.c index 52b5b649f7..a562df7ca3 100644 --- a/thirdparty/mbedtls/library/x509.c +++ b/thirdparty/mbedtls/library/x509.c @@ -67,8 +67,15 @@ #include <time.h> #endif -#define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); } -#define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); } +#define CHECK(code) if( ( ret = ( code ) ) != 0 ){ return( ret ); } +#define CHECK_RANGE(min, max, val) \ + do \ + { \ + if( ( val ) < ( min ) || ( val ) > ( max ) ) \ + { \ + return( ret ); \ + } \ + } while( 0 ) /* * CertificateSerialNumber ::= INTEGER @@ -354,6 +361,8 @@ static int x509_get_attr_type_value( unsigned char **p, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); + end = *p + len; + if( ( end - *p ) < 1 ) return( MBEDTLS_ERR_X509_INVALID_NAME + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); @@ -387,6 +396,12 @@ static int x509_get_attr_type_value( unsigned char **p, val->p = *p; *p += val->len; + if( *p != end ) + { + return( MBEDTLS_ERR_X509_INVALID_NAME + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + cur->next = NULL; return( 0 ); @@ -693,30 +708,25 @@ int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x50 * be either manually updated or extensions should be parsed!) */ int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, - mbedtls_x509_buf *ext, int tag ) + mbedtls_x509_buf *ext, int tag ) { int ret; size_t len; - if( *p == end ) - return( 0 ); - - ext->tag = **p; - - if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len, - MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ) ) != 0 ) - return( ret ); + /* Extension structure use EXPLICIT tagging. That is, the actual + * `Extensions` structure is wrapped by a tag-length pair using + * the respective context-specific tag. */ + ret = mbedtls_asn1_get_tag( p, end, &ext->len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ); + if( ret != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); - ext->p = *p; - end = *p + ext->len; + ext->tag = MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag; + ext->p = *p; + end = *p + ext->len; /* * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - * - * Extension ::= SEQUENCE { - * extnID OBJECT IDENTIFIER, - * critical BOOLEAN DEFAULT FALSE, - * extnValue OCTET STRING } */ if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) @@ -1001,8 +1011,8 @@ int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) */ int mbedtls_x509_self_test( int verbose ) { + int ret = 0; #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C) - int ret; uint32_t flags; mbedtls_x509_crt cacert; mbedtls_x509_crt clicert; @@ -1010,6 +1020,7 @@ int mbedtls_x509_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( " X.509 certificate load: " ); + mbedtls_x509_crt_init( &cacert ); mbedtls_x509_crt_init( &clicert ); ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, @@ -1019,11 +1030,9 @@ int mbedtls_x509_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - return( ret ); + goto cleanup; } - mbedtls_x509_crt_init( &cacert ); - ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt, mbedtls_test_ca_crt_len ); if( ret != 0 ) @@ -1031,7 +1040,7 @@ int mbedtls_x509_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - return( ret ); + goto cleanup; } if( verbose != 0 ) @@ -1043,20 +1052,19 @@ int mbedtls_x509_self_test( int verbose ) if( verbose != 0 ) mbedtls_printf( "failed\n" ); - return( ret ); + goto cleanup; } if( verbose != 0 ) mbedtls_printf( "passed\n\n"); +cleanup: mbedtls_x509_crt_free( &cacert ); mbedtls_x509_crt_free( &clicert ); - - return( 0 ); #else ((void) verbose); - return( 0 ); #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */ + return( ret ); } #endif /* MBEDTLS_SELF_TEST */ diff --git a/thirdparty/mbedtls/library/x509_crl.c b/thirdparty/mbedtls/library/x509_crl.c index 8450f87e03..00f8545d7c 100644 --- a/thirdparty/mbedtls/library/x509_crl.c +++ b/thirdparty/mbedtls/library/x509_crl.c @@ -103,17 +103,17 @@ static int x509_get_crl_ext( unsigned char **p, { int ret; + if( *p == end ) + return( 0 ); + /* * crlExtensions [0] EXPLICIT Extensions OPTIONAL * -- if present, version MUST be v2 */ if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0 ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( 0 ); - return( ret ); - } + + end = ext->p + ext->len; while( *p < end ) { diff --git a/thirdparty/mbedtls/library/x509_crt.c b/thirdparty/mbedtls/library/x509_crt.c index 35a134950e..97e1d72e3c 100644 --- a/thirdparty/mbedtls/library/x509_crt.c +++ b/thirdparty/mbedtls/library/x509_crt.c @@ -65,19 +65,6 @@ #if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) #include <windows.h> -#if defined(_MSC_VER) && _MSC_VER <= 1600 -/* Visual Studio 2010 and earlier issue a warning when both <stdint.h> and - * <intsafe.h> are included, as they redefine a number of <TYPE>_MAX constants. - * These constants are guaranteed to be the same, though, so we suppress the - * warning when including intsafe.h. - */ -#pragma warning( push ) -#pragma warning( disable : 4005 ) -#endif -#include <intsafe.h> -#if defined(_MSC_VER) && _MSC_VER <= 1600 -#pragma warning( pop ) -#endif #else #include <time.h> #endif @@ -381,7 +368,7 @@ static void x509_crt_verify_chain_reset( for( i = 0; i < MBEDTLS_X509_MAX_VERIFY_CHAIN_SIZE; i++ ) { ver_chain->items[i].crt = NULL; - ver_chain->items[i].flags = -1; + ver_chain->items[i].flags = (uint32_t) -1; } ver_chain->len = 0; @@ -406,7 +393,7 @@ static int x509_get_version( unsigned char **p, return( 0 ); } - return( ret ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); } end = *p + len; @@ -473,7 +460,7 @@ static int x509_get_uid( unsigned char **p, if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) return( 0 ); - return( ret ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); } uid->p = *p; @@ -712,14 +699,13 @@ static int x509_get_crt_ext( unsigned char **p, size_t len; unsigned char *end_ext_data, *end_ext_octet; - if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) - { - if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) - return( 0 ); + if( *p == end ) + return( 0 ); + if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) return( ret ); - } + end = crt->v3_ext.p + crt->v3_ext.len; while( *p < end ) { /* @@ -1291,7 +1277,6 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) char filename[MAX_PATH]; char *p; size_t len = strlen( path ); - int lengthAsInt = 0; WIN32_FIND_DATAW file_data; HANDLE hFind; @@ -1306,18 +1291,7 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) p = filename + len; filename[len++] = '*'; - if ( FAILED ( SizeTToInt( len, &lengthAsInt ) ) ) - return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); - - /* - * Note this function uses the code page CP_ACP, and assumes the incoming - * string is encoded in ANSI, before translating it into Unicode. If the - * incoming string were changed to be UTF-8, then the length check needs to - * change to check the number of characters, not the number of bytes, in the - * incoming string are less than MAX_PATH to avoid a buffer overrun with - * MultiByteToWideChar(). - */ - w_ret = MultiByteToWideChar( CP_ACP, 0, filename, lengthAsInt, szDir, + w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir, MAX_PATH - 3 ); if( w_ret == 0 ) return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); @@ -1334,11 +1308,8 @@ int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) continue; - if ( FAILED( SizeTToInt( wcslen( file_data.cFileName ), &lengthAsInt ) ) ) - return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); - w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, - lengthAsInt, + lstrlenW( file_data.cFileName ), p, (int) len - 1, NULL, NULL ); if( w_ret == 0 ) @@ -1467,7 +1438,7 @@ static int x509_info_subject_alt_name( char **buf, size_t *size, } #define CERT_TYPE(type,name) \ - if( ns_cert_type & type ) \ + if( ns_cert_type & (type) ) \ PRINT_ITEM( name ); static int x509_info_cert_type( char **buf, size_t *size, @@ -1494,7 +1465,7 @@ static int x509_info_cert_type( char **buf, size_t *size, } #define KEY_USAGE(code,name) \ - if( key_usage & code ) \ + if( key_usage & (code) ) \ PRINT_ITEM( name ); static int x509_info_key_usage( char **buf, size_t *size, diff --git a/thirdparty/mbedtls/library/x509_csr.c b/thirdparty/mbedtls/library/x509_csr.c index f84425728a..c8c08c87b2 100644 --- a/thirdparty/mbedtls/library/x509_csr.c +++ b/thirdparty/mbedtls/library/x509_csr.c @@ -279,15 +279,24 @@ int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, siz { mbedtls_pem_init( &pem ); ret = mbedtls_pem_read_buffer( &pem, - "-----BEGIN CERTIFICATE REQUEST-----", - "-----END CERTIFICATE REQUEST-----", - buf, NULL, 0, &use_len ); + "-----BEGIN CERTIFICATE REQUEST-----", + "-----END CERTIFICATE REQUEST-----", + buf, NULL, 0, &use_len ); + if( ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN NEW CERTIFICATE REQUEST-----", + "-----END NEW CERTIFICATE REQUEST-----", + buf, NULL, 0, &use_len ); + } if( ret == 0 ) + { /* * Was PEM encoded, parse the result */ ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen ); + } mbedtls_pem_free( &pem ); if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) diff --git a/thirdparty/mbedtls/library/x509write_crt.c b/thirdparty/mbedtls/library/x509write_crt.c index b1ef216c95..10497e752b 100644 --- a/thirdparty/mbedtls/library/x509write_crt.c +++ b/thirdparty/mbedtls/library/x509write_crt.c @@ -218,26 +218,51 @@ int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert * } #endif /* MBEDTLS_SHA1_C */ +static size_t crt_get_unused_bits_for_named_bitstring( unsigned char bitstring, + size_t bit_offset ) +{ + size_t unused_bits; + + /* Count the unused bits removing trailing 0s */ + for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ ) + if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 ) + break; + + return( unused_bits ); +} + int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, unsigned int key_usage ) { unsigned char buf[4], ku; unsigned char *c; int ret; - - /* We currently only support 7 bits, from 0x80 to 0x02 */ - if( ( key_usage & ~0xfe ) != 0 ) + size_t unused_bits; + const unsigned int allowed_bits = MBEDTLS_X509_KU_DIGITAL_SIGNATURE | + MBEDTLS_X509_KU_NON_REPUDIATION | + MBEDTLS_X509_KU_KEY_ENCIPHERMENT | + MBEDTLS_X509_KU_DATA_ENCIPHERMENT | + MBEDTLS_X509_KU_KEY_AGREEMENT | + MBEDTLS_X509_KU_KEY_CERT_SIGN | + MBEDTLS_X509_KU_CRL_SIGN; + + /* Check that nothing other than the allowed flags is set */ + if( ( key_usage & ~allowed_bits ) != 0 ) return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); c = buf + 4; - ku = (unsigned char) key_usage; + ku = (unsigned char)key_usage; + unused_bits = crt_get_unused_bits_for_named_bitstring( ku, 1 ); + ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 8 - unused_bits ); - if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 7 ) ) != 4 ) + if( ret < 0 ) return( ret ); + else if( ret < 3 || ret > 4 ) + return( MBEDTLS_ERR_X509_INVALID_FORMAT ); ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), - 1, buf, 4 ); + 1, c, (size_t)ret ); if( ret != 0 ) return( ret ); @@ -249,16 +274,22 @@ int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, { unsigned char buf[4]; unsigned char *c; + size_t unused_bits; int ret; c = buf + 4; - if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 ) + unused_bits = crt_get_unused_bits_for_named_bitstring( ns_cert_type, 0 ); + ret = mbedtls_asn1_write_bitstring( &c, + buf, + &ns_cert_type, + 8 - unused_bits ); + if( ret < 3 || ret > 4 ) return( ret ); ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), - 0, buf, 4 ); + 0, c, (size_t)ret ); if( ret != 0 ) return( ret ); diff --git a/thirdparty/mbedtls/library/x509write_csr.c b/thirdparty/mbedtls/library/x509write_csr.c index 66cee56014..d70ba0ed92 100644 --- a/thirdparty/mbedtls/library/x509write_csr.c +++ b/thirdparty/mbedtls/library/x509write_csr.c @@ -81,20 +81,39 @@ int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx, 0, val, val_len ); } +static size_t csr_get_unused_bits_for_named_bitstring( unsigned char bitstring, + size_t bit_offset ) +{ + size_t unused_bits; + + /* Count the unused bits removing trailing 0s */ + for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ ) + if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 ) + break; + + return( unused_bits ); +} + int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ) { unsigned char buf[4]; unsigned char *c; + size_t unused_bits; int ret; c = buf + 4; - if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 ) + unused_bits = csr_get_unused_bits_for_named_bitstring( key_usage, 0 ); + ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 8 - unused_bits ); + + if( ret < 0 ) return( ret ); + else if( ret < 3 || ret > 4 ) + return( MBEDTLS_ERR_X509_INVALID_FORMAT ); ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), - buf, 4 ); + c, (size_t)ret ); if( ret != 0 ) return( ret ); @@ -106,16 +125,25 @@ int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx, { unsigned char buf[4]; unsigned char *c; + size_t unused_bits; int ret; c = buf + 4; - if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 ) + unused_bits = csr_get_unused_bits_for_named_bitstring( ns_cert_type, 0 ); + ret = mbedtls_asn1_write_bitstring( &c, + buf, + &ns_cert_type, + 8 - unused_bits ); + + if( ret < 0 ) + return( ret ); + else if( ret < 3 || ret > 4 ) return( ret ); ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), - buf, 4 ); + c, (size_t)ret ); if( ret != 0 ) return( ret ); diff --git a/thirdparty/misc/aes256.cpp b/thirdparty/misc/aes256.cpp deleted file mode 100644 index dc271928b4..0000000000 --- a/thirdparty/misc/aes256.cpp +++ /dev/null @@ -1,397 +0,0 @@ -/* -* Byte-oriented AES-256 implementation. -* All lookup tables replaced with 'on the fly' calculations. -* -* Copyright (c) 2007-2011 Ilya O. Levin, http://www.literatecode.com -* Other contributors: Hal Finney -* -* Permission to use, copy, modify, and distribute this software for any -* purpose with or without fee is hereby granted, provided that the above -* copyright notice and this permission notice appear in all copies. -* -* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -#include "aes256.h" - -#define FD(x) (((x) >> 1) ^ (((x) & 1) ? 0x8d : 0)) - -#define BACK_TO_TABLES - -static uint8_t rj_xtime(uint8_t); -static void aes_subBytes(uint8_t *); -static void aes_subBytes_inv(uint8_t *); -static void aes_addRoundKey(uint8_t *, uint8_t *); -static void aes_addRoundKey_cpy(uint8_t *, uint8_t *, uint8_t *); -static void aes_shiftRows(uint8_t *); -static void aes_shiftRows_inv(uint8_t *); -static void aes_mixColumns(uint8_t *); -static void aes_mixColumns_inv(uint8_t *); -static void aes_expandEncKey(uint8_t *, uint8_t *); -static void aes_expandDecKey(uint8_t *, uint8_t *); -#ifndef BACK_TO_TABLES -static uint8_t gf_alog(uint8_t); -static uint8_t gf_log(uint8_t); -static uint8_t gf_mulinv(uint8_t); -static uint8_t rj_sbox(uint8_t); -static uint8_t rj_sbox_inv(uint8_t); -#endif - -#ifdef BACK_TO_TABLES - -static const uint8_t sbox[256] = { - 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, - 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, - 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, - 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, - 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, - 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, - 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, - 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, - 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, - 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, - 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, - 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, - 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, - 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, - 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, - 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, - 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, - 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, - 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, - 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, - 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, - 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, - 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, - 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, - 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, - 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, - 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, - 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, - 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, - 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, - 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, - 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 -}; -static const uint8_t sboxinv[256] = { - 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, - 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, - 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, - 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, - 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, - 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, - 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, - 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, - 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, - 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, - 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, - 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, - 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, - 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, - 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, - 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, - 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, - 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, - 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, - 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, - 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, - 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, - 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, - 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, - 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, - 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, - 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, - 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, - 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, - 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, - 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, - 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d -}; - -#define rj_sbox(x) sbox[(x)] -#define rj_sbox_inv(x) sboxinv[(x)] - -#else /* tableless subroutines */ - -/* -------------------------------------------------------------------------- */ -static uint8_t gf_alog(uint8_t x) // calculate anti-logarithm gen 3 -{ - uint8_t y = 1, i; - - for (i = 0; i < x; i++) y ^= rj_xtime(y); - - return y; -} /* gf_alog */ - -/* -------------------------------------------------------------------------- */ -static uint8_t gf_log(uint8_t x) // calculate logarithm gen 3 -{ - uint8_t y, i = 0; - - if (x) - for (i = 1, y = 1; i > 0; i++ ) - { - y ^= rj_xtime(y); - if (y == x) break; - } - - return i; -} /* gf_log */ - - -/* -------------------------------------------------------------------------- */ -static uint8_t gf_mulinv(uint8_t x) // calculate multiplicative inverse -{ - return (x) ? gf_alog(255 - gf_log(x)) : 0; -} /* gf_mulinv */ - -/* -------------------------------------------------------------------------- */ -static uint8_t rj_sbox(uint8_t x) -{ - uint8_t y, sb; - - sb = y = gf_mulinv(x); - y = (uint8_t)(y << 1) | (y >> 7), sb ^= y; - y = (uint8_t)(y << 1) | (y >> 7), sb ^= y; - y = (uint8_t)(y << 1) | (y >> 7), sb ^= y; - y = (uint8_t)(y << 1) | (y >> 7), sb ^= y; - - return (sb ^ 0x63); -} /* rj_sbox */ - -/* -------------------------------------------------------------------------- */ -static uint8_t rj_sbox_inv(uint8_t x) -{ - uint8_t y, sb; - - y = x ^ 0x63; - sb = y = (uint8_t)(y << 1) | (y >> 7); - y = (uint8_t)(y << 2) | (y >> 6); - sb ^= y; - y = (uint8_t)(y << 3) | (y >> 5); - sb ^= y; - - return gf_mulinv(sb); -} /* rj_sbox_inv */ - -#endif - -/* -------------------------------------------------------------------------- */ -static uint8_t rj_xtime(uint8_t x) -{ - uint8_t y = (uint8_t)(x << 1); - return (x & 0x80) ? (y ^ 0x1b) : y; -} /* rj_xtime */ - -/* -------------------------------------------------------------------------- */ -static void aes_subBytes(uint8_t *buf) -{ - register uint8_t i = 16; - - while (i--) buf[i] = rj_sbox(buf[i]); -} /* aes_subBytes */ - -/* -------------------------------------------------------------------------- */ -static void aes_subBytes_inv(uint8_t *buf) -{ - register uint8_t i = 16; - - while (i--) buf[i] = rj_sbox_inv(buf[i]); -} /* aes_subBytes_inv */ - -/* -------------------------------------------------------------------------- */ -static void aes_addRoundKey(uint8_t *buf, uint8_t *key) -{ - register uint8_t i = 16; - - while (i--) buf[i] ^= key[i]; -} /* aes_addRoundKey */ - -/* -------------------------------------------------------------------------- */ -static void aes_addRoundKey_cpy(uint8_t *buf, uint8_t *key, uint8_t *cpk) -{ - register uint8_t i = 16; - - while (i--) buf[i] ^= (cpk[i] = key[i]), cpk[16 + i] = key[16 + i]; -} /* aes_addRoundKey_cpy */ - - -/* -------------------------------------------------------------------------- */ -static void aes_shiftRows(uint8_t *buf) -{ - register uint8_t i, j; /* to make it potentially parallelable :) */ - - i = buf[1], buf[1] = buf[5], buf[5] = buf[9], buf[9] = buf[13], buf[13] = i; - i = buf[10], buf[10] = buf[2], buf[2] = i; - j = buf[3], buf[3] = buf[15], buf[15] = buf[11], buf[11] = buf[7], buf[7] = j; - j = buf[14], buf[14] = buf[6], buf[6] = j; - -} /* aes_shiftRows */ - -/* -------------------------------------------------------------------------- */ -static void aes_shiftRows_inv(uint8_t *buf) -{ - register uint8_t i, j; /* same as above :) */ - - i = buf[1], buf[1] = buf[13], buf[13] = buf[9], buf[9] = buf[5], buf[5] = i; - i = buf[2], buf[2] = buf[10], buf[10] = i; - j = buf[3], buf[3] = buf[7], buf[7] = buf[11], buf[11] = buf[15], buf[15] = j; - j = buf[6], buf[6] = buf[14], buf[14] = j; - -} /* aes_shiftRows_inv */ - -/* -------------------------------------------------------------------------- */ -static void aes_mixColumns(uint8_t *buf) -{ - register uint8_t i, a, b, c, d, e; - - for (i = 0; i < 16; i += 4) - { - a = buf[i]; - b = buf[i + 1]; - c = buf[i + 2]; - d = buf[i + 3]; - e = a ^ b ^ c ^ d; - buf[i] ^= e ^ rj_xtime(a ^ b); - buf[i + 1] ^= e ^ rj_xtime(b ^ c); - buf[i + 2] ^= e ^ rj_xtime(c ^ d); - buf[i + 3] ^= e ^ rj_xtime(d ^ a); - } -} /* aes_mixColumns */ - -/* -------------------------------------------------------------------------- */ -void aes_mixColumns_inv(uint8_t *buf) -{ - register uint8_t i, a, b, c, d, e, x, y, z; - - for (i = 0; i < 16; i += 4) - { - a = buf[i]; - b = buf[i + 1]; - c = buf[i + 2]; - d = buf[i + 3]; - e = a ^ b ^ c ^ d; - z = rj_xtime(e); - x = e ^ rj_xtime(rj_xtime(z ^ a ^ c)); - y = e ^ rj_xtime(rj_xtime(z ^ b ^ d)); - buf[i] ^= x ^ rj_xtime(a ^ b); - buf[i + 1] ^= y ^ rj_xtime(b ^ c); - buf[i + 2] ^= x ^ rj_xtime(c ^ d); - buf[i + 3] ^= y ^ rj_xtime(d ^ a); - } -} /* aes_mixColumns_inv */ - -/* -------------------------------------------------------------------------- */ -static void aes_expandEncKey(uint8_t *k, uint8_t *rc) -{ - register uint8_t i; - - k[0] ^= rj_sbox(k[29]) ^ (*rc); - k[1] ^= rj_sbox(k[30]); - k[2] ^= rj_sbox(k[31]); - k[3] ^= rj_sbox(k[28]); - *rc = rj_xtime( *rc); - - for(i = 4; i < 16; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3], - k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1]; - k[16] ^= rj_sbox(k[12]); - k[17] ^= rj_sbox(k[13]); - k[18] ^= rj_sbox(k[14]); - k[19] ^= rj_sbox(k[15]); - - for(i = 20; i < 32; i += 4) k[i] ^= k[i - 4], k[i + 1] ^= k[i - 3], - k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1]; - -} /* aes_expandEncKey */ - -/* -------------------------------------------------------------------------- */ -void aes_expandDecKey(uint8_t *k, uint8_t *rc) -{ - uint8_t i; - - for(i = 28; i > 16; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3], - k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1]; - - k[16] ^= rj_sbox(k[12]); - k[17] ^= rj_sbox(k[13]); - k[18] ^= rj_sbox(k[14]); - k[19] ^= rj_sbox(k[15]); - - for(i = 12; i > 0; i -= 4) k[i + 0] ^= k[i - 4], k[i + 1] ^= k[i - 3], - k[i + 2] ^= k[i - 2], k[i + 3] ^= k[i - 1]; - - *rc = FD(*rc); - k[0] ^= rj_sbox(k[29]) ^ (*rc); - k[1] ^= rj_sbox(k[30]); - k[2] ^= rj_sbox(k[31]); - k[3] ^= rj_sbox(k[28]); -} /* aes_expandDecKey */ - - -/* -------------------------------------------------------------------------- */ -void aes256_init(aes256_context *ctx, uint8_t *k) -{ - uint8_t rcon = 1; - register uint8_t i; - - for (i = 0; i < sizeof(ctx->key); i++) ctx->enckey[i] = ctx->deckey[i] = k[i]; - for (i = 8; --i;) aes_expandEncKey(ctx->deckey, &rcon); -} /* aes256_init */ - -/* -------------------------------------------------------------------------- */ -void aes256_done(aes256_context *ctx) -{ - register uint8_t i; - - for (i = 0; i < sizeof(ctx->key); i++) - ctx->key[i] = ctx->enckey[i] = ctx->deckey[i] = 0; -} /* aes256_done */ - -/* -------------------------------------------------------------------------- */ -void aes256_encrypt_ecb(aes256_context *ctx, uint8_t *buf) -{ - uint8_t i, rcon; - - aes_addRoundKey_cpy(buf, ctx->enckey, ctx->key); - for(i = 1, rcon = 1; i < 14; ++i) - { - aes_subBytes(buf); - aes_shiftRows(buf); - aes_mixColumns(buf); - if( i & 1 ) aes_addRoundKey( buf, &ctx->key[16]); - else aes_expandEncKey(ctx->key, &rcon), aes_addRoundKey(buf, ctx->key); - } - aes_subBytes(buf); - aes_shiftRows(buf); - aes_expandEncKey(ctx->key, &rcon); - aes_addRoundKey(buf, ctx->key); -} /* aes256_encrypt */ - -/* -------------------------------------------------------------------------- */ -void aes256_decrypt_ecb(aes256_context *ctx, uint8_t *buf) -{ - uint8_t i, rcon; - - aes_addRoundKey_cpy(buf, ctx->deckey, ctx->key); - aes_shiftRows_inv(buf); - aes_subBytes_inv(buf); - - for (i = 14, rcon = 0x80; --i;) - { - if( ( i & 1 ) ) - { - aes_expandDecKey(ctx->key, &rcon); - aes_addRoundKey(buf, &ctx->key[16]); - } - else aes_addRoundKey(buf, ctx->key); - aes_mixColumns_inv(buf); - aes_shiftRows_inv(buf); - aes_subBytes_inv(buf); - } - aes_addRoundKey( buf, ctx->key); -} /* aes256_decrypt */ diff --git a/thirdparty/misc/aes256.h b/thirdparty/misc/aes256.h deleted file mode 100644 index 150a0670f5..0000000000 --- a/thirdparty/misc/aes256.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* Byte-oriented AES-256 implementation. -* All lookup tables replaced with 'on the fly' calculations. -* -* Copyright (c) 2007-2009 Ilya O. Levin, http://www.literatecode.com -* Other contributors: Hal Finney -* -* Permission to use, copy, modify, and distribute this software for any -* purpose with or without fee is hereby granted, provided that the above -* copyright notice and this permission notice appear in all copies. -* -* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#ifndef AES_256_H -#define AES_256_H - -#include "core/typedefs.h" - -#ifdef __cplusplus -extern "C" { -#endif - - typedef struct { - uint8_t key[32]; - uint8_t enckey[32]; - uint8_t deckey[32]; - } aes256_context; - - - void aes256_init(aes256_context *, uint8_t * /* key */); - void aes256_done(aes256_context *); - void aes256_encrypt_ecb(aes256_context *, uint8_t * /* plaintext */); - void aes256_decrypt_ecb(aes256_context *, uint8_t * /* cipertext */); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/thirdparty/misc/base64.c b/thirdparty/misc/base64.c deleted file mode 100644 index 0929ae5db5..0000000000 --- a/thirdparty/misc/base64.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * File: base64.c - * Description: Simple BASE64 conversion methods - * Author: Ari Edelkind - * License: Public Domain - * Website: http://episec.com/people/edelkind/c.html - */ - -#include <string.h> - -char b64string[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -long base64_encode (to, from, len) - char *to, *from; - unsigned int len; -{ - char *fromp = from; - char *top = to; - unsigned char cbyte; - unsigned char obyte; - char end[3]; - - for (; len >= 3; len -= 3) { - cbyte = *fromp++; - *top++ = b64string[(int)(cbyte >> 2)]; - obyte = (cbyte << 4) & 0x30; /* 0011 0000 */ - - cbyte = *fromp++; - obyte |= (cbyte >> 4); /* 0000 1111 */ - *top++ = b64string[(int)obyte]; - obyte = (cbyte << 2) & 0x3C; /* 0011 1100 */ - - cbyte = *fromp++; - obyte |= (cbyte >> 6); /* 0000 0011 */ - *top++ = b64string[(int)obyte]; - *top++ = b64string[(int)(cbyte & 0x3F)];/* 0011 1111 */ - } - - if (len) { - end[0] = *fromp++; - if (--len) end[1] = *fromp++; else end[1] = 0; - end[2] = 0; - - cbyte = end[0]; - *top++ = b64string[(int)(cbyte >> 2)]; - obyte = (cbyte << 4) & 0x30; /* 0011 0000 */ - - cbyte = end[1]; - obyte |= (cbyte >> 4); - *top++ = b64string[(int)obyte]; - obyte = (cbyte << 2) & 0x3C; /* 0011 1100 */ - - if (len) *top++ = b64string[(int)obyte]; - else *top++ = '='; - *top++ = '='; - } - *top = 0; - return top - to; -} - -/* badchar(): check if c is decent; puts either the */ -/* location of c or null into p. */ -#define badchar(c,p) (!(p = memchr(b64string, c, 64))) - -long base64_decode (to, from, len) - char *to, *from; - unsigned int len; -{ - char *fromp = from; - char *top = to; - char *p; - unsigned char cbyte; - unsigned char obyte; - int padding = 0; - - for (; len >= 4; len -= 4) { - if ((cbyte = *fromp++) == '=') cbyte = 0; - else { - if (badchar(cbyte, p)) return -1; - cbyte = (p - b64string); - } - obyte = cbyte << 2; /* 1111 1100 */ - - if ((cbyte = *fromp++) == '=') cbyte = 0; - else { - if (badchar(cbyte, p)) return -1; - cbyte = p - b64string; - } - obyte |= cbyte >> 4; /* 0000 0011 */ - *top++ = obyte; - - obyte = cbyte << 4; /* 1111 0000 */ - if ((cbyte = *fromp++) == '=') { cbyte = 0; padding++; } - else { - padding = 0; - if (badchar (cbyte, p)) return -1; - cbyte = p - b64string; - } - obyte |= cbyte >> 2; /* 0000 1111 */ - *top++ = obyte; - - obyte = cbyte << 6; /* 1100 0000 */ - if ((cbyte = *fromp++) == '=') { cbyte = 0; padding++; } - else { - padding = 0; - if (badchar (cbyte, p)) return -1; - cbyte = p - b64string; - } - obyte |= cbyte; /* 0011 1111 */ - *top++ = obyte; - } - - *top = 0; - if (len) return -1; - return (top - to) - padding; -} - diff --git a/thirdparty/misc/base64.h b/thirdparty/misc/base64.h deleted file mode 100644 index ffcd0af973..0000000000 --- a/thirdparty/misc/base64.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * File: base64.h - * Description: Simple BASE64 conversion methods - * Author: Ari Edelkind - * License: Public Domain - * Website: http://episec.com/people/edelkind/c.html - */ - -#ifndef BASE64_H -#define BASE64_H - -extern "C" { - -long base64_encode(char *to, char *from, unsigned int len); -long base64_decode(char *to, char *from, unsigned int len); -}; - -#endif /* BASE64_H */ diff --git a/thirdparty/misc/md5.cpp b/thirdparty/misc/md5.cpp deleted file mode 100644 index 1653ab0be5..0000000000 --- a/thirdparty/misc/md5.cpp +++ /dev/null @@ -1,267 +0,0 @@ -/* - ********************************************************************** - ** md5.c ** - ** RSA Data Security, Inc. MD5 Message Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 1/91 SRD,AJ,BSK,JT Reference C Version ** - ********************************************************************** - */ - -/* - ********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - ********************************************************************** - */ - -/* -- include the following line if the md5.h header file is separate -- */ -#include "md5.h" - -/* forward declaration */ -static void Transform (uint32_t *buf, uint32_t *in); - - -static unsigned char PADDING[64] = { - 0x80, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -/* F, G and H are basic MD5 functions: selection, majority, parity */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4 */ -/* Rotation is separate from addition to prevent recomputation */ -#define FF(a, b, c, d, x, s, ac) \ - {(a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) \ - {(a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) \ - {(a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) \ - {(a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -void MD5Init (MD5_CTX *mdContext) -{ - mdContext->i[0] = mdContext->i[1] = (uint32_t)0; - - /* Load magic initialization constants. - */ - mdContext->buf[0] = (uint32_t)0x67452301; - mdContext->buf[1] = (uint32_t)0xefcdab89; - mdContext->buf[2] = (uint32_t)0x98badcfe; - mdContext->buf[3] = (uint32_t)0x10325476; -} - -void MD5Update (MD5_CTX *mdContext,unsigned char *inBuf,unsigned int inLen) { - uint32_t in[16]; - int mdi; - unsigned int i, ii; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* update number of bits */ - if ((mdContext->i[0] + ((uint32_t)inLen << 3)) < mdContext->i[0]) - mdContext->i[1]++; - mdContext->i[0] += ((uint32_t)inLen << 3); - mdContext->i[1] += ((uint32_t)inLen >> 29); - - while (inLen--) { - /* add new character to buffer, increment mdi */ - mdContext->in[mdi++] = *inBuf++; - - /* transform if necessary */ - if (mdi == 0x40) { - for (i = 0, ii = 0; i < 16; i++, ii += 4) - in[i] = (((uint32_t)mdContext->in[ii+3]) << 24) | - (((uint32_t)mdContext->in[ii+2]) << 16) | - (((uint32_t)mdContext->in[ii+1]) << 8) | - ((uint32_t)mdContext->in[ii]); - Transform (mdContext->buf, in); - mdi = 0; - } - } -} - -void MD5Final (MD5_CTX *mdContext) { - uint32_t in[16]; - int mdi; - unsigned int i, ii; - unsigned int padLen; - - /* save number of bits */ - in[14] = mdContext->i[0]; - in[15] = mdContext->i[1]; - - /* compute number of bytes mod 64 */ - mdi = (int)((mdContext->i[0] >> 3) & 0x3F); - - /* pad out to 56 mod 64 */ - padLen = (mdi < 56) ? (56 - mdi) : (120 - mdi); - MD5Update (mdContext, PADDING, padLen); - - /* append length in bits and transform */ - for (i = 0, ii = 0; i < 14; i++, ii += 4) - in[i] = (((uint32_t)mdContext->in[ii+3]) << 24) | - (((uint32_t)mdContext->in[ii+2]) << 16) | - (((uint32_t)mdContext->in[ii+1]) << 8) | - ((uint32_t)mdContext->in[ii]); - Transform (mdContext->buf, in); - - /* store buffer in digest */ - for (i = 0, ii = 0; i < 4; i++, ii += 4) { - mdContext->digest[ii] = (unsigned char)(mdContext->buf[i] & 0xFF); - mdContext->digest[ii+1] = - (unsigned char)((mdContext->buf[i] >> 8) & 0xFF); - mdContext->digest[ii+2] = - (unsigned char)((mdContext->buf[i] >> 16) & 0xFF); - mdContext->digest[ii+3] = - (unsigned char)((mdContext->buf[i] >> 24) & 0xFF); - } -} - -/* Basic MD5 step. Transform buf based on in. - */ -static void Transform (uint32_t *buf, uint32_t *in) { - uint32_t a = buf[0], b = buf[1], c = buf[2], d = buf[3]; - - /* Round 1 */ -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 - FF ( a, b, c, d, in[ 0], S11, 3614090360); /* 1 */ - FF ( d, a, b, c, in[ 1], S12, 3905402710); /* 2 */ - FF ( c, d, a, b, in[ 2], S13, 606105819); /* 3 */ - FF ( b, c, d, a, in[ 3], S14, 3250441966); /* 4 */ - FF ( a, b, c, d, in[ 4], S11, 4118548399); /* 5 */ - FF ( d, a, b, c, in[ 5], S12, 1200080426); /* 6 */ - FF ( c, d, a, b, in[ 6], S13, 2821735955); /* 7 */ - FF ( b, c, d, a, in[ 7], S14, 4249261313); /* 8 */ - FF ( a, b, c, d, in[ 8], S11, 1770035416); /* 9 */ - FF ( d, a, b, c, in[ 9], S12, 2336552879); /* 10 */ - FF ( c, d, a, b, in[10], S13, 4294925233); /* 11 */ - FF ( b, c, d, a, in[11], S14, 2304563134); /* 12 */ - FF ( a, b, c, d, in[12], S11, 1804603682); /* 13 */ - FF ( d, a, b, c, in[13], S12, 4254626195); /* 14 */ - FF ( c, d, a, b, in[14], S13, 2792965006); /* 15 */ - FF ( b, c, d, a, in[15], S14, 1236535329); /* 16 */ - - /* Round 2 */ -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 - GG ( a, b, c, d, in[ 1], S21, 4129170786); /* 17 */ - GG ( d, a, b, c, in[ 6], S22, 3225465664); /* 18 */ - GG ( c, d, a, b, in[11], S23, 643717713); /* 19 */ - GG ( b, c, d, a, in[ 0], S24, 3921069994); /* 20 */ - GG ( a, b, c, d, in[ 5], S21, 3593408605); /* 21 */ - GG ( d, a, b, c, in[10], S22, 38016083); /* 22 */ - GG ( c, d, a, b, in[15], S23, 3634488961); /* 23 */ - GG ( b, c, d, a, in[ 4], S24, 3889429448); /* 24 */ - GG ( a, b, c, d, in[ 9], S21, 568446438); /* 25 */ - GG ( d, a, b, c, in[14], S22, 3275163606); /* 26 */ - GG ( c, d, a, b, in[ 3], S23, 4107603335); /* 27 */ - GG ( b, c, d, a, in[ 8], S24, 1163531501); /* 28 */ - GG ( a, b, c, d, in[13], S21, 2850285829); /* 29 */ - GG ( d, a, b, c, in[ 2], S22, 4243563512); /* 30 */ - GG ( c, d, a, b, in[ 7], S23, 1735328473); /* 31 */ - GG ( b, c, d, a, in[12], S24, 2368359562); /* 32 */ - - /* Round 3 */ -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 - HH ( a, b, c, d, in[ 5], S31, 4294588738); /* 33 */ - HH ( d, a, b, c, in[ 8], S32, 2272392833); /* 34 */ - HH ( c, d, a, b, in[11], S33, 1839030562); /* 35 */ - HH ( b, c, d, a, in[14], S34, 4259657740); /* 36 */ - HH ( a, b, c, d, in[ 1], S31, 2763975236); /* 37 */ - HH ( d, a, b, c, in[ 4], S32, 1272893353); /* 38 */ - HH ( c, d, a, b, in[ 7], S33, 4139469664); /* 39 */ - HH ( b, c, d, a, in[10], S34, 3200236656); /* 40 */ - HH ( a, b, c, d, in[13], S31, 681279174); /* 41 */ - HH ( d, a, b, c, in[ 0], S32, 3936430074); /* 42 */ - HH ( c, d, a, b, in[ 3], S33, 3572445317); /* 43 */ - HH ( b, c, d, a, in[ 6], S34, 76029189); /* 44 */ - HH ( a, b, c, d, in[ 9], S31, 3654602809); /* 45 */ - HH ( d, a, b, c, in[12], S32, 3873151461); /* 46 */ - HH ( c, d, a, b, in[15], S33, 530742520); /* 47 */ - HH ( b, c, d, a, in[ 2], S34, 3299628645); /* 48 */ - - /* Round 4 */ -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - II ( a, b, c, d, in[ 0], S41, 4096336452); /* 49 */ - II ( d, a, b, c, in[ 7], S42, 1126891415); /* 50 */ - II ( c, d, a, b, in[14], S43, 2878612391); /* 51 */ - II ( b, c, d, a, in[ 5], S44, 4237533241); /* 52 */ - II ( a, b, c, d, in[12], S41, 1700485571); /* 53 */ - II ( d, a, b, c, in[ 3], S42, 2399980690); /* 54 */ - II ( c, d, a, b, in[10], S43, 4293915773); /* 55 */ - II ( b, c, d, a, in[ 1], S44, 2240044497); /* 56 */ - II ( a, b, c, d, in[ 8], S41, 1873313359); /* 57 */ - II ( d, a, b, c, in[15], S42, 4264355552); /* 58 */ - II ( c, d, a, b, in[ 6], S43, 2734768916); /* 59 */ - II ( b, c, d, a, in[13], S44, 1309151649); /* 60 */ - II ( a, b, c, d, in[ 4], S41, 4149444226); /* 61 */ - II ( d, a, b, c, in[11], S42, 3174756917); /* 62 */ - II ( c, d, a, b, in[ 2], S43, 718787259); /* 63 */ - II ( b, c, d, a, in[ 9], S44, 3951481745); /* 64 */ - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -/* - ********************************************************************** - ** End of md5.c ** - ******************************* (cut) ******************************** - */ diff --git a/thirdparty/misc/md5.h b/thirdparty/misc/md5.h deleted file mode 100644 index 14b3cd3ddf..0000000000 --- a/thirdparty/misc/md5.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef MD5_H -#define MD5_H - -/* - ********************************************************************** - ** md5.h -- Header file for implementation of MD5 ** - ** RSA Data Security, Inc. MD5 Message Digest Algorithm ** - ** Created: 2/17/90 RLR ** - ** Revised: 12/27/90 SRD,AJ,BSK,JT Reference C version ** - ** Revised (for MD5): RLR 4/27/91 ** - ** -- G modified to have y&~z instead of y&z ** - ** -- FF, GG, HH modified to add in last register done ** - ** -- Access pattern: round 2 works mod 5, round 3 works mod 3 ** - ** -- distinct additive constant for each step ** - ** -- round 4 added, working mod 7 ** - ********************************************************************** - */ - -/* - ********************************************************************** - ** Copyright (C) 1990, RSA Data Security, Inc. All rights reserved. ** - ** ** - ** License to copy and use this software is granted provided that ** - ** it is identified as the "RSA Data Security, Inc. MD5 Message ** - ** Digest Algorithm" in all material mentioning or referencing this ** - ** software or this function. ** - ** ** - ** License is also granted to make and use derivative works ** - ** provided that such works are identified as "derived from the RSA ** - ** Data Security, Inc. MD5 Message Digest Algorithm" in all ** - ** material mentioning or referencing the derived work. ** - ** ** - ** RSA Data Security, Inc. makes no representations concerning ** - ** either the merchantability of this software or the suitability ** - ** of this software for any particular purpose. It is provided "as ** - ** is" without express or implied warranty of any kind. ** - ** ** - ** These notices must be retained in any copies of any part of this ** - ** documentation and/or software. ** - ********************************************************************** - */ - -/* NOT typedef a 32 bit type */ - -#include "core/typedefs.h" - -/* Data structure for MD5 (Message Digest) computation */ -typedef struct { - uint32_t i[2]; /* number of _bits_ handled mod 2^64 */ - uint32_t buf[4]; /* scratch buffer */ - unsigned char in[64]; /* input buffer */ - unsigned char digest[16]; /* actual digest after MD5Final call */ -} MD5_CTX; - -void MD5Init (MD5_CTX *mdContext); -void MD5Update (MD5_CTX *mdContext,unsigned char *inBuf,unsigned int inLen); -void MD5Final (MD5_CTX *mdContext); - - - -#endif // MD5_H diff --git a/thirdparty/misc/sha256.c b/thirdparty/misc/sha256.c deleted file mode 100644 index 68a4339af9..0000000000 --- a/thirdparty/misc/sha256.c +++ /dev/null @@ -1,245 +0,0 @@ -/* -* SHA-256 implementation. -* -* Copyright (c) 2010 Ilya O. Levin, http://www.literatecode.com -* -* Permission to use, copy, modify, and distribute this software for any -* purpose with or without fee is hereby granted, provided that the above -* copyright notice and this permission notice appear in all copies. -* -* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -#define SWAP_BYTES -// #define USE_STD_MEMCPY -// #define SELF_TEST - -#ifdef USE_STD_MEMCPY -#include <string.h> -#endif -#include "sha256.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define RL(x,n) (((x) << n) | ((x) >> (32 - n))) -#define RR(x,n) (((x) >> n) | ((x) << (32 - n))) - -#define S0(x) (RR((x), 2) ^ RR((x),13) ^ RR((x),22)) -#define S1(x) (RR((x), 6) ^ RR((x),11) ^ RR((x),25)) -#define G0(x) (RR((x), 7) ^ RR((x),18) ^ ((x) >> 3)) -#define G1(x) (RR((x),17) ^ RR((x),19) ^ ((x) >> 10)) - -#ifdef SWAP_BYTES -#define BSWP(x,y) _bswapw((uint32_t *)(x), (uint32_t)(y)) -#else -#define BSWP(p,n) -#endif -#ifdef USE_STD_MEMCPY -#define MEMCP(x,y,z) memcpy((x),(y),(z)) -#else -#define MEMCP(x,y,z) _memcp((x),(y),(z)) -#endif - -#ifndef __cdecl -#define __cdecl -#endif - -static const uint32_t K[64] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, - 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, - 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, - 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, - 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, - 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, - 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, - 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, - 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 -}; - -/* -------------------------------------------------------------------------- */ -static void _bswapw(uint32_t *p, uint32_t i) -{ - while (i--) p[i] = (RR(p[i],24) & 0x00ff00ff) | (RR(p[i],8) & 0xff00ff00); - -} /* _bswapw */ - -/* -------------------------------------------------------------------------- */ -#ifndef USE_STD_MEMCPY -void * __cdecl _memcp (void *d, const void *s, uint32_t sz) -{ - void *rv = d; - - while (sz--) *(char *)d = *(char *)s, d = (char *)d + 1, s = (char *)s + 1; - - return(rv); -} /* _memcp */ -#endif - -/* -------------------------------------------------------------------------- */ -static void _rtrf(uint32_t *b, uint32_t *p, uint32_t i, uint32_t j) -{ - #define B(x, y) b[(x-y) & 7] - #define P(x, y) p[(x+y) & 15] - - B(7,i) += (j ? (p[i & 15] += G1(P(i,14)) + P(i,9) + G0(P(i,1))) : p[i & 15]) - + K[i+j] + S1(B(4,i)) - + (B(6,i) ^ (B(4,i) & (B(5,i) ^ B(6,i)))); - B(3,i) += B(7,i); - B(7,i) += S0(B(0,i)) + ( (B(0,i) & B(1,i)) | (B(2,i) & (B(0,i) ^ B(1,i))) ); - - #undef P - #undef B -} /* _rtrf */ - -/* -------------------------------------------------------------------------- */ -static void _hash(sha256_context *ctx) -{ - uint32_t b[8], *p, j; - - b[0] = ctx->hash[0]; b[1] = ctx->hash[1]; b[2] = ctx->hash[2]; - b[3] = ctx->hash[3]; b[4] = ctx->hash[4]; b[5] = ctx->hash[5]; - b[6] = ctx->hash[6]; b[7] = ctx->hash[7]; - - for (p = ctx->buf, j = 0; j < 64; j += 16) - _rtrf(b, p, 0, j), _rtrf(b, p, 1, j), _rtrf(b, p, 2, j), - _rtrf(b, p, 3, j), _rtrf(b, p, 4, j), _rtrf(b, p, 5, j), - _rtrf(b, p, 6, j), _rtrf(b, p, 7, j), _rtrf(b, p, 8, j), - _rtrf(b, p, 9, j), _rtrf(b, p, 10, j), _rtrf(b, p, 11, j), - _rtrf(b, p, 12, j), _rtrf(b, p, 13, j), _rtrf(b, p, 14, j), - _rtrf(b, p, 15, j); - - ctx->hash[0] += b[0]; ctx->hash[1] += b[1]; ctx->hash[2] += b[2]; - ctx->hash[3] += b[3]; ctx->hash[4] += b[4]; ctx->hash[5] += b[5]; - ctx->hash[6] += b[6]; ctx->hash[7] += b[7]; - -} /* _hash */ - -/* -------------------------------------------------------------------------- */ -void sha256_init(sha256_context ctx[1]) -{ - ctx->len[0] = ctx->len[1] = 0; - ctx->hash[0] = 0x6a09e667; ctx->hash[1] = 0xbb67ae85; - ctx->hash[2] = 0x3c6ef372; ctx->hash[3] = 0xa54ff53a; - ctx->hash[4] = 0x510e527f; ctx->hash[5] = 0x9b05688c; - ctx->hash[6] = 0x1f83d9ab; ctx->hash[7] = 0x5be0cd19; - -} /* sha256_init */ - -/* -------------------------------------------------------------------------- */ -void sha256_hash(sha256_context *ctx, uint8_t *dat, uint32_t sz) -{ - register uint32_t i = ctx->len[0] & 63, l, j; - - if ((ctx->len[0] += sz) < sz) ++(ctx->len[1]); - - for (j = 0, l = 64-i; sz >= l; j += l, sz -= l, l = 64, i = 0) - { - MEMCP(&ctx->buf[i], &dat[j], l); - BSWP(ctx->buf, 16 ); - _hash(ctx); - } - MEMCP(&ctx->buf[i], &dat[j], sz); - -} /* _hash */ - -/* -------------------------------------------------------------------------- */ -void sha256_done(sha256_context *ctx, uint8_t *buf) -{ - uint32_t i = (uint32_t)(ctx->len[0] & 63), j = ((~i) & 3) << 3; - - BSWP(ctx->buf, (i + 3) >> 2); - - ctx->buf[i >> 2] &= 0xffffff80 << j; /* add padding */ - ctx->buf[i >> 2] |= 0x00000080 << j; - - if (i < 56) i = (i >> 2) + 1; - else ctx->buf[15] ^= (i < 60) ? ctx->buf[15] : 0, _hash(ctx), i = 0; - - while (i < 14) ctx->buf[i++] = 0; - - ctx->buf[14] = (ctx->len[1] << 3)|(ctx->len[0] >> 29); /* add length */ - ctx->buf[15] = ctx->len[0] << 3; - - _hash(ctx); - - for (i = 0; i < 32; i++) - ctx->buf[i % 16] = 0, /* may remove this line in case of a DIY cleanup */ - buf[i] = (uint8_t)(ctx->hash[i >> 2] >> ((~i & 3) << 3)); - -} /* sha256_done */ - - -#ifdef SELF_TEST -#pragma warning (push, 0) -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#pragma warning(pop) - -char *buf[] = { - "", - "e3b0c442 98fc1c14 9afbf4c8 996fb924 27ae41e4 649b934c a495991b 7852b855", - - "abc", - "ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad", - - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", - "248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1", - - "The quick brown fox jumps over the lazy dog", - "d7a8fbb3 07d78094 69ca9abc b0082e4f 8d5651e4 6d3cdb76 2d02d0bf 37c9e592", - - "The quick brown fox jumps over the lazy cog", /* avalanche effect test */ - "e4c4d8f3 bf76b692 de791a17 3e053211 50f7a345 b46484fe 427f6acc 7ecc81be", - - "bhn5bjmoniertqea40wro2upyflkydsibsk8ylkmgbvwi420t44cq034eou1szc1k0mk46oeb7ktzmlxqkbte2sy", - "9085df2f 02e0cc45 5928d0f5 1b27b4bf 1d9cd260 a66ed1fd a11b0a3f f5756d99" -}; - -int main(int argc, char *argv[]) -{ - sha256_context ctx; - uint8_t hv[32]; - uint32_t i, j; - - for (j = 0; j < (sizeof(buf)/sizeof(buf[0])); j += 2) - { - sha256_init(&ctx); - sha256_hash(&ctx, (uint8_t *)buf[j], (uint32_t)strlen(buf[j])); - sha256_done(&ctx, hv); - printf("input = %s\ndigest: %s\nresult: ", buf[j], buf[j+1]); - for (i = 0; i < 32; i++) printf("%02x%s", hv[i], ((i%4)==3)?" ":""); - printf("\n\n"); - } - - for (j = 1; j < (uint32_t)argc; j++) - { - printf("argv[%d]: %s\nresult: ", (int)j, argv[j]); - sha256_init(&ctx); - sha256_hash(&ctx, (uint8_t *)argv[j], (uint32_t)strlen(argv[j])); - sha256_done(&ctx, hv); - for (i = 0; i < 32; i++) printf("%02x%s", hv[i], ((i%4)==3)?" ":""); - printf("\n\n"); - } - - return 0; -} /* main */ -#endif - -#ifdef __cplusplus -} -#endif diff --git a/thirdparty/misc/sha256.h b/thirdparty/misc/sha256.h deleted file mode 100644 index e19e56b4cc..0000000000 --- a/thirdparty/misc/sha256.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -* SHA-256 implementation. -* -* Copyright (c) 2010 Ilya O. Levin, http://www.literatecode.com -* -* Permission to use, copy, modify, and distribute this software for any -* purpose with or without fee is hereby granted, provided that the above -* copyright notice and this permission notice appear in all copies. -* -* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ -#ifdef _MSC_VER -#ifndef uint8_t -typedef unsigned __int8 uint8_t; -#endif -#ifndef uint32_t -typedef unsigned __int32 uint32_t; -#endif -#ifndef uint64_t -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#endif -#else -#include <stdint.h> -#endif - -#ifdef __cplusplus -extern "C" -{ -#endif - - typedef struct { - uint32_t buf[16]; - uint32_t hash[8]; - uint32_t len[2]; - } sha256_context; - - void sha256_init(sha256_context *); - void sha256_hash(sha256_context *, uint8_t * /* data */, uint32_t /* len */); - void sha256_done(sha256_context *, uint8_t * /* hash */); - -#ifdef __cplusplus -} -#endif diff --git a/thirdparty/misc/stb_vorbis.c b/thirdparty/misc/stb_vorbis.c index 88276026ef..71af404dae 100644 --- a/thirdparty/misc/stb_vorbis.c +++ b/thirdparty/misc/stb_vorbis.c @@ -1,4 +1,4 @@ -// Ogg Vorbis audio decoder - v1.15 - public domain +// Ogg Vorbis audio decoder - v1.16 - public domain // http://nothings.org/stb_vorbis/ // // Original version written by Sean Barrett in 2007. @@ -33,6 +33,7 @@ // Timur Gagiev // // Partial history: +// 1.16 - 2019-03-04 - fix warnings // 1.15 - 2019-02-07 - explicit failure if Ogg Skeleton data is found // 1.14 - 2018-02-11 - delete bogus dealloca usage // 1.13 - 2018-01-29 - fix truncation of last frame (hopefully) @@ -4990,7 +4991,13 @@ stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, con stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc) { - FILE *f = fopen(filename, "rb"); + FILE *f; +#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__) + if (0 != fopen_s(&f, filename, "rb")) + f = NULL; +#else + f = fopen(filename, "rb"); +#endif if (f) return stb_vorbis_open_file(f, TRUE, error, alloc); if (error) *error = VORBIS_file_open_failure; diff --git a/thirdparty/pcre2/AUTHORS b/thirdparty/pcre2/AUTHORS index d5592bbc5b..8d4e15a247 100644 --- a/thirdparty/pcre2/AUTHORS +++ b/thirdparty/pcre2/AUTHORS @@ -8,7 +8,7 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2018 University of Cambridge +Copyright (c) 1997-2019 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-2018 Zoltan Herczeg +Copyright(c) 2010-2019 Zoltan Herczeg All rights reserved. @@ -30,7 +30,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Emain domain: freemail.hu -Copyright(c) 2009-2018 Zoltan Herczeg +Copyright(c) 2009-2019 Zoltan Herczeg All rights reserved. #### diff --git a/thirdparty/pcre2/LICENCE b/thirdparty/pcre2/LICENCE index b0f8804fff..142b3b3f9a 100644 --- a/thirdparty/pcre2/LICENCE +++ b/thirdparty/pcre2/LICENCE @@ -26,7 +26,7 @@ Email domain: cam.ac.uk University of Cambridge Computing Service, Cambridge, England. -Copyright (c) 1997-2018 University of Cambridge +Copyright (c) 1997-2019 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-2018 Zoltan Herczeg +Copyright(c) 2010-2019 Zoltan Herczeg All rights reserved. @@ -48,7 +48,7 @@ Written by: Zoltan Herczeg Email local part: hzmester Email domain: freemail.hu -Copyright(c) 2009-2018 Zoltan Herczeg +Copyright(c) 2009-2019 Zoltan Herczeg All rights reserved. diff --git a/thirdparty/pcre2/src/config.h b/thirdparty/pcre2/src/config.h index 89a52ef848..25d45eeb38 100644 --- a/thirdparty/pcre2/src/config.h +++ b/thirdparty/pcre2/src/config.h @@ -35,6 +35,10 @@ sure both macros are undefined; an emulation function will then be used. */ */ /* #undef BSR_ANYCRLF */ +/* Define to any value to disable the use of the z and t modifiers in + formatting settings such as %zu or %td (this is rarely needed). */ +/* #undef DISABLE_PERCENT_ZT */ + /* If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro to any value. When EBCDIC is set, PCRE2 assumes that all input strings are in EBCDIC. If you do not define this @@ -214,7 +218,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.32" +#define PACKAGE_STRING "PCRE2 10.33" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "pcre2" @@ -223,7 +227,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.32" +#define PACKAGE_VERSION "10.33" /* 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 @@ -299,6 +303,11 @@ sure both macros are undefined; an emulation function will then be used. */ /* Define to any value to enable callout script support in pcre2grep. */ /* #undef SUPPORT_PCRE2GREP_CALLOUT */ +/* Define to any value to enable fork support in pcre2grep callout scripts. + This will have no effect unless SUPPORT_PCRE2GREP_CALLOUT is also defined. + */ +/* #undef SUPPORT_PCRE2GREP_CALLOUT_FORK */ + /* Define to any value to enable JIT support in pcre2grep. Note that this will have no effect unless SUPPORT_JIT is also defined. */ /* #undef SUPPORT_PCRE2GREP_JIT */ @@ -343,7 +352,7 @@ sure both macros are undefined; an emulation function will then be used. */ #endif /* Version number of package */ -#define VERSION "10.32" +#define VERSION "10.33" /* Define to 1 if on MINIX. */ /* #undef _MINIX */ diff --git a/thirdparty/pcre2/src/pcre2.h b/thirdparty/pcre2/src/pcre2.h index 3d2feb7a6b..102b5d91f1 100644 --- a/thirdparty/pcre2/src/pcre2.h +++ b/thirdparty/pcre2/src/pcre2.h @@ -42,15 +42,9 @@ POSSIBILITY OF SUCH DAMAGE. /* The current PCRE version information. */ #define PCRE2_MAJOR 10 -#define PCRE2_MINOR 32 +#define PCRE2_MINOR 33 #define PCRE2_PRERELEASE -#define PCRE2_DATE 2018-09-10 - -/* For the benefit of systems without stdint.h, an alternative is to use -inttypes.h. The existence of these headers is checked by configure or CMake. */ - -#define PCRE2_HAVE_STDINT_H 1 -#define PCRE2_HAVE_INTTYPES_H 1 +#define PCRE2_DATE 2019-04-16 /* 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 @@ -87,18 +81,15 @@ set, we ensure here that it has no effect. */ #define PCRE2_CALL_CONVENTION #endif -/* Have to include limits.h, stdlib.h and stdint.h (or inttypes.h) to ensure -that size_t and uint8_t, UCHAR_MAX, etc are defined. If the system has neither -header, the relevant values must be provided by some other means. */ +/* Have to include limits.h, stdlib.h, and inttypes.h to ensure that size_t and +uint8_t, UCHAR_MAX, etc are defined. Some systems that do have inttypes.h do +not have stdint.h, which is why we use inttypes.h, which according to the C +standard is a superset of stdint.h. If none of these headers are available, +the relevant values must be provided by some other means. */ #include <limits.h> #include <stdlib.h> - -#if PCRE2_HAVE_STDINT_H -#include <stdint.h> -#elif PCRE2_HAVE_INTTYPES_H #include <inttypes.h> -#endif /* Allow for C++ users compiling this directly. */ @@ -158,43 +149,37 @@ D is inspected during pcre2_dfa_match() execution #define PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL 0x00000002u /* C */ #define PCRE2_EXTRA_MATCH_WORD 0x00000004u /* C */ #define PCRE2_EXTRA_MATCH_LINE 0x00000008u /* C */ +#define PCRE2_EXTRA_ESCAPED_CR_IS_LF 0x00000010u /* C */ +#define PCRE2_EXTRA_ALT_BSUX 0x00000020u /* C */ /* These are for pcre2_jit_compile(). */ #define PCRE2_JIT_COMPLETE 0x00000001u /* For full matching */ #define PCRE2_JIT_PARTIAL_SOFT 0x00000002u #define PCRE2_JIT_PARTIAL_HARD 0x00000004u - -/* These are for pcre2_match(), pcre2_dfa_match(), and pcre2_jit_match(). Note -that PCRE2_ANCHORED and PCRE2_NO_UTF_CHECK can also be passed to these -functions (though pcre2_jit_match() ignores the latter since it bypasses all -sanity checks). */ - -#define PCRE2_NOTBOL 0x00000001u -#define PCRE2_NOTEOL 0x00000002u -#define PCRE2_NOTEMPTY 0x00000004u /* ) These two must be kept */ -#define PCRE2_NOTEMPTY_ATSTART 0x00000008u /* ) adjacent to each other. */ -#define PCRE2_PARTIAL_SOFT 0x00000010u -#define PCRE2_PARTIAL_HARD 0x00000020u - -/* These are additional options for pcre2_dfa_match(). */ - -#define PCRE2_DFA_RESTART 0x00000040u -#define PCRE2_DFA_SHORTEST 0x00000080u - -/* These are additional options for pcre2_substitute(), which passes any others -through to pcre2_match(). */ - -#define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u -#define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u -#define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u -#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u -#define PCRE2_SUBSTITUTE_OVERFLOW_LENGTH 0x00001000u - -/* A further option for pcre2_match(), not allowed for pcre2_dfa_match(), -ignored for pcre2_jit_match(). */ - -#define PCRE2_NO_JIT 0x00002000u +#define PCRE2_JIT_INVALID_UTF 0x00000100u + +/* These are for pcre2_match(), pcre2_dfa_match(), pcre2_jit_match(), and +pcre2_substitute(). Some are allowed only for one of the functions, and in +these cases it is noted below. Note that PCRE2_ANCHORED, PCRE2_ENDANCHORED and +PCRE2_NO_UTF_CHECK can also be passed to these functions (though +pcre2_jit_match() ignores the latter since it bypasses all sanity checks). */ + +#define PCRE2_NOTBOL 0x00000001u +#define PCRE2_NOTEOL 0x00000002u +#define PCRE2_NOTEMPTY 0x00000004u /* ) These two must be kept */ +#define PCRE2_NOTEMPTY_ATSTART 0x00000008u /* ) adjacent to each other. */ +#define PCRE2_PARTIAL_SOFT 0x00000010u +#define PCRE2_PARTIAL_HARD 0x00000020u +#define PCRE2_DFA_RESTART 0x00000040u /* pcre2_dfa_match() only */ +#define PCRE2_DFA_SHORTEST 0x00000080u /* pcre2_dfa_match() only */ +#define PCRE2_SUBSTITUTE_GLOBAL 0x00000100u /* pcre2_substitute() only */ +#define PCRE2_SUBSTITUTE_EXTENDED 0x00000200u /* pcre2_substitute() only */ +#define PCRE2_SUBSTITUTE_UNSET_EMPTY 0x00000400u /* pcre2_substitute() only */ +#define PCRE2_SUBSTITUTE_UNKNOWN_UNSET 0x00000800u /* pcre2_substitute() only */ +#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 /* Options for pcre2_pattern_convert(). */ @@ -318,6 +303,8 @@ pcre2_pattern_convert(). */ #define PCRE2_ERROR_BAD_LITERAL_OPTIONS 192 #define PCRE2_ERROR_SUPPORTED_ONLY_IN_UNICODE 193 #define PCRE2_ERROR_INVALID_HYPHEN_IN_OPTIONS 194 +#define PCRE2_ERROR_ALPHA_ASSERTION_UNKNOWN 195 +#define PCRE2_ERROR_SCRIPT_RUN_NOT_AVAILABLE 196 /* "Expected" matching error codes: no match and partial match. */ @@ -504,10 +491,10 @@ typedef struct pcre2_real_jit_stack pcre2_jit_stack; \ typedef pcre2_jit_stack *(*pcre2_jit_callback)(void *); -/* The structure for passing out data via the pcre_callout_function. We use a -structure so that new fields can be added on the end in future versions, -without changing the API of the function, thereby allowing old clients to work -without modification. Define the generic version in a macro; the width-specific +/* The structures for passing out data via callout functions. We use structures +so that new fields can be added on the end in future versions, without changing +the API of the function, thereby allowing old clients to work without +modification. Define the generic versions in a macro; the width-specific versions are generated from this macro below. */ /* Flags for the callout_flags field. These are cleared after a callout. */ @@ -549,7 +536,19 @@ typedef struct pcre2_callout_enumerate_block { \ PCRE2_SIZE callout_string_length; /* Length of string compiled into pattern */ \ PCRE2_SPTR callout_string; /* String compiled into pattern */ \ /* ------------------------------------------------------------------ */ \ -} pcre2_callout_enumerate_block; +} pcre2_callout_enumerate_block; \ +\ +typedef struct pcre2_substitute_callout_block { \ + uint32_t version; /* Identifies version of block */ \ + /* ------------------------ Version 0 ------------------------------- */ \ + PCRE2_SPTR input; /* Pointer to input subject string */ \ + PCRE2_SPTR output; /* Pointer to output buffer */ \ + PCRE2_SIZE output_offsets[2]; /* Changed portion of the output */ \ + PCRE2_SIZE *ovector; /* Pointer to current ovector */ \ + uint32_t oveccount; /* Count of pairs set in ovector */ \ + uint32_t subscount; /* Substitution number */ \ + /* ------------------------------------------------------------------ */ \ +} pcre2_substitute_callout_block; /* List the generic forms of all other functions in macros, which will be @@ -605,6 +604,9 @@ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_callout(pcre2_match_context *, \ int (*)(pcre2_callout_block *, void *), void *); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ + pcre2_set_substitute_callout(pcre2_match_context *, \ + int (*)(pcre2_substitute_callout_block *, void *), void *); \ +PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_depth_limit(pcre2_match_context *, uint32_t); \ PCRE2_EXP_DECL int PCRE2_CALL_CONVENTION \ pcre2_set_heap_limit(pcre2_match_context *, uint32_t); \ @@ -807,6 +809,7 @@ pcre2_compile are called by application code. */ #define pcre2_callout_block PCRE2_SUFFIX(pcre2_callout_block_) #define pcre2_callout_enumerate_block PCRE2_SUFFIX(pcre2_callout_enumerate_block_) +#define pcre2_substitute_callout_block PCRE2_SUFFIX(pcre2_substitute_callout_block_) #define pcre2_general_context PCRE2_SUFFIX(pcre2_general_context_) #define pcre2_compile_context PCRE2_SUFFIX(pcre2_compile_context_) #define pcre2_convert_context PCRE2_SUFFIX(pcre2_convert_context_) @@ -872,6 +875,7 @@ pcre2_compile are called by application code. */ #define pcre2_set_newline PCRE2_SUFFIX(pcre2_set_newline_) #define pcre2_set_parens_nest_limit PCRE2_SUFFIX(pcre2_set_parens_nest_limit_) #define pcre2_set_offset_limit PCRE2_SUFFIX(pcre2_set_offset_limit_) +#define pcre2_set_substitute_callout PCRE2_SUFFIX(pcre2_set_substitute_callout_) #define pcre2_substitute PCRE2_SUFFIX(pcre2_substitute_) #define pcre2_substring_copy_byname PCRE2_SUFFIX(pcre2_substring_copy_byname_) #define pcre2_substring_copy_bynumber PCRE2_SUFFIX(pcre2_substring_copy_bynumber_) diff --git a/thirdparty/pcre2/src/pcre2_auto_possess.c b/thirdparty/pcre2/src/pcre2_auto_possess.c index 2ce152e952..6d7b7c4a4d 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-2018 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -605,6 +605,15 @@ for(;;) if (cb->had_recurse) return FALSE; break; + /* A script run might have to backtrack if the iterated item can match + characters from more than one script. So give up unless repeating an + explicit character. */ + + case OP_SCRIPT_RUN: + if (base_list[0] != OP_CHAR && base_list[0] != OP_CHARI) + return FALSE; + break; + /* Atomic sub-patterns and assertions can always auto-possessify their last iterator. However, if the group was entered as a result of checking a previous iterator, this is not possible. */ @@ -614,7 +623,6 @@ for(;;) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: - return !entered_a_group; } @@ -1043,7 +1051,7 @@ for(;;) if (chr > 255) break; class_bitset = (uint8_t *) ((list_ptr == list ? code : base_end) - list_ptr[2]); - if ((class_bitset[chr >> 3] & (1 << (chr & 7))) != 0) return FALSE; + if ((class_bitset[chr >> 3] & (1u << (chr & 7))) != 0) return FALSE; break; #ifdef SUPPORT_WIDE_CHARS diff --git a/thirdparty/pcre2/src/pcre2_chartables.c b/thirdparty/pcre2/src/pcre2_chartables.c index 4046500c00..0e07edb494 100644 --- a/thirdparty/pcre2/src/pcre2_chartables.c +++ b/thirdparty/pcre2/src/pcre2_chartables.c @@ -157,8 +157,8 @@ graph print, punct, and cntrl. Other classes are built from combinations. */ /* This table identifies various classes of character by individual bits: 0x01 white space character 0x02 letter - 0x04 decimal digit - 0x08 hexadecimal digit + 0x04 lower case letter + 0x08 decimal digit 0x10 alphanumeric or '_' */ @@ -168,16 +168,16 @@ graph print, punct, and cntrl. Other classes are built from combinations. */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */ - 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ - 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */ - 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ + 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, /* 0 - 7 */ + 0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */ + 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* @ - G */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ 0x12,0x12,0x12,0x00,0x00,0x00,0x00,0x10, /* X - _ */ - 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ - 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ - 0x12,0x12,0x12,0x00,0x00,0x00,0x00,0x00, /* x -127 */ + 0x00,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* ` - g */ + 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* h - o */ + 0x16,0x16,0x16,0x16,0x16,0x16,0x16,0x16, /* p - w */ + 0x16,0x16,0x16,0x00,0x00,0x00,0x00,0x00, /* x -127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ diff --git a/thirdparty/pcre2/src/pcre2_compile.c b/thirdparty/pcre2/src/pcre2_compile.c index 6bb1de3610..068735ae8e 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-2018 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -240,49 +240,57 @@ code (meta_extra_lengths, just below) must be updated to remain in step. */ #define META_RANGE_LITERAL 0x801f0000u /* range defined literally */ #define META_RECURSE 0x80200000u /* Recursion */ #define META_RECURSE_BYNAME 0x80210000u /* (?&name) */ +#define META_SCRIPT_RUN 0x80220000u /* (*script_run:...) */ /* These must be kept together to make it easy to check that an assertion is present where expected in a conditional group. */ -#define META_LOOKAHEAD 0x80220000u /* (?= */ -#define META_LOOKAHEADNOT 0x80230000u /* (?! */ -#define META_LOOKBEHIND 0x80240000u /* (?<= */ -#define META_LOOKBEHINDNOT 0x80250000u /* (?<! */ +#define META_LOOKAHEAD 0x80230000u /* (?= */ +#define META_LOOKAHEADNOT 0x80240000u /* (?! */ +#define META_LOOKBEHIND 0x80250000u /* (?<= */ +#define META_LOOKBEHINDNOT 0x80260000u /* (?<! */ /* These must be kept in this order, with consecutive values, and the _ARG versions of COMMIT, PRUNE, SKIP, and THEN immediately after their non-argument versions. */ -#define META_MARK 0x80260000u /* (*MARK) */ -#define META_ACCEPT 0x80270000u /* (*ACCEPT) */ -#define META_FAIL 0x80280000u /* (*FAIL) */ -#define META_COMMIT 0x80290000u /* These */ -#define META_COMMIT_ARG 0x802a0000u /* pairs */ -#define META_PRUNE 0x802b0000u /* must */ -#define META_PRUNE_ARG 0x802c0000u /* be */ -#define META_SKIP 0x802d0000u /* kept */ -#define META_SKIP_ARG 0x802e0000u /* in */ -#define META_THEN 0x802f0000u /* this */ -#define META_THEN_ARG 0x80300000u /* order */ +#define META_MARK 0x80270000u /* (*MARK) */ +#define META_ACCEPT 0x80280000u /* (*ACCEPT) */ +#define META_FAIL 0x80290000u /* (*FAIL) */ +#define META_COMMIT 0x802a0000u /* These */ +#define META_COMMIT_ARG 0x802b0000u /* pairs */ +#define META_PRUNE 0x802c0000u /* must */ +#define META_PRUNE_ARG 0x802d0000u /* be */ +#define META_SKIP 0x802e0000u /* kept */ +#define META_SKIP_ARG 0x802f0000u /* in */ +#define META_THEN 0x80300000u /* this */ +#define META_THEN_ARG 0x80310000u /* order */ /* These must be kept in groups of adjacent 3 values, and all together. */ -#define META_ASTERISK 0x80310000u /* * */ -#define META_ASTERISK_PLUS 0x80320000u /* *+ */ -#define META_ASTERISK_QUERY 0x80330000u /* *? */ -#define META_PLUS 0x80340000u /* + */ -#define META_PLUS_PLUS 0x80350000u /* ++ */ -#define META_PLUS_QUERY 0x80360000u /* +? */ -#define META_QUERY 0x80370000u /* ? */ -#define META_QUERY_PLUS 0x80380000u /* ?+ */ -#define META_QUERY_QUERY 0x80390000u /* ?? */ -#define META_MINMAX 0x803a0000u /* {n,m} repeat */ -#define META_MINMAX_PLUS 0x803b0000u /* {n,m}+ repeat */ -#define META_MINMAX_QUERY 0x803c0000u /* {n,m}? repeat */ +#define META_ASTERISK 0x80320000u /* * */ +#define META_ASTERISK_PLUS 0x80330000u /* *+ */ +#define META_ASTERISK_QUERY 0x80340000u /* *? */ +#define META_PLUS 0x80350000u /* + */ +#define META_PLUS_PLUS 0x80360000u /* ++ */ +#define META_PLUS_QUERY 0x80370000u /* +? */ +#define META_QUERY 0x80380000u /* ? */ +#define META_QUERY_PLUS 0x80390000u /* ?+ */ +#define META_QUERY_QUERY 0x803a0000u /* ?? */ +#define META_MINMAX 0x803b0000u /* {n,m} repeat */ +#define META_MINMAX_PLUS 0x803c0000u /* {n,m}+ repeat */ +#define META_MINMAX_QUERY 0x803d0000u /* {n,m}? repeat */ #define META_FIRST_QUANTIFIER META_ASTERISK #define META_LAST_QUANTIFIER META_MINMAX_QUERY +/* This is a special "meta code" that is used only to distinguish (*asr: from +(*sr: in the table of aphabetic assertions. It is never stored in the parsed +pattern because (*asr: is turned into (*sr:(*atomic: at that stage. There is +therefore no need for it to have a length entry, so use a high value. */ + +#define META_ATOMIC_SCRIPT_RUN 0x8fff0000u + /* Table of extra lengths for each of the meta codes. Must be kept in step with the definitions above. For some items these values are a basic length to which a variable amount has to be added. */ @@ -322,6 +330,7 @@ static unsigned char meta_extra_lengths[] = { 0, /* META_RANGE_LITERAL */ SIZEOFFSET, /* META_RECURSE */ 1+SIZEOFFSET, /* META_RECURSE_BYNAME */ + 0, /* META_SCRIPT_RUN */ 0, /* META_LOOKAHEAD */ 0, /* META_LOOKAHEADNOT */ SIZEOFFSET, /* META_LOOKBEHIND */ @@ -359,17 +368,17 @@ enum { PSKIP_ALT, PSKIP_CLASS, PSKIP_KET }; experimenting to figure out how to stop gcc 5.3.0 from warning with -Wconversion. This version gets a warning: - #define SETBIT(a,b) a[(b)/8] |= (uint8_t)(1 << ((b)&7)) + #define SETBIT(a,b) a[(b)/8] |= (uint8_t)(1u << ((b)&7)) Let's hope the apparently less efficient version isn't actually so bad if the compiler is clever with identical subexpressions. */ -#define SETBIT(a,b) a[(b)/8] = (uint8_t)(a[(b)/8] | (1 << ((b)&7))) +#define SETBIT(a,b) a[(b)/8] = (uint8_t)(a[(b)/8] | (1u << ((b)&7))) /* Private flags added to firstcu and reqcu. */ -#define REQ_CASELESS (1 << 0) /* Indicates caselessness */ -#define REQ_VARY (1 << 1) /* reqcu followed non-literal item */ +#define REQ_CASELESS (1u << 0) /* Indicates caselessness */ +#define REQ_VARY (1u << 1) /* reqcu followed non-literal item */ /* Negative values for the firstcu and reqcu flags */ #define REQ_UNSET (-2) /* Not yet found anything */ #define REQ_NONE (-1) /* Found not fixed char */ @@ -615,6 +624,46 @@ static const uint32_t verbops[] = { OP_MARK, OP_ACCEPT, OP_FAIL, OP_COMMIT, OP_COMMIT_ARG, OP_PRUNE, OP_PRUNE_ARG, OP_SKIP, OP_SKIP_ARG, OP_THEN, OP_THEN_ARG }; +/* Table of "alpha assertions" like (*pla:...), similar to the (*VERB) table. */ + +typedef struct alasitem { + unsigned int len; /* Length of name */ + uint32_t meta; /* Base META_ code */ +} alasitem; + +static const char alasnames[] = + STRING_pla0 + STRING_plb0 + STRING_nla0 + STRING_nlb0 + STRING_positive_lookahead0 + STRING_positive_lookbehind0 + STRING_negative_lookahead0 + STRING_negative_lookbehind0 + STRING_atomic0 + STRING_sr0 + STRING_asr0 + STRING_script_run0 + STRING_atomic_script_run; + +static const alasitem alasmeta[] = { + { 3, META_LOOKAHEAD }, + { 3, META_LOOKBEHIND }, + { 3, META_LOOKAHEADNOT }, + { 3, META_LOOKBEHINDNOT }, + { 18, META_LOOKAHEAD }, + { 19, META_LOOKBEHIND }, + { 18, META_LOOKAHEADNOT }, + { 19, META_LOOKBEHINDNOT }, + { 6, META_ATOMIC }, + { 2, META_SCRIPT_RUN }, /* sr = script run */ + { 3, META_ATOMIC_SCRIPT_RUN }, /* asr = atomic script run */ + { 10, META_SCRIPT_RUN }, /* script run */ + { 17, META_ATOMIC_SCRIPT_RUN } /* atomic script run */ +}; + +static const int alascount = sizeof(alasmeta)/sizeof(alasitem); + /* Offsets from OP_STAR for case-independent and negative repeat opcodes. */ static uint32_t chartypeoffset[] = { @@ -714,7 +763,8 @@ are allowed. */ #define PUBLIC_COMPILE_EXTRA_OPTIONS \ (PUBLIC_LITERAL_COMPILE_EXTRA_OPTIONS| \ - PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES|PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) + PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES|PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL| \ + PCRE2_EXTRA_ESCAPED_CR_IS_LF|PCRE2_EXTRA_ALT_BSUX) /* Compile time error code numbers. They are given names so that they can more easily be tracked. When a new number is added, the tables called eint1 and @@ -731,7 +781,7 @@ enum { ERR0 = COMPILE_ERROR_BASE, ERR61, ERR62, ERR63, ERR64, ERR65, ERR66, ERR67, ERR68, ERR69, ERR70, ERR71, ERR72, ERR73, ERR74, ERR75, ERR76, ERR77, ERR78, ERR79, ERR80, ERR81, ERR82, ERR83, ERR84, ERR85, ERR86, ERR87, ERR88, ERR89, ERR90, - ERR91, ERR92, ERR93, ERR94 }; + ERR91, ERR92, ERR93, ERR94, ERR95, ERR96 }; /* This is a table of start-of-pattern options such as (*UTF) and settings such as (*LIMIT_MATCH=nnnn) and (*CRLF). For completeness and backward @@ -962,6 +1012,7 @@ for (;;) case META_NOCAPTURE: fprintf(stderr, "META (?:"); break; case META_LOOKAHEAD: fprintf(stderr, "META (?="); break; case META_LOOKAHEADNOT: fprintf(stderr, "META (?!"); break; + case META_SCRIPT_RUN: fprintf(stderr, "META (*sr:"); break; case META_KET: fprintf(stderr, "META )"); break; case META_ALT: fprintf(stderr, "META | %d", meta_arg); break; @@ -1191,7 +1242,7 @@ if (code != NULL) if ((code->flags & PCRE2_DEREF_TABLES) != 0) { /* Decoded tables belong to the codes after deserialization, and they must - be freed when there are no more reference to them. The *ref_count should + 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); @@ -1398,7 +1449,7 @@ Arguments: errorcodeptr points to the errorcode variable (containing zero) options the current options bits isclass TRUE if inside a character class - cb compile data block + cb compile data block or NULL when called from pcre2_substitute() Returns: zero => a data character positive => a special escape sequence @@ -1408,7 +1459,8 @@ Returns: zero => a data character int PRIV(check_escape)(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t *chptr, - int *errorcodeptr, uint32_t options, BOOL isclass, compile_block *cb) + int *errorcodeptr, uint32_t options, uint32_t extra_options, BOOL isclass, + compile_block *cb) { BOOL utf = (options & PCRE2_UTF) != 0; PCRE2_SPTR ptr = *ptrptr; @@ -1429,14 +1481,25 @@ GETCHARINCTEST(c, ptr); /* Get character value, increment pointer */ /* Non-alphanumerics are literals, so we just leave the value in c. An initial value test saves a memory lookup for code points outside the alphanumeric -range. Otherwise, do a table lookup. A non-zero result is something that can be -returned immediately. Otherwise further processing is required. */ +range. */ if (c < ESCAPES_FIRST || c > ESCAPES_LAST) {} /* Definitely literal */ +/* Otherwise, do a table lookup. Non-zero values need little processing here. A +positive value is a literal value for something like \n. A negative value is +the negation of one of the ESC_ macros that is passed back for handling by the +calling function. Some extra checking is needed for \N because only \N{U+dddd} +is supported. If the value is zero, further processing is handled below. */ + else if ((i = escapes[c - ESCAPES_FIRST]) != 0) { - if (i > 0) c = (uint32_t)i; else /* Positive is a data character */ + if (i > 0) + { + c = (uint32_t)i; + if (c == CHAR_CR && (extra_options & PCRE2_EXTRA_ESCAPED_CR_IS_LF) != 0) + c = CHAR_LF; + } + else /* Negative table entry */ { escape = -i; /* Else return a special escape */ if (cb != NULL && (escape == ESC_P || escape == ESC_p || escape == ESC_X)) @@ -1486,23 +1549,29 @@ else if ((i = escapes[c - ESCAPES_FIRST]) != 0) } } -/* Escapes that need further processing, including those that are unknown. -When called from pcre2_substitute(), only \c, \o, and \x are recognized (and \u -when BSUX is set). */ +/* Escapes that need further processing, including those that are unknown, have +a zero entry in the lookup table. When called from pcre2_substitute(), only \c, +\o, and \x are recognized (\u and \U can never appear as they are used for case +forcing). */ else { + int s; PCRE2_SPTR oldptr; BOOL overflow; - int s; + BOOL alt_bsux = + ((options & PCRE2_ALT_BSUX) | (extra_options & PCRE2_EXTRA_ALT_BSUX)) != 0; /* Filter calls from pcre2_substitute(). */ - if (cb == NULL && c != CHAR_c && c != CHAR_o && c != CHAR_x && - (c != CHAR_u || (options & PCRE2_ALT_BSUX) != 0)) + if (cb == NULL) { - *errorcodeptr = ERR3; - return 0; + if (c != CHAR_c && c != CHAR_o && c != CHAR_x) + { + *errorcodeptr = ERR3; + return 0; + } + alt_bsux = FALSE; /* Do not modify \x handling */ } switch (c) @@ -1516,40 +1585,75 @@ else *errorcodeptr = ERR37; break; - /* \u is unrecognized when PCRE2_ALT_BSUX is not set. When it is treated - specially, \u must be followed by four hex digits. Otherwise it is a - lowercase u letter. */ + /* \u is unrecognized when neither PCRE2_ALT_BSUX nor PCRE2_EXTRA_ALT_BSUX + is set. Otherwise, \u must be followed by exactly four hex digits or, if + PCRE2_EXTRA_ALT_BSUX is set, by any number of hex digits in braces. + Otherwise it is a lowercase u letter. This gives some compatibility with + ECMAScript (aka JavaScript). */ case CHAR_u: - if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37; else + if (!alt_bsux) *errorcodeptr = ERR37; else { uint32_t xc; - if (ptrend - ptr < 4) break; /* Less than 4 chars */ - if ((cc = XDIGIT(ptr[0])) == 0xff) break; /* Not a hex digit */ - if ((xc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ - cc = (cc << 4) | xc; - if ((xc = XDIGIT(ptr[2])) == 0xff) break; /* Not a hex digit */ - cc = (cc << 4) | xc; - if ((xc = XDIGIT(ptr[3])) == 0xff) break; /* Not a hex digit */ - c = (cc << 4) | xc; - ptr += 4; + + if (ptr >= ptrend) break; + if (*ptr == CHAR_LEFT_CURLY_BRACKET && + (extra_options & PCRE2_EXTRA_ALT_BSUX) != 0) + { + PCRE2_SPTR hptr = ptr + 1; + cc = 0; + + while (hptr < ptrend && (xc = XDIGIT(*hptr)) != 0xff) + { + if ((cc & 0xf0000000) != 0) /* Test for 32-bit overflow */ + { + *errorcodeptr = ERR77; + ptr = hptr; /* Show where */ + break; /* *hptr != } will cause another break below */ + } + cc = (cc << 4) | xc; + hptr++; + } + + if (hptr == ptr + 1 || /* No hex digits */ + hptr >= ptrend || /* Hit end of input */ + *hptr != CHAR_RIGHT_CURLY_BRACKET) /* No } terminator */ + break; /* Hex escape not recognized */ + + c = cc; /* Accept the code point */ + ptr = hptr + 1; + } + + else /* Must be exactly 4 hex digits */ + { + if (ptrend - ptr < 4) break; /* Less than 4 chars */ + if ((cc = XDIGIT(ptr[0])) == 0xff) break; /* Not a hex digit */ + if ((xc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ + cc = (cc << 4) | xc; + if ((xc = XDIGIT(ptr[2])) == 0xff) break; /* Not a hex digit */ + cc = (cc << 4) | xc; + if ((xc = XDIGIT(ptr[3])) == 0xff) break; /* Not a hex digit */ + c = (cc << 4) | xc; + ptr += 4; + } + if (utf) { if (c > 0x10ffffU) *errorcodeptr = ERR77; else if (c >= 0xd800 && c <= 0xdfff && - (cb->cx->extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) - *errorcodeptr = ERR73; + (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) + *errorcodeptr = ERR73; } else if (c > MAX_NON_UTF_CHAR) *errorcodeptr = ERR77; } break; - /* \U is unrecognized unless PCRE2_ALT_BSUX is set, in which case it is an - upper case letter. */ + /* \U is unrecognized unless PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX is set, + in which case it is an upper case letter. */ case CHAR_U: - if ((options & PCRE2_ALT_BSUX) == 0) *errorcodeptr = ERR37; + if (!alt_bsux) *errorcodeptr = ERR37; break; /* In a character class, \g is just a literal "g". Outside a character @@ -1728,8 +1832,8 @@ else } else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET) { - if (utf && c >= 0xd800 && c <= 0xdfff && (cb == NULL || - (cb->cx->extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)) + if (utf && c >= 0xd800 && c <= 0xdfff && + (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) { ptr--; *errorcodeptr = ERR73; @@ -1743,11 +1847,11 @@ else } break; - /* \x is complicated. When PCRE2_ALT_BSUX is set, \x must be followed by - two hexadecimal digits. Otherwise it is a lowercase x letter. */ + /* When PCRE2_ALT_BSUX or PCRE2_EXTRA_ALT_BSUX is set, \x must be followed + by two hexadecimal digits. Otherwise it is a lowercase x letter. */ case CHAR_x: - if ((options & PCRE2_ALT_BSUX) != 0) + if (alt_bsux) { uint32_t xc; if (ptrend - ptr < 2) break; /* Less than 2 characters */ @@ -1755,9 +1859,9 @@ else if ((xc = XDIGIT(ptr[1])) == 0xff) break; /* Not a hex digit */ c = (cc << 4) | xc; ptr += 2; - } /* End PCRE2_ALT_BSUX handling */ + } - /* Handle \x in Perl's style. \x{ddd} is a character number which can be + /* Handle \x in Perl's style. \x{ddd} is a character code which can be greater than 0xff in UTF-8 or non-8bit mode, but only if the ddd are hex digits. If not, { used to be treated as a data character. However, Perl seems to read hex digits up to the first non-such, and ignore the rest, so @@ -1801,8 +1905,8 @@ else } else if (ptr < ptrend && *ptr++ == CHAR_RIGHT_CURLY_BRACKET) { - if (utf && c >= 0xd800 && c <= 0xdfff && (cb == NULL || - (cb->cx->extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0)) + if (utf && c >= 0xd800 && c <= 0xdfff && + (extra_options & PCRE2_EXTRA_ALLOW_SURROGATE_ESCAPES) == 0) { ptr--; *errorcodeptr = ERR73; @@ -1874,9 +1978,9 @@ else c ^= 0x40; /* Handle \c in an EBCDIC environment. The special case \c? is converted to - 255 (0xff) or 95 (0x5f) if other character suggest we are using th POSIX-BC - encoding. (This is the way Perl indicates that it handles \c?.) The other - valid sequences correspond to a list of specific characters. */ + 255 (0xff) or 95 (0x5f) if other characters suggest we are using the + POSIX-BC encoding. (This is the way Perl indicates that it handles \c?.) + The other valid sequences correspond to a list of specific characters. */ #else if (c == CHAR_QUESTION_MARK) @@ -2120,9 +2224,10 @@ return -1; *************************************************/ /* This function is called from parse_regex() below whenever it needs to read -the name of a subpattern or a (*VERB). The initial pointer must be to the -character before the name. If that character is '*' we are reading a verb name. -The pointer is updated to point after the name, for a VERB, or after tha name's +the name of a subpattern or a (*VERB) or an (*alpha_assertion). The initial +pointer must be to the character before the name. If that character is '*' we +are reading a verb or alpha assertion name. The pointer is updated to point +after the name, for a VERB or alpha assertion name, or after tha name's terminator for a subpattern name. Returning both the offset and the name pointer is redundant information, but some callers use one and some the other, so it is simplest just to return both. @@ -2130,6 +2235,7 @@ so it is simplest just to return both. Arguments: ptrptr points to the character pointer variable ptrend points to the end of the input string + utf true if the input is UTF-encoded terminator the terminator of a subpattern name must be this offsetptr where to put the offset from the start of the pattern nameptr where to put a pointer to the name in the input @@ -2142,48 +2248,88 @@ Returns: TRUE if a name was read */ static BOOL -read_name(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, uint32_t terminator, +read_name(PCRE2_SPTR *ptrptr, PCRE2_SPTR ptrend, BOOL utf, uint32_t terminator, PCRE2_SIZE *offsetptr, PCRE2_SPTR *nameptr, uint32_t *namelenptr, int *errorcodeptr, compile_block *cb) { PCRE2_SPTR ptr = *ptrptr; -BOOL is_verb = (*ptr == CHAR_ASTERISK); -uint32_t namelen = 0; -uint32_t ctype = is_verb? ctype_letter : ctype_word; +BOOL is_group = (*ptr != CHAR_ASTERISK); -if (++ptr >= ptrend) +if (++ptr >= ptrend) /* No characters in name */ { - *errorcodeptr = is_verb? ERR60: /* Verb not recognized or malformed */ - ERR62; /* Subpattern name expected */ + *errorcodeptr = is_group? ERR62: /* Subpattern name expected */ + ERR60; /* Verb not recognized or malformed */ goto FAILED; } *nameptr = ptr; *offsetptr = (PCRE2_SIZE)(ptr - cb->start_pattern); -if (IS_DIGIT(*ptr)) +/* In UTF mode, a group name may contain letters and decimal digits as defined +by Unicode properties, and underscores, but must not start with a digit. */ + +#ifdef SUPPORT_UNICODE +if (utf && is_group) { - *errorcodeptr = ERR44; /* Group name must not start with digit */ - goto FAILED; + uint32_t c, type; + + GETCHAR(c, ptr); + type = UCD_CHARTYPE(c); + + if (type == ucp_Nd) + { + *errorcodeptr = ERR44; + goto FAILED; + } + + for(;;) + { + if (type != ucp_Nd && PRIV(ucp_gentype)[type] != ucp_L && + c != CHAR_UNDERSCORE) break; + ptr++; + FORWARDCHARTEST(ptr, ptrend); + if (ptr >= ptrend) break; + GETCHAR(c, ptr); + type = UCD_CHARTYPE(c); + } } +else +#else +(void)utf; /* Avoid compiler warning */ +#endif /* SUPPORT_UNICODE */ + +/* Handle non-group names and group names in non-UTF modes. A group name must +not start with a digit. If either of the others start with a digit it just +won't be recognized. */ -while (ptr < ptrend && MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype) != 0) { - ptr++; - namelen++; - if (namelen > MAX_NAME_SIZE) + if (is_group && IS_DIGIT(*ptr)) { - *errorcodeptr = ERR48; + *errorcodeptr = ERR44; goto FAILED; } + + while (ptr < ptrend && MAX_255(*ptr) && (cb->ctypes[*ptr] & ctype_word) != 0) + { + ptr++; + } } +/* Check name length */ + +if (ptr > *nameptr + MAX_NAME_SIZE) + { + *errorcodeptr = ERR48; + goto FAILED; + } +*namelenptr = ptr - *nameptr; + /* Subpattern names must not be empty, and their terminator is checked here. -(What follows a verb name is checked separately.) */ +(What follows a verb or alpha assertion name is checked separately.) */ -if (!is_verb) +if (is_group) { - if (namelen == 0) + if (ptr == *nameptr) { *errorcodeptr = ERR62; /* Subpattern name expected */ goto FAILED; @@ -2196,7 +2342,6 @@ if (!is_verb) ptr++; } -*namelenptr = namelen; *ptrptr = ptr; return TRUE; @@ -2289,6 +2434,7 @@ typedef struct nest_save { #define NSF_RESET 0x0001u #define NSF_CONDASSERT 0x0002u +#define NSF_ATOMICSR 0x0004u /* Options that are changeable within the pattern must be tracked during parsing. Some (e.g. PCRE2_EXTENDED) are implemented entirely during parsing, @@ -2333,6 +2479,7 @@ uint32_t *parsed_pattern = cb->parsed_pattern; uint32_t *parsed_pattern_end = cb->parsed_pattern_end; uint32_t meta_quantifier = 0; uint32_t add_after_mark = 0; +uint32_t extra_options = cb->cx->extra_options; uint16_t nest_depth = 0; int after_manual_callout = 0; int expect_cond_assert = 0; @@ -2356,12 +2503,12 @@ nest_save *top_nest, *end_nests; /* Insert leading items for word and line matching (features provided for the benefit of pcre2grep). */ -if ((cb->cx->extra_options & PCRE2_EXTRA_MATCH_LINE) != 0) +if ((extra_options & PCRE2_EXTRA_MATCH_LINE) != 0) { *parsed_pattern++ = META_CIRCUMFLEX; *parsed_pattern++ = META_NOCAPTURE; } -else if ((cb->cx->extra_options & PCRE2_EXTRA_MATCH_WORD) != 0) +else if ((extra_options & PCRE2_EXTRA_MATCH_WORD) != 0) { *parsed_pattern++ = META_ESCAPE + ESC_b; *parsed_pattern++ = META_NOCAPTURE; @@ -2526,7 +2673,7 @@ while (ptr < ptrend) if ((options & PCRE2_ALT_VERBNAMES) != 0) { escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - FALSE, cb); + cb->cx->extra_options, FALSE, cb); if (errorcode != 0) goto FAILED; } else escape = 0; /* Treat all as literal */ @@ -2639,23 +2786,30 @@ while (ptr < ptrend) if (expect_cond_assert > 0) { BOOL ok = c == CHAR_LEFT_PARENTHESIS && ptrend - ptr >= 3 && - ptr[0] == CHAR_QUESTION_MARK; - if (ok) switch(ptr[1]) + (ptr[0] == CHAR_QUESTION_MARK || ptr[0] == CHAR_ASTERISK); + if (ok) { - case CHAR_C: - ok = expect_cond_assert == 2; - break; + if (ptr[0] == CHAR_ASTERISK) /* New alpha assertion format, possibly */ + { + ok = MAX_255(ptr[1]) && (cb->ctypes[ptr[1]] & ctype_lcletter) != 0; + } + else switch(ptr[1]) /* Traditional symbolic format */ + { + case CHAR_C: + ok = expect_cond_assert == 2; + break; - case CHAR_EQUALS_SIGN: - case CHAR_EXCLAMATION_MARK: - break; + case CHAR_EQUALS_SIGN: + case CHAR_EXCLAMATION_MARK: + break; - case CHAR_LESS_THAN_SIGN: - ok = ptr[2] == CHAR_EQUALS_SIGN || ptr[2] == CHAR_EXCLAMATION_MARK; - break; + case CHAR_LESS_THAN_SIGN: + ok = ptr[2] == CHAR_EQUALS_SIGN || ptr[2] == CHAR_EXCLAMATION_MARK; + break; - default: - ok = FALSE; + default: + ok = FALSE; + } } if (!ok) @@ -2709,11 +2863,11 @@ while (ptr < ptrend) case CHAR_BACKSLASH: tempptr = ptr; escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, - FALSE, cb); + cb->cx->extra_options, FALSE, cb); if (errorcode != 0) { ESCAPE_FAILED: - if ((cb->cx->extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) + if ((extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) goto FAILED; ptr = tempptr; if (ptr >= ptrend) c = CHAR_BACKSLASH; else @@ -2907,7 +3061,7 @@ while (ptr < ptrend) /* Not a numerical recursion */ - if (!read_name(&ptr, ptrend, terminator, &offset, &name, &namelen, + if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen, &errorcode, cb)) goto ESCAPE_FAILED; /* \k and \g when used with braces are back references, whereas \g used @@ -3270,12 +3424,12 @@ while (ptr < ptrend) else { tempptr = ptr; - escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, - options, TRUE, cb); + escape = PRIV(check_escape)(&ptr, ptrend, &c, &errorcode, options, + cb->cx->extra_options, TRUE, cb); + if (errorcode != 0) { - CLASS_ESCAPE_FAILED: - if ((cb->cx->extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) + if ((extra_options & PCRE2_EXTRA_BAD_ESCAPE_IS_LITERAL) == 0) goto FAILED; ptr = tempptr; if (ptr >= ptrend) c = CHAR_BACKSLASH; else @@ -3285,30 +3439,32 @@ while (ptr < ptrend) escape = 0; /* Treat as literal character */ } - if (escape == 0) /* Escaped character code point is in c */ + switch(escape) { + case 0: /* Escaped character code point is in c */ char_is_literal = FALSE; goto CLASS_LITERAL; - } - - /* These three escapes do not alter the class range state. */ - if (escape == ESC_b) - { - c = CHAR_BS; /* \b is backspace in a class */ + case ESC_b: + c = CHAR_BS; /* \b is backspace in a class */ char_is_literal = FALSE; goto CLASS_LITERAL; - } - else if (escape == ESC_Q) - { + case ESC_Q: inescq = TRUE; /* Enter literal mode */ goto CLASS_CONTINUE; - } - else if (escape == ESC_E) /* Ignore orphan \E */ + case ESC_E: /* Ignore orphan \E */ goto CLASS_CONTINUE; + case ESC_B: /* Always an error in a class */ + case ESC_R: + case ESC_X: + errorcode = ERR7; + ptr--; + goto FAILED; + } + /* The second part of a range can be a single-character escape sequence (detected above), but not any of the other escapes. Perl treats a hyphen as a literal in such circumstances. However, in Perl's @@ -3318,7 +3474,7 @@ while (ptr < ptrend) if (class_range_state == RANGE_STARTED) { errorcode = ERR50; - goto CLASS_ESCAPE_FAILED; + goto FAILED; /* Not CLASS_ESCAPE_FAILED; always an error */ } /* Of the remaining escapes, only those that define characters are @@ -3328,8 +3484,8 @@ while (ptr < ptrend) switch(escape) { case ESC_N: - errorcode = ERR71; /* Not supported in a class */ - goto CLASS_ESCAPE_FAILED; + errorcode = ERR71; + goto FAILED; case ESC_H: case ESC_h: @@ -3392,14 +3548,14 @@ while (ptr < ptrend) } #else errorcode = ERR45; - goto CLASS_ESCAPE_FAILED; + goto FAILED; #endif break; /* End \P and \p */ default: /* All others are not allowed in a class */ errorcode = ERR7; ptr--; - goto CLASS_ESCAPE_FAILED; + goto FAILED; } /* Perl gives a warning unless a following hyphen is the last character @@ -3440,7 +3596,8 @@ while (ptr < ptrend) case CHAR_LEFT_PARENTHESIS: if (ptr >= ptrend) goto UNCLOSED_PARENTHESIS; - /* If ( is not followed by ? it is either a capture or a special verb. */ + /* If ( is not followed by ? it is either a capture or a special verb or an + alpha assertion. */ if (*ptr != CHAR_QUESTION_MARK) { @@ -3460,17 +3617,122 @@ while (ptr < ptrend) else *parsed_pattern++ = META_NOCAPTURE; } + /* Do nothing for (* followed by end of pattern or ) so it gives a "bad + quantifier" error rather than "(*MARK) must have an argument". */ - /* ---- Handle (*VERB) and (*VERB:NAME) ---- */ + else if (ptrend - ptr <= 1 || (c = ptr[1]) == CHAR_RIGHT_PARENTHESIS) + 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. */ + + else if (CHMAX_255(c) && (cb->ctypes[c] & ctype_lcletter) != 0) + { + uint32_t meta; + + vn = alasnames; + if (!read_name(&ptr, ptrend, utf, 0, &offset, &name, &namelen, + &errorcode, cb)) goto FAILED; + if (ptr >= ptrend || *ptr != CHAR_COLON) + { + errorcode = ERR95; /* Malformed */ + goto FAILED; + } + + /* Scan the table of alpha assertion names */ + + for (i = 0; i < alascount; i++) + { + if (namelen == alasmeta[i].len && + PRIV(strncmp_c8)(name, vn, namelen) == 0) + break; + vn += alasmeta[i].len + 1; + } + + if (i >= alascount) + { + errorcode = ERR95; /* Alpha assertion not recognized */ + goto FAILED; + } + + /* Check for expecting an assertion condition. If so, only lookaround + assertions are valid. */ + + meta = alasmeta[i].meta; + if (prev_expect_cond_assert > 0 && + (meta < META_LOOKAHEAD || meta > META_LOOKBEHINDNOT)) + { + errorcode = ERR28; /* Assertion expected */ + goto FAILED; + } + + /* The lookaround alphabetic synonyms can be almost entirely handled by + jumping to the code that handles the traditional symbolic forms. */ + + switch(meta) + { + default: + errorcode = ERR89; /* Unknown code; should never occur because */ + goto FAILED; /* the meta values come from a table above. */ + + case META_ATOMIC: + goto ATOMIC_GROUP; + + case META_LOOKAHEAD: + goto POSITIVE_LOOK_AHEAD; + + case META_LOOKAHEADNOT: + goto NEGATIVE_LOOK_AHEAD; + + case META_LOOKBEHIND: + case META_LOOKBEHINDNOT: + *parsed_pattern++ = meta; + ptr--; + goto POST_LOOKBEHIND; - /* Do nothing for (*) so it gives a "bad quantifier" error rather than - "(*MARK) must have an argument". */ + /* The script run facilities are handled here. Unicode support is + required (give an error if not, as this is a security issue). Always + record a META_SCRIPT_RUN item. Then, for the atomic version, insert + META_ATOMIC and remember that we need two META_KETs at the end. */ - else if (ptrend - ptr > 1 && ptr[1] != CHAR_RIGHT_PARENTHESIS) + case META_SCRIPT_RUN: + case META_ATOMIC_SCRIPT_RUN: +#ifdef SUPPORT_UNICODE + *parsed_pattern++ = META_SCRIPT_RUN; + nest_depth++; + ptr++; + if (meta == META_ATOMIC_SCRIPT_RUN) + { + *parsed_pattern++ = META_ATOMIC; + if (top_nest == NULL) top_nest = (nest_save *)(cb->start_workspace); + else if (++top_nest >= end_nests) + { + errorcode = ERR84; + goto FAILED; + } + top_nest->nest_depth = nest_depth; + top_nest->flags = NSF_ATOMICSR; + top_nest->options = options & PARSE_TRACKED_OPTIONS; + } + break; +#else /* SUPPORT_UNICODE */ + errorcode = ERR96; + goto FAILED; +#endif + } + } + + + /* ---- Handle (*VERB) and (*VERB:NAME) ---- */ + + else { vn = verbnames; - if (!read_name(&ptr, ptrend, 0, &offset, &name, &namelen, &errorcode, - cb)) goto FAILED; + if (!read_name(&ptr, ptrend, utf, 0, &offset, &name, &namelen, + &errorcode, cb)) goto FAILED; if (ptr >= ptrend || (*ptr != CHAR_COLON && *ptr != CHAR_RIGHT_PARENTHESIS)) { @@ -3725,7 +3987,7 @@ while (ptr < ptrend) errorcode = ERR41; goto FAILED; } - if (!read_name(&ptr, ptrend, CHAR_RIGHT_PARENTHESIS, &offset, &name, + if (!read_name(&ptr, ptrend, utf, CHAR_RIGHT_PARENTHESIS, &offset, &name, &namelen, &errorcode, cb)) goto FAILED; *parsed_pattern++ = META_BACKREF_BYNAME; *parsed_pattern++ = namelen; @@ -3785,7 +4047,7 @@ while (ptr < ptrend) case CHAR_AMPERSAND: RECURSE_BY_NAME: - if (!read_name(&ptr, ptrend, CHAR_RIGHT_PARENTHESIS, &offset, &name, + if (!read_name(&ptr, ptrend, utf, CHAR_RIGHT_PARENTHESIS, &offset, &name, &namelen, &errorcode, cb)) goto FAILED; *parsed_pattern++ = META_RECURSE_BYNAME; *parsed_pattern++ = namelen; @@ -3933,14 +4195,15 @@ while (ptr < ptrend) if (++ptr >= ptrend) goto UNCLOSED_PARENTHESIS; nest_depth++; - /* If the next character is ? there must be an assertion next (optionally - preceded by a callout). We do not check this here, but instead we set - expect_cond_assert to 2. If this is still greater than zero (callouts - decrement it) when the next assertion is read, it will be marked as a - condition that must not be repeated. A value greater than zero also - causes checking that an assertion (possibly with callout) follows. */ + /* If the next character is ? or * there must be an assertion next + (optionally preceded by a callout). We do not check this here, but + instead we set expect_cond_assert to 2. If this is still greater than + zero (callouts decrement it) when the next assertion is read, it will be + marked as a condition that must not be repeated. A value greater than + zero also causes checking that an assertion (possibly with callout) + follows. */ - if (*ptr == CHAR_QUESTION_MARK) + if (*ptr == CHAR_QUESTION_MARK || *ptr == CHAR_ASTERISK) { *parsed_pattern++ = META_COND_ASSERT; ptr--; /* Pull pointer back to the opening parenthesis. */ @@ -4032,7 +4295,7 @@ while (ptr < ptrend) terminator = CHAR_RIGHT_PARENTHESIS; ptr--; /* Point to char before name */ } - if (!read_name(&ptr, ptrend, terminator, &offset, &name, &namelen, + if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen, &errorcode, cb)) goto FAILED; /* Handle (?(R&name) */ @@ -4086,6 +4349,7 @@ while (ptr < ptrend) /* ---- Atomic group ---- */ case CHAR_GREATER_THAN_SIGN: + ATOMIC_GROUP: /* Come from (*atomic: */ *parsed_pattern++ = META_ATOMIC; nest_depth++; ptr++; @@ -4095,11 +4359,13 @@ while (ptr < ptrend) /* ---- Lookahead assertions ---- */ case CHAR_EQUALS_SIGN: + POSITIVE_LOOK_AHEAD: /* Come from (*pla: */ *parsed_pattern++ = META_LOOKAHEAD; ptr++; goto POST_ASSERTION; case CHAR_EXCLAMATION_MARK: + NEGATIVE_LOOK_AHEAD: /* Come from (*nla: */ *parsed_pattern++ = META_LOOKAHEADNOT; ptr++; goto POST_ASSERTION; @@ -4119,6 +4385,8 @@ while (ptr < ptrend) } *parsed_pattern++ = (ptr[1] == CHAR_EQUALS_SIGN)? META_LOOKBEHIND : META_LOOKBEHINDNOT; + + POST_LOOKBEHIND: /* Come from (*plb: and (*nlb: */ *has_lookbehind = TRUE; offset = (PCRE2_SIZE)(ptr - cb->start_pattern - 2); PUTOFFSET(offset, parsed_pattern); @@ -4161,7 +4429,7 @@ while (ptr < ptrend) terminator = CHAR_APOSTROPHE; /* Terminator */ DEFINE_NAME: - if (!read_name(&ptr, ptrend, terminator, &offset, &name, &namelen, + if (!read_name(&ptr, ptrend, utf, terminator, &offset, &name, &namelen, &errorcode, cb)) goto FAILED; /* We have a name for this capturing group. It is also assigned a number, @@ -4280,6 +4548,14 @@ while (ptr < ptrend) cb->bracount = top_nest->max_group; if ((top_nest->flags & NSF_CONDASSERT) != 0) okquantifier = FALSE; + + if ((top_nest->flags & NSF_ATOMICSR) != 0) + { + *parsed_pattern++ = META_KET; + } + + + if (top_nest == (nest_save *)(cb->start_workspace)) top_nest = NULL; else top_nest--; } @@ -4311,12 +4587,12 @@ parsed_pattern = manage_callouts(ptr, &previous_callout, auto_callout, /* Insert trailing items for word and line matching (features provided for the benefit of pcre2grep). */ -if ((cb->cx->extra_options & PCRE2_EXTRA_MATCH_LINE) != 0) +if ((extra_options & PCRE2_EXTRA_MATCH_LINE) != 0) { *parsed_pattern++ = META_KET; *parsed_pattern++ = META_DOLLAR; } -else if ((cb->cx->extra_options & PCRE2_EXTRA_MATCH_WORD) != 0) +else if ((extra_options & PCRE2_EXTRA_MATCH_WORD) != 0) { *parsed_pattern++ = META_KET; *parsed_pattern++ = META_ESCAPE + ESC_b; @@ -4421,6 +4697,14 @@ for (;;) code += GET(code, 1) + 1 + LINK_SIZE; break; + case OP_MARK: + case OP_COMMIT_ARG: + case OP_PRUNE_ARG: + case OP_SKIP_ARG: + case OP_THEN_ARG: + code += code[1] + PRIV(OP_lengths)[*code]; + break; + default: return code; } @@ -5516,10 +5800,10 @@ for (;; pptr++) if (range_is_literal && (cb->ctypes[c] & ctype_letter) != 0 && (cb->ctypes[d] & ctype_letter) != 0 && - (d <= CHAR_z) == (d <= CHAR_z)) + (c <= CHAR_z) == (d <= CHAR_z)) { uint32_t uc = (d <= CHAR_z)? 0 : 64; - uint32_t C = d - uc; + uint32_t C = c - uc; uint32_t D = d - uc; if (C <= CHAR_i) @@ -5664,7 +5948,10 @@ for (;; pptr++) (void)memmove(code + (32 / sizeof(PCRE2_UCHAR)), code, CU2BYTES(class_uchardata - code)); if (negate_class && !xclass_has_prop) - for (i = 0; i < 32; i++) classbits[i] = ~classbits[i]; + { + /* Using 255 ^ instead of ~ avoids clang sanitize warning. */ + for (i = 0; i < 32; i++) classbits[i] = 255 ^ classbits[i]; + } memcpy(code, classbits, 32); code = class_uchardata + (32 / sizeof(PCRE2_UCHAR)); } @@ -5687,7 +5974,10 @@ for (;; pptr++) if (lengthptr == NULL) /* Save time in the pre-compile phase */ { if (negate_class) - for (i = 0; i < 32; i++) classbits[i] = ~classbits[i]; + { + /* Using 255 ^ instead of ~ avoids clang sanitize warning. */ + for (i = 0; i < 32; i++) classbits[i] = 255 ^ classbits[i]; + } memcpy(code, classbits, 32); } code += 32 / sizeof(PCRE2_UCHAR); @@ -5901,7 +6191,7 @@ for (;; pptr++) } goto GROUP_PROCESS_NOTE_EMPTY; - /* The DEFINE condition is always false. It's internal groups may never + /* The DEFINE condition is always false. Its internal groups may never be called, so matched_char must remain false, hence the jump to GROUP_PROCESS rather than GROUP_PROCESS_NOTE_EMPTY. */ @@ -5997,6 +6287,10 @@ for (;; pptr++) bravalue = OP_ONCE; goto GROUP_PROCESS_NOTE_EMPTY; + case META_SCRIPT_RUN: + bravalue = OP_SCRIPT_RUN; + goto GROUP_PROCESS_NOTE_EMPTY; + case META_NOCAPTURE: bravalue = OP_BRA; /* Fall through */ @@ -6237,8 +6531,8 @@ for (;; pptr++) groupnumber = ng->number; /* For a recursion, that's all that is needed. We can now go to - the code above that handles numerical recursion, applying it to - the first group with the given name. */ + the code that handles numerical recursion, applying it to the first + group with the given name. */ if (meta == META_RECURSE_BYNAME) { @@ -6632,6 +6926,7 @@ for (;; pptr++) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: + case OP_SCRIPT_RUN: case OP_BRA: case OP_CBRA: case OP_COND: @@ -6844,16 +7139,16 @@ for (;; pptr++) } /* If the maximum is unlimited, set a repeater in the final copy. For - ONCE brackets, that's all we need to do. However, possessively repeated - ONCE brackets can be converted into non-capturing brackets, as the - behaviour of (?:xx)++ is the same as (?>xx)++ and this saves having to - deal with possessive ONCEs specially. + SCRIPT_RUN and ONCE brackets, that's all we need to do. However, + possessively repeated ONCE brackets can be converted into non-capturing + brackets, as the behaviour of (?:xx)++ is the same as (?>xx)++ and this + saves having to deal with possessive ONCEs specially. Otherwise, when we are doing the actual compile phase, check to see whether this group is one that could match an empty string. If so, convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so that runtime checking can be done. [This check is also applied to ONCE - groups at runtime, but in a different way.] + and SCRIPT_RUN groups at runtime, but in a different way.] Then, if the quantifier was possessive and the bracket is not a conditional, we convert the BRA code to the POS form, and the KET code to @@ -6877,13 +7172,14 @@ for (;; pptr++) if (*bracode == OP_ONCE && possessive_quantifier) *bracode = OP_BRA; - /* For non-possessive ONCE brackets, all we need to do is to - set the KET. */ + /* For non-possessive ONCE and for SCRIPT_RUN brackets, all we need + to do is to set the KET. */ - if (*bracode == OP_ONCE) *ketcode = OP_KETRMAX + repeat_type; + if (*bracode == OP_ONCE || *bracode == OP_SCRIPT_RUN) + *ketcode = OP_KETRMAX + repeat_type; - /* Handle non-ONCE brackets and possessive ONCEs (which have been - converted to non-capturing above). */ + /* Handle non-SCRIPT_RUN and non-ONCE brackets and possessive ONCEs + (which have been converted to non-capturing above). */ else { @@ -7267,9 +7563,8 @@ for (;; pptr++) scanned and these numbers are replaced by offsets within the pattern. It is done like this to avoid problems with forward references and adjusting offsets when groups are duplicated and moved (as discovered in previous - implementations). Note that a recursion does not have a set first character - (relevant if it is repeated, because it will then be wrapped with ONCE - brackets). */ + implementations). Note that a recursion does not have a set first + character. */ case META_RECURSE: GETPLUSOFFSET(offset, pptr); @@ -7286,6 +7581,8 @@ for (;; pptr++) groupsetfirstcu = FALSE; cb->had_recurse = TRUE; if (firstcuflags == REQ_UNSET) firstcuflags = REQ_NONE; + zerofirstcu = firstcu; + zerofirstcuflags = firstcuflags; break; @@ -7340,9 +7637,20 @@ for (;; pptr++) { uint32_t ptype = *(++pptr) >> 16; uint32_t pdata = *pptr & 0xffff; - *code++ = (meta_arg == ESC_p)? OP_PROP : OP_NOTPROP; - *code++ = ptype; - *code++ = pdata; + + /* The special case of \p{Any} is compiled to OP_ALLANY so as to benefit + from the auto-anchoring code. */ + + if (meta_arg == ESC_p && ptype == PT_ANY) + { + *code++ = OP_ALLANY; + } + else + { + *code++ = (meta_arg == ESC_p)? OP_PROP : OP_NOTPROP; + *code++ = ptype; + *code++ = pdata; + } break; /* End META_ESCAPE */ } #endif @@ -8240,6 +8548,7 @@ do { case OP_SCBRAPOS: case OP_ASSERT: case OP_ONCE: + case OP_SCRIPT_RUN: d = find_firstassertedcu(scode, &dflags, inassert + ((op==OP_ASSERT)?1:0)); if (dflags < 0) return 0; @@ -8439,6 +8748,7 @@ for (;; pptr++) case META_LOOKBEHIND: case META_LOOKBEHINDNOT: case META_NOCAPTURE: + case META_SCRIPT_RUN: nestlevel++; break; @@ -8851,6 +9161,7 @@ for (;; pptr++) case META_ATOMIC: case META_NOCAPTURE: + case META_SCRIPT_RUN: pptr++; CHECK_GROUP: grouplength = get_grouplength(&pptr, TRUE, errcodeptr, lcptr, group, @@ -9030,6 +9341,7 @@ for (pptr = cb->parsed_pattern; *pptr != META_END; pptr++) case META_QUERY_QUERY: case META_RANGE_ESCAPED: case META_RANGE_LITERAL: + case META_SCRIPT_RUN: case META_SKIP: case META_THEN: break; diff --git a/thirdparty/pcre2/src/pcre2_context.c b/thirdparty/pcre2/src/pcre2_context.c index 2c14df0080..9c2886a6d0 100644 --- a/thirdparty/pcre2/src/pcre2_context.c +++ b/thirdparty/pcre2/src/pcre2_context.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-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -163,11 +163,13 @@ when no context is supplied to a match function. */ const pcre2_match_context PRIV(default_match_context) = { { default_malloc, default_free, NULL }, #ifdef SUPPORT_JIT - NULL, - NULL, + NULL, /* JIT callback */ + NULL, /* JIT callback data */ #endif - NULL, - NULL, + NULL, /* Callout function */ + NULL, /* Callout data */ + NULL, /* Substitute callout function */ + NULL, /* Substitute callout data */ PCRE2_UNSET, /* Offset limit */ HEAP_LIMIT, MATCH_LIMIT, @@ -404,6 +406,16 @@ return 0; } PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION +pcre2_set_substitute_callout(pcre2_match_context *mcontext, + int (*substitute_callout)(pcre2_substitute_callout_block *, void *), + void *substitute_callout_data) +{ +mcontext->substitute_callout = substitute_callout; +mcontext->substitute_callout_data = substitute_callout_data; +return 0; +} + +PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_set_heap_limit(pcre2_match_context *mcontext, uint32_t limit) { mcontext->heap_limit = limit; diff --git a/thirdparty/pcre2/src/pcre2_convert.c b/thirdparty/pcre2/src/pcre2_convert.c index 1dd5c337dc..d45b6fee97 100644 --- a/thirdparty/pcre2/src/pcre2_convert.c +++ b/thirdparty/pcre2/src/pcre2_convert.c @@ -276,7 +276,7 @@ while (plength > 0) break; case CHAR_BACKSLASH: - if (plength <= 0) return PCRE2_ERROR_END_BACKSLASH; + if (plength == 0) return PCRE2_ERROR_END_BACKSLASH; if (extended) nextisliteral = TRUE; else { if (*posix < 127 && strchr(posix_meta_escapes, *posix) != NULL) diff --git a/thirdparty/pcre2/src/pcre2_dfa_match.c b/thirdparty/pcre2/src/pcre2_dfa_match.c index 9b43237da7..bbf3e21064 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-2018 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -85,7 +85,8 @@ in others, so I abandoned this code. */ #define PUBLIC_DFA_MATCH_OPTIONS \ (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \ PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \ - PCRE2_PARTIAL_SOFT|PCRE2_DFA_SHORTEST|PCRE2_DFA_RESTART) + PCRE2_PARTIAL_SOFT|PCRE2_DFA_SHORTEST|PCRE2_DFA_RESTART| \ + PCRE2_COPY_MATCHED_SUBJECT) /************************************************* @@ -173,6 +174,7 @@ static const uint8_t coptable[] = { 0, /* Assert behind */ 0, /* Assert behind not */ 0, /* ONCE */ + 0, /* SCRIPT_RUN */ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ 0, 0, /* CREF, DNCREF */ @@ -247,6 +249,7 @@ static const uint8_t poptable[] = { 0, /* Assert behind */ 0, /* Assert behind not */ 0, /* ONCE */ + 0, /* SCRIPT_RUN */ 0, 0, 0, 0, 0, /* BRA, BRAPOS, CBRA, CBRAPOS, COND */ 0, 0, 0, 0, 0, /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND */ 0, 0, /* CREF, DNCREF */ @@ -316,8 +319,8 @@ finding the minimum heap requirement for a match. */ typedef struct RWS_anchor { struct RWS_anchor *next; - unsigned int size; /* Number of ints */ - unsigned int free; /* Number of ints */ + uint32_t size; /* Number of ints */ + uint32_t free; /* Number of ints */ } RWS_anchor; #define RWS_ANCHOR_SIZE (sizeof(RWS_anchor)/sizeof(int)) @@ -413,20 +416,24 @@ if (rws->next != NULL) new = rws->next; } -/* All sizes are in units of sizeof(int), except for mb->heaplimit, which is in -kibibytes. */ +/* Sizes in the RWS_anchor blocks are in units of sizeof(int), but +mb->heap_limit and mb->heap_used are in kibibytes. Play carefully, to avoid +overflow. */ else { - unsigned int newsize = rws->size * 2; - unsigned int heapleft = (unsigned int) - (((1024/sizeof(int))*mb->heap_limit - mb->heap_used)); - if (newsize > heapleft) newsize = heapleft; + uint32_t newsize = (rws->size >= UINT32_MAX/2)? UINT32_MAX/2 : rws->size * 2; + uint32_t newsizeK = newsize/(1024/sizeof(int)); + + if (newsizeK + mb->heap_used > mb->heap_limit) + newsizeK = (uint32_t)(mb->heap_limit - mb->heap_used); + newsize = newsizeK*(1024/sizeof(int)); + if (newsize < RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE) return PCRE2_ERROR_HEAPLIMIT; new = mb->memctl.malloc(newsize*sizeof(int), mb->memctl.memory_data); if (new == NULL) return PCRE2_ERROR_NOMEMORY; - mb->heap_used += newsize; + mb->heap_used += newsizeK; new->next = NULL; new->size = newsize; rws->next = new; @@ -2560,7 +2567,7 @@ for (;;) if (clen > 0) { isinclass = (c > 255)? (codevalue == OP_NCLASS) : - ((((uint8_t *)(code + 1))[c/8] & (1 << (c&7))) != 0); + ((((uint8_t *)(code + 1))[c/8] & (1u << (c&7))) != 0); } } @@ -2753,7 +2760,7 @@ for (;;) /* There is also an always-true condition */ else if (condcode == OP_TRUE) - { ADD_ACTIVE(state_offset + LINK_SIZE + 2 + IMM2_SIZE, 0); } + { ADD_ACTIVE(state_offset + LINK_SIZE + 2, 0); } /* The only supported version of OP_RREF is for the value RREF_ANY, which means "test if in any recursion". We can't test for specifically @@ -3226,6 +3233,8 @@ pcre2_dfa_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, pcre2_match_context *mcontext, int *workspace, PCRE2_SIZE wscount) { int rc; +int was_zero_terminated = 0; + const pcre2_real_code *re = (const pcre2_real_code *)code; PCRE2_SPTR start_match; @@ -3265,7 +3274,11 @@ rws->free = RWS_BASE_SIZE - RWS_ANCHOR_SIZE; /* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated subject string. */ -if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); +if (length == PCRE2_ZERO_TERMINATED) + { + length = PRIV(strlen)(subject); + was_zero_terminated = 1; + } /* Plausibility checks */ @@ -3518,10 +3531,20 @@ if ((re->flags & PCRE2_LASTSET) != 0) } } +/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT, +free the memory that was obtained. */ + +if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0) + { + match_data->memctl.free((void *)match_data->subject, + match_data->memctl.memory_data); + match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT; + } + /* Fill in fields that are always returned in the match data. */ match_data->code = re; -match_data->subject = subject; +match_data->subject = NULL; /* Default for no match */ match_data->mark = NULL; match_data->matchedby = PCRE2_MATCHEDBY_DFA_INTERPRETER; @@ -3586,7 +3609,7 @@ for (;;) #if PCRE2_CODE_UNIT_WIDTH != 8 if (c > 255) c = 255; #endif - ok = (start_bits[c/8] & (1 << (c&7))) != 0; + ok = (start_bits[c/8] & (1u << (c&7))) != 0; } } if (!ok) break; @@ -3697,7 +3720,7 @@ for (;;) #if PCRE2_CODE_UNIT_WIDTH != 8 if (c > 255) c = 255; #endif - if ((start_bits[c/8] & (1 << (c&7))) != 0) break; + if ((start_bits[c/8] & (1u << (c&7))) != 0) break; start_match++; } @@ -3816,6 +3839,20 @@ for (;;) match_data->rightchar = (PCRE2_SIZE)( mb->last_used_ptr - subject); match_data->startchar = (PCRE2_SIZE)(start_match - subject); match_data->rc = rc; + + if (rc >= 0 &&(options & PCRE2_COPY_MATCHED_SUBJECT) != 0) + { + length = CU2BYTES(length + was_zero_terminated); + match_data->subject = match_data->memctl.malloc(length, + match_data->memctl.memory_data); + if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY; + memcpy((void *)match_data->subject, subject, length); + match_data->flags |= PCRE2_MD_COPIED_SUBJECT; + } + else + { + if (rc >= 0 || rc == PCRE2_ERROR_PARTIAL) match_data->subject = subject; + } goto EXIT; } diff --git a/thirdparty/pcre2/src/pcre2_error.c b/thirdparty/pcre2/src/pcre2_error.c index 4b3b3f1bc0..1d02cf14a3 100644 --- a/thirdparty/pcre2/src/pcre2_error.c +++ b/thirdparty/pcre2/src/pcre2_error.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-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -71,7 +71,7 @@ static const unsigned char compile_error_texts[] = /* 5 */ "number too big in {} quantifier\0" "missing terminating ] for character class\0" - "invalid escape sequence in character class\0" + "escape sequence is invalid in character class\0" "range out of order in character class\0" "quantifier does not follow a repeatable item\0" /* 10 */ @@ -95,7 +95,7 @@ static const unsigned char compile_error_texts[] = /* 25 */ "lookbehind assertion is not fixed length\0" "a relative value of zero is not allowed\0" - "conditional group contains more than two branches\0" + "conditional subpattern contains more than two branches\0" "assertion expected after (?( or (?(?C)\0" "digit expected after (?+ or (?-\0" /* 30 */ @@ -113,21 +113,21 @@ static const unsigned char compile_error_texts[] = /* 40 */ "invalid escape sequence in (*VERB) name\0" "unrecognized character after (?P\0" - "syntax error in subpattern name (missing terminator)\0" + "syntax error in subpattern name (missing terminator?)\0" "two named subpatterns have the same name (PCRE2_DUPNAMES not set)\0" - "group name must start with a non-digit\0" + "subpattern name must start with a non-digit\0" /* 45 */ "this version of PCRE2 does not have support for \\P, \\p, or \\X\0" "malformed \\P or \\p sequence\0" "unknown property name after \\P or \\p\0" - "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0" + "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " code units)\0" "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0" /* 50 */ "invalid range in character class\0" "octal value is greater than \\377 in 8-bit non-UTF-8 mode\0" "internal error: overran compiling workspace\0" "internal error: previously-checked referenced subpattern not found\0" - "DEFINE group contains more than one branch\0" + "DEFINE subpattern contains more than one branch\0" /* 55 */ "missing opening brace after \\o\0" "internal error: unknown newline setting\0" @@ -137,7 +137,7 @@ static const unsigned char compile_error_texts[] = "obsolete error (should not occur)\0" /* Was the above */ /* 60 */ "(*VERB) not recognized or malformed\0" - "group number is too big\0" + "subpattern number is too big\0" "subpattern name expected\0" "internal error: parsed pattern overflow\0" "non-octal character in \\o{} (closing brace missing?)\0" @@ -181,6 +181,9 @@ static const unsigned char compile_error_texts[] = "invalid option bits with PCRE2_LITERAL\0" "\\N{U+dddd} is supported only in Unicode (UTF) mode\0" "invalid hyphen in option setting\0" + /* 95 */ + "(*alpha_assertion) not recognized\0" + "script runs require Unicode support, which this version of PCRE2 does not have\0" ; /* Match-time and UTF error texts are in the same format. */ diff --git a/thirdparty/pcre2/src/pcre2_extuni.c b/thirdparty/pcre2/src/pcre2_extuni.c index 237211abf7..5a719e9cb4 100644 --- a/thirdparty/pcre2/src/pcre2_extuni.c +++ b/thirdparty/pcre2/src/pcre2_extuni.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-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -100,7 +100,7 @@ while (eptr < end_subject) int len = 1; if (!utf) c = *eptr; else { GETCHARLEN(c, eptr, len); } rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break; /* Not breaking between Regional Indicators is allowed only if there are an even number of preceding RIs. */ diff --git a/thirdparty/pcre2/src/pcre2_internal.h b/thirdparty/pcre2/src/pcre2_internal.h index 8750f2f174..814d91bddb 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-2018 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -148,16 +148,7 @@ pcre2_match() because of the way it backtracks. */ /* When checking for integer overflow in pcre2_compile(), we need to handle large integers. If a 64-bit integer type is available, we can use that. Otherwise we have to cast to double, which of course requires floating point -arithmetic. Handle this by defining a macro for the appropriate type. If -stdint.h is available, include it; it may define INT64_MAX. Systems that do not -have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set -by "configure". */ - -#if defined HAVE_STDINT_H -#include <stdint.h> -#elif defined HAVE_INTTYPES_H -#include <inttypes.h> -#endif +arithmetic. Handle this by defining a macro for the appropriate type. */ #if defined INT64_MAX || defined int64_t #define INT64_OR_DOUBLE int64_t @@ -535,6 +526,10 @@ enum { PCRE2_MATCHEDBY_INTERPRETER, /* pcre2_match() */ PCRE2_MATCHEDBY_DFA_INTERPRETER, /* pcre2_dfa_match() */ PCRE2_MATCHEDBY_JIT }; /* pcre2_jit_match() */ +/* Values for the flags field in a match data block. */ + +#define PCRE2_MD_COPIED_SUBJECT 0x01u + /* Magic number to provide a small check against being handed junk. */ #define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ @@ -569,11 +564,11 @@ these tables. */ without checking pcre2_jit_compile.c, which has an assertion to ensure that ctype_word has the value 16. */ -#define ctype_space 0x01 -#define ctype_letter 0x02 -#define ctype_digit 0x04 -#define ctype_xdigit 0x08 /* not actually used any more */ -#define ctype_word 0x10 /* alphanumeric or '_' */ +#define ctype_space 0x01 +#define ctype_letter 0x02 +#define ctype_lcletter 0x04 +#define ctype_digit 0x08 +#define ctype_word 0x10 /* alphanumeric or '_' */ /* Offsets of the various tables from the base tables pointer, and total length of the tables. */ @@ -874,34 +869,48 @@ a positive value. */ #define STR_RIGHT_CURLY_BRACKET "}" #define STR_TILDE "~" -#define STRING_ACCEPT0 "ACCEPT\0" -#define STRING_COMMIT0 "COMMIT\0" -#define STRING_F0 "F\0" -#define STRING_FAIL0 "FAIL\0" -#define STRING_MARK0 "MARK\0" -#define STRING_PRUNE0 "PRUNE\0" -#define STRING_SKIP0 "SKIP\0" -#define STRING_THEN "THEN" - -#define STRING_alpha0 "alpha\0" -#define STRING_lower0 "lower\0" -#define STRING_upper0 "upper\0" -#define STRING_alnum0 "alnum\0" -#define STRING_ascii0 "ascii\0" -#define STRING_blank0 "blank\0" -#define STRING_cntrl0 "cntrl\0" -#define STRING_digit0 "digit\0" -#define STRING_graph0 "graph\0" -#define STRING_print0 "print\0" -#define STRING_punct0 "punct\0" -#define STRING_space0 "space\0" -#define STRING_word0 "word\0" -#define STRING_xdigit "xdigit" - -#define STRING_DEFINE "DEFINE" -#define STRING_VERSION "VERSION" -#define STRING_WEIRD_STARTWORD "[:<:]]" -#define STRING_WEIRD_ENDWORD "[:>:]]" +#define STRING_ACCEPT0 "ACCEPT\0" +#define STRING_COMMIT0 "COMMIT\0" +#define STRING_F0 "F\0" +#define STRING_FAIL0 "FAIL\0" +#define STRING_MARK0 "MARK\0" +#define STRING_PRUNE0 "PRUNE\0" +#define STRING_SKIP0 "SKIP\0" +#define STRING_THEN "THEN" + +#define STRING_atomic0 "atomic\0" +#define STRING_pla0 "pla\0" +#define STRING_plb0 "plb\0" +#define STRING_nla0 "nla\0" +#define STRING_nlb0 "nlb\0" +#define STRING_sr0 "sr\0" +#define STRING_asr0 "asr\0" +#define STRING_positive_lookahead0 "positive_lookahead\0" +#define STRING_positive_lookbehind0 "positive_lookbehind\0" +#define STRING_negative_lookahead0 "negative_lookahead\0" +#define STRING_negative_lookbehind0 "negative_lookbehind\0" +#define STRING_script_run0 "script_run\0" +#define STRING_atomic_script_run "atomic_script_run" + +#define STRING_alpha0 "alpha\0" +#define STRING_lower0 "lower\0" +#define STRING_upper0 "upper\0" +#define STRING_alnum0 "alnum\0" +#define STRING_ascii0 "ascii\0" +#define STRING_blank0 "blank\0" +#define STRING_cntrl0 "cntrl\0" +#define STRING_digit0 "digit\0" +#define STRING_graph0 "graph\0" +#define STRING_print0 "print\0" +#define STRING_punct0 "punct\0" +#define STRING_space0 "space\0" +#define STRING_word0 "word\0" +#define STRING_xdigit "xdigit" + +#define STRING_DEFINE "DEFINE" +#define STRING_VERSION "VERSION" +#define STRING_WEIRD_STARTWORD "[:<:]]" +#define STRING_WEIRD_ENDWORD "[:>:]]" #define STRING_CR_RIGHTPAR "CR)" #define STRING_LF_RIGHTPAR "LF)" @@ -1150,34 +1159,48 @@ only. */ #define STR_RIGHT_CURLY_BRACKET "\175" #define STR_TILDE "\176" -#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0" -#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0" -#define STRING_F0 STR_F "\0" -#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0" -#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0" -#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0" -#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0" -#define STRING_THEN STR_T STR_H STR_E STR_N - -#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0" -#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0" -#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0" -#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0" -#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0" -#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0" -#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0" -#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0" -#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0" -#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0" -#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0" -#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0" -#define STRING_word0 STR_w STR_o STR_r STR_d "\0" -#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t - -#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E -#define STRING_VERSION STR_V STR_E STR_R STR_S STR_I STR_O STR_N -#define STRING_WEIRD_STARTWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET -#define STRING_WEIRD_ENDWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET +#define STRING_ACCEPT0 STR_A STR_C STR_C STR_E STR_P STR_T "\0" +#define STRING_COMMIT0 STR_C STR_O STR_M STR_M STR_I STR_T "\0" +#define STRING_F0 STR_F "\0" +#define STRING_FAIL0 STR_F STR_A STR_I STR_L "\0" +#define STRING_MARK0 STR_M STR_A STR_R STR_K "\0" +#define STRING_PRUNE0 STR_P STR_R STR_U STR_N STR_E "\0" +#define STRING_SKIP0 STR_S STR_K STR_I STR_P "\0" +#define STRING_THEN STR_T STR_H STR_E STR_N + +#define STRING_atomic0 STR_a STR_t STR_o STR_m STR_i STR_c "\0" +#define STRING_pla0 STR_p STR_l STR_a "\0" +#define STRING_plb0 STR_p STR_l STR_b "\0" +#define STRING_nla0 STR_n STR_l STR_a "\0" +#define STRING_nlb0 STR_n STR_l STR_b "\0" +#define STRING_sr0 STR_s STR_r "\0" +#define STRING_asr0 STR_a STR_s STR_r "\0" +#define STRING_positive_lookahead0 STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0" +#define STRING_positive_lookbehind0 STR_p STR_o STR_s STR_i STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0" +#define STRING_negative_lookahead0 STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_a STR_h STR_e STR_a STR_d "\0" +#define STRING_negative_lookbehind0 STR_n STR_e STR_g STR_a STR_t STR_i STR_v STR_e STR_UNDERSCORE STR_l STR_o STR_o STR_k STR_b STR_e STR_h STR_i STR_n STR_d "\0" +#define STRING_script_run0 STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n "\0" +#define STRING_atomic_script_run STR_a STR_t STR_o STR_m STR_i STR_c STR_UNDERSCORE STR_s STR_c STR_r STR_i STR_p STR_t STR_UNDERSCORE STR_r STR_u STR_n + +#define STRING_alpha0 STR_a STR_l STR_p STR_h STR_a "\0" +#define STRING_lower0 STR_l STR_o STR_w STR_e STR_r "\0" +#define STRING_upper0 STR_u STR_p STR_p STR_e STR_r "\0" +#define STRING_alnum0 STR_a STR_l STR_n STR_u STR_m "\0" +#define STRING_ascii0 STR_a STR_s STR_c STR_i STR_i "\0" +#define STRING_blank0 STR_b STR_l STR_a STR_n STR_k "\0" +#define STRING_cntrl0 STR_c STR_n STR_t STR_r STR_l "\0" +#define STRING_digit0 STR_d STR_i STR_g STR_i STR_t "\0" +#define STRING_graph0 STR_g STR_r STR_a STR_p STR_h "\0" +#define STRING_print0 STR_p STR_r STR_i STR_n STR_t "\0" +#define STRING_punct0 STR_p STR_u STR_n STR_c STR_t "\0" +#define STRING_space0 STR_s STR_p STR_a STR_c STR_e "\0" +#define STRING_word0 STR_w STR_o STR_r STR_d "\0" +#define STRING_xdigit STR_x STR_d STR_i STR_g STR_i STR_t + +#define STRING_DEFINE STR_D STR_E STR_F STR_I STR_N STR_E +#define STRING_VERSION STR_V STR_E STR_R STR_S STR_I STR_O STR_N +#define STRING_WEIRD_STARTWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_LESS_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET +#define STRING_WEIRD_ENDWORD STR_LEFT_SQUARE_BRACKET STR_COLON STR_GREATER_THAN_SIGN STR_COLON STR_RIGHT_SQUARE_BRACKET STR_RIGHT_SQUARE_BRACKET #define STRING_CR_RIGHTPAR STR_C STR_R STR_RIGHT_PARENTHESIS #define STRING_LF_RIGHTPAR STR_L STR_F STR_RIGHT_PARENTHESIS @@ -1485,70 +1508,71 @@ enum { OP_ASSERTBACK, /* 128 Positive lookbehind */ OP_ASSERTBACK_NOT, /* 129 Negative lookbehind */ - /* ONCE, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately after the - assertions, with ONCE first, as there's a test for >= ONCE for a subpattern - that isn't an assertion. The POS versions must immediately follow the non-POS - versions in each case. */ + /* ONCE, SCRIPT_RUN, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come + immediately after the assertions, with ONCE first, as there's a test for >= + ONCE for a subpattern that isn't an assertion. The POS versions must + immediately follow the non-POS versions in each case. */ OP_ONCE, /* 130 Atomic group, contains captures */ - OP_BRA, /* 131 Start of non-capturing bracket */ - OP_BRAPOS, /* 132 Ditto, with unlimited, possessive repeat */ - OP_CBRA, /* 133 Start of capturing bracket */ - OP_CBRAPOS, /* 134 Ditto, with unlimited, possessive repeat */ - OP_COND, /* 135 Conditional group */ + OP_SCRIPT_RUN, /* 131 Non-capture, but check characters' scripts */ + OP_BRA, /* 132 Start of non-capturing bracket */ + OP_BRAPOS, /* 133 Ditto, with unlimited, possessive repeat */ + OP_CBRA, /* 134 Start of capturing bracket */ + OP_CBRAPOS, /* 135 Ditto, with unlimited, possessive repeat */ + OP_COND, /* 136 Conditional group */ /* These five must follow the previous five, in the same order. There's a check for >= SBRA to distinguish the two sets. */ - OP_SBRA, /* 136 Start of non-capturing bracket, check empty */ - OP_SBRAPOS, /* 137 Ditto, with unlimited, possessive repeat */ - OP_SCBRA, /* 138 Start of capturing bracket, check empty */ - OP_SCBRAPOS, /* 139 Ditto, with unlimited, possessive repeat */ - OP_SCOND, /* 140 Conditional group, check empty */ + OP_SBRA, /* 137 Start of non-capturing bracket, check empty */ + OP_SBRAPOS, /* 138 Ditto, with unlimited, possessive repeat */ + OP_SCBRA, /* 139 Start of capturing bracket, check empty */ + OP_SCBRAPOS, /* 140 Ditto, with unlimited, possessive repeat */ + OP_SCOND, /* 141 Conditional group, check empty */ /* The next two pairs must (respectively) be kept together. */ - OP_CREF, /* 141 Used to hold a capture number as condition */ - OP_DNCREF, /* 142 Used to point to duplicate names as a condition */ - OP_RREF, /* 143 Used to hold a recursion number as condition */ - OP_DNRREF, /* 144 Used to point to duplicate names as a condition */ - OP_FALSE, /* 145 Always false (used by DEFINE and VERSION) */ - OP_TRUE, /* 146 Always true (used by VERSION) */ + OP_CREF, /* 142 Used to hold a capture number as condition */ + OP_DNCREF, /* 143 Used to point to duplicate names as a condition */ + OP_RREF, /* 144 Used to hold a recursion number as condition */ + OP_DNRREF, /* 145 Used to point to duplicate names as a condition */ + OP_FALSE, /* 146 Always false (used by DEFINE and VERSION) */ + OP_TRUE, /* 147 Always true (used by VERSION) */ - OP_BRAZERO, /* 147 These two must remain together and in this */ - OP_BRAMINZERO, /* 148 order. */ - OP_BRAPOSZERO, /* 149 */ + OP_BRAZERO, /* 148 These two must remain together and in this */ + OP_BRAMINZERO, /* 149 order. */ + OP_BRAPOSZERO, /* 150 */ /* These are backtracking control verbs */ - OP_MARK, /* 150 always has an argument */ - OP_PRUNE, /* 151 */ - OP_PRUNE_ARG, /* 152 same, but with argument */ - OP_SKIP, /* 153 */ - OP_SKIP_ARG, /* 154 same, but with argument */ - OP_THEN, /* 155 */ - OP_THEN_ARG, /* 156 same, but with argument */ - OP_COMMIT, /* 157 */ - OP_COMMIT_ARG, /* 158 same, but with argument */ + OP_MARK, /* 151 always has an argument */ + OP_PRUNE, /* 152 */ + OP_PRUNE_ARG, /* 153 same, but with argument */ + OP_SKIP, /* 154 */ + OP_SKIP_ARG, /* 155 same, but with argument */ + OP_THEN, /* 156 */ + OP_THEN_ARG, /* 157 same, but with argument */ + OP_COMMIT, /* 158 */ + OP_COMMIT_ARG, /* 159 same, but with argument */ /* These are forced failure and success verbs. FAIL and ACCEPT do accept an argument, but these cases can be compiled as, for example, (*MARK:X)(*FAIL) without the need for a special opcode. */ - OP_FAIL, /* 159 */ - OP_ACCEPT, /* 160 */ - OP_ASSERT_ACCEPT, /* 161 Used inside assertions */ - OP_CLOSE, /* 162 Used before OP_ACCEPT to close open captures */ + OP_FAIL, /* 160 */ + OP_ACCEPT, /* 161 */ + OP_ASSERT_ACCEPT, /* 162 Used inside assertions */ + OP_CLOSE, /* 163 Used before OP_ACCEPT to close open captures */ /* This is used to skip a subpattern with a {0} quantifier */ - OP_SKIPZERO, /* 163 */ + OP_SKIPZERO, /* 164 */ /* This is used to identify a DEFINE group during compilation so that it can be checked for having only one branch. It is changed to OP_FALSE before compilation finishes. */ - OP_DEFINE, /* 164 */ + OP_DEFINE, /* 165 */ /* This is not an opcode, but is used to check that tables indexed by opcode are the correct length, in order to catch updating errors - there have been @@ -1596,6 +1620,7 @@ some cases doesn't actually use these names at all). */ "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos", \ "Reverse", "Assert", "Assert not", "AssertB", "AssertB not", \ "Once", \ + "Script run", \ "Bra", "BraPos", "CBra", "CBraPos", \ "Cond", \ "SBra", "SBraPos", "SCBra", "SCBraPos", \ @@ -1679,6 +1704,7 @@ in UTF-8 mode. The code that uses this table must know about such things. */ 1+LINK_SIZE, /* Assert behind */ \ 1+LINK_SIZE, /* Assert behind not */ \ 1+LINK_SIZE, /* ONCE */ \ + 1+LINK_SIZE, /* SCRIPT_RUN */ \ 1+LINK_SIZE, /* BRA */ \ 1+LINK_SIZE, /* BRAPOS */ \ 1+LINK_SIZE+IMM2_SIZE, /* CBRA */ \ @@ -1747,6 +1773,8 @@ typedef struct { uint8_t gbprop; /* ucp_gbControl, etc. (grapheme break property) */ uint8_t caseset; /* offset to multichar other cases or zero */ int32_t other_case; /* offset to other case, or zero if none */ + int16_t scriptx; /* script extension value */ + int16_t dummy; /* spare - to round to multiple of 4 bytes */ } ucd_record; /* UCD access macros */ @@ -1769,6 +1797,7 @@ typedef struct { #define UCD_GRAPHBREAK(ch) GET_UCD(ch)->gbprop #define UCD_CASESET(ch) GET_UCD(ch)->caseset #define UCD_OTHERCASE(ch) ((uint32_t)((int)ch + (int)(GET_UCD(ch)->other_case))) +#define UCD_SCRIPTX(ch) GET_UCD(ch)->scriptx /* Header for serialized pcre2 codes. */ @@ -1826,6 +1855,8 @@ extern const uint8_t PRIV(utf8_table4)[]; #define _pcre2_hspace_list PCRE2_SUFFIX(_pcre2_hspace_list_) #define _pcre2_vspace_list PCRE2_SUFFIX(_pcre2_vspace_list_) #define _pcre2_ucd_caseless_sets PCRE2_SUFFIX(_pcre2_ucd_caseless_sets_) +#define _pcre2_ucd_digit_sets PCRE2_SUFFIX(_pcre2_ucd_digit_sets_) +#define _pcre2_ucd_script_sets PCRE2_SUFFIX(_pcre2_ucd_script_sets_) #define _pcre2_ucd_records PCRE2_SUFFIX(_pcre2_ucd_records_) #define _pcre2_ucd_stage1 PCRE2_SUFFIX(_pcre2_ucd_stage1_) #define _pcre2_ucd_stage2 PCRE2_SUFFIX(_pcre2_ucd_stage2_) @@ -1847,6 +1878,8 @@ extern const uint8_t PRIV(default_tables)[]; extern const uint32_t PRIV(hspace_list)[]; extern const uint32_t PRIV(vspace_list)[]; extern const uint32_t PRIV(ucd_caseless_sets)[]; +extern const uint32_t PRIV(ucd_digit_sets)[]; +extern const uint8_t PRIV(ucd_script_sets)[]; extern const ucd_record PRIV(ucd_records)[]; #if PCRE2_CODE_UNIT_WIDTH == 32 extern const ucd_record PRIV(dummy_ucd_record)[]; @@ -1894,6 +1927,7 @@ is available. */ #define _pcre2_jit_get_target PCRE2_SUFFIX(_pcre2_jit_get_target_) #define _pcre2_memctl_malloc PCRE2_SUFFIX(_pcre2_memctl_malloc_) #define _pcre2_ord2utf PCRE2_SUFFIX(_pcre2_ord2utf_) +#define _pcre2_script_run PCRE2_SUFFIX(_pcre2_script_run_) #define _pcre2_strcmp PCRE2_SUFFIX(_pcre2_strcmp_) #define _pcre2_strcmp_c8 PCRE2_SUFFIX(_pcre2_strcmp_c8_) #define _pcre2_strcpy_c8 PCRE2_SUFFIX(_pcre2_strcpy_c8_) @@ -1908,7 +1942,7 @@ is available. */ extern int _pcre2_auto_possessify(PCRE2_UCHAR *, BOOL, const compile_block *); extern int _pcre2_check_escape(PCRE2_SPTR *, PCRE2_SPTR, uint32_t *, - int *, uint32_t, BOOL, compile_block *); + int *, uint32_t, uint32_t, BOOL, compile_block *); extern PCRE2_SPTR _pcre2_extuni(uint32_t, PCRE2_SPTR, PCRE2_SPTR, PCRE2_SPTR, BOOL, int *); extern PCRE2_SPTR _pcre2_find_bracket(PCRE2_SPTR, BOOL, int); @@ -1920,6 +1954,7 @@ extern size_t _pcre2_jit_get_size(void *); const char * _pcre2_jit_get_target(void); extern void * _pcre2_memctl_malloc(size_t, pcre2_memctl *); extern unsigned int _pcre2_ord2utf(uint32_t, PCRE2_UCHAR *); +extern BOOL _pcre2_script_run(PCRE2_SPTR, PCRE2_SPTR, BOOL); extern int _pcre2_strcmp(PCRE2_SPTR, PCRE2_SPTR); extern int _pcre2_strcmp_c8(PCRE2_SPTR, const char *); extern PCRE2_SIZE _pcre2_strcpy_c8(PCRE2_UCHAR *, const char *); diff --git a/thirdparty/pcre2/src/pcre2_intmodedep.h b/thirdparty/pcre2/src/pcre2_intmodedep.h index 62626d0a8a..bf3a235984 100644 --- a/thirdparty/pcre2/src/pcre2_intmodedep.h +++ b/thirdparty/pcre2/src/pcre2_intmodedep.h @@ -585,6 +585,8 @@ typedef struct pcre2_real_match_context { #endif int (*callout)(pcre2_callout_block *, void *); void *callout_data; + int (*substitute_callout)(pcre2_substitute_callout_block *, void *); + void *substitute_callout_data; PCRE2_SIZE offset_limit; uint32_t heap_limit; uint32_t match_limit; @@ -656,7 +658,8 @@ typedef struct pcre2_real_match_data { PCRE2_SIZE leftchar; /* Offset to leftmost code unit */ PCRE2_SIZE rightchar; /* Offset to rightmost code unit */ PCRE2_SIZE startchar; /* Offset to starting code unit */ - uint16_t matchedby; /* Type of match (normal, JIT, DFA) */ + uint8_t matchedby; /* Type of match (normal, JIT, DFA) */ + uint8_t flags; /* Various flags */ uint16_t oveccount; /* Number of pairs */ int rc; /* The return code from the match */ PCRE2_SIZE ovector[131072]; /* Must be last in the structure */ diff --git a/thirdparty/pcre2/src/pcre2_jit_compile.c b/thirdparty/pcre2/src/pcre2_jit_compile.c index 32e985b793..1f21bfb6ad 100644 --- a/thirdparty/pcre2/src/pcre2_jit_compile.c +++ b/thirdparty/pcre2/src/pcre2_jit_compile.c @@ -477,12 +477,22 @@ typedef struct compiler_common { BOOL alt_circumflex; #ifdef SUPPORT_UNICODE BOOL utf; + BOOL invalid_utf; BOOL use_ucp; + /* Points to saving area for iref. */ + sljit_s32 iref_ptr; jump_list *getucd; + jump_list *getucdtype; #if PCRE2_CODE_UNIT_WIDTH == 8 jump_list *utfreadchar; - jump_list *utfreadchar16; jump_list *utfreadtype8; + jump_list *utfpeakcharback; +#endif +#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 + jump_list *utfreadchar_invalid; + jump_list *utfreadnewline_invalid; + jump_list *utfmoveback_invalid; + jump_list *utfpeakcharback_invalid; #endif #endif /* SUPPORT_UNICODE */ } compiler_common; @@ -616,7 +626,183 @@ the start pointers when the end of the capturing group has not yet reached. */ #define READ_CHAR_MAX 0x7fffffff -#define INVALID_UTF_CHAR 888 +#define INVALID_UTF_CHAR -1 +#define UNASSIGNED_UTF_CHAR 888 + +#if defined SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 + +#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \ + { \ + if (ptr[0] <= 0x7f) \ + c = *ptr++; \ + else if (ptr + 1 < end && ptr[1] >= 0x80 && ptr[1] < 0xc0) \ + { \ + c = ptr[1] - 0x80; \ + \ + if (ptr[0] >= 0xc2 && ptr[0] <= 0xdf) \ + { \ + c |= (ptr[0] - 0xc0) << 6; \ + ptr += 2; \ + } \ + else if (ptr + 2 < end && ptr[2] >= 0x80 && ptr[2] < 0xc0) \ + { \ + c = c << 6 | (ptr[2] - 0x80); \ + \ + if (ptr[0] >= 0xe0 && ptr[0] <= 0xef) \ + { \ + c |= (ptr[0] - 0xe0) << 12; \ + ptr += 3; \ + \ + if (c < 0x800 || (c >= 0xd800 && c < 0xe000)) \ + { \ + invalid_action; \ + } \ + } \ + else if (ptr + 3 < end && ptr[3] >= 0x80 && ptr[3] < 0xc0) \ + { \ + c = c << 6 | (ptr[3] - 0x80); \ + \ + if (ptr[0] >= 0xf0 && ptr[0] <= 0xf4) \ + { \ + c |= (ptr[0] - 0xf0) << 18; \ + ptr += 4; \ + \ + if (c >= 0x110000 || c < 0x10000) \ + { \ + invalid_action; \ + } \ + } \ + else \ + { \ + invalid_action; \ + } \ + } \ + else \ + { \ + invalid_action; \ + } \ + } \ + else \ + { \ + invalid_action; \ + } \ + } \ + else \ + { \ + invalid_action; \ + } \ + } + +#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \ + { \ + if (ptr[-1] <= 0x7f) \ + c = *ptr--; \ + else if (ptr - 1 > start && ptr[-1] >= 0x80 && ptr[-1] < 0xc0) \ + { \ + c = ptr[-1] - 0x80; \ + \ + if (ptr[-2] >= 0xc2 && ptr[-2] <= 0xdf) \ + { \ + c |= (ptr[-2] - 0xc0) << 6; \ + ptr -= 2; \ + } \ + else if (ptr - 2 > start && ptr[-2] >= 0x80 && ptr[-2] < 0xc0) \ + { \ + c = c << 6 | (ptr[-2] - 0x80); \ + \ + if (ptr[-3] >= 0xe0 && ptr[-3] <= 0xef) \ + { \ + c |= (ptr[-3] - 0xe0) << 12; \ + ptr -= 3; \ + \ + if (c < 0x800 || (c >= 0xd800 && c < 0xe000)) \ + { \ + invalid_action; \ + } \ + } \ + else if (ptr - 3 > start && ptr[-3] >= 0x80 && ptr[-3] < 0xc0) \ + { \ + c = c << 6 | (ptr[-3] - 0x80); \ + \ + if (ptr[-4] >= 0xf0 && ptr[-4] <= 0xf4) \ + { \ + c |= (ptr[-4] - 0xf0) << 18; \ + ptr -= 4; \ + \ + if (c >= 0x110000 || c < 0x10000) \ + { \ + invalid_action; \ + } \ + } \ + else \ + { \ + invalid_action; \ + } \ + } \ + else \ + { \ + invalid_action; \ + } \ + } \ + else \ + { \ + invalid_action; \ + } \ + } \ + else \ + { \ + invalid_action; \ + } \ + } + +#elif PCRE2_CODE_UNIT_WIDTH == 16 + +#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \ + { \ + if (ptr[0] < 0xd800 || ptr[0] >= 0xe000) \ + c = *ptr++; \ + else if (ptr[0] < 0xdc00 && ptr + 1 < end && ptr[1] >= 0xdc00 && ptr[1] < 0xe000) \ + { \ + c = (((ptr[0] - 0xd800) << 10) | (ptr[1] - 0xdc00)) + 0x10000; \ + ptr += 2; \ + } \ + else \ + { \ + invalid_action; \ + } \ + } + +#define GETCHARBACK_INVALID(c, ptr, start, invalid_action) \ + { \ + if (ptr[-1] < 0xd800 || ptr[-1] >= 0xe000) \ + c = *ptr--; \ + else if (ptr[-1] >= 0xdc00 && ptr - 1 > start && ptr[-2] >= 0xd800 && ptr[-2] < 0xdc00) \ + { \ + c = (((ptr[-2] - 0xd800) << 10) | (ptr[-1] - 0xdc00)) + 0x10000; \ + ptr -= 2; \ + } \ + else \ + { \ + invalid_action; \ + } \ + } + + +#elif PCRE2_CODE_UNIT_WIDTH == 32 + +#define GETCHARINC_INVALID(c, ptr, end, invalid_action) \ + { \ + if (ptr[0] < 0x110000) \ + c = *ptr++; \ + else \ + { \ + invalid_action; \ + } \ + } + +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ +#endif /* SUPPORT_UNICODE */ static PCRE2_SPTR bracketend(PCRE2_SPTR cc) { @@ -716,6 +902,7 @@ switch(*cc) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: + case OP_SCRIPT_RUN: case OP_BRA: case OP_BRAPOS: case OP_CBRA: @@ -869,8 +1056,16 @@ while (cc < ccend) cc += 1; break; - case OP_REF: case OP_REFI: +#ifdef SUPPORT_UNICODE + if (common->iref_ptr == 0) + { + common->iref_ptr = common->ovector_start; + common->ovector_start += 3 * sizeof(sljit_sw); + } +#endif /* SUPPORT_UNICODE */ + /* Fall through. */ + case OP_REF: common->optimized_cbracket[GET2(cc, 1)] = 0; cc += 1 + IMM2_SIZE; break; @@ -1375,6 +1570,7 @@ while (cc < ccend) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: + case OP_SCRIPT_RUN: case OP_BRAPOS: case OP_SBRA: case OP_SBRAPOS: @@ -1951,6 +2147,7 @@ while (cc < ccend) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: + case OP_SCRIPT_RUN: case OP_BRAPOS: case OP_SBRA: case OP_SBRAPOS: @@ -2174,14 +2371,14 @@ if (base_reg != TMP2) else { status.saved_tmp_regs[1] = RETURN_ADDR; - if (sljit_get_register_index (RETURN_ADDR) == -1) + if (sljit_get_register_index(RETURN_ADDR) == -1) status.tmp_regs[1] = STR_PTR; else status.tmp_regs[1] = RETURN_ADDR; } status.saved_tmp_regs[2] = TMP3; -if (sljit_get_register_index (TMP3) == -1) +if (sljit_get_register_index(TMP3) == -1) status.tmp_regs[2] = STR_END; else status.tmp_regs[2] = TMP3; @@ -2274,6 +2471,7 @@ while (cc < ccend) case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: + case OP_SCRIPT_RUN: case OP_BRAPOS: case OP_SBRA: case OP_SBRAPOS: @@ -3059,13 +3257,13 @@ return (0 << 8) | bit; #ifdef SUPPORT_UNICODE if (common->utf && c > 65535) { - if (bit >= (1 << 10)) + if (bit >= (1u << 10)) bit >>= 10; else return (bit < 256) ? ((2 << 8) | bit) : ((3 << 8) | (bit >> 8)); } #endif /* SUPPORT_UNICODE */ -return (bit < 256) ? ((0 << 8) | bit) : ((1 << 8) | (bit >> 8)); +return (bit < 256) ? ((0u << 8) | bit) : ((1u << 8) | (bit >> 8)); #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ } @@ -3159,95 +3357,152 @@ else JUMPHERE(jump); } -static void peek_char(compiler_common *common, sljit_u32 max) +static void peek_char(compiler_common *common, sljit_u32 max, sljit_s32 dst, sljit_sw dstw, jump_list **backtracks) { /* Reads the character into TMP1, keeps STR_PTR. -Does not check STR_END. TMP2 Destroyed. */ +Does not check STR_END. TMP2, dst, RETURN_ADDR Destroyed. */ DEFINE_COMPILER; #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 struct sljit_jump *jump; -#endif +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ SLJIT_UNUSED_ARG(max); +SLJIT_UNUSED_ARG(dst); +SLJIT_UNUSED_ARG(dstw); +SLJIT_UNUSED_ARG(backtracks); -OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf) { if (max < 128) return; - jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80); + OP1(SLJIT_MOV, dst, dstw, STR_PTR, 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); - OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + add_jump(compiler, common->invalid_utf ? &common->utfreadchar_invalid : &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, STR_PTR, 0, dst, dstw); + if (backtracks && common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR)); JUMPHERE(jump); } -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 +#elif PCRE2_CODE_UNIT_WIDTH == 16 if (common->utf) { if (max < 0xd800) return; OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); - jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); - /* TMP2 contains the high surrogate. */ - OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); - OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); - JUMPHERE(jump); - } -#endif -} -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 - -static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass) -{ -/* Tells whether the character codes below 128 are enough -to determine a match. */ -const sljit_u8 value = nclass ? 0xff : 0; -const sljit_u8 *end = bitset + 32; + if (common->invalid_utf) + { + jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800); + OP1(SLJIT_MOV, dst, dstw, STR_PTR, 0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, STR_PTR, 0, dst, dstw); + if (backtracks && common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR)); + } + else + { + /* TMP2 contains the high surrogate. */ + jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); + } -bitset += 16; -do + JUMPHERE(jump); + } +#elif PCRE2_CODE_UNIT_WIDTH == 32 +if (common->invalid_utf) { - if (*bitset++ != value) - return FALSE; + if (backtracks != NULL) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000)); + else + { + OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000); + CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + } } -while (bitset < end); -return TRUE; +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ +#endif /* SUPPORT_UNICODE */ } -static void read_char7_type(compiler_common *common, BOOL full_read) +static void peek_char_back(compiler_common *common, sljit_u32 max, jump_list **backtracks) { -/* Reads the precise character type of a character into TMP1, if the character -is less than 128. Otherwise it returns with zero. Does not check STR_END. The -full_read argument tells whether characters above max are accepted or not. */ +/* Reads one character back without moving STR_PTR. TMP2 must +contain the start of the subject buffer. Affects TMP1, TMP2, and RETURN_ADDR. */ DEFINE_COMPILER; -struct sljit_jump *jump; -SLJIT_ASSERT(common->utf); +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_jump *jump; +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +SLJIT_UNUSED_ARG(max); +SLJIT_UNUSED_ARG(backtracks); -OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); -if (full_read) +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 +if (common->utf) { - jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); - OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + if (max < 128) return; + + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80); + if (common->invalid_utf) + { + add_jump(compiler, &common->utfpeakcharback_invalid, JUMP(SLJIT_FAST_CALL)); + if (backtracks != NULL) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR)); + } + else + add_jump(compiler, &common->utfpeakcharback, JUMP(SLJIT_FAST_CALL)); JUMPHERE(jump); } +#elif PCRE2_CODE_UNIT_WIDTH == 16 +if (common->utf) + { + if (max < 0xd800) return; + + if (common->invalid_utf) + { + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); + add_jump(compiler, &common->utfpeakcharback_invalid, JUMP(SLJIT_FAST_CALL)); + if (backtracks != NULL) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR)); + } + else + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xdc00); + jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xdc00); + /* TMP2 contains the low surrogate. */ + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x10000); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 10); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); + } + JUMPHERE(jump); + } +#elif PCRE2_CODE_UNIT_WIDTH == 32 + if (common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000)); +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ +#endif /* SUPPORT_UNICODE */ } -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ +#define READ_CHAR_UPDATE_STR_PTR 0x1 +#define READ_CHAR_UTF8_NEWLINE 0x2 +#define READ_CHAR_NEWLINE (READ_CHAR_UPDATE_STR_PTR | READ_CHAR_UTF8_NEWLINE) +#define READ_CHAR_VALID_UTF 0x4 -static void read_char_range(compiler_common *common, sljit_u32 min, sljit_u32 max, BOOL update_str_ptr) +static void read_char(compiler_common *common, sljit_u32 min, sljit_u32 max, + jump_list **backtracks, sljit_u32 options) { /* Reads the precise value of a character into TMP1, if the character is between min and max (c >= min && c <= max). Otherwise it returns with a value @@ -3260,24 +3515,41 @@ struct sljit_jump *jump; struct sljit_jump *jump2; #endif -SLJIT_UNUSED_ARG(update_str_ptr); SLJIT_UNUSED_ARG(min); SLJIT_UNUSED_ARG(max); +SLJIT_UNUSED_ARG(backtracks); +SLJIT_UNUSED_ARG(options); SLJIT_ASSERT(min <= max); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 +#ifdef SUPPORT_UNICODE +#if PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf) { - if (max < 128 && !update_str_ptr) return; + if (max < 128 && !(options & READ_CHAR_UPDATE_STR_PTR)) return; + + if (common->invalid_utf && !(options & READ_CHAR_VALID_UTF)) + { + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80); + + if (options & READ_CHAR_UTF8_NEWLINE) + add_jump(compiler, &common->utfreadnewline_invalid, JUMP(SLJIT_FAST_CALL)); + else + add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL)); + + if (backtracks != NULL) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR)); + JUMPHERE(jump); + return; + } jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); if (min >= 0x10000) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xf0); - if (update_str_ptr) + if (options & READ_CHAR_UPDATE_STR_PTR) OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0x7); @@ -3289,19 +3561,19 @@ if (common->utf) OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); - if (!update_str_ptr) + if (!(options & READ_CHAR_UPDATE_STR_PTR)) 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); JUMPHERE(jump2); - if (update_str_ptr) + if (options & READ_CHAR_UPDATE_STR_PTR) OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); } else if (min >= 0x800 && max <= 0xffff) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xe0); - if (update_str_ptr) + if (options & READ_CHAR_UPDATE_STR_PTR) OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xf); @@ -3309,17 +3581,19 @@ if (common->utf) OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); - if (!update_str_ptr) + if (!(options & READ_CHAR_UPDATE_STR_PTR)) OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); 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); JUMPHERE(jump2); - if (update_str_ptr) + if (options & READ_CHAR_UPDATE_STR_PTR) OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); } else if (max >= 0x800) - add_jump(compiler, (max < 0x10000) ? &common->utfreadchar16 : &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); + { + add_jump(compiler, &common->utfreadchar, JUMP(SLJIT_FAST_CALL)); + } else if (max < 128) { OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); @@ -3328,7 +3602,7 @@ if (common->utf) else { OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - if (!update_str_ptr) + if (!(options & READ_CHAR_UPDATE_STR_PTR)) OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); else OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); @@ -3336,51 +3610,141 @@ if (common->utf) 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); - if (update_str_ptr) + if (options & READ_CHAR_UPDATE_STR_PTR) OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, RETURN_ADDR, 0); } JUMPHERE(jump); } -#endif - -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 +#elif PCRE2_CODE_UNIT_WIDTH == 16 if (common->utf) { + if (max < 0xd800 && !(options & READ_CHAR_UPDATE_STR_PTR)) return; + + if (common->invalid_utf && !(options & READ_CHAR_VALID_UTF)) + { + OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); + jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800); + + if (options & READ_CHAR_UTF8_NEWLINE) + add_jump(compiler, &common->utfreadnewline_invalid, JUMP(SLJIT_FAST_CALL)); + else + add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL)); + + if (backtracks != NULL) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR)); + JUMPHERE(jump); + return; + } + if (max >= 0x10000) { OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); - jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); + jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800); /* TMP2 contains the high surrogate. */ OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); - OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x40); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3ff); - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); JUMPHERE(jump); return; } - if (max < 0xd800 && !update_str_ptr) return; - /* Skip low surrogate if necessary. */ OP2(SLJIT_SUB, TMP2, 0, TMP1, 0, SLJIT_IMM, 0xd800); - jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); - if (update_str_ptr) - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); - if (max >= 0xd800) - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000); - JUMPHERE(jump); + + if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && sljit_get_register_index(RETURN_ADDR) >= 0) + { + if (options & READ_CHAR_UPDATE_STR_PTR) + OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400); + if (options & READ_CHAR_UPDATE_STR_PTR) + CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0); + if (max >= 0xd800) + CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, 0x10000); + } + else + { + jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400); + if (options & READ_CHAR_UPDATE_STR_PTR) + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + if (max >= 0xd800) + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0x10000); + JUMPHERE(jump); + } } -#endif +#elif PCRE2_CODE_UNIT_WIDTH == 32 +if (common->invalid_utf) + { + if (backtracks != NULL) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000)); + else + { + OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000); + CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + } + } +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ +#endif /* SUPPORT_UNICODE */ +} + +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 + +static BOOL is_char7_bitset(const sljit_u8 *bitset, BOOL nclass) +{ +/* Tells whether the character codes below 128 are enough +to determine a match. */ +const sljit_u8 value = nclass ? 0xff : 0; +const sljit_u8 *end = bitset + 32; + +bitset += 16; +do + { + if (*bitset++ != value) + return FALSE; + } +while (bitset < end); +return TRUE; } -static SLJIT_INLINE void read_char(compiler_common *common) +static void read_char7_type(compiler_common *common, jump_list **backtracks, BOOL negated) { -read_char_range(common, 0, READ_CHAR_MAX, TRUE); +/* Reads the precise character type of a character into TMP1, if the character +is less than 128. Otherwise it returns with zero. Does not check STR_END. The +full_read argument tells whether characters above max are accepted or not. */ +DEFINE_COMPILER; +struct sljit_jump *jump; + +SLJIT_ASSERT(common->utf); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +/* All values > 127 are zero in ctypes. */ +OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + +if (negated) + { + jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x80); + + if (common->invalid_utf) + { + add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); + } + else + { + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(utf8_table4) - 0xc0); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); + } + JUMPHERE(jump); + } } -static void read_char8_type(compiler_common *common, BOOL update_str_ptr) +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ + +static void read_char8_type(compiler_common *common, jump_list **backtracks, BOOL negated) { /* Reads the character type into TMP1, updates STR_PTR. Does not check STR_END. */ DEFINE_COMPILER; @@ -3391,7 +3755,8 @@ struct sljit_jump *jump; struct sljit_jump *jump2; #endif -SLJIT_UNUSED_ARG(update_str_ptr); +SLJIT_UNUSED_ARG(backtracks); +SLJIT_UNUSED_ARG(negated); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); @@ -3399,18 +3764,38 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf) { - /* This can be an extra read in some situations, but hopefully - it is needed in most cases. */ + /* The result of this read may be unused, but saves an "else" part. */ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); - jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0xc0); - if (!update_str_ptr) + jump = CMP(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x80); + + if (!negated) { + if (common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + OP1(MOV_UCHAR, TMP1, 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, 0x3f); + OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2); + if (common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe0 - 0xc2)); + 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); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80); + if (common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40)); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); + jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); + JUMPHERE(jump2); + } + else if (common->invalid_utf) + { + add_jump(compiler, &common->utfreadchar_invalid, JUMP(SLJIT_FAST_CALL)); + OP1(SLJIT_MOV, TMP2, 0, TMP1, 0); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR)); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); jump2 = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); @@ -3418,43 +3803,98 @@ if (common->utf) } else add_jump(compiler, &common->utfreadtype8, JUMP(SLJIT_FAST_CALL)); + JUMPHERE(jump); return; } #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 */ +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32 +if (common->invalid_utf && negated) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x110000)); +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 32 */ + #if PCRE2_CODE_UNIT_WIDTH != 8 /* The ctypes array contains only 256 values. */ OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, 0); jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 255); -#endif +#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP2), common->ctypes); #if PCRE2_CODE_UNIT_WIDTH != 8 JUMPHERE(jump); -#endif +#endif /* PCRE2_CODE_UNIT_WIDTH != 8 */ #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 -if (common->utf && update_str_ptr) +if (common->utf && negated) { /* Skip low surrogate if necessary. */ + if (!common->invalid_utf) + { + OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800); + + if (sljit_has_cpu_feature(SLJIT_HAS_CMOV) && sljit_get_register_index(RETURN_ADDR) >= 0) + { + OP2(SLJIT_ADD, RETURN_ADDR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400); + CMOV(SLJIT_LESS, STR_PTR, RETURN_ADDR, 0); + } + else + { + jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + JUMPHERE(jump); + } + return; + } + OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800); - jump = CMP(SLJIT_GREATER, TMP2, 0, SLJIT_IMM, 0xdc00 - 0xd800 - 1); + jump = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0xe000 - 0xd800); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400)); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + + 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_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xdc00); + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400)); + JUMPHERE(jump); + return; } #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 16 */ } -static void skip_char_back(compiler_common *common) +static void move_back(compiler_common *common, jump_list **backtracks, BOOL must_be_valid) { -/* Goes one character back. Affects STR_PTR and TMP1. Does not check begin. */ +/* Goes one character back. TMP2 must contain the start of +the subject buffer. Affects STR_PTR and TMP1. Does not modify +STR_PTR for invalid character sequences. */ DEFINE_COMPILER; + +SLJIT_UNUSED_ARG(backtracks); +SLJIT_UNUSED_ARG(must_be_valid); + #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +struct sljit_jump *jump; +#endif + +#ifdef SUPPORT_UNICODE #if PCRE2_CODE_UNIT_WIDTH == 8 struct sljit_label *label; if (common->utf) { + if (!must_be_valid && common->invalid_utf) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x80); + add_jump(compiler, &common->utfmoveback_invalid, JUMP(SLJIT_FAST_CALL)); + if (backtracks != NULL) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0)); + JUMPHERE(jump); + return; + } + label = LABEL(); OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); @@ -3467,16 +3907,45 @@ if (common->utf) { OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + + if (!must_be_valid && common->invalid_utf) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); + jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000 - 0xd800); + add_jump(compiler, &common->utfmoveback_invalid, JUMP(SLJIT_FAST_CALL)); + if (backtracks != NULL) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0)); + JUMPHERE(jump); + return; + } + /* Skip low surrogate if necessary. */ OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xdc00); OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); return; } -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ -#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ +#elif PCRE2_CODE_UNIT_WIDTH == 32 +if (common->invalid_utf && !must_be_valid) + { + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -IN_UCHARS(1)); + if (backtracks != NULL) + { + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x110000)); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + return; + } + + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x110000); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_LESS); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + return; + } +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16|32] */ +#endif /* SUPPORT_UNICODE */ OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); } @@ -3519,13 +3988,12 @@ else static void do_utfreadchar(compiler_common *common) { /* Fast decoding a UTF-8 character. TMP1 contains the first byte -of the character (>= 0xc0). Return char value in TMP1, length in TMP2. */ +of the character (>= 0xc0). Return char value in TMP1. */ DEFINE_COMPILER; struct sljit_jump *jump; sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); -OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 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); @@ -3534,13 +4002,12 @@ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); 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)); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(2)); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(jump); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); -OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800); 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); @@ -3548,55 +4015,18 @@ OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000); 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)); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); /* Four byte sequence. */ JUMPHERE(jump); OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); -OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); -OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); +OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xf0000); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); -OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x3f); -OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); -OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, IN_UCHARS(4)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); -} - -static void do_utfreadchar16(compiler_common *common) -{ -/* Fast decoding a UTF-8 character. TMP1 contains the first byte -of the character (>= 0xc0). Return value in TMP1. */ -DEFINE_COMPILER; -struct sljit_jump *jump; - -sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); -OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x3f); 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); - -/* Searching for the first zero. */ -OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); -jump = JUMP(SLJIT_NOT_ZERO); -/* Two byte sequence. */ -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -sljit_emit_fast_return(compiler, RETURN_ADDR, 0); - -JUMPHERE(jump); -OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400); -OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_NOT_ZERO); -/* This code runs only in 8 bit mode. No need to shift the value. */ -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); -OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); -OP2(SLJIT_XOR, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x800); -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); -/* Three byte sequence. */ -OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } @@ -3636,8 +4066,644 @@ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP2, 0); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } +static void do_utfreadchar_invalid(compiler_common *common) +{ +/* Slow decoding a UTF-8 character. TMP1 contains the first byte +of the character (>= 0xc0). Return char value in TMP1. STR_PTR is +undefined for invalid characters. */ +DEFINE_COMPILER; +sljit_s32 i; +sljit_s32 has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV); +struct sljit_jump *jump; +struct sljit_jump *buffer_end_close; +struct sljit_label *three_byte_entry; +struct sljit_label *exit_invalid_label; +struct sljit_jump *exit_invalid[11]; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc2); + +/* Usually more than 3 characters remained in the subject buffer. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); + +/* Not a valid start of a multi-byte sequence, no more bytes read. */ +exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xf5 - 0xc2); + +buffer_end_close = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3)); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); +/* If TMP2 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */ +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80); +exit_invalid[1] = 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); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(jump); + +/* Three-byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); +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); +if (has_cmov) + { + OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x40); + CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0x20000); + exit_invalid[2] = NULL; + } +else + exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); + +OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x10000); +jump = JUMP(SLJIT_NOT_ZERO); + +three_byte_entry = LABEL(); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x2d800); +if (has_cmov) + { + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); + CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0xd800); + exit_invalid[3] = NULL; + } +else + exit_invalid[3] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +if (has_cmov) + { + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); + CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + exit_invalid[4] = NULL; + } +else + exit_invalid[4] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800); +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(jump); + +/* Four-byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); +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); +if (has_cmov) + { + OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x40); + CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, 0); + exit_invalid[5] = NULL; + } +else + exit_invalid[5] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc10000); +if (has_cmov) + { + OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x100000); + CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000); + exit_invalid[6] = NULL; + } +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); + +JUMPHERE(buffer_end_close); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); +exit_invalid[7] = CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0); + +/* Two-byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); +OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 6); +/* If TMP2 is in 0x80-0xbf range, TMP1 is also increased by (0x2 << 6). */ +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0x80); +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); + +/* Three-byte sequence. */ +JUMPHERE(jump); +exit_invalid[9] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +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); +if (has_cmov) + { + OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x40); + CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + exit_invalid[10] = NULL; + } +else + exit_invalid[10] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); + +/* One will be substracted from STR_PTR later. */ +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + +/* Four byte sequences are not possible. */ +CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x30000, three_byte_entry); + +exit_invalid_label = LABEL(); +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); +} + +static void do_utfreadnewline_invalid(compiler_common *common) +{ +/* Slow decoding a UTF-8 character, specialized for newlines. +TMP1 contains the first byte of the character (>= 0xc0). Return +char value in TMP1. */ +DEFINE_COMPILER; +struct sljit_label *loop; +struct sljit_label *skip_start; +struct sljit_label *three_byte_exit; +struct sljit_jump *jump[5]; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +if (common->nltype != NLTYPE_ANY) + { + SLJIT_ASSERT(common->nltype != NLTYPE_FIXED || common->newline < 128); + + /* 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)); + 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)); + + JUMPHERE(jump[0]); + + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); + sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + return; + } + +jump[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +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)); + +jump[1] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xc2); +jump[2] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, 0xe2); + +skip_start = LABEL(); +OP2(SLJIT_AND, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc0); +jump[3] = CMP(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80); + +/* Skip intermediate octets. */ +loop = LABEL(); +jump[4] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); +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); + +JUMPHERE(jump[3]); +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +three_byte_exit = LABEL(); +JUMPHERE(jump[0]); +JUMPHERE(jump[4]); + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); +sljit_emit_fast_return(compiler, 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); + +/* Three byte long newlines: 0x2028 and 0x2029. */ +JUMPHERE(jump[2]); +CMPTO(SLJIT_NOT_EQUAL, TMP2, 0, SLJIT_IMM, 0x80, skip_start); +CMPTO(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0, three_byte_exit); + +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_SUB, TMP1, 0, TMP2, 0, SLJIT_IMM, 0x80); +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); +} + +static void do_utfmoveback_invalid(compiler_common *common) +{ +/* Goes one character back. */ +DEFINE_COMPILER; +sljit_s32 i; +struct sljit_jump *jump; +struct sljit_jump *buffer_start_close; +struct sljit_label *exit_ok_label; +struct sljit_label *exit_invalid_label; +struct sljit_jump *exit_invalid[7]; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(3)); +exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0); + +/* Two-byte sequence. */ +buffer_start_close = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(2)); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); +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); + +/* Three-byte sequence. */ +JUMPHERE(jump); +exit_invalid[1] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, -0x40); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(1)); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0); +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); + +/* Four-byte sequence. */ +JUMPHERE(jump); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0 - 0x80); +exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0x40); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xf0); +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); + +/* Two-byte sequence. */ +JUMPHERE(buffer_start_close); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + +exit_invalid[4] = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); +CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x20, exit_ok_label); + +/* Three-byte sequence. */ +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); +exit_invalid[5] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, -0x40); +exit_invalid[6] = CMP(SLJIT_LESS, STR_PTR, 0, TMP2, 0); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0); +CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x10, exit_ok_label); + +/* Four-byte sequences are not possible. */ + +exit_invalid_label = LABEL(); +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); + +JUMPHERE(exit_invalid[4]); +/* -2 + 4 = 2 */ +OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + +exit_invalid_label = LABEL(); +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); +} + +static void do_utfpeakcharback(compiler_common *common) +{ +/* Peak a character back. */ +DEFINE_COMPILER; +struct sljit_jump *jump[2]; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xc0); +jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x20); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3)); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0); +jump[1] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x10); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-4)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xe0 - 0x80); +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf0); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + +JUMPHERE(jump[1]); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); +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); + +JUMPHERE(jump[0]); +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); +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); +} + +static void do_utfpeakcharback_invalid(compiler_common *common) +{ +/* Peak a character back. */ +DEFINE_COMPILER; +sljit_s32 i; +sljit_s32 has_cmov = sljit_has_cpu_feature(SLJIT_HAS_CMOV); +struct sljit_jump *jump[2]; +struct sljit_label *two_byte_entry; +struct sljit_label *three_byte_entry; +struct sljit_label *exit_invalid_label; +struct sljit_jump *exit_invalid[8]; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(3)); +exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xc0); +jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0); + +/* Two-byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2); +jump[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x1e); + +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); + +JUMPHERE(jump[1]); +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2 - 0x80); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80); +exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + +/* Three-byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3)); +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0); +jump[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x10); + +three_byte_entry = LABEL(); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); +if (has_cmov) + { + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); + CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, -0xd800); + exit_invalid[2] = NULL; + } +else + exit_invalid[2] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800); + +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); +if (has_cmov) + { + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x800); + CMOV(SLJIT_LESS, TMP1, SLJIT_IMM, INVALID_UTF_CHAR); + exit_invalid[3] = NULL; + } +else + exit_invalid[3] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x800); + +sljit_emit_fast_return(compiler, RETURN_ADDR, 0); + +JUMPHERE(jump[1]); +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xe0 - 0x80); +exit_invalid[4] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 12); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + +/* Four-byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-4)); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000); +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xf0); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 18); +/* ADD is used instead of OR because of the SUB 0x10000 above. */ +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP2, 0); + +if (has_cmov) + { + OP2(SLJIT_SUB | SLJIT_SET_GREATER_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x100000); + CMOV(SLJIT_GREATER_EQUAL, TMP1, SLJIT_IMM, INVALID_UTF_CHAR - 0x10000); + exit_invalid[5] = NULL; + } +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); + +JUMPHERE(jump[0]); +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); +jump[0] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0); + +/* Two-byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2); +CMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x1e, two_byte_entry); + +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2 - 0x80); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80); +exit_invalid[6] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x40); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 6); +OP2(SLJIT_OR, TMP1, 0, TMP1, 0, TMP2, 0); + +/* Three-byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-3)); +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); + +JUMPHERE(jump[0]); +exit_invalid[7] = CMP(SLJIT_GREATER, TMP2, 0, STR_PTR, 0); + +/* Two-byte sequence. */ +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xc2); +CMPTO(SLJIT_LESS, TMP2, 0, SLJIT_IMM, 0x1e, two_byte_entry); + +exit_invalid_label = LABEL(); +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); +} + #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ +#if PCRE2_CODE_UNIT_WIDTH == 16 + +static void do_utfreadchar_invalid(compiler_common *common) +{ +/* Slow decoding a UTF-16 character. TMP1 contains the first half +of the character (>= 0xd800). Return char value in TMP1. STR_PTR is +undefined for invalid characters. */ +DEFINE_COMPILER; +struct sljit_jump *exit_invalid[3]; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +/* TMP2 contains the high surrogate. */ +exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00); +exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 10); +OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xdc00); +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); + +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); +} + +static void do_utfreadnewline_invalid(compiler_common *common) +{ +/* Slow decoding a UTF-16 character, specialized for newlines. +TMP1 contains the first half of the character (>= 0xd800). Return +char value in TMP1. */ + +DEFINE_COMPILER; +struct sljit_jump *exit_invalid[2]; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +/* TMP2 contains the high surrogate. */ +exit_invalid[0] = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(0)); +exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xdc00); + +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xdc00); +OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0x400); +OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS); +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); + +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); +} + +static void do_utfmoveback_invalid(compiler_common *common) +{ +/* Goes one character back. */ +DEFINE_COMPILER; +struct sljit_jump *exit_invalid[3]; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +exit_invalid[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x400); +exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0); + +OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-1)); +OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); +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); + +JUMPHERE(exit_invalid[0]); +JUMPHERE(exit_invalid[1]); +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); +} + +static void do_utfpeakcharback_invalid(compiler_common *common) +{ +/* Peak a character back. */ +DEFINE_COMPILER; +struct sljit_jump *jump; +struct sljit_jump *exit_invalid[3]; + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +jump = CMP(SLJIT_GREATER_EQUAL, TMP1, 0, SLJIT_IMM, 0xe000); +OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, IN_UCHARS(1)); +exit_invalid[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xdc00); +exit_invalid[1] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, STR_PTR, 0); + +OP1(MOV_UCHAR, TMP2, 0, SLJIT_MEM1(STR_PTR), IN_UCHARS(-2)); +OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x10000 - 0xdc00); +OP2(SLJIT_SUB, TMP2, 0, TMP2, 0, SLJIT_IMM, 0xd800); +exit_invalid[2] = CMP(SLJIT_GREATER_EQUAL, TMP2, 0, SLJIT_IMM, 0x400); +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); + +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); +} + +#endif /* PCRE2_CODE_UNIT_WIDTH == 16 */ + /* UCD_BLOCK_SIZE must be 128 (see the assert below). */ #define UCD_BLOCK_MASK 127 #define UCD_BLOCK_SHIFT 7 @@ -3653,12 +4719,12 @@ struct sljit_jump *jump; #if defined SLJIT_DEBUG && SLJIT_DEBUG /* dummy_ucd_record */ -const ucd_record *record = GET_UCD(INVALID_UTF_CHAR); -SLJIT_ASSERT(record->script == ucp_Common && record->chartype == ucp_Cn && record->gbprop == ucp_gbOther); +const ucd_record *record = GET_UCD(UNASSIGNED_UTF_CHAR); +SLJIT_ASSERT(record->script == ucp_Unknown && record->chartype == ucp_Cn && record->gbprop == ucp_gbOther); SLJIT_ASSERT(record->caseset == 0 && record->other_case == 0); #endif -SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 8); +SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 12); sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); @@ -3666,7 +4732,47 @@ sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); if (!common->utf) { jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, UNASSIGNED_UTF_CHAR); + JUMPHERE(jump); + } +#endif + +OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); +OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); +OP1(SLJIT_MOV_U16, TMP2, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_stage1)); +OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_MASK); +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); +} + +static void do_getucdtype(compiler_common *common) +{ +/* Search the UCD record for the character comes in TMP1. +Returns chartype in TMP1 and UCD offset in TMP2. */ +DEFINE_COMPILER; +#if PCRE2_CODE_UNIT_WIDTH == 32 +struct sljit_jump *jump; +#endif + +#if defined SLJIT_DEBUG && SLJIT_DEBUG +/* dummy_ucd_record */ +const ucd_record *record = GET_UCD(UNASSIGNED_UTF_CHAR); +SLJIT_ASSERT(record->script == ucp_Unknown && record->chartype == ucp_Cn && record->gbprop == ucp_gbOther); +SLJIT_ASSERT(record->caseset == 0 && record->other_case == 0); +#endif + +SLJIT_ASSERT(UCD_BLOCK_SIZE == 128 && sizeof(ucd_record) == 12); + +sljit_emit_fast_enter(compiler, RETURN_ADDR, 0); + +#if PCRE2_CODE_UNIT_WIDTH == 32 +if (!common->utf) + { + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, UNASSIGNED_UTF_CHAR); JUMPHERE(jump); } #endif @@ -3679,8 +4785,19 @@ 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); + +// PH hacking +//fprintf(stderr, "~~A\n"); + 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, chartype)); + 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), 3); + + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 0); + +// OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); sljit_emit_fast_return(compiler, RETURN_ADDR, 0); } @@ -3695,8 +4812,9 @@ struct sljit_jump *start; struct sljit_jump *end = NULL; struct sljit_jump *end2 = NULL; #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 -struct sljit_jump *singlechar; -#endif +struct sljit_label *loop; +struct sljit_jump *jump; +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ jump_list *newline = NULL; sljit_u32 overall_options = common->re->overall_options; BOOL hascrorlf = (common->re->flags & PCRE2_HASCRORLF) != 0; @@ -3733,7 +4851,7 @@ if ((overall_options & PCRE2_FIRSTLINE) != 0) mainloop = LABEL(); /* Continual stores does not cause data dependency. */ OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->match_end_ptr, STR_PTR, 0); - read_char_range(common, common->nlmin, common->nlmax, TRUE); + read_char(common, common->nlmin, common->nlmax, NULL, READ_CHAR_NEWLINE); check_newlinechar(common, common->nltype, &newline, TRUE); CMPTO(SLJIT_LESS, STR_PTR, 0, STR_END, 0, mainloop); JUMPHERE(end); @@ -3753,11 +4871,9 @@ else if ((overall_options & PCRE2_USE_OFFSET_LIMIT) != 0) OP1(SLJIT_MOV, TMP2, 0, STR_END, 0); end = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, (sljit_sw) PCRE2_UNSET); OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); -#if PCRE2_CODE_UNIT_WIDTH == 16 - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); -#elif PCRE2_CODE_UNIT_WIDTH == 32 - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 2); -#endif +#if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); +#endif /* PCRE2_CODE_UNIT_WIDTH == [16|32] */ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); end2 = CMP(SLJIT_LESS_EQUAL, TMP2, 0, STR_END, 0); @@ -3781,7 +4897,7 @@ if (newlinecheck) OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); #if PCRE2_CODE_UNIT_WIDTH == 16 || PCRE2_CODE_UNIT_WIDTH == 32 OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); -#endif +#endif /* PCRE2_CODE_UNIT_WIDTH == [16|32] */ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); end2 = JUMP(SLJIT_JUMP); } @@ -3789,9 +4905,9 @@ if (newlinecheck) mainloop = LABEL(); /* Increasing the STR_PTR here requires one less jump in the most common case. */ -#ifdef SUPPORT_UNICODE -if (common->utf) readuchar = TRUE; -#endif +#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +if (common->utf && !common->invalid_utf) readuchar = TRUE; +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ if (newlinecheck) readuchar = TRUE; if (readuchar) @@ -3803,23 +4919,55 @@ if (newlinecheck) OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 #if PCRE2_CODE_UNIT_WIDTH == 8 -if (common->utf) +if (common->invalid_utf) + { + /* Skip continuation code units. */ + loop = LABEL(); + jump = 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)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0x80); + CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x40, loop); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + JUMPHERE(jump); + } +else if (common->utf) { - singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); + jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - JUMPHERE(singlechar); + JUMPHERE(jump); } #elif PCRE2_CODE_UNIT_WIDTH == 16 -if (common->utf) +if (common->invalid_utf) { - singlechar = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xd800); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xfc00); - OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0xd800); - OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); - OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); - JUMPHERE(singlechar); + /* Skip continuation code units. */ + loop = LABEL(); + jump = 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)); + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xdc00); + CMPTO(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0x400, loop); + OP2(SLJIT_SUB, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + JUMPHERE(jump); + } +else if (common->utf) + { + OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, 0xd800); + + if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) + { + OP2(SLJIT_ADD, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400); + CMOV(SLJIT_LESS, STR_PTR, TMP2, 0); + } + else + { + OP2(SLJIT_SUB | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, 0x400); + OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_LESS); + OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, UCHAR_SHIFT); + OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); + } } #endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ #endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 */ @@ -4305,16 +5453,16 @@ return CMP(SLJIT_NOT_EQUAL, reg, 0, SLJIT_IMM, 0xdc00); static sljit_s32 character_to_int32(PCRE2_UCHAR chr) { -sljit_s32 value = (sljit_s32)chr; +sljit_u32 value = chr; #if PCRE2_CODE_UNIT_WIDTH == 8 #define SSE2_COMPARE_TYPE_INDEX 0 -return (value << 24) | (value << 16) | (value << 8) | value; +return (sljit_s32)((value << 24) | (value << 16) | (value << 8) | value); #elif PCRE2_CODE_UNIT_WIDTH == 16 #define SSE2_COMPARE_TYPE_INDEX 1 -return (value << 16) | value; +return (sljit_s32)((value << 16) | value); #elif PCRE2_CODE_UNIT_WIDTH == 32 #define SSE2_COMPARE_TYPE_INDEX 2 -return value; +return (sljit_s32)(value); #else #error "Unsupported unit width" #endif @@ -5120,7 +6268,7 @@ for (i = 0; i < max; i++) } #if (defined SLJIT_CONFIG_X86 && SLJIT_CONFIG_X86) && !(defined SUPPORT_VALGRIND) && !(defined _WIN64) -if (check_fast_forward_char_pair_sse2(common, chars, max)) +if (sljit_has_cpu_feature(SLJIT_HAS_SSE2) && check_fast_forward_char_pair_sse2(common, chars, max)) return TRUE; #endif @@ -5356,14 +6504,15 @@ if (common->nltype == NLTYPE_FIXED && common->newline > 255) } OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); +/* Example: match /^/ to \r\n from offset 1. */ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, str)); firstchar = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); -skip_char_back(common); +move_back(common, NULL, FALSE); loop = LABEL(); common->ff_newline_shortcut = loop; -read_char_range(common, common->nlmin, common->nlmax, TRUE); +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); @@ -5544,7 +6693,7 @@ OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(STACK_TOP), -sizeof(sljit_sw)); jump = CMP(SLJIT_SIG_LESS_EQUAL, TMP2, 0, SLJIT_IMM, 0); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); -if (sljit_get_register_index (TMP3) < 0) +if (sljit_get_register_index(TMP3) < 0) { OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw))); OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), sizeof(sljit_sw), SLJIT_MEM1(STACK_TOP), -(3 * sizeof(sljit_sw))); @@ -5569,7 +6718,7 @@ sljit_emit_fast_return(compiler, RETURN_ADDR, 0); JUMPHERE(jump); OP1(SLJIT_NEG, TMP2, 0, TMP2, 0); OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); -if (sljit_get_register_index (TMP3) < 0) +if (sljit_get_register_index(TMP3) < 0) { OP1(SLJIT_MOV, SLJIT_MEM1(TMP2), 0, SLJIT_MEM1(STACK_TOP), -(2 * sizeof(sljit_sw))); OP2(SLJIT_SUB, STACK_TOP, 0, STACK_TOP, 0, SLJIT_IMM, 2 * sizeof(sljit_sw)); @@ -5588,21 +6737,29 @@ static void check_wordboundary(compiler_common *common) DEFINE_COMPILER; struct sljit_jump *skipread; jump_list *skipread_list = NULL; +jump_list *invalid_utf = NULL; #if PCRE2_CODE_UNIT_WIDTH != 8 || defined SUPPORT_UNICODE struct sljit_jump *jump; -#endif +#endif /* PCRE2_CODE_UNIT_WIDTH != 8 || SUPPORT_UNICODE */ SLJIT_COMPILE_ASSERT(ctype_word == 0x10, ctype_word_must_be_16); sljit_emit_fast_enter(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); -/* Get type of the previous char, and put it to LOCALS1. */ +/* Get type of the previous char, and put it to TMP3. */ OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); -OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); -OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, SLJIT_IMM, 0); -skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP1, 0); -skip_char_back(common); -check_start_used_ptr(common); -read_char(common); +OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); +OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, 0); +skipread = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0); + +if (common->mode == PCRE2_JIT_COMPLETE) + peek_char_back(common, READ_CHAR_MAX, &invalid_utf); +else + { + move_back(common, &invalid_utf, FALSE); + check_start_used_ptr(common); + /* No need precise read since match fails anyway. */ + read_char(common, 0, READ_CHAR_MAX, &invalid_utf, READ_CHAR_UPDATE_STR_PTR); + } /* Testing char type. */ #ifdef SUPPORT_UNICODE @@ -5610,7 +6767,7 @@ if (common->use_ucp) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); - add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); @@ -5618,23 +6775,22 @@ if (common->use_ucp) OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_No - ucp_Nd); OP_FLAGS(SLJIT_OR, TMP2, 0, SLJIT_LESS_EQUAL); JUMPHERE(jump); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP2, 0); + OP1(SLJIT_MOV, TMP3, 0, TMP2, 0); } else -#endif +#endif /* SUPPORT_UNICODE */ { #if PCRE2_CODE_UNIT_WIDTH != 8 jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); #elif defined SUPPORT_UNICODE - /* Here LOCALS1 has already been zeroed. */ + /* Here TMP3 has already been zeroed. */ jump = NULL; if (common->utf) jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), common->ctypes); OP2(SLJIT_LSHR, TMP1, 0, TMP1, 0, SLJIT_IMM, 4 /* ctype_word */); - OP2(SLJIT_AND, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, TMP1, 0); + OP2(SLJIT_AND, TMP3, 0, TMP1, 0, SLJIT_IMM, 1); #if PCRE2_CODE_UNIT_WIDTH != 8 JUMPHERE(jump); #elif defined SUPPORT_UNICODE @@ -5646,7 +6802,7 @@ JUMPHERE(skipread); OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 0); check_str_end(common, &skipread_list); -peek_char(common, READ_CHAR_MAX); +peek_char(common, READ_CHAR_MAX, SLJIT_MEM1(SLJIT_SP), LOCALS1, &invalid_utf); /* Testing char type. This is a code duplication. */ #ifdef SUPPORT_UNICODE @@ -5654,7 +6810,7 @@ if (common->use_ucp) { OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, 1); jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_UNDERSCORE); - add_jump(compiler, &common->getucd, JUMP(SLJIT_FAST_CALL)); + add_jump(compiler, &common->getucdtype, JUMP(SLJIT_FAST_CALL)); OP2(SLJIT_SUB, TMP1, 0, TMP1, 0, SLJIT_IMM, ucp_Ll); OP2(SLJIT_SUB | SLJIT_SET_LESS_EQUAL, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ucp_Lu - ucp_Ll); OP_FLAGS(SLJIT_MOV, TMP2, 0, SLJIT_LESS_EQUAL); @@ -5664,7 +6820,7 @@ if (common->use_ucp) JUMPHERE(jump); } else -#endif +#endif /* SUPPORT_UNICODE */ { #if PCRE2_CODE_UNIT_WIDTH != 8 /* TMP2 may be destroyed by peek_char. */ @@ -5688,8 +6844,22 @@ else } set_jumps(skipread_list, LABEL()); -OP2(SLJIT_XOR | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); -sljit_emit_fast_return(compiler, SLJIT_MEM1(SLJIT_SP), LOCALS0); +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); + +#ifdef SUPPORT_UNICODE +if (common->invalid_utf) + { + SLJIT_ASSERT(invalid_utf != NULL); + + set_jumps(invalid_utf, LABEL()); + 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); + return; + } +#endif /* SUPPORT_UNICODE */ } static BOOL optimize_class_ranges(compiler_common *common, const sljit_u8 *bits, BOOL nclass, BOOL invert, jump_list **backtracks) @@ -5856,9 +7026,6 @@ int i, j, k, len, c; if (!sljit_has_cpu_feature(SLJIT_HAS_CMOV)) return FALSE; -if (invert) - nclass = !nclass; - len = 0; for (i = 0; i < 32; i++) @@ -5940,6 +7107,9 @@ if (j != 0) } } +if (invert) + nclass = !nclass; + type = nclass ? SLJIT_NOT_EQUAL : SLJIT_EQUAL; add_jump(compiler, backtracks, CMP(type, TMP2, 0, SLJIT_IMM, 0)); return TRUE; @@ -6225,37 +7395,6 @@ OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); sljit_emit_fast_return(compiler, TMP1, 0); } -#if defined SUPPORT_UNICODE - -static PCRE2_SPTR SLJIT_FUNC do_utf_caselesscmp(PCRE2_SPTR src1, PCRE2_SPTR src2, PCRE2_SPTR end1, PCRE2_SPTR end2) -{ -/* This function would be ineffective to do in JIT level. */ -sljit_u32 c1, c2; -const ucd_record *ur; -const sljit_u32 *pp; - -while (src1 < end1) - { - if (src2 >= end2) - return (PCRE2_SPTR)1; - GETCHARINC(c1, src1); - GETCHARINC(c2, src2); - ur = GET_UCD(c2); - if (c1 != c2 && c1 != c2 + ur->other_case) - { - pp = PRIV(ucd_caseless_sets) + ur->caseset; - for (;;) - { - if (c1 < *pp) return NULL; - if (c1 == *pp++) break; - } - } - } -return src2; -} - -#endif /* SUPPORT_UNICODE */ - static PCRE2_SPTR byte_sequence_compare(compiler_common *common, BOOL caseless, PCRE2_SPTR cc, compare_context *context, jump_list **backtracks) { @@ -6297,7 +7436,7 @@ if (context->sourcereg == -1) OP1(SLJIT_MOV_U16, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); else #endif - OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); + OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), -context->length); #elif PCRE2_CODE_UNIT_WIDTH == 16 #if defined SLJIT_UNALIGNED && SLJIT_UNALIGNED if (context->length >= 4) @@ -6444,7 +7583,7 @@ PCRE2_SPTR ccbegin; int compares, invertcmp, numberofcmps; #if defined SUPPORT_UNICODE && (PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16) BOOL utf = common->utf; -#endif +#endif /* SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == [8|16] */ #ifdef SUPPORT_UNICODE BOOL needstype = FALSE, needsscript = FALSE, needschar = FALSE; @@ -6452,7 +7591,7 @@ BOOL charsaved = FALSE; int typereg = TMP1; const sljit_u32 *other_cases; sljit_uw typeoffset; -#endif +#endif /* SUPPORT_UNICODE */ /* Scanning the necessary info. */ cc++; @@ -6476,7 +7615,7 @@ while (*cc != XCL_END) if (c < min) min = c; #ifdef SUPPORT_UNICODE needschar = TRUE; -#endif +#endif /* SUPPORT_UNICODE */ } else if (*cc == XCL_RANGE) { @@ -6487,7 +7626,7 @@ while (*cc != XCL_END) if (c > max) max = c; #ifdef SUPPORT_UNICODE needschar = TRUE; -#endif +#endif /* SUPPORT_UNICODE */ } #ifdef SUPPORT_UNICODE else @@ -6555,13 +7694,16 @@ while (*cc != XCL_END) } cc += 2; } -#endif +#endif /* SUPPORT_UNICODE */ } SLJIT_ASSERT(compares > 0); /* We are not necessary in utf mode even in 8 bit mode. */ cc = ccbegin; -read_char_range(common, min, max, (cc[-1] & XCL_NOT) != 0); +if ((cc[-1] & XCL_NOT) != 0) + read_char(common, min, max, backtracks, READ_CHAR_UPDATE_STR_PTR); +else + read_char(common, min, max, NULL, 0); if ((cc[-1] & XCL_HASPROP) == 0) { @@ -6594,13 +7736,13 @@ else if ((cc[-1] & XCL_MAP) != 0) OP1(SLJIT_MOV, RETURN_ADDR, 0, TMP1, 0); #ifdef SUPPORT_UNICODE charsaved = TRUE; -#endif +#endif /* SUPPORT_UNICODE */ if (!optimize_class(common, (const sljit_u8 *)cc, FALSE, TRUE, list)) { #if PCRE2_CODE_UNIT_WIDTH == 8 jump = NULL; if (common->utf) -#endif +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ jump = CMP(SLJIT_GREATER, TMP1, 0, SLJIT_IMM, 255); OP2(SLJIT_AND, TMP2, 0, TMP1, 0, SLJIT_IMM, 0x7); @@ -6612,7 +7754,7 @@ else if ((cc[-1] & XCL_MAP) != 0) #if PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf) -#endif +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ JUMPHERE(jump); } @@ -6630,10 +7772,10 @@ if (needstype || needsscript) if (!common->utf) { jump = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, MAX_UTF_CODE_POINT + 1); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, INVALID_UTF_CHAR); + OP1(SLJIT_MOV, TMP1, 0, SLJIT_IMM, UNASSIGNED_UTF_CHAR); JUMPHERE(jump); } -#endif +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ OP2(SLJIT_LSHR, TMP2, 0, TMP1, 0, SLJIT_IMM, UCD_BLOCK_SHIFT); OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); @@ -6647,8 +7789,18 @@ if (needstype || needsscript) /* Before anything else, we deal with scripts. */ if (needsscript) { +// PH hacking +//fprintf(stderr, "~~B\n"); + + 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), 3); + + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 0); + + // OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); ccbegin = cc; @@ -6686,33 +7838,49 @@ if (needstype || needsscript) } if (needschar) - { OP1(SLJIT_MOV, TMP1, 0, RETURN_ADDR, 0); - } if (needstype) { if (!needschar) { +// PH hacking +//fprintf(stderr, "~~C\n"); + 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); + 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), 3); + + OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 0); + +// OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM2(TMP1, TMP2), 3); } else { +// PH hacking +//fprintf(stderr, "~~D\n"); + 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); + OP1(SLJIT_MOV_U8, RETURN_ADDR, 0, SLJIT_MEM1(TMP2), (sljit_sw)PRIV(ucd_records) + SLJIT_OFFSETOF(ucd_record, chartype)); typereg = RETURN_ADDR; } } } -#endif +#endif /* SUPPORT_UNICODE */ /* Generating code. */ charoffset = 0; numberofcmps = 0; #ifdef SUPPORT_UNICODE typeoffset = 0; -#endif +#endif /* SUPPORT_UNICODE */ while (*cc != XCL_END) { @@ -6979,7 +8147,7 @@ while (*cc != XCL_END) } cc += 2; } -#endif +#endif /* SUPPORT_UNICODE */ if (jump != NULL) add_jump(compiler, compares > 0 ? list : backtracks, jump); @@ -7020,6 +8188,15 @@ switch(type) case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: add_jump(compiler, &common->wordboundary, JUMP(SLJIT_FAST_CALL)); +#ifdef SUPPORT_UNICODE + if (common->invalid_utf) + { + OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_SIG_LESS, SLJIT_UNUSED, 0, TMP2, 0, SLJIT_IMM, 0); + add_jump(compiler, backtracks, JUMP(SLJIT_SIG_LESS)); + add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO)); + return cc; + } +#endif /* SUPPORT_UNICODE */ sljit_set_current_flags(compiler, SLJIT_SET_Z); add_jump(compiler, backtracks, JUMP(type == OP_NOT_WORD_BOUNDARY ? SLJIT_NOT_ZERO : SLJIT_ZERO)); return cc; @@ -7078,13 +8255,13 @@ switch(type) } else { - OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), LOCALS1, STR_PTR, 0); - read_char_range(common, common->nlmin, common->nlmax, TRUE); + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, STR_END, 0)); add_jump(compiler, &common->anynewline, JUMP(SLJIT_FAST_CALL)); sljit_set_current_flags(compiler, SLJIT_SET_Z); add_jump(compiler, backtracks, JUMP(SLJIT_ZERO)); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), LOCALS1); + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); } JUMPHERE(jump[2]); JUMPHERE(jump[3]); @@ -7143,7 +8320,7 @@ switch(type) } else { - peek_char(common, common->nlmax); + peek_char(common, common->nlmax, TMP3, 0, NULL); check_newlinechar(common, common->nltype, backtracks, FALSE); } JUMPHERE(jump[0]); @@ -7158,10 +8335,10 @@ switch(type) return cc; case OP_CIRCM: - OP1(SLJIT_MOV, TMP2, 0, ARGUMENTS, 0); - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, begin)); - jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP1, 0); - OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); + OP1(SLJIT_MOV, TMP1, 0, ARGUMENTS, 0); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + jump[1] = CMP(SLJIT_GREATER, STR_PTR, 0, TMP2, 0); + OP2(SLJIT_AND32 | SLJIT_SET_Z, SLJIT_UNUSED, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, options), SLJIT_IMM, PCRE2_NOTBOL); add_jump(compiler, backtracks, JUMP(SLJIT_NOT_ZERO32)); jump[0] = JUMP(SLJIT_JUMP); JUMPHERE(jump[1]); @@ -7171,8 +8348,8 @@ switch(type) if (common->nltype == NLTYPE_FIXED && common->newline > 255) { - OP2(SLJIT_SUB, TMP2, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); - add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP2, 0, TMP1, 0)); + OP2(SLJIT_SUB, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(2)); + add_jump(compiler, backtracks, CMP(SLJIT_LESS, TMP1, 0, TMP2, 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)); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff)); @@ -7180,8 +8357,7 @@ switch(type) } else { - skip_char_back(common); - read_char_range(common, common->nlmin, common->nlmax, TRUE); + peek_char_back(common, common->nlmax, backtracks); check_newlinechar(common, common->nltype, backtracks, FALSE); } JUMPHERE(jump[0]); @@ -7195,12 +8371,12 @@ switch(type) #ifdef SUPPORT_UNICODE if (common->utf) { - OP1(SLJIT_MOV, TMP3, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); - OP1(SLJIT_MOV, TMP2, 0, SLJIT_IMM, length); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP1), SLJIT_OFFSETOF(jit_arguments, begin)); + OP1(SLJIT_MOV, TMP3, 0, SLJIT_IMM, length); label = LABEL(); - add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP3, 0)); - skip_char_back(common); - OP2(SLJIT_SUB | SLJIT_SET_Z, TMP2, 0, TMP2, 0, SLJIT_IMM, 1); + add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, TMP2, 0)); + move_back(common, backtracks, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_Z, TMP3, 0, TMP3, 0, SLJIT_IMM, 1); JUMPTO(SLJIT_NOT_ZERO, label); } else @@ -7225,21 +8401,28 @@ static PCRE2_SPTR SLJIT_FUNC do_extuni_utf(jit_arguments *args, PCRE2_SPTR cc) { PCRE2_SPTR start_subject = args->begin; PCRE2_SPTR end_subject = args->end; -int lgb, rgb, len, ricount; -PCRE2_SPTR prevcc, bptr; +int lgb, rgb, ricount; +PCRE2_SPTR prevcc, startcc, bptr; +BOOL first = TRUE; uint32_t c; prevcc = cc; -GETCHARINC(c, cc); -lgb = UCD_GRAPHBREAK(c); - -while (cc < end_subject) +startcc = NULL; +do { - len = 1; - GETCHARLEN(c, cc, len); + GETCHARINC(c, cc); rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + if (first) + { + lgb = rgb; + startcc = cc; + first = FALSE; + continue; + } + + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) + break; /* Not breaking between Regional Indicators is allowed only if there are an even number of preceding RIs. */ @@ -7256,7 +8439,8 @@ while (cc < end_subject) BACKCHAR(bptr); GETCHAR(c, bptr); - if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) break; + if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) + break; ricount++; } @@ -7271,14 +8455,80 @@ while (cc < end_subject) lgb != ucp_gbExtended_Pictographic) lgb = rgb; - prevcc = cc; - cc += len; + prevcc = startcc; + startcc = cc; } +while (cc < end_subject); -return cc; +return startcc; } -#endif +static PCRE2_SPTR SLJIT_FUNC do_extuni_utf_invalid(jit_arguments *args, PCRE2_SPTR cc) +{ +PCRE2_SPTR start_subject = args->begin; +PCRE2_SPTR end_subject = args->end; +int lgb, rgb, ricount; +PCRE2_SPTR prevcc, startcc, bptr; +BOOL first = TRUE; +uint32_t c; + +prevcc = cc; +startcc = NULL; +do + { + GETCHARINC_INVALID(c, cc, end_subject, break); + rgb = UCD_GRAPHBREAK(c); + + if (first) + { + lgb = rgb; + startcc = cc; + first = FALSE; + continue; + } + + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) + break; + + /* Not breaking between Regional Indicators is allowed only if there + are an even number of preceding RIs. */ + + if (lgb == ucp_gbRegionalIndicator && rgb == ucp_gbRegionalIndicator) + { + ricount = 0; + bptr = prevcc; + + /* bptr is pointing to the left-hand character */ + while (bptr > start_subject) + { + GETCHARBACK_INVALID(c, bptr, start_subject, break); + + if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) + break; + + ricount++; + } + + if ((ricount & 1) != 0) + break; /* Grapheme break required */ + } + + /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this + allows any number of them before a following Extended_Pictographic. */ + + if ((rgb != ucp_gbExtend && rgb != ucp_gbZWJ) || + lgb != ucp_gbExtended_Pictographic) + lgb = rgb; + + prevcc = startcc; + startcc = cc; + } +while (cc < end_subject); + +return startcc; +} + +#endif /* PCRE2_CODE_UNIT_WIDTH != 32 */ static PCRE2_SPTR SLJIT_FUNC do_extuni_no_utf(jit_arguments *args, PCRE2_SPTR cc) { @@ -7289,14 +8539,23 @@ PCRE2_SPTR bptr; uint32_t c; GETCHARINC(c, cc); +#if PCRE2_CODE_UNIT_WIDTH == 32 +if (c >= 0x110000) + return NULL; +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ lgb = UCD_GRAPHBREAK(c); while (cc < end_subject) { c = *cc; +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c >= 0x110000) + break; +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ rgb = UCD_GRAPHBREAK(c); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) + break; /* Not breaking between Regional Indicators is allowed only if there are an even number of preceding RIs. */ @@ -7311,13 +8570,18 @@ while (cc < end_subject) { bptr--; c = *bptr; +#if PCRE2_CODE_UNIT_WIDTH == 32 + if (c >= 0x110000) + break; +#endif /* PCRE2_CODE_UNIT_WIDTH == 32 */ if (UCD_GRAPHBREAK(c) != ucp_gbRegionalIndicator) break; ricount++; } - if ((ricount & 1) != 0) break; /* Grapheme break required */ + if ((ricount & 1) != 0) + break; /* Grapheme break required */ } /* If Extend or ZWJ follows Extended_Pictographic, do not update lgb; this @@ -7333,7 +8597,7 @@ while (cc < end_subject) return cc; } -#endif +#endif /* SUPPORT_UNICODE */ static PCRE2_SPTR compile_char1_matchingpath(compiler_common *common, PCRE2_UCHAR type, PCRE2_SPTR cc, jump_list **backtracks, BOOL check_str_ptr) { @@ -7356,10 +8620,10 @@ switch(type) detect_partial_match(common, backtracks); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_digit, FALSE)) - read_char7_type(common, type == OP_NOT_DIGIT); + read_char7_type(common, backtracks, type == OP_NOT_DIGIT); else #endif - read_char8_type(common, type == OP_NOT_DIGIT); + read_char8_type(common, backtracks, type == OP_NOT_DIGIT); /* Flip the starting bit in the negative case. */ OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_digit); add_jump(compiler, backtracks, JUMP(type == OP_DIGIT ? SLJIT_ZERO : SLJIT_NOT_ZERO)); @@ -7371,10 +8635,10 @@ switch(type) detect_partial_match(common, backtracks); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_space, FALSE)) - read_char7_type(common, type == OP_NOT_WHITESPACE); + read_char7_type(common, backtracks, type == OP_NOT_WHITESPACE); else #endif - read_char8_type(common, type == OP_NOT_WHITESPACE); + read_char8_type(common, backtracks, type == OP_NOT_WHITESPACE); OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_space); add_jump(compiler, backtracks, JUMP(type == OP_WHITESPACE ? SLJIT_ZERO : SLJIT_NOT_ZERO)); return cc; @@ -7385,10 +8649,10 @@ switch(type) detect_partial_match(common, backtracks); #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 if (common->utf && is_char7_bitset((const sljit_u8*)common->ctypes - cbit_length + cbit_word, FALSE)) - read_char7_type(common, type == OP_NOT_WORDCHAR); + read_char7_type(common, backtracks, type == OP_NOT_WORDCHAR); else #endif - read_char8_type(common, type == OP_NOT_WORDCHAR); + read_char8_type(common, backtracks, type == OP_NOT_WORDCHAR); OP2(SLJIT_AND | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, ctype_word); add_jump(compiler, backtracks, JUMP(type == OP_WORDCHAR ? SLJIT_ZERO : SLJIT_NOT_ZERO)); return cc; @@ -7396,7 +8660,7 @@ switch(type) case OP_ANY: if (check_str_ptr) detect_partial_match(common, backtracks); - read_char_range(common, common->nlmin, common->nlmax, TRUE); + read_char(common, common->nlmin, common->nlmax, backtracks, READ_CHAR_UPDATE_STR_PTR); if (common->nltype == NLTYPE_FIXED && common->newline > 255) { jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, (common->newline >> 8) & 0xff); @@ -7418,12 +8682,18 @@ switch(type) case OP_ALLANY: if (check_str_ptr) detect_partial_match(common, backtracks); -#if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH != 32 +#ifdef SUPPORT_UNICODE if (common->utf) { + if (common->invalid_utf) + { + read_char(common, 0, READ_CHAR_MAX, backtracks, READ_CHAR_UPDATE_STR_PTR); + return cc; + } + +#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 OP1(MOV_UCHAR, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); -#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 #if PCRE2_CODE_UNIT_WIDTH == 8 jump[0] = CMP(SLJIT_LESS, TMP1, 0, SLJIT_IMM, 0xc0); OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(TMP1), (sljit_sw)PRIV(utf8_table4) - 0xc0); @@ -7435,12 +8705,12 @@ switch(type) OP_FLAGS(SLJIT_MOV, TMP1, 0, SLJIT_EQUAL); OP2(SLJIT_SHL, TMP1, 0, TMP1, 0, SLJIT_IMM, 1); OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, TMP1, 0); -#endif +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ JUMPHERE(jump[0]); -#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ return cc; +#endif /* PCRE2_CODE_UNIT_WIDTH == [8|16] */ } -#endif +#endif /* SUPPORT_UNICODE */ OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(1)); return cc; @@ -7467,7 +8737,7 @@ switch(type) case OP_ANYNL: if (check_str_ptr) detect_partial_match(common, backtracks); - read_char_range(common, common->bsr_nlmin, common->bsr_nlmax, FALSE); + read_char(common, common->bsr_nlmin, common->bsr_nlmax, NULL, 0); jump[0] = CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, CHAR_CR); /* We don't need to handle soft partial matching case. */ end_list = NULL; @@ -7490,7 +8760,12 @@ switch(type) case OP_HSPACE: if (check_str_ptr) detect_partial_match(common, backtracks); - read_char_range(common, 0x9, 0x3000, type == OP_NOT_HSPACE); + + if (type == OP_NOT_HSPACE) + read_char(common, 0x9, 0x3000, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0x9, 0x3000, NULL, 0); + add_jump(compiler, &common->hspace, JUMP(SLJIT_FAST_CALL)); sljit_set_current_flags(compiler, SLJIT_SET_Z); add_jump(compiler, backtracks, JUMP(type == OP_NOT_HSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); @@ -7500,7 +8775,12 @@ switch(type) case OP_VSPACE: if (check_str_ptr) detect_partial_match(common, backtracks); - read_char_range(common, 0xa, 0x2029, type == OP_NOT_VSPACE); + + if (type == OP_NOT_VSPACE) + read_char(common, 0xa, 0x2029, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0xa, 0x2029, NULL, 0); + add_jump(compiler, &common->vspace, JUMP(SLJIT_FAST_CALL)); sljit_set_current_flags(compiler, SLJIT_SET_Z); add_jump(compiler, backtracks, JUMP(type == OP_NOT_VSPACE ? SLJIT_NOT_ZERO : SLJIT_ZERO)); @@ -7516,9 +8796,12 @@ switch(type) #if PCRE2_CODE_UNIT_WIDTH != 32 sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, - common->utf ? SLJIT_FUNC_OFFSET(do_extuni_utf) : SLJIT_FUNC_OFFSET(do_extuni_no_utf)); + common->utf ? (common->invalid_utf ? SLJIT_FUNC_OFFSET(do_extuni_utf_invalid) : SLJIT_FUNC_OFFSET(do_extuni_utf)) : SLJIT_FUNC_OFFSET(do_extuni_no_utf)); + if (common->invalid_utf) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); #else sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_extuni_no_utf)); + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); #endif OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); @@ -7539,11 +8822,15 @@ switch(type) #ifdef SUPPORT_UNICODE if (common->utf && HAS_EXTRALEN(*cc)) length += GET_EXTRALEN(*cc); #endif - if (common->mode == PCRE2_JIT_COMPLETE && check_str_ptr - && (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0)) + + if (check_str_ptr && common->mode != PCRE2_JIT_COMPLETE) + detect_partial_match(common, backtracks); + + if (type == OP_CHAR || !char_has_othercase(common, cc) || char_get_othercase_bit(common, cc) != 0) { OP2(SLJIT_ADD, STR_PTR, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(length)); - add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); + if (length > 1 || (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE)) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER, STR_PTR, 0, STR_END, 0)); context.length = IN_UCHARS(length); context.sourcereg = -1; @@ -7553,8 +8840,6 @@ switch(type) return byte_sequence_compare(common, type == OP_CHARI, cc, &context, backtracks); } - if (check_str_ptr) - detect_partial_match(common, backtracks); #ifdef SUPPORT_UNICODE if (common->utf) { @@ -7564,24 +8849,28 @@ switch(type) #endif c = *cc; - if (type == OP_CHAR || !char_has_othercase(common, cc)) + SLJIT_ASSERT(type == OP_CHARI && char_has_othercase(common, cc)); + + if (check_str_ptr && common->mode == PCRE2_JIT_COMPLETE) + add_jump(compiler, backtracks, CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0)); + + oc = char_othercase(common, c); + read_char(common, c < oc ? c : oc, c > oc ? c : oc, NULL, 0); + + SLJIT_ASSERT(!is_powerof2(c ^ oc)); + + if (sljit_has_cpu_feature(SLJIT_HAS_CMOV)) { - read_char_range(common, c, c, FALSE); + OP2(SLJIT_SUB | SLJIT_SET_Z, SLJIT_UNUSED, 0, TMP1, 0, SLJIT_IMM, oc); + CMOV(SLJIT_EQUAL, TMP1, SLJIT_IMM, c); add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c)); - return cc + length; } - oc = char_othercase(common, c); - read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, FALSE); - bit = c ^ oc; - if (is_powerof2(bit)) + else { - OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, bit); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, c | bit)); - return cc + length; + jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c); + add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); + JUMPHERE(jump[0]); } - jump[0] = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c); - add_jump(compiler, backtracks, CMP(SLJIT_NOT_EQUAL, TMP1, 0, SLJIT_IMM, oc)); - JUMPHERE(jump[0]); return cc + length; case OP_NOT: @@ -7595,7 +8884,7 @@ switch(type) { #if PCRE2_CODE_UNIT_WIDTH == 8 c = *cc; - if (c < 128) + if (c < 128 && !common->invalid_utf) { OP1(SLJIT_MOV_U8, TMP1, 0, SLJIT_MEM1(STR_PTR), 0); if (type == OP_NOT || !char_has_othercase(common, cc)) @@ -7626,13 +8915,13 @@ switch(type) if (type == OP_NOT || !char_has_othercase(common, cc)) { - read_char_range(common, c, c, TRUE); + read_char(common, c, c, backtracks, READ_CHAR_UPDATE_STR_PTR); add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, c)); } else { oc = char_othercase(common, c); - read_char_range(common, c < oc ? c : oc, c > oc ? c : oc, TRUE); + read_char(common, c < oc ? c : oc, c > oc ? c : oc, backtracks, READ_CHAR_UPDATE_STR_PTR); bit = c ^ oc; if (is_powerof2(bit)) { @@ -7654,9 +8943,15 @@ switch(type) #if defined SUPPORT_UNICODE && PCRE2_CODE_UNIT_WIDTH == 8 bit = (common->utf && is_char7_bitset((const sljit_u8 *)cc, type == OP_NCLASS)) ? 127 : 255; - read_char_range(common, 0, bit, type == OP_NCLASS); + if (type == OP_NCLASS) + read_char(common, 0, bit, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0, bit, NULL, 0); #else - read_char_range(common, 0, 255, type == OP_NCLASS); + if (type == OP_NCLASS) + read_char(common, 0, 255, backtracks, READ_CHAR_UPDATE_STR_PTR); + else + read_char(common, 0, 255, NULL, 0); #endif if (optimize_class(common, (const sljit_u8 *)cc, type == OP_NCLASS, FALSE, backtracks)) @@ -7843,6 +9138,14 @@ int offset = 0; struct sljit_jump *jump = NULL; struct sljit_jump *partial; struct sljit_jump *nopartial; +#if defined SUPPORT_UNICODE +struct sljit_label *loop; +struct sljit_label *caseless_loop; +jump_list *no_match = NULL; +int source_reg = COUNT_MATCH; +int source_end_reg = ARGUMENTS; +int char1_reg = STACK_LIMIT; +#endif /* SUPPORT_UNICODE */ if (ref) { @@ -7858,34 +9161,98 @@ else #if defined SUPPORT_UNICODE if (common->utf && *cc == OP_REFI) { - SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); + SLJIT_ASSERT(common->iref_ptr != 0); + if (ref) - OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(SLJIT_SP), OVECTOR(offset + 1)); else - OP1(SLJIT_MOV, SLJIT_R2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); + OP1(SLJIT_MOV, TMP2, 0, SLJIT_MEM1(TMP2), sizeof(sljit_sw)); - if (withchecks) - jump = CMP(SLJIT_EQUAL, TMP1, 0, SLJIT_R2, 0); - /* No free saved registers so save data on stack. */ + if (withchecks && emptyfail) + add_jump(compiler, backtracks, CMP(SLJIT_EQUAL, TMP1, 0, TMP2, 0)); - OP1(SLJIT_MOV, SLJIT_R3, 0, STR_END, 0); - sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW) | SLJIT_ARG3(SW) | SLJIT_ARG4(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_utf_caselesscmp)); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr, source_reg, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw), source_end_reg, 0); + OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2, char1_reg, 0); + + OP1(SLJIT_MOV, source_reg, 0, TMP1, 0); + OP1(SLJIT_MOV, source_end_reg, 0, TMP2, 0); + + loop = LABEL(); + jump = CMP(SLJIT_GREATER_EQUAL, source_reg, 0, source_end_reg, 0); + partial = CMP(SLJIT_GREATER_EQUAL, STR_PTR, 0, STR_END, 0); + /* Read original character. It must be a valid UTF character. */ + OP1(SLJIT_MOV, TMP3, 0, STR_PTR, 0); + OP1(SLJIT_MOV, STR_PTR, 0, source_reg, 0); + + read_char(common, 0, READ_CHAR_MAX, NULL, READ_CHAR_UPDATE_STR_PTR | READ_CHAR_VALID_UTF); + + OP1(SLJIT_MOV, source_reg, 0, STR_PTR, 0); + OP1(SLJIT_MOV, STR_PTR, 0, TMP3, 0); + OP1(SLJIT_MOV, char1_reg, 0, TMP1, 0); + + /* Read second character. */ + read_char(common, 0, READ_CHAR_MAX, &no_match, READ_CHAR_UPDATE_STR_PTR); + + CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop); + +// PH hacking +//fprintf(stderr, "~~E\n"); + + 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, TMP2, 0, TMP2, 0, SLJIT_IMM, 3); + + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, TMP1, 0); + + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_records)); + + OP1(SLJIT_MOV_S32, TMP1, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(ucd_record, other_case)); + OP1(SLJIT_MOV_U8, TMP2, 0, SLJIT_MEM1(TMP2), SLJIT_OFFSETOF(ucd_record, caseset)); + OP2(SLJIT_ADD, TMP1, 0, TMP1, 0, TMP3, 0); + CMPTO(SLJIT_EQUAL, TMP1, 0, char1_reg, 0, loop); + + add_jump(compiler, &no_match, CMP(SLJIT_EQUAL, TMP2, 0, SLJIT_IMM, 0)); + OP2(SLJIT_SHL, TMP2, 0, TMP2, 0, SLJIT_IMM, 2); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, (sljit_sw)PRIV(ucd_caseless_sets)); + + caseless_loop = LABEL(); + OP1(SLJIT_MOV_U32, TMP1, 0, SLJIT_MEM1(TMP2), 0); + OP2(SLJIT_ADD, TMP2, 0, TMP2, 0, SLJIT_IMM, sizeof(uint32_t)); + OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, SLJIT_UNUSED, 0, TMP1, 0, char1_reg, 0); + JUMPTO(SLJIT_EQUAL, loop); + JUMPTO(SLJIT_LESS, caseless_loop); + + set_jumps(no_match, LABEL()); if (common->mode == PCRE2_JIT_COMPLETE) - add_jump(compiler, backtracks, CMP(SLJIT_LESS_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1)); - else - { - OP2(SLJIT_SUB | SLJIT_SET_Z | SLJIT_SET_LESS, SLJIT_UNUSED, 0, SLJIT_RETURN_REG, 0, SLJIT_IMM, 1); + JUMPHERE(partial); - add_jump(compiler, backtracks, JUMP(SLJIT_LESS)); + OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr); + OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2); + add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); + + if (common->mode != PCRE2_JIT_COMPLETE) + { + JUMPHERE(partial); + OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr); + OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2); - nopartial = JUMP(SLJIT_NOT_EQUAL); - OP1(SLJIT_MOV, STR_PTR, 0, STR_END, 0); check_partial(common, FALSE); add_jump(compiler, backtracks, JUMP(SLJIT_JUMP)); - JUMPHERE(nopartial); } + + JUMPHERE(jump); + OP1(SLJIT_MOV, source_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr); + OP1(SLJIT_MOV, source_end_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw)); + OP1(SLJIT_MOV, char1_reg, 0, SLJIT_MEM1(SLJIT_SP), common->iref_ptr + sizeof(sljit_sw) * 2); + return; } else #endif /* SUPPORT_UNICODE */ @@ -8862,6 +10229,42 @@ if (common->optimized_cbracket[offset >> 1] == 0) return stacksize; } +static PCRE2_SPTR SLJIT_FUNC do_script_run(PCRE2_SPTR ptr, PCRE2_SPTR endptr) +{ + if (PRIV(script_run)(ptr, endptr, FALSE)) + return endptr; + return NULL; +} + +#ifdef SUPPORT_UNICODE + +static PCRE2_SPTR SLJIT_FUNC do_script_run_utf(PCRE2_SPTR ptr, PCRE2_SPTR endptr) +{ + if (PRIV(script_run)(ptr, endptr, TRUE)) + return endptr; + return NULL; +} + +#endif /* SUPPORT_UNICODE */ + +static SLJIT_INLINE void match_script_run_common(compiler_common *common, int private_data_ptr, backtrack_common *parent) +{ +DEFINE_COMPILER; + +SLJIT_ASSERT(TMP1 == SLJIT_R0 && STR_PTR == SLJIT_R1); + +OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); +#ifdef SUPPORT_UNICODE +sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, + common->utf ? SLJIT_FUNC_OFFSET(do_script_run_utf) : SLJIT_FUNC_OFFSET(do_script_run)); +#else +sljit_emit_icall(compiler, SLJIT_CALL, SLJIT_RET(SW) | SLJIT_ARG1(SW) | SLJIT_ARG2(SW), SLJIT_IMM, SLJIT_FUNC_OFFSET(do_script_run)); +#endif + +OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_RETURN_REG, 0); +add_jump(compiler, parent->top != NULL ? &parent->top->nextbacktracks : &parent->topbacktracks, CMP(SLJIT_EQUAL, SLJIT_RETURN_REG, 0, SLJIT_IMM, 0)); +} + /* Handling bracketed expressions is probably the most complex part. @@ -8997,7 +10400,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_SBRA || opcode == OP_SCOND) +else if (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); @@ -9036,35 +10439,32 @@ if (bra == OP_BRAMINZERO) free_stack(common, 1); braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); } - else + else if (opcode == OP_ONCE || opcode >= OP_SBRA) { - if (opcode == OP_ONCE || opcode >= OP_SBRA) + jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + /* Nothing stored during the first run. */ + skip = JUMP(SLJIT_JUMP); + JUMPHERE(jump); + /* Checking zero-length iteration. */ + if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) { - jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - /* Nothing stored during the first run. */ - skip = JUMP(SLJIT_JUMP); - JUMPHERE(jump); - /* Checking zero-length iteration. */ - if (opcode != OP_ONCE || BACKTRACK_AS(bracket_backtrack)->u.framesize < 0) - { - /* When we come from outside, private_data_ptr contains the previous STR_PTR. */ - braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - } - else - { - /* Except when the whole stack frame must be saved. */ - OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); - braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), STACK(-BACKTRACK_AS(bracket_backtrack)->u.framesize - 2)); - } - JUMPHERE(skip); + /* When we come from outside, private_data_ptr contains the previous STR_PTR. */ + braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); } else { - jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); - OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); - JUMPHERE(jump); + /* Except when the whole stack frame must be saved. */ + OP1(SLJIT_MOV, TMP1, 0, SLJIT_MEM1(SLJIT_SP), private_data_ptr); + braminzero = CMP(SLJIT_EQUAL, STR_PTR, 0, SLJIT_MEM1(TMP1), STACK(-BACKTRACK_AS(bracket_backtrack)->u.framesize - 2)); } + JUMPHERE(skip); + } + else + { + jump = CMP(SLJIT_NOT_EQUAL, STR_PTR, 0, SLJIT_IMM, 0); + OP1(SLJIT_MOV, STR_PTR, 0, SLJIT_MEM1(STACK_TOP), STACK(1)); + JUMPHERE(jump); } } @@ -9081,7 +10481,7 @@ if (ket == OP_KETRMIN) if (ket == OP_KETRMAX) { rmax_label = LABEL(); - if (has_alternatives && opcode != OP_ONCE && opcode < OP_SBRA && repeat_type == 0) + if (has_alternatives && opcode >= OP_BRA && opcode < OP_SBRA && repeat_type == 0) BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = rmax_label; } @@ -9185,7 +10585,7 @@ else if (opcode == OP_CBRA || opcode == OP_SCBRA) OP1(SLJIT_MOV, SLJIT_MEM1(STACK_TOP), STACK(0), TMP2, 0); } } -else if (opcode == OP_SBRA || opcode == OP_SCOND) +else if (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); @@ -9314,6 +10714,9 @@ if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) if (opcode == OP_ONCE) match_once_common(common, ket, BACKTRACK_AS(bracket_backtrack)->u.framesize, private_data_ptr, has_alternatives, needs_control_head); +if (opcode == OP_SCRIPT_RUN) + match_script_run_common(common, private_data_ptr, backtrack); + stacksize = 0; if (repeat_type == OP_MINUPTO) { @@ -9383,13 +10786,15 @@ if (ket == OP_KETRMAX) if (opcode != OP_ONCE) free_stack(common, 1); } - else if (opcode == OP_ONCE || opcode >= OP_SBRA) + else if (opcode < OP_BRA || opcode >= OP_SBRA) { if (has_alternatives) BACKTRACK_AS(bracket_backtrack)->alternative_matchingpath = LABEL(); + /* Checking zero-length iteration. */ if (opcode != OP_ONCE) { + /* This case includes opcodes such as OP_SCRIPT_RUN. */ CMPTO(SLJIT_NOT_EQUAL, SLJIT_MEM1(SLJIT_SP), private_data_ptr, STR_PTR, 0, rmax_label); /* Drop STR_PTR for greedy plus quantifier. */ if (bra != OP_BRAZERO) @@ -9456,7 +10861,7 @@ if (opcode == OP_ONCE) /* We temporarily encode the needs_control_head in the lowest bit. Note: on the target architectures of SLJIT the ((x << 1) >> 1) returns the same value for small signed numbers (including negative numbers). */ - BACKTRACK_AS(bracket_backtrack)->u.framesize = (BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0); + BACKTRACK_AS(bracket_backtrack)->u.framesize = (int)((unsigned)BACKTRACK_AS(bracket_backtrack)->u.framesize << 1) | (needs_control_head ? 1 : 0); } return cc + repeat_length; } @@ -9951,7 +11356,7 @@ if (exact > 1) #ifdef SUPPORT_UNICODE && !common->utf #endif - ) + && type != OP_ANYNL && type != OP_EXTUNI) { OP2(SLJIT_ADD, TMP1, 0, STR_PTR, 0, SLJIT_IMM, IN_UCHARS(exact)); add_jump(compiler, &backtrack->topbacktracks, CMP(SLJIT_GREATER, TMP1, 0, STR_END, 0)); @@ -10634,6 +12039,7 @@ while (cc < ccend) break; case OP_ONCE: + case OP_SCRIPT_RUN: case OP_BRA: case OP_CBRA: case OP_COND: @@ -10787,14 +12193,14 @@ switch(opcode) if (CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit != 0) OP2(SLJIT_OR, TMP1, 0, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.othercasebit); CMPTO(SLJIT_EQUAL, TMP1, 0, SLJIT_IMM, CURRENT_AS(char_iterator_backtrack)->u.charpos.chr, CURRENT_AS(char_iterator_backtrack)->matchingpath); - skip_char_back(common); + move_back(common, NULL, TRUE); CMPTO(SLJIT_GREATER, STR_PTR, 0, TMP2, 0, label); } else { OP1(SLJIT_MOV, STR_PTR, 0, base, offset0); jump = CMP(SLJIT_LESS_EQUAL, STR_PTR, 0, base, offset1); - skip_char_back(common); + move_back(common, NULL, TRUE); OP1(SLJIT_MOV, base, offset0, STR_PTR, 0); JUMPTO(SLJIT_JUMP, CURRENT_AS(char_iterator_backtrack)->matchingpath); } @@ -11240,6 +12646,9 @@ if (has_alternatives) compile_matchingpath(common, ccprev, cc, current); if (SLJIT_UNLIKELY(sljit_get_compiler_error(compiler))) return; + + if (opcode == OP_SCRIPT_RUN) + match_script_run_common(common, private_data_ptr, current); } /* Instructions after the current alternative is successfully matched. */ @@ -11368,7 +12777,7 @@ if (offset != 0) OP1(SLJIT_MOV, SLJIT_MEM1(SLJIT_SP), private_data_ptr, TMP1, 0); } } -else if (opcode == OP_SBRA || opcode == OP_SCOND) +else if (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); @@ -11717,6 +13126,7 @@ while (current) break; case OP_ONCE: + case OP_SCRIPT_RUN: case OP_BRA: case OP_CBRA: case OP_COND: @@ -12016,6 +13426,9 @@ sljit_emit_fast_return(compiler, TMP2, 0); #undef COMPILE_BACKTRACKINGPATH #undef CURRENT_AS +#define PUBLIC_JIT_COMPILE_CONFIGURATION_OPTIONS \ + (PCRE2_JIT_INVALID_UTF) + static int jit_compile(pcre2_code *code, sljit_u32 mode) { pcre2_real_code *re = (pcre2_real_code *)code; @@ -12052,6 +13465,11 @@ common->re = re; common->name_table = (PCRE2_SPTR)((uint8_t *)re + sizeof(pcre2_real_code)); rootbacktrack.cc = common->name_table + re->name_count * re->name_entry_size; +#ifdef SUPPORT_UNICODE +common->invalid_utf = (mode & PCRE2_JIT_INVALID_UTF) != 0; +#endif /* SUPPORT_UNICODE */ +mode &= ~PUBLIC_JIT_COMPILE_CONFIGURATION_OPTIONS; + common->start = rootbacktrack.cc; common->read_only_data_head = NULL; common->fcc = tables + fcc_offset; @@ -12066,6 +13484,7 @@ switch(re->newline_convention) case PCRE2_NEWLINE_CRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; break; case PCRE2_NEWLINE_ANY: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANY; break; case PCRE2_NEWLINE_ANYCRLF: common->newline = (CHAR_CR << 8) | CHAR_NL; common->nltype = NLTYPE_ANYCRLF; break; + case PCRE2_NEWLINE_NUL: common->newline = CHAR_NUL; break; default: return PCRE2_ERROR_INTERNAL; } common->nlmax = READ_CHAR_MAX; @@ -12117,6 +13536,8 @@ if (common->utf) common->bsr_nlmax = (CHAR_CR > CHAR_NL) ? CHAR_CR : CHAR_NL; common->bsr_nlmin = (CHAR_CR < CHAR_NL) ? CHAR_CR : CHAR_NL; } +else + common->invalid_utf = FALSE; #endif /* SUPPORT_UNICODE */ ccend = bracketend(common->start); @@ -12557,22 +13978,49 @@ if (common->utfreadchar != NULL) set_jumps(common->utfreadchar, LABEL()); do_utfreadchar(common); } -if (common->utfreadchar16 != NULL) - { - set_jumps(common->utfreadchar16, LABEL()); - do_utfreadchar16(common); - } if (common->utfreadtype8 != NULL) { set_jumps(common->utfreadtype8, LABEL()); do_utfreadtype8(common); } +if (common->utfpeakcharback != NULL) + { + set_jumps(common->utfpeakcharback, LABEL()); + do_utfpeakcharback(common); + } #endif /* PCRE2_CODE_UNIT_WIDTH == 8 */ +#if PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 +if (common->utfreadchar_invalid != NULL) + { + set_jumps(common->utfreadchar_invalid, LABEL()); + do_utfreadchar_invalid(common); + } +if (common->utfreadnewline_invalid != NULL) + { + set_jumps(common->utfreadnewline_invalid, LABEL()); + do_utfreadnewline_invalid(common); + } +if (common->utfmoveback_invalid) + { + set_jumps(common->utfmoveback_invalid, LABEL()); + do_utfmoveback_invalid(common); + } +if (common->utfpeakcharback_invalid) + { + set_jumps(common->utfpeakcharback_invalid, LABEL()); + do_utfpeakcharback_invalid(common); + } +#endif /* PCRE2_CODE_UNIT_WIDTH == 8 || PCRE2_CODE_UNIT_WIDTH == 16 */ if (common->getucd != NULL) { set_jumps(common->getucd, LABEL()); do_getucd(common); } +if (common->getucdtype != NULL) + { + set_jumps(common->getucdtype, LABEL()); + do_getucdtype(common); + } #endif /* SUPPORT_UNICODE */ SLJIT_FREE(common->optimized_cbracket, allocator_data); @@ -12644,7 +14092,7 @@ Returns: 0: success or (*NOJIT) was used */ #define PUBLIC_JIT_COMPILE_OPTIONS \ - (PCRE2_JIT_COMPLETE|PCRE2_JIT_PARTIAL_SOFT|PCRE2_JIT_PARTIAL_HARD) + (PCRE2_JIT_COMPLETE|PCRE2_JIT_PARTIAL_SOFT|PCRE2_JIT_PARTIAL_HARD|PCRE2_JIT_INVALID_UTF) PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION pcre2_jit_compile(pcre2_code *code, uint32_t options) @@ -12659,6 +14107,7 @@ return PCRE2_ERROR_JIT_BADOPTION; pcre2_real_code *re = (pcre2_real_code *)code; executable_functions *functions; +uint32_t excluded_options; int result; if (code == NULL) @@ -12673,21 +14122,24 @@ functions = (executable_functions *)re->executable_jit; if ((options & PCRE2_JIT_COMPLETE) != 0 && (functions == NULL || functions->executable_funcs[0] == NULL)) { - result = jit_compile(code, PCRE2_JIT_COMPLETE); + excluded_options = (PCRE2_JIT_PARTIAL_SOFT | PCRE2_JIT_PARTIAL_HARD); + result = jit_compile(code, options & ~excluded_options); if (result != 0) return result; } if ((options & PCRE2_JIT_PARTIAL_SOFT) != 0 && (functions == NULL || functions->executable_funcs[1] == NULL)) { - result = jit_compile(code, PCRE2_JIT_PARTIAL_SOFT); + excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_HARD); + result = jit_compile(code, options & ~excluded_options); if (result != 0) return result; } if ((options & PCRE2_JIT_PARTIAL_HARD) != 0 && (functions == NULL || functions->executable_funcs[2] == NULL)) { - result = jit_compile(code, PCRE2_JIT_PARTIAL_HARD); + excluded_options = (PCRE2_JIT_COMPLETE | PCRE2_JIT_PARTIAL_SOFT); + result = jit_compile(code, options & ~excluded_options); if (result != 0) return result; } diff --git a/thirdparty/pcre2/src/pcre2_jit_match.c b/thirdparty/pcre2/src/pcre2_jit_match.c index 5a66545bae..eee038644d 100644 --- a/thirdparty/pcre2/src/pcre2_jit_match.c +++ b/thirdparty/pcre2/src/pcre2_jit_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 University of Cambridge + New API code Copyright (c) 2016-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -152,8 +152,6 @@ else jit_stack = NULL; } -/* JIT only need two offsets for each ovector entry. Hence - the last 1/3 of the ovector will never be touched. */ max_oveccount = functions->top_bracket; if (oveccount > max_oveccount) @@ -173,7 +171,7 @@ else if (rc > (int)oveccount) rc = 0; match_data->code = re; -match_data->subject = subject; +match_data->subject = (rc >= 0 || rc == PCRE2_ERROR_PARTIAL)? subject : NULL; match_data->rc = rc; match_data->startchar = arguments.startchar_ptr - subject; match_data->leftchar = 0; diff --git a/thirdparty/pcre2/src/pcre2_maketables.c b/thirdparty/pcre2/src/pcre2_maketables.c index 537edba8c3..5921e90793 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-2018 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -114,17 +114,17 @@ test for alnum specially. */ memset(p, 0, cbit_length); for (i = 0; i < 256; i++) { - if (isdigit(i)) p[cbit_digit + i/8] |= 1 << (i&7); - if (isupper(i)) p[cbit_upper + i/8] |= 1 << (i&7); - if (islower(i)) p[cbit_lower + i/8] |= 1 << (i&7); - if (isalnum(i)) p[cbit_word + i/8] |= 1 << (i&7); - if (i == '_') p[cbit_word + i/8] |= 1 << (i&7); - if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7); - if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7); - if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7); - if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7); - if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7); - if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (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; @@ -138,8 +138,8 @@ for (i = 0; i < 256; i++) int x = 0; if (isspace(i)) x += ctype_space; if (isalpha(i)) x += ctype_letter; + if (islower(i)) x += ctype_lcletter; if (isdigit(i)) x += ctype_digit; - if (isxdigit(i)) x += ctype_xdigit; if (isalnum(i) || i == '_') x += ctype_word; *p++ = x; } diff --git a/thirdparty/pcre2/src/pcre2_match.c b/thirdparty/pcre2/src/pcre2_match.c index 8741e1432d..419561fd64 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-2018 University of Cambridge + New API code Copyright (c) 2015-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -69,11 +69,12 @@ information, and fields within it. */ #define PUBLIC_MATCH_OPTIONS \ (PCRE2_ANCHORED|PCRE2_ENDANCHORED|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY| \ PCRE2_NOTEMPTY_ATSTART|PCRE2_NO_UTF_CHECK|PCRE2_PARTIAL_HARD| \ - PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT) + PCRE2_PARTIAL_SOFT|PCRE2_NO_JIT|PCRE2_COPY_MATCHED_SUBJECT) #define PUBLIC_JIT_MATCH_OPTIONS \ (PCRE2_NO_UTF_CHECK|PCRE2_NOTBOL|PCRE2_NOTEOL|PCRE2_NOTEMPTY|\ - PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_SOFT|PCRE2_PARTIAL_HARD) + PCRE2_NOTEMPTY_ATSTART|PCRE2_PARTIAL_SOFT|PCRE2_PARTIAL_HARD|\ + PCRE2_COPY_MATCHED_SUBJECT) /* Non-error returns from and within the match() function. Error returns are externally defined PCRE2_ERROR_xxx codes, which are all negative. */ @@ -1848,7 +1849,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH); } else - if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) RRETURN(MATCH_NOMATCH); + if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH); } } else @@ -1870,7 +1871,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); } else #endif - if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) RRETURN(MATCH_NOMATCH); + if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH); } } @@ -1902,7 +1903,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (Fop == OP_CLASS) RRETURN(MATCH_NOMATCH); } else - if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) RRETURN(MATCH_NOMATCH); + if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH); } } else @@ -1927,7 +1928,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); } else #endif - if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) RRETURN(MATCH_NOMATCH); + if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ @@ -1956,7 +1957,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); if (Fop == OP_CLASS) break; } else - if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) break; + if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) break; Feptr += len; } @@ -1993,7 +1994,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); } else #endif - if ((Lbyte_map[fc/8] & (1 << (fc&7))) == 0) break; + if ((Lbyte_map[fc/8] & (1u << (fc&7))) == 0) break; Feptr++; } @@ -4084,7 +4085,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); GETCHAR(fc, fptr); } lgb = UCD_GRAPHBREAK(fc); - if ((PRIV(ucp_gbtable)[lgb] & (1 << rgb)) == 0) break; + if ((PRIV(ucp_gbtable)[lgb] & (1u << rgb)) == 0) break; Feptr = fptr; rgb = lgb; } @@ -5014,6 +5015,7 @@ fprintf(stderr, "++ op=%d\n", *Fecode); must record a backtracking point and also set up a chained frame. */ case OP_ONCE: + case OP_SCRIPT_RUN: case OP_SBRA: Lframe_type = GF_NOCAPTURE | Fop; @@ -5526,6 +5528,14 @@ fprintf(stderr, "++ op=%d\n", *Fecode); case OP_ASSERTBACK_NOT: RRETURN(MATCH_MATCH); + /* At the end of a script run, apply the script-checking rules. This code + will never by exercised if Unicode support it not compiled, because in + that environment script runs cause an error at compile time. */ + + case OP_SCRIPT_RUN: + if (!PRIV(script_run)(P->eptr, Feptr, utf)) RRETURN(MATCH_NOMATCH); + break; + /* Whole-pattern recursion is coded as a recurse into group 0, so it won't be picked up here. Instead, we catch it when the OP_END is reached. Other recursion is handled here. */ @@ -6000,10 +6010,11 @@ pcre2_match(const pcre2_code *code, PCRE2_SPTR subject, PCRE2_SIZE length, pcre2_match_context *mcontext) { int rc; +int was_zero_terminated = 0; const uint8_t *start_bits = NULL; - const pcre2_real_code *re = (const pcre2_real_code *)code; + BOOL anchored; BOOL firstline; BOOL has_first_cu = FALSE; @@ -6043,7 +6054,11 @@ mb->stack_frames = (heapframe *)stack_frames_vector; /* A length equal to PCRE2_ZERO_TERMINATED implies a zero-terminated subject string. */ -if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); +if (length == PCRE2_ZERO_TERMINATED) + { + length = PRIV(strlen)(subject); + was_zero_terminated = 1; + } end_subject = subject + length; /* Plausibility checks */ @@ -6158,6 +6173,17 @@ if (mcontext != NULL && mcontext->offset_limit != PCRE2_UNSET && (re->overall_options & PCRE2_USE_OFFSET_LIMIT) == 0) return PCRE2_ERROR_BADOFFSETLIMIT; +/* If the match data block was previously used with PCRE2_COPY_MATCHED_SUBJECT, +free the memory that was obtained. Set the field to NULL for no match cases. */ + +if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0) + { + match_data->memctl.free((void *)match_data->subject, + match_data->memctl.memory_data); + match_data->flags &= ~PCRE2_MD_COPIED_SUBJECT; + } +match_data->subject = NULL; + /* If the pattern was successfully studied with JIT support, run the JIT executable instead of the rest of this function. Most options must be set at compile time for the JIT code to be usable. Fallback to the normal code path if @@ -6169,7 +6195,19 @@ if (re->executable_jit != NULL && (options & ~PUBLIC_JIT_MATCH_OPTIONS) == 0) { rc = pcre2_jit_match(code, subject, length, start_offset, options, match_data, mcontext); - if (rc != PCRE2_ERROR_JIT_BADOPTION) return rc; + if (rc != PCRE2_ERROR_JIT_BADOPTION) + { + if (rc >= 0 && (options & PCRE2_COPY_MATCHED_SUBJECT) != 0) + { + length = CU2BYTES(length + was_zero_terminated); + match_data->subject = match_data->memctl.malloc(length, + match_data->memctl.memory_data); + if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY; + memcpy((void *)match_data->subject, subject, length); + match_data->flags |= PCRE2_MD_COPIED_SUBJECT; + } + return rc; + } } #endif @@ -6421,7 +6459,7 @@ for(;;) #if PCRE2_CODE_UNIT_WIDTH != 8 if (c > 255) c = 255; #endif - ok = (start_bits[c/8] & (1 << (c&7))) != 0; + ok = (start_bits[c/8] & (1u << (c&7))) != 0; } } if (!ok) @@ -6538,7 +6576,7 @@ for(;;) #if PCRE2_CODE_UNIT_WIDTH != 8 if (c > 255) c = 255; #endif - if ((start_bits[c/8] & (1 << (c&7))) != 0) break; + if ((start_bits[c/8] & (1u << (c&7))) != 0) break; start_match++; } @@ -6809,13 +6847,13 @@ if (mb->match_frames != mb->stack_frames) /* Fill in fields that are always returned in the match data. */ match_data->code = re; -match_data->subject = subject; match_data->mark = mb->mark; match_data->matchedby = PCRE2_MATCHEDBY_INTERPRETER; /* Handle a fully successful match. Set the return code to the number of captured strings, or 0 if there were too many to fit into the ovector, and then -set the remaining returned values before returning. */ +set the remaining returned values before returning. Make a copy of the subject +string if requested. */ if (rc == MATCH_MATCH) { @@ -6825,6 +6863,16 @@ if (rc == MATCH_MATCH) match_data->leftchar = mb->start_used_ptr - subject; match_data->rightchar = ((mb->last_used_ptr > mb->end_match_ptr)? mb->last_used_ptr : mb->end_match_ptr) - subject; + if ((options & PCRE2_COPY_MATCHED_SUBJECT) != 0) + { + length = CU2BYTES(length + was_zero_terminated); + match_data->subject = match_data->memctl.malloc(length, + match_data->memctl.memory_data); + if (match_data->subject == NULL) return PCRE2_ERROR_NOMEMORY; + memcpy((void *)match_data->subject, subject, length); + match_data->flags |= PCRE2_MD_COPIED_SUBJECT; + } + else match_data->subject = subject; return match_data->rc; } @@ -6838,10 +6886,14 @@ match_data->mark = mb->nomatch_mark; if (rc != MATCH_NOMATCH && rc != PCRE2_ERROR_PARTIAL) match_data->rc = rc; -/* Handle a partial match. */ +/* Handle a partial match. If a "soft" partial match was requested, searching +for a complete match will have continued, and the value of rc at this point +will be MATCH_NOMATCH. For a "hard" partial match, it will already be +PCRE2_ERROR_PARTIAL. */ else if (match_partial != NULL) { + match_data->subject = subject; match_data->ovector[0] = match_partial - subject; match_data->ovector[1] = end_subject - subject; match_data->startchar = match_partial - subject; diff --git a/thirdparty/pcre2/src/pcre2_match_data.c b/thirdparty/pcre2/src/pcre2_match_data.c index b297f326b5..ccc5f6740e 100644 --- a/thirdparty/pcre2/src/pcre2_match_data.c +++ b/thirdparty/pcre2/src/pcre2_match_data.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-2018 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -63,6 +63,7 @@ yield = PRIV(memctl_malloc)( (pcre2_memctl *)gcontext); if (yield == NULL) return NULL; yield->oveccount = oveccount; +yield->flags = 0; return yield; } @@ -93,7 +94,12 @@ PCRE2_EXP_DEFN void PCRE2_CALL_CONVENTION pcre2_match_data_free(pcre2_match_data *match_data) { if (match_data != NULL) + { + if ((match_data->flags & PCRE2_MD_COPIED_SUBJECT) != 0) + match_data->memctl.free((void *)match_data->subject, + match_data->memctl.memory_data); match_data->memctl.free(match_data, match_data->memctl.memory_data); + } } diff --git a/thirdparty/pcre2/src/pcre2_script_run.c b/thirdparty/pcre2/src/pcre2_script_run.c new file mode 100644 index 0000000000..91a4833028 --- /dev/null +++ b/thirdparty/pcre2/src/pcre2_script_run.c @@ -0,0 +1,441 @@ +/************************************************* +* Perl-Compatible Regular Expressions * +*************************************************/ + +/* PCRE is a library of functions to support regular expressions whose syntax +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 + +----------------------------------------------------------------------------- +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. + + * Neither the name of the University of Cambridge nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +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. +----------------------------------------------------------------------------- +*/ + +/* This module contains the function for checking a script run. */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pcre2_internal.h" + + +/************************************************* +* Check script run * +*************************************************/ + +/* A script run is conceptually a sequence of characters all in the same +Unicode script. However, it isn't quite that simple. There are special rules +for scripts that are commonly used together, and also special rules for digits. +This function implements the appropriate checks, which is possible only when +PCRE2 is compiled with Unicode support. The function returns TRUE if there is +no Unicode support; however, it should never be called in that circumstance +because an error is given by pcre2_compile() if a script run is called for in a +version of PCRE2 compiled without Unicode support. + +Arguments: + pgr point to the first character + endptr point after the last character + utf TRUE if in UTF mode + +Returns: TRUE if this is a valid script run +*/ + +/* These dummy values must be less than the negation of the largest offset in +the PRIV(ucd_script_sets) vector, which is held in a 16-bit field in UCD +records (and is only likely to be a few hundred). */ + +#define SCRIPT_UNSET (-99999) +#define SCRIPT_HANPENDING (-99998) +#define SCRIPT_HANHIRAKATA (-99997) +#define SCRIPT_HANBOPOMOFO (-99996) +#define SCRIPT_HANHANGUL (-99995) +#define SCRIPT_LIST (-99994) + +#define INTERSECTION_LIST_SIZE 50 + +BOOL +PRIV(script_run)(PCRE2_SPTR ptr, PCRE2_SPTR endptr, BOOL utf) +{ +#ifdef SUPPORT_UNICODE +int require_script = SCRIPT_UNSET; +uint8_t intersection_list[INTERSECTION_LIST_SIZE]; +const uint8_t *require_list = NULL; +uint32_t require_digitset = 0; +uint32_t c; + +#if PCRE2_CODE_UNIT_WIDTH == 32 +(void)utf; /* Avoid compiler warning */ +#endif + +/* Any string containing fewer than 2 characters is a valid script run. */ + +if (ptr >= endptr) return TRUE; +GETCHARINCTEST(c, ptr); +if (ptr >= endptr) return TRUE; + +/* Scan strings of two or more characters, checking the Unicode characteristics +of each code point. We make use of the Script Extensions property. There is +special code for scripts that can be combined with characters from the Han +Chinese script. This may be used in conjunction with four other scripts in +these combinations: + +. Han with Hiragana and Katakana is allowed (for Japanese). +. Han with Bopomofo is allowed (for Taiwanese Mandarin). +. Han with Hangul is allowed (for Korean). + +If the first significant character's script is one of the four, the required +script type is immediately known. However, if the first significant +character's script is Han, we have to keep checking for a non-Han character. +Hence the SCRIPT_HANPENDING state. */ + +for (;;) + { + const ucd_record *ucd = GET_UCD(c); + int32_t scriptx = ucd->scriptx; + + /* If the script extension is Unknown, the string is not a valid script run. + Such characters can only form script runs of length one. */ + + if (scriptx == ucp_Unknown) return FALSE; + + /* A character whose script extension is Inherited is always accepted with + any script, and plays no further part in this testing. A character whose + script is Common is always accepted, but must still be tested for a digit + below. The scriptx value at this point is non-zero, because zero is + ucp_Unknown, tested for above. */ + + if (scriptx != ucp_Inherited) + { + if (scriptx != ucp_Common) + { + /* If the script extension value is positive, the character is not a mark + that can be used with many scripts. In the simple case we either set or + compare with the required script. However, handling the scripts that can + combine with Han are more complicated, as is the case when the previous + characters have been man-script marks. */ + + if (scriptx > 0) + { + switch(require_script) + { + /* Either the first significant character (require_script unset) or + after only Han characters. */ + + case SCRIPT_UNSET: + case SCRIPT_HANPENDING: + switch(scriptx) + { + case ucp_Han: + require_script = SCRIPT_HANPENDING; + break; + + case ucp_Hiragana: + case ucp_Katakana: + require_script = SCRIPT_HANHIRAKATA; + break; + + case ucp_Bopomofo: + require_script = SCRIPT_HANBOPOMOFO; + break; + + case ucp_Hangul: + require_script = SCRIPT_HANHANGUL; + break; + + /* Not a Han-related script. If expecting one, fail. Otherise set + the requirement to this script. */ + + default: + if (require_script == SCRIPT_HANPENDING) return FALSE; + require_script = scriptx; + break; + } + break; + + /* Previously encountered one of the "with Han" scripts. Check that + this character is appropriate. */ + + case SCRIPT_HANHIRAKATA: + if (scriptx != ucp_Han && scriptx != ucp_Hiragana && + scriptx != ucp_Katakana) + return FALSE; + break; + + case SCRIPT_HANBOPOMOFO: + if (scriptx != ucp_Han && scriptx != ucp_Bopomofo) return FALSE; + break; + + case SCRIPT_HANHANGUL: + if (scriptx != ucp_Han && scriptx != ucp_Hangul) return FALSE; + break; + + /* We have a list of scripts to check that is derived from one or + more previous characters. This is either one of the lists in + ucd_script_sets[] (for one previous character) or the intersection of + several lists for multiple characters. */ + + case SCRIPT_LIST: + { + const uint8_t *list; + for (list = require_list; *list != 0; list++) + { + if (*list == scriptx) break; + } + if (*list == 0) return FALSE; + } + + /* The rest of the string must be in this script, but we have to + allow for the Han complications. */ + + switch(scriptx) + { + case ucp_Han: + require_script = SCRIPT_HANPENDING; + break; + + case ucp_Hiragana: + case ucp_Katakana: + require_script = SCRIPT_HANHIRAKATA; + break; + + case ucp_Bopomofo: + require_script = SCRIPT_HANBOPOMOFO; + break; + + case ucp_Hangul: + require_script = SCRIPT_HANHANGUL; + break; + + default: + require_script = scriptx; + break; + } + break; + + /* This is the easy case when a single script is required. */ + + default: + if (scriptx != require_script) return FALSE; + break; + } + } /* End of handing positive scriptx */ + + /* If scriptx is negative, this character is a mark-type character that + has a list of permitted scripts. */ + + else + { + uint32_t chspecial; + const uint8_t *clist, *rlist; + const uint8_t *list = PRIV(ucd_script_sets) - scriptx; + + switch(require_script) + { + case SCRIPT_UNSET: + require_list = PRIV(ucd_script_sets) - scriptx; + require_script = SCRIPT_LIST; + break; + + /* An inspection of the Unicode 11.0.0 files shows that there are the + following types of Script Extension list that involve the Han, + Bopomofo, Hiragana, Katakana, and Hangul scripts: + + . Bopomofo + Han + . Han + Hiragana + Katakana + . Hiragana + Katakana + . Bopopmofo + Hangul + Han + Hiragana + Katakana + + The following code tries to make sense of this. */ + +#define FOUND_BOPOMOFO 1 +#define FOUND_HIRAGANA 2 +#define FOUND_KATAKANA 4 +#define FOUND_HANGUL 8 + + case SCRIPT_HANPENDING: + chspecial = 0; + for (; *list != 0; list++) + { + switch (*list) + { + case ucp_Bopomofo: chspecial |= FOUND_BOPOMOFO; break; + case ucp_Hiragana: chspecial |= FOUND_HIRAGANA; break; + case ucp_Katakana: chspecial |= FOUND_KATAKANA; break; + case ucp_Hangul: chspecial |= FOUND_HANGUL; break; + default: break; + } + } + + if (chspecial == 0) return FALSE; + + if (chspecial == FOUND_BOPOMOFO) + { + require_script = SCRIPT_HANBOPOMOFO; + } + else if (chspecial == (FOUND_HIRAGANA|FOUND_KATAKANA)) + { + require_script = SCRIPT_HANHIRAKATA; + } + + /* Otherwise it must be allowed with all of them, so remain in + the pending state. */ + + break; + + case SCRIPT_HANHIRAKATA: + for (; *list != 0; list++) + { + if (*list == ucp_Hiragana || *list == ucp_Katakana) break; + } + if (*list == 0) return FALSE; + break; + + case SCRIPT_HANBOPOMOFO: + for (; *list != 0; list++) + { + if (*list == ucp_Bopomofo) break; + } + if (*list == 0) return FALSE; + break; + + case SCRIPT_HANHANGUL: + for (; *list != 0; list++) + { + if (*list == ucp_Hangul) break; + } + if (*list == 0) return FALSE; + break; + + /* Previously encountered one or more characters that are allowed + with a list of scripts. Build the intersection of the required list + with this character's list in intersection_list[]. This code is + written so that it still works OK if the required list is already in + that vector. */ + + case SCRIPT_LIST: + { + int i = 0; + for (rlist = require_list; *rlist != 0; rlist++) + { + for (clist = list; *clist != 0; clist++) + { + if (*rlist == *clist) + { + intersection_list[i++] = *rlist; + break; + } + } + } + if (i == 0) return FALSE; /* No scripts in common */ + + /* If there's just one script in common, we can set it as the + unique required script. Otherwise, terminate the intersection list + and make it the required list. */ + + if (i == 1) + { + require_script = intersection_list[0]; + } + else + { + intersection_list[i] = 0; + require_list = intersection_list; + } + } + break; + + /* The previously set required script is a single script, not + Han-related. Check that it is in this character's list. */ + + default: + for (; *list != 0; list++) + { + if (*list == require_script) break; + } + if (*list == 0) return FALSE; + break; + } + } /* End of handling negative scriptx */ + } /* End of checking non-Common character */ + + /* The character is in an acceptable script. We must now ensure that all + decimal digits in the string come from the same set. Some scripts (e.g. + Common, Arabic) have more than one set of decimal digits. This code does + not allow mixing sets, even within the same script. The vector called + PRIV(ucd_digit_sets)[] contains, in its first element, the number of + following elements, and then, in ascending order, the code points of the + '9' characters in every set of 10 digits. Each set is identified by the + offset in the vector of its '9' character. An initial check of the first + value picks up ASCII digits quickly. Otherwise, a binary chop is used. */ + + if (ucd->chartype == ucp_Nd) + { + uint32_t digitset; + + if (c <= PRIV(ucd_digit_sets)[1]) digitset = 1; else + { + int mid; + int bot = 1; + int top = PRIV(ucd_digit_sets)[0]; + for (;;) + { + if (top <= bot + 1) /* <= rather than == is paranoia */ + { + digitset = top; + break; + } + mid = (top + bot) / 2; + if (c <= PRIV(ucd_digit_sets)[mid]) top = mid; else bot = mid; + } + } + + /* A required value of 0 means "unset". */ + + if (require_digitset == 0) require_digitset = digitset; + else if (digitset != require_digitset) return FALSE; + } /* End digit handling */ + } /* End checking non-Inherited character */ + + /* If we haven't yet got to the end, pick up the next character. */ + + if (ptr >= endptr) return TRUE; + GETCHARINCTEST(c, ptr); + } /* End checking loop */ + +#else /* NOT SUPPORT_UNICODE */ +(void)ptr; +(void)endptr; +(void)utf; +return TRUE; +#endif /* SUPPORT_UNICODE */ +} + +/* End of pcre2_script_run.c */ diff --git a/thirdparty/pcre2/src/pcre2_study.c b/thirdparty/pcre2/src/pcre2_study.c index acbf98b41b..e883c2eb4c 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-2018 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -54,7 +54,7 @@ collecting data (e.g. minimum matching length). */ /* Set a bit in the starting code unit bit map. */ -#define SET_BIT(c) re->start_bitmap[(c)/8] |= (1 << ((c)&7)) +#define SET_BIT(c) re->start_bitmap[(c)/8] |= (1u << ((c)&7)) /* Returns from set_start_bits() */ @@ -171,6 +171,7 @@ for (;;) /* Fall through */ case OP_ONCE: + case OP_SCRIPT_RUN: case OP_SBRA: case OP_BRAPOS: case OP_SBRAPOS: @@ -842,7 +843,7 @@ for (c = 0; c < table_limit; c++) if (table_limit == 32) return; for (c = 128; c < 256; c++) { - if ((re->tables[cbits_offset + c/8] & (1 << (c&7))) != 0) + if ((re->tables[cbits_offset + c/8] & (1u << (c&7))) != 0) { PCRE2_UCHAR buff[6]; (void)PRIV(ord2utf)(c, buff); @@ -1075,6 +1076,7 @@ do case OP_CBRAPOS: case OP_SCBRAPOS: case OP_ONCE: + case OP_SCRIPT_RUN: case OP_ASSERT: rc = set_start_bits(re, tcode, utf); if (rc == SSB_FAIL || rc == SSB_UNKNOWN) return rc; @@ -1505,11 +1507,11 @@ do for (c = 0; c < 16; c++) re->start_bitmap[c] |= classmap[c]; for (c = 128; c < 256; c++) { - if ((classmap[c/8] & (1 << (c&7))) != 0) + if ((classmap[c/8] & (1u << (c&7))) != 0) { - int d = (c >> 6) | 0xc0; /* Set bit for this starter */ - re->start_bitmap[d/8] |= (1 << (d&7)); /* and then skip on to the */ - c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ + int d = (c >> 6) | 0xc0; /* Set bit for this starter */ + re->start_bitmap[d/8] |= (1u << (d&7)); /* and then skip on to the */ + c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ } } } diff --git a/thirdparty/pcre2/src/pcre2_substitute.c b/thirdparty/pcre2/src/pcre2_substitute.c index ab8d10908a..ec3dd66df9 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-2018 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -129,7 +129,7 @@ for (; ptr < ptrend; ptr++) ptr += 1; /* Must point after \ */ erc = PRIV(check_escape)(&ptr, ptrend, &ch, &errorcode, - code->overall_options, FALSE, NULL); + code->overall_options, code->extra_options, FALSE, NULL); ptr -= 1; /* Back to last code unit of escape */ if (errorcode != 0) { @@ -239,13 +239,17 @@ PCRE2_SIZE extra_needed = 0; PCRE2_SIZE buff_offset, buff_length, lengthleft, fraglength; PCRE2_SIZE *ovector; PCRE2_SIZE ovecsave[3]; +pcre2_substitute_callout_block scb; + +/* General initialization */ buff_offset = 0; lengthleft = buff_length = *blength; *blength = PCRE2_UNSET; ovecsave[0] = ovecsave[1] = ovecsave[2] = PCRE2_UNSET; -/* Partial matching is not valid. */ +/* 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; @@ -264,6 +268,13 @@ if (match_data == NULL) ovector = pcre2_get_ovector_pointer(match_data); ovector_count = pcre2_get_ovector_count(match_data); +/* Fixed things in the callout block */ + +scb.version = 0; +scb.input = subject; +scb.output = (PCRE2_SPTR)buffer; +scb.ovector = ovector; + /* Find lengths of zero-terminated strings and the end of the replacement. */ if (length == PCRE2_ZERO_TERMINATED) length = PRIV(strlen)(subject); @@ -390,7 +401,7 @@ do rc = PCRE2_ERROR_INTERNAL_DUPMATCH; goto EXIT; } - + /* Count substitutions with a paranoid check for integer overflow; surely no real call to this function would ever hit this! */ @@ -401,11 +412,14 @@ do } subs++; - /* Copy the text leading up to the match. */ + /* Copy the text leading up to the match, 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); + 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 @@ -421,7 +435,7 @@ do if (ptr >= repend) { - if (ptrstackptr <= 0) break; /* End of replacement string */ + if (ptrstackptr == 0) break; /* End of replacement string */ repend = ptrstack[--ptrstackptr]; ptr = ptrstack[--ptrstackptr]; continue; @@ -702,7 +716,7 @@ do { if (((code->tables + cbits_offset + ((forcecase > 0)? cbit_upper:cbit_lower) - )[ch/8] & (1 << (ch%8))) == 0) + )[ch/8] & (1u << (ch%8))) == 0) ch = (code->tables + fcc_offset)[ch]; } forcecase = forcecasereset; @@ -760,7 +774,7 @@ do ptr++; /* Point after \ */ rc = PRIV(check_escape)(&ptr, repend, &ch, &errorcode, - code->overall_options, FALSE, NULL); + code->overall_options, code->extra_options, FALSE, NULL); if (errorcode != 0) goto BADESCAPE; switch(rc) @@ -804,7 +818,7 @@ do { if (((code->tables + cbits_offset + ((forcecase > 0)? cbit_upper:cbit_lower) - )[ch/8] & (1 << (ch%8))) == 0) + )[ch/8] & (1u << (ch%8))) == 0) ch = (code->tables + fcc_offset)[ch]; } forcecase = forcecasereset; @@ -821,10 +835,37 @@ do } /* End handling a literal code unit */ } /* End of loop for scanning the replacement. */ - /* The replacement has been copied to the output. 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. */ + /* 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.output_offsets[1] = buff_offset; + rc = mcontext->substitute_callout(&scb, mcontext->substitute_callout_data); + + /* 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); + + /* 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]; diff --git a/thirdparty/pcre2/src/pcre2_tables.c b/thirdparty/pcre2/src/pcre2_tables.c index 83d6f9de55..84019361fc 100644 --- a/thirdparty/pcre2/src/pcre2_tables.c +++ b/thirdparty/pcre2/src/pcre2_tables.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-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -142,7 +142,7 @@ ucp_gbXX values defined in pcre2_ucp.h. These changed between Unicode versions code points. The left property selects a word from the table, and the right property selects a bit from that word like this: - PRIV(ucp_gbtable)[left-property] & (1 << right-property) + PRIV(ucp_gbtable)[left-property] & (1u << right-property) The value is non-zero if a grapheme break is NOT permitted between the relevant two code points. The breaking rules are as follows: @@ -183,25 +183,25 @@ are implementing). #define ESZ (1<<ucp_gbExtend)|(1<<ucp_gbSpacingMark)|(1<<ucp_gbZWJ) const uint32_t PRIV(ucp_gbtable)[] = { - (1<<ucp_gbLF), /* 0 CR */ - 0, /* 1 LF */ - 0, /* 2 Control */ - ESZ, /* 3 Extend */ - ESZ|(1<<ucp_gbPrepend)| /* 4 Prepend */ - (1<<ucp_gbL)|(1<<ucp_gbV)|(1<<ucp_gbT)| - (1<<ucp_gbLV)|(1<<ucp_gbLVT)|(1<<ucp_gbOther)| - (1<<ucp_gbRegionalIndicator), - ESZ, /* 5 SpacingMark */ - ESZ|(1<<ucp_gbL)|(1<<ucp_gbV)|(1<<ucp_gbLV)| /* 6 L */ - (1<<ucp_gbLVT), - ESZ|(1<<ucp_gbV)|(1<<ucp_gbT), /* 7 V */ - ESZ|(1<<ucp_gbT), /* 8 T */ - ESZ|(1<<ucp_gbV)|(1<<ucp_gbT), /* 9 LV */ - ESZ|(1<<ucp_gbT), /* 10 LVT */ - (1<<ucp_gbRegionalIndicator), /* 11 RegionalIndicator */ - ESZ, /* 12 Other */ - ESZ, /* 13 ZWJ */ - ESZ|(1<<ucp_gbExtended_Pictographic) /* 14 Extended Pictographic */ + (1u<<ucp_gbLF), /* 0 CR */ + 0, /* 1 LF */ + 0, /* 2 Control */ + ESZ, /* 3 Extend */ + ESZ|(1u<<ucp_gbPrepend)| /* 4 Prepend */ + (1u<<ucp_gbL)|(1u<<ucp_gbV)|(1u<<ucp_gbT)| + (1u<<ucp_gbLV)|(1u<<ucp_gbLVT)|(1u<<ucp_gbOther)| + (1u<<ucp_gbRegionalIndicator), + ESZ, /* 5 SpacingMark */ + ESZ|(1u<<ucp_gbL)|(1u<<ucp_gbV)|(1u<<ucp_gbLV)| /* 6 L */ + (1u<<ucp_gbLVT), + ESZ|(1u<<ucp_gbV)|(1u<<ucp_gbT), /* 7 V */ + ESZ|(1u<<ucp_gbT), /* 8 T */ + ESZ|(1u<<ucp_gbV)|(1u<<ucp_gbT), /* 9 LV */ + ESZ|(1u<<ucp_gbT), /* 10 LVT */ + (1u<<ucp_gbRegionalIndicator), /* 11 RegionalIndicator */ + ESZ, /* 12 Other */ + ESZ, /* 13 ZWJ */ + ESZ|(1u<<ucp_gbExtended_Pictographic) /* 14 Extended Pictographic */ }; #undef ESZ @@ -417,6 +417,7 @@ strings to make sure that UTF-8 support works on EBCDIC platforms. */ #define STRING_Tifinagh0 STR_T STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0" #define STRING_Tirhuta0 STR_T STR_i STR_r STR_h STR_u STR_t STR_a "\0" #define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0" +#define STRING_Unknown0 STR_U STR_n STR_k STR_n STR_o STR_w STR_n "\0" #define STRING_Vai0 STR_V STR_a STR_i "\0" #define STRING_Warang_Citi0 STR_W STR_a STR_r STR_a STR_n STR_g STR_UNDERSCORE STR_C STR_i STR_t STR_i "\0" #define STRING_Xan0 STR_X STR_a STR_n "\0" @@ -611,6 +612,7 @@ const char PRIV(utt_names)[] = STRING_Tifinagh0 STRING_Tirhuta0 STRING_Ugaritic0 + STRING_Unknown0 STRING_Vai0 STRING_Warang_Citi0 STRING_Xan0 @@ -805,19 +807,20 @@ const ucp_type_table PRIV(utt)[] = { { 1424, PT_SC, ucp_Tifinagh }, { 1433, PT_SC, ucp_Tirhuta }, { 1441, PT_SC, ucp_Ugaritic }, - { 1450, PT_SC, ucp_Vai }, - { 1454, PT_SC, ucp_Warang_Citi }, - { 1466, PT_ALNUM, 0 }, - { 1470, PT_PXSPACE, 0 }, - { 1474, PT_SPACE, 0 }, - { 1478, PT_UCNC, 0 }, - { 1482, PT_WORD, 0 }, - { 1486, PT_SC, ucp_Yi }, - { 1489, PT_GC, ucp_Z }, - { 1491, PT_SC, ucp_Zanabazar_Square }, - { 1508, PT_PC, ucp_Zl }, - { 1511, PT_PC, ucp_Zp }, - { 1514, PT_PC, ucp_Zs } + { 1450, PT_SC, ucp_Unknown }, + { 1458, PT_SC, ucp_Vai }, + { 1462, PT_SC, ucp_Warang_Citi }, + { 1474, PT_ALNUM, 0 }, + { 1478, PT_PXSPACE, 0 }, + { 1482, PT_SPACE, 0 }, + { 1486, PT_UCNC, 0 }, + { 1490, PT_WORD, 0 }, + { 1494, PT_SC, ucp_Yi }, + { 1497, PT_GC, ucp_Z }, + { 1499, PT_SC, ucp_Zanabazar_Square }, + { 1516, PT_PC, ucp_Zl }, + { 1519, PT_PC, ucp_Zp }, + { 1522, 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 275a4be2fe..cc53c24001 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: 92592 bytes, block size: 128. */ +/* Total size: 97152 bytes, block size: 128. */ /* The tables herein are needed only when UCP support is built, and in PCRE2 that happens automatically with UTF support. @@ -30,10 +30,10 @@ a comment was received about space saving - maybe the guy linked all the modules rather than using a library - so we include a condition to cut out the tables when not needed. But don't leave a totally empty module because some compilers barf at that. -Instead, just supply small dummy tables. */ +Instead, just supply some small dummy tables. */ #ifndef SUPPORT_UNICODE -const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0 }}; +const ucd_record PRIV(ucd_records)[] = {{0,0,0,0,0,0,0 }}; const uint16_t PRIV(ucd_stage1)[] = {0}; const uint16_t PRIV(ucd_stage2)[] = {0}; const uint32_t PRIV(ucd_caseless_sets)[] = {0}; @@ -47,11 +47,13 @@ special record. */ #if PCRE2_CODE_UNIT_WIDTH == 32 const ucd_record PRIV(dummy_ucd_record)[] = {{ - ucp_Common, /* script */ - ucp_Cn, /* type unassigned */ - ucp_gbOther, /* grapheme break property */ - 0, /* case set */ - 0, /* other case */ + ucp_Unknown, /* script */ + ucp_Cn, /* type unassigned */ + ucp_gbOther, /* grapheme break property */ + 0, /* case set */ + 0, /* other case */ + ucp_Unknown, /* script extension */ + 0, /* dummy filler */ }}; #endif @@ -65,9 +67,13 @@ uint8_t property_1; uint8_t property_2; uint8_t property_3; pcre_int32 property_4; +pcre_int16 property_5; +uint16_t property_6; } ucd_record; */ +/* This table contains lists of characters that are caseless sets of +more than one character. Each list is terminated by NOTACHAR. */ const uint32_t PRIV(ucd_caseless_sets)[] = { NOTACHAR, @@ -100,865 +106,1014 @@ const uint32_t PRIV(ucd_caseless_sets)[] = { 0x1c88, 0xa64a, 0xa64b, NOTACHAR, }; -/* When #included in pcre2test, we don't need this large table. */ +/* When #included in pcre2test, we don't need the table of digit +sets, nor the the large main UCD tables. */ #ifndef PCRE2_PCRE2TEST -const ucd_record PRIV(ucd_records)[] = { /* 6832 bytes, record size 8 */ - { 9, 0, 2, 0, 0, }, /* 0 */ - { 9, 0, 1, 0, 0, }, /* 1 */ - { 9, 0, 0, 0, 0, }, /* 2 */ - { 9, 29, 12, 0, 0, }, /* 3 */ - { 9, 21, 12, 0, 0, }, /* 4 */ - { 9, 23, 12, 0, 0, }, /* 5 */ - { 9, 22, 12, 0, 0, }, /* 6 */ - { 9, 18, 12, 0, 0, }, /* 7 */ - { 9, 25, 12, 0, 0, }, /* 8 */ - { 9, 17, 12, 0, 0, }, /* 9 */ - { 9, 13, 12, 0, 0, }, /* 10 */ - { 33, 9, 12, 0, 32, }, /* 11 */ - { 33, 9, 12, 100, 32, }, /* 12 */ - { 33, 9, 12, 1, 32, }, /* 13 */ - { 9, 24, 12, 0, 0, }, /* 14 */ - { 9, 16, 12, 0, 0, }, /* 15 */ - { 33, 5, 12, 0, -32, }, /* 16 */ - { 33, 5, 12, 100, -32, }, /* 17 */ - { 33, 5, 12, 1, -32, }, /* 18 */ - { 9, 26, 12, 0, 0, }, /* 19 */ - { 9, 26, 14, 0, 0, }, /* 20 */ - { 33, 7, 12, 0, 0, }, /* 21 */ - { 9, 20, 12, 0, 0, }, /* 22 */ - { 9, 1, 2, 0, 0, }, /* 23 */ - { 9, 15, 12, 0, 0, }, /* 24 */ - { 9, 5, 12, 26, 775, }, /* 25 */ - { 9, 19, 12, 0, 0, }, /* 26 */ - { 33, 9, 12, 104, 32, }, /* 27 */ - { 33, 5, 12, 0, 7615, }, /* 28 */ - { 33, 5, 12, 104, -32, }, /* 29 */ - { 33, 5, 12, 0, 121, }, /* 30 */ - { 33, 9, 12, 0, 1, }, /* 31 */ - { 33, 5, 12, 0, -1, }, /* 32 */ - { 33, 9, 12, 0, 0, }, /* 33 */ - { 33, 5, 12, 0, 0, }, /* 34 */ - { 33, 9, 12, 0, -121, }, /* 35 */ - { 33, 5, 12, 1, -268, }, /* 36 */ - { 33, 5, 12, 0, 195, }, /* 37 */ - { 33, 9, 12, 0, 210, }, /* 38 */ - { 33, 9, 12, 0, 206, }, /* 39 */ - { 33, 9, 12, 0, 205, }, /* 40 */ - { 33, 9, 12, 0, 79, }, /* 41 */ - { 33, 9, 12, 0, 202, }, /* 42 */ - { 33, 9, 12, 0, 203, }, /* 43 */ - { 33, 9, 12, 0, 207, }, /* 44 */ - { 33, 5, 12, 0, 97, }, /* 45 */ - { 33, 9, 12, 0, 211, }, /* 46 */ - { 33, 9, 12, 0, 209, }, /* 47 */ - { 33, 5, 12, 0, 163, }, /* 48 */ - { 33, 9, 12, 0, 213, }, /* 49 */ - { 33, 5, 12, 0, 130, }, /* 50 */ - { 33, 9, 12, 0, 214, }, /* 51 */ - { 33, 9, 12, 0, 218, }, /* 52 */ - { 33, 9, 12, 0, 217, }, /* 53 */ - { 33, 9, 12, 0, 219, }, /* 54 */ - { 33, 5, 12, 0, 56, }, /* 55 */ - { 33, 9, 12, 5, 2, }, /* 56 */ - { 33, 8, 12, 5, 1, }, /* 57 */ - { 33, 5, 12, 5, -2, }, /* 58 */ - { 33, 9, 12, 9, 2, }, /* 59 */ - { 33, 8, 12, 9, 1, }, /* 60 */ - { 33, 5, 12, 9, -2, }, /* 61 */ - { 33, 9, 12, 13, 2, }, /* 62 */ - { 33, 8, 12, 13, 1, }, /* 63 */ - { 33, 5, 12, 13, -2, }, /* 64 */ - { 33, 5, 12, 0, -79, }, /* 65 */ - { 33, 9, 12, 17, 2, }, /* 66 */ - { 33, 8, 12, 17, 1, }, /* 67 */ - { 33, 5, 12, 17, -2, }, /* 68 */ - { 33, 9, 12, 0, -97, }, /* 69 */ - { 33, 9, 12, 0, -56, }, /* 70 */ - { 33, 9, 12, 0, -130, }, /* 71 */ - { 33, 9, 12, 0, 10795, }, /* 72 */ - { 33, 9, 12, 0, -163, }, /* 73 */ - { 33, 9, 12, 0, 10792, }, /* 74 */ - { 33, 5, 12, 0, 10815, }, /* 75 */ - { 33, 9, 12, 0, -195, }, /* 76 */ - { 33, 9, 12, 0, 69, }, /* 77 */ - { 33, 9, 12, 0, 71, }, /* 78 */ - { 33, 5, 12, 0, 10783, }, /* 79 */ - { 33, 5, 12, 0, 10780, }, /* 80 */ - { 33, 5, 12, 0, 10782, }, /* 81 */ - { 33, 5, 12, 0, -210, }, /* 82 */ - { 33, 5, 12, 0, -206, }, /* 83 */ - { 33, 5, 12, 0, -205, }, /* 84 */ - { 33, 5, 12, 0, -202, }, /* 85 */ - { 33, 5, 12, 0, -203, }, /* 86 */ - { 33, 5, 12, 0, 42319, }, /* 87 */ - { 33, 5, 12, 0, 42315, }, /* 88 */ - { 33, 5, 12, 0, -207, }, /* 89 */ - { 33, 5, 12, 0, 42280, }, /* 90 */ - { 33, 5, 12, 0, 42308, }, /* 91 */ - { 33, 5, 12, 0, -209, }, /* 92 */ - { 33, 5, 12, 0, -211, }, /* 93 */ - { 33, 5, 12, 0, 10743, }, /* 94 */ - { 33, 5, 12, 0, 42305, }, /* 95 */ - { 33, 5, 12, 0, 10749, }, /* 96 */ - { 33, 5, 12, 0, -213, }, /* 97 */ - { 33, 5, 12, 0, -214, }, /* 98 */ - { 33, 5, 12, 0, 10727, }, /* 99 */ - { 33, 5, 12, 0, -218, }, /* 100 */ - { 33, 5, 12, 0, 42282, }, /* 101 */ - { 33, 5, 12, 0, -69, }, /* 102 */ - { 33, 5, 12, 0, -217, }, /* 103 */ - { 33, 5, 12, 0, -71, }, /* 104 */ - { 33, 5, 12, 0, -219, }, /* 105 */ - { 33, 5, 12, 0, 42261, }, /* 106 */ - { 33, 5, 12, 0, 42258, }, /* 107 */ - { 33, 6, 12, 0, 0, }, /* 108 */ - { 9, 6, 12, 0, 0, }, /* 109 */ - { 3, 24, 12, 0, 0, }, /* 110 */ - { 27, 12, 3, 0, 0, }, /* 111 */ - { 27, 12, 3, 21, 116, }, /* 112 */ - { 19, 9, 12, 0, 1, }, /* 113 */ - { 19, 5, 12, 0, -1, }, /* 114 */ - { 19, 24, 12, 0, 0, }, /* 115 */ - { 9, 2, 12, 0, 0, }, /* 116 */ - { 19, 6, 12, 0, 0, }, /* 117 */ - { 19, 5, 12, 0, 130, }, /* 118 */ - { 19, 9, 12, 0, 116, }, /* 119 */ - { 19, 9, 12, 0, 38, }, /* 120 */ - { 19, 9, 12, 0, 37, }, /* 121 */ - { 19, 9, 12, 0, 64, }, /* 122 */ - { 19, 9, 12, 0, 63, }, /* 123 */ - { 19, 5, 12, 0, 0, }, /* 124 */ - { 19, 9, 12, 0, 32, }, /* 125 */ - { 19, 9, 12, 34, 32, }, /* 126 */ - { 19, 9, 12, 59, 32, }, /* 127 */ - { 19, 9, 12, 38, 32, }, /* 128 */ - { 19, 9, 12, 21, 32, }, /* 129 */ - { 19, 9, 12, 51, 32, }, /* 130 */ - { 19, 9, 12, 26, 32, }, /* 131 */ - { 19, 9, 12, 47, 32, }, /* 132 */ - { 19, 9, 12, 55, 32, }, /* 133 */ - { 19, 9, 12, 30, 32, }, /* 134 */ - { 19, 9, 12, 43, 32, }, /* 135 */ - { 19, 9, 12, 96, 32, }, /* 136 */ - { 19, 5, 12, 0, -38, }, /* 137 */ - { 19, 5, 12, 0, -37, }, /* 138 */ - { 19, 5, 12, 0, -32, }, /* 139 */ - { 19, 5, 12, 34, -32, }, /* 140 */ - { 19, 5, 12, 59, -32, }, /* 141 */ - { 19, 5, 12, 38, -32, }, /* 142 */ - { 19, 5, 12, 21, -116, }, /* 143 */ - { 19, 5, 12, 51, -32, }, /* 144 */ - { 19, 5, 12, 26, -775, }, /* 145 */ - { 19, 5, 12, 47, -32, }, /* 146 */ - { 19, 5, 12, 55, -32, }, /* 147 */ - { 19, 5, 12, 30, 1, }, /* 148 */ - { 19, 5, 12, 30, -32, }, /* 149 */ - { 19, 5, 12, 43, -32, }, /* 150 */ - { 19, 5, 12, 96, -32, }, /* 151 */ - { 19, 5, 12, 0, -64, }, /* 152 */ - { 19, 5, 12, 0, -63, }, /* 153 */ - { 19, 9, 12, 0, 8, }, /* 154 */ - { 19, 5, 12, 34, -30, }, /* 155 */ - { 19, 5, 12, 38, -25, }, /* 156 */ - { 19, 9, 12, 0, 0, }, /* 157 */ - { 19, 5, 12, 43, -15, }, /* 158 */ - { 19, 5, 12, 47, -22, }, /* 159 */ - { 19, 5, 12, 0, -8, }, /* 160 */ - { 10, 9, 12, 0, 1, }, /* 161 */ - { 10, 5, 12, 0, -1, }, /* 162 */ - { 19, 5, 12, 51, -54, }, /* 163 */ - { 19, 5, 12, 55, -48, }, /* 164 */ - { 19, 5, 12, 0, 7, }, /* 165 */ - { 19, 5, 12, 0, -116, }, /* 166 */ - { 19, 9, 12, 38, -60, }, /* 167 */ - { 19, 5, 12, 59, -64, }, /* 168 */ - { 19, 25, 12, 0, 0, }, /* 169 */ - { 19, 9, 12, 0, -7, }, /* 170 */ - { 19, 9, 12, 0, -130, }, /* 171 */ - { 12, 9, 12, 0, 80, }, /* 172 */ - { 12, 9, 12, 0, 32, }, /* 173 */ - { 12, 9, 12, 63, 32, }, /* 174 */ - { 12, 9, 12, 67, 32, }, /* 175 */ - { 12, 9, 12, 71, 32, }, /* 176 */ - { 12, 9, 12, 75, 32, }, /* 177 */ - { 12, 9, 12, 79, 32, }, /* 178 */ - { 12, 9, 12, 84, 32, }, /* 179 */ - { 12, 5, 12, 0, -32, }, /* 180 */ - { 12, 5, 12, 63, -32, }, /* 181 */ - { 12, 5, 12, 67, -32, }, /* 182 */ - { 12, 5, 12, 71, -32, }, /* 183 */ - { 12, 5, 12, 75, -32, }, /* 184 */ - { 12, 5, 12, 79, -32, }, /* 185 */ - { 12, 5, 12, 84, -32, }, /* 186 */ - { 12, 5, 12, 0, -80, }, /* 187 */ - { 12, 9, 12, 0, 1, }, /* 188 */ - { 12, 5, 12, 0, -1, }, /* 189 */ - { 12, 9, 12, 88, 1, }, /* 190 */ - { 12, 5, 12, 88, -1, }, /* 191 */ - { 12, 26, 12, 0, 0, }, /* 192 */ - { 12, 12, 3, 0, 0, }, /* 193 */ - { 12, 11, 3, 0, 0, }, /* 194 */ - { 12, 9, 12, 0, 15, }, /* 195 */ - { 12, 5, 12, 0, -15, }, /* 196 */ - { 1, 9, 12, 0, 48, }, /* 197 */ - { 1, 6, 12, 0, 0, }, /* 198 */ - { 1, 21, 12, 0, 0, }, /* 199 */ - { 1, 5, 12, 0, 0, }, /* 200 */ - { 1, 5, 12, 0, -48, }, /* 201 */ - { 1, 17, 12, 0, 0, }, /* 202 */ - { 1, 26, 12, 0, 0, }, /* 203 */ - { 1, 23, 12, 0, 0, }, /* 204 */ - { 25, 12, 3, 0, 0, }, /* 205 */ - { 25, 17, 12, 0, 0, }, /* 206 */ - { 25, 21, 12, 0, 0, }, /* 207 */ - { 25, 7, 12, 0, 0, }, /* 208 */ - { 0, 1, 4, 0, 0, }, /* 209 */ - { 9, 1, 4, 0, 0, }, /* 210 */ - { 0, 25, 12, 0, 0, }, /* 211 */ - { 0, 21, 12, 0, 0, }, /* 212 */ - { 0, 23, 12, 0, 0, }, /* 213 */ - { 0, 26, 12, 0, 0, }, /* 214 */ - { 0, 12, 3, 0, 0, }, /* 215 */ - { 0, 1, 2, 0, 0, }, /* 216 */ - { 0, 7, 12, 0, 0, }, /* 217 */ - { 0, 13, 12, 0, 0, }, /* 218 */ - { 0, 6, 12, 0, 0, }, /* 219 */ - { 49, 21, 12, 0, 0, }, /* 220 */ - { 49, 1, 4, 0, 0, }, /* 221 */ - { 49, 7, 12, 0, 0, }, /* 222 */ - { 49, 12, 3, 0, 0, }, /* 223 */ - { 55, 7, 12, 0, 0, }, /* 224 */ - { 55, 12, 3, 0, 0, }, /* 225 */ - { 63, 13, 12, 0, 0, }, /* 226 */ - { 63, 7, 12, 0, 0, }, /* 227 */ - { 63, 12, 3, 0, 0, }, /* 228 */ - { 63, 6, 12, 0, 0, }, /* 229 */ - { 63, 26, 12, 0, 0, }, /* 230 */ - { 63, 21, 12, 0, 0, }, /* 231 */ - { 63, 23, 12, 0, 0, }, /* 232 */ - { 89, 7, 12, 0, 0, }, /* 233 */ - { 89, 12, 3, 0, 0, }, /* 234 */ - { 89, 6, 12, 0, 0, }, /* 235 */ - { 89, 21, 12, 0, 0, }, /* 236 */ - { 94, 7, 12, 0, 0, }, /* 237 */ - { 94, 12, 3, 0, 0, }, /* 238 */ - { 94, 21, 12, 0, 0, }, /* 239 */ - { 14, 12, 3, 0, 0, }, /* 240 */ - { 14, 10, 5, 0, 0, }, /* 241 */ - { 14, 7, 12, 0, 0, }, /* 242 */ - { 14, 13, 12, 0, 0, }, /* 243 */ - { 14, 21, 12, 0, 0, }, /* 244 */ - { 14, 6, 12, 0, 0, }, /* 245 */ - { 2, 7, 12, 0, 0, }, /* 246 */ - { 2, 12, 3, 0, 0, }, /* 247 */ - { 2, 10, 5, 0, 0, }, /* 248 */ - { 2, 10, 3, 0, 0, }, /* 249 */ - { 2, 13, 12, 0, 0, }, /* 250 */ - { 2, 23, 12, 0, 0, }, /* 251 */ - { 2, 15, 12, 0, 0, }, /* 252 */ - { 2, 26, 12, 0, 0, }, /* 253 */ - { 2, 21, 12, 0, 0, }, /* 254 */ - { 21, 12, 3, 0, 0, }, /* 255 */ - { 21, 10, 5, 0, 0, }, /* 256 */ - { 21, 7, 12, 0, 0, }, /* 257 */ - { 21, 13, 12, 0, 0, }, /* 258 */ - { 21, 21, 12, 0, 0, }, /* 259 */ - { 20, 12, 3, 0, 0, }, /* 260 */ - { 20, 10, 5, 0, 0, }, /* 261 */ - { 20, 7, 12, 0, 0, }, /* 262 */ - { 20, 13, 12, 0, 0, }, /* 263 */ - { 20, 21, 12, 0, 0, }, /* 264 */ - { 20, 23, 12, 0, 0, }, /* 265 */ - { 43, 12, 3, 0, 0, }, /* 266 */ - { 43, 10, 5, 0, 0, }, /* 267 */ - { 43, 7, 12, 0, 0, }, /* 268 */ - { 43, 10, 3, 0, 0, }, /* 269 */ - { 43, 13, 12, 0, 0, }, /* 270 */ - { 43, 26, 12, 0, 0, }, /* 271 */ - { 43, 15, 12, 0, 0, }, /* 272 */ - { 53, 12, 3, 0, 0, }, /* 273 */ - { 53, 7, 12, 0, 0, }, /* 274 */ - { 53, 10, 3, 0, 0, }, /* 275 */ - { 53, 10, 5, 0, 0, }, /* 276 */ - { 53, 13, 12, 0, 0, }, /* 277 */ - { 53, 15, 12, 0, 0, }, /* 278 */ - { 53, 26, 12, 0, 0, }, /* 279 */ - { 53, 23, 12, 0, 0, }, /* 280 */ - { 54, 12, 3, 0, 0, }, /* 281 */ - { 54, 10, 5, 0, 0, }, /* 282 */ - { 54, 7, 12, 0, 0, }, /* 283 */ - { 54, 13, 12, 0, 0, }, /* 284 */ - { 54, 15, 12, 0, 0, }, /* 285 */ - { 54, 26, 12, 0, 0, }, /* 286 */ - { 28, 7, 12, 0, 0, }, /* 287 */ - { 28, 12, 3, 0, 0, }, /* 288 */ - { 28, 10, 5, 0, 0, }, /* 289 */ - { 28, 21, 12, 0, 0, }, /* 290 */ - { 28, 10, 3, 0, 0, }, /* 291 */ - { 28, 13, 12, 0, 0, }, /* 292 */ - { 36, 12, 3, 0, 0, }, /* 293 */ - { 36, 10, 5, 0, 0, }, /* 294 */ - { 36, 7, 12, 0, 0, }, /* 295 */ - { 36, 10, 3, 0, 0, }, /* 296 */ - { 36, 7, 4, 0, 0, }, /* 297 */ - { 36, 26, 12, 0, 0, }, /* 298 */ - { 36, 15, 12, 0, 0, }, /* 299 */ - { 36, 13, 12, 0, 0, }, /* 300 */ - { 47, 10, 5, 0, 0, }, /* 301 */ - { 47, 7, 12, 0, 0, }, /* 302 */ - { 47, 12, 3, 0, 0, }, /* 303 */ - { 47, 10, 3, 0, 0, }, /* 304 */ - { 47, 13, 12, 0, 0, }, /* 305 */ - { 47, 21, 12, 0, 0, }, /* 306 */ - { 56, 7, 12, 0, 0, }, /* 307 */ - { 56, 12, 3, 0, 0, }, /* 308 */ - { 56, 7, 5, 0, 0, }, /* 309 */ - { 56, 6, 12, 0, 0, }, /* 310 */ - { 56, 21, 12, 0, 0, }, /* 311 */ - { 56, 13, 12, 0, 0, }, /* 312 */ - { 32, 7, 12, 0, 0, }, /* 313 */ - { 32, 12, 3, 0, 0, }, /* 314 */ - { 32, 7, 5, 0, 0, }, /* 315 */ - { 32, 6, 12, 0, 0, }, /* 316 */ - { 32, 13, 12, 0, 0, }, /* 317 */ - { 57, 7, 12, 0, 0, }, /* 318 */ - { 57, 26, 12, 0, 0, }, /* 319 */ - { 57, 21, 12, 0, 0, }, /* 320 */ - { 57, 12, 3, 0, 0, }, /* 321 */ - { 57, 13, 12, 0, 0, }, /* 322 */ - { 57, 15, 12, 0, 0, }, /* 323 */ - { 57, 22, 12, 0, 0, }, /* 324 */ - { 57, 18, 12, 0, 0, }, /* 325 */ - { 57, 10, 5, 0, 0, }, /* 326 */ - { 38, 7, 12, 0, 0, }, /* 327 */ - { 38, 10, 12, 0, 0, }, /* 328 */ - { 38, 12, 3, 0, 0, }, /* 329 */ - { 38, 10, 5, 0, 0, }, /* 330 */ - { 38, 13, 12, 0, 0, }, /* 331 */ - { 38, 21, 12, 0, 0, }, /* 332 */ - { 38, 26, 12, 0, 0, }, /* 333 */ - { 16, 9, 12, 0, 7264, }, /* 334 */ - { 16, 5, 12, 0, 3008, }, /* 335 */ - { 16, 6, 12, 0, 0, }, /* 336 */ - { 23, 7, 6, 0, 0, }, /* 337 */ - { 23, 7, 7, 0, 0, }, /* 338 */ - { 23, 7, 8, 0, 0, }, /* 339 */ - { 15, 7, 12, 0, 0, }, /* 340 */ - { 15, 12, 3, 0, 0, }, /* 341 */ - { 15, 21, 12, 0, 0, }, /* 342 */ - { 15, 15, 12, 0, 0, }, /* 343 */ - { 15, 26, 12, 0, 0, }, /* 344 */ - { 8, 9, 12, 0, 38864, }, /* 345 */ - { 8, 9, 12, 0, 8, }, /* 346 */ - { 8, 5, 12, 0, -8, }, /* 347 */ - { 7, 17, 12, 0, 0, }, /* 348 */ - { 7, 7, 12, 0, 0, }, /* 349 */ - { 7, 21, 12, 0, 0, }, /* 350 */ - { 40, 29, 12, 0, 0, }, /* 351 */ - { 40, 7, 12, 0, 0, }, /* 352 */ - { 40, 22, 12, 0, 0, }, /* 353 */ - { 40, 18, 12, 0, 0, }, /* 354 */ - { 45, 7, 12, 0, 0, }, /* 355 */ - { 45, 14, 12, 0, 0, }, /* 356 */ - { 50, 7, 12, 0, 0, }, /* 357 */ - { 50, 12, 3, 0, 0, }, /* 358 */ - { 24, 7, 12, 0, 0, }, /* 359 */ - { 24, 12, 3, 0, 0, }, /* 360 */ - { 6, 7, 12, 0, 0, }, /* 361 */ - { 6, 12, 3, 0, 0, }, /* 362 */ - { 51, 7, 12, 0, 0, }, /* 363 */ - { 51, 12, 3, 0, 0, }, /* 364 */ - { 31, 7, 12, 0, 0, }, /* 365 */ - { 31, 12, 3, 0, 0, }, /* 366 */ - { 31, 10, 5, 0, 0, }, /* 367 */ - { 31, 21, 12, 0, 0, }, /* 368 */ - { 31, 6, 12, 0, 0, }, /* 369 */ - { 31, 23, 12, 0, 0, }, /* 370 */ - { 31, 13, 12, 0, 0, }, /* 371 */ - { 31, 15, 12, 0, 0, }, /* 372 */ - { 37, 21, 12, 0, 0, }, /* 373 */ - { 37, 17, 12, 0, 0, }, /* 374 */ - { 37, 12, 3, 0, 0, }, /* 375 */ - { 37, 1, 2, 0, 0, }, /* 376 */ - { 37, 13, 12, 0, 0, }, /* 377 */ - { 37, 7, 12, 0, 0, }, /* 378 */ - { 37, 6, 12, 0, 0, }, /* 379 */ - { 34, 7, 12, 0, 0, }, /* 380 */ - { 34, 12, 3, 0, 0, }, /* 381 */ - { 34, 10, 5, 0, 0, }, /* 382 */ - { 34, 26, 12, 0, 0, }, /* 383 */ - { 34, 21, 12, 0, 0, }, /* 384 */ - { 34, 13, 12, 0, 0, }, /* 385 */ - { 52, 7, 12, 0, 0, }, /* 386 */ - { 39, 7, 12, 0, 0, }, /* 387 */ - { 39, 13, 12, 0, 0, }, /* 388 */ - { 39, 15, 12, 0, 0, }, /* 389 */ - { 39, 26, 12, 0, 0, }, /* 390 */ - { 31, 26, 12, 0, 0, }, /* 391 */ - { 5, 7, 12, 0, 0, }, /* 392 */ - { 5, 12, 3, 0, 0, }, /* 393 */ - { 5, 10, 5, 0, 0, }, /* 394 */ - { 5, 21, 12, 0, 0, }, /* 395 */ - { 90, 7, 12, 0, 0, }, /* 396 */ - { 90, 10, 5, 0, 0, }, /* 397 */ - { 90, 12, 3, 0, 0, }, /* 398 */ - { 90, 10, 12, 0, 0, }, /* 399 */ - { 90, 13, 12, 0, 0, }, /* 400 */ - { 90, 21, 12, 0, 0, }, /* 401 */ - { 90, 6, 12, 0, 0, }, /* 402 */ - { 27, 11, 3, 0, 0, }, /* 403 */ - { 61, 12, 3, 0, 0, }, /* 404 */ - { 61, 10, 5, 0, 0, }, /* 405 */ - { 61, 7, 12, 0, 0, }, /* 406 */ - { 61, 13, 12, 0, 0, }, /* 407 */ - { 61, 21, 12, 0, 0, }, /* 408 */ - { 61, 26, 12, 0, 0, }, /* 409 */ - { 75, 12, 3, 0, 0, }, /* 410 */ - { 75, 10, 5, 0, 0, }, /* 411 */ - { 75, 7, 12, 0, 0, }, /* 412 */ - { 75, 13, 12, 0, 0, }, /* 413 */ - { 92, 7, 12, 0, 0, }, /* 414 */ - { 92, 12, 3, 0, 0, }, /* 415 */ - { 92, 10, 5, 0, 0, }, /* 416 */ - { 92, 21, 12, 0, 0, }, /* 417 */ - { 69, 7, 12, 0, 0, }, /* 418 */ - { 69, 10, 5, 0, 0, }, /* 419 */ - { 69, 12, 3, 0, 0, }, /* 420 */ - { 69, 21, 12, 0, 0, }, /* 421 */ - { 69, 13, 12, 0, 0, }, /* 422 */ - { 72, 13, 12, 0, 0, }, /* 423 */ - { 72, 7, 12, 0, 0, }, /* 424 */ - { 72, 6, 12, 0, 0, }, /* 425 */ - { 72, 21, 12, 0, 0, }, /* 426 */ - { 12, 5, 12, 63, -6222, }, /* 427 */ - { 12, 5, 12, 67, -6221, }, /* 428 */ - { 12, 5, 12, 71, -6212, }, /* 429 */ - { 12, 5, 12, 75, -6210, }, /* 430 */ - { 12, 5, 12, 79, -6210, }, /* 431 */ - { 12, 5, 12, 79, -6211, }, /* 432 */ - { 12, 5, 12, 84, -6204, }, /* 433 */ - { 12, 5, 12, 88, -6180, }, /* 434 */ - { 12, 5, 12, 108, 35267, }, /* 435 */ - { 16, 9, 12, 0, -3008, }, /* 436 */ - { 75, 21, 12, 0, 0, }, /* 437 */ - { 9, 10, 5, 0, 0, }, /* 438 */ - { 9, 7, 12, 0, 0, }, /* 439 */ - { 12, 5, 12, 0, 0, }, /* 440 */ - { 12, 6, 12, 0, 0, }, /* 441 */ - { 33, 5, 12, 0, 35332, }, /* 442 */ - { 33, 5, 12, 0, 3814, }, /* 443 */ - { 33, 9, 12, 92, 1, }, /* 444 */ - { 33, 5, 12, 92, -1, }, /* 445 */ - { 33, 5, 12, 92, -58, }, /* 446 */ - { 33, 9, 12, 0, -7615, }, /* 447 */ - { 19, 5, 12, 0, 8, }, /* 448 */ - { 19, 9, 12, 0, -8, }, /* 449 */ - { 19, 5, 12, 0, 74, }, /* 450 */ - { 19, 5, 12, 0, 86, }, /* 451 */ - { 19, 5, 12, 0, 100, }, /* 452 */ - { 19, 5, 12, 0, 128, }, /* 453 */ - { 19, 5, 12, 0, 112, }, /* 454 */ - { 19, 5, 12, 0, 126, }, /* 455 */ - { 19, 8, 12, 0, -8, }, /* 456 */ - { 19, 5, 12, 0, 9, }, /* 457 */ - { 19, 9, 12, 0, -74, }, /* 458 */ - { 19, 8, 12, 0, -9, }, /* 459 */ - { 19, 5, 12, 21, -7173, }, /* 460 */ - { 19, 9, 12, 0, -86, }, /* 461 */ - { 19, 9, 12, 0, -100, }, /* 462 */ - { 19, 9, 12, 0, -112, }, /* 463 */ - { 19, 9, 12, 0, -128, }, /* 464 */ - { 19, 9, 12, 0, -126, }, /* 465 */ - { 27, 1, 3, 0, 0, }, /* 466 */ - { 27, 1, 13, 0, 0, }, /* 467 */ - { 9, 27, 2, 0, 0, }, /* 468 */ - { 9, 28, 2, 0, 0, }, /* 469 */ - { 9, 21, 14, 0, 0, }, /* 470 */ - { 9, 2, 2, 0, 0, }, /* 471 */ - { 9, 9, 12, 0, 0, }, /* 472 */ - { 9, 5, 12, 0, 0, }, /* 473 */ - { 19, 9, 12, 96, -7517, }, /* 474 */ - { 33, 9, 12, 100, -8383, }, /* 475 */ - { 33, 9, 12, 104, -8262, }, /* 476 */ - { 33, 9, 12, 0, 28, }, /* 477 */ - { 9, 5, 14, 0, 0, }, /* 478 */ - { 33, 5, 12, 0, -28, }, /* 479 */ - { 33, 14, 12, 0, 16, }, /* 480 */ - { 33, 14, 12, 0, -16, }, /* 481 */ - { 33, 14, 12, 0, 0, }, /* 482 */ - { 9, 25, 14, 0, 0, }, /* 483 */ - { 9, 26, 12, 0, 26, }, /* 484 */ - { 9, 26, 14, 0, 26, }, /* 485 */ - { 9, 26, 12, 0, -26, }, /* 486 */ - { 4, 26, 12, 0, 0, }, /* 487 */ - { 17, 9, 12, 0, 48, }, /* 488 */ - { 17, 5, 12, 0, -48, }, /* 489 */ - { 33, 9, 12, 0, -10743, }, /* 490 */ - { 33, 9, 12, 0, -3814, }, /* 491 */ - { 33, 9, 12, 0, -10727, }, /* 492 */ - { 33, 5, 12, 0, -10795, }, /* 493 */ - { 33, 5, 12, 0, -10792, }, /* 494 */ - { 33, 9, 12, 0, -10780, }, /* 495 */ - { 33, 9, 12, 0, -10749, }, /* 496 */ - { 33, 9, 12, 0, -10783, }, /* 497 */ - { 33, 9, 12, 0, -10782, }, /* 498 */ - { 33, 9, 12, 0, -10815, }, /* 499 */ - { 10, 5, 12, 0, 0, }, /* 500 */ - { 10, 26, 12, 0, 0, }, /* 501 */ - { 10, 12, 3, 0, 0, }, /* 502 */ - { 10, 21, 12, 0, 0, }, /* 503 */ - { 10, 15, 12, 0, 0, }, /* 504 */ - { 16, 5, 12, 0, -7264, }, /* 505 */ - { 58, 7, 12, 0, 0, }, /* 506 */ - { 58, 6, 12, 0, 0, }, /* 507 */ - { 58, 21, 12, 0, 0, }, /* 508 */ - { 58, 12, 3, 0, 0, }, /* 509 */ - { 22, 26, 12, 0, 0, }, /* 510 */ - { 22, 6, 12, 0, 0, }, /* 511 */ - { 22, 14, 12, 0, 0, }, /* 512 */ - { 23, 10, 3, 0, 0, }, /* 513 */ - { 9, 17, 14, 0, 0, }, /* 514 */ - { 26, 7, 12, 0, 0, }, /* 515 */ - { 26, 6, 12, 0, 0, }, /* 516 */ - { 29, 7, 12, 0, 0, }, /* 517 */ - { 29, 6, 12, 0, 0, }, /* 518 */ - { 3, 7, 12, 0, 0, }, /* 519 */ - { 23, 7, 12, 0, 0, }, /* 520 */ - { 23, 26, 12, 0, 0, }, /* 521 */ - { 29, 26, 12, 0, 0, }, /* 522 */ - { 22, 7, 12, 0, 0, }, /* 523 */ - { 60, 7, 12, 0, 0, }, /* 524 */ - { 60, 6, 12, 0, 0, }, /* 525 */ - { 60, 26, 12, 0, 0, }, /* 526 */ - { 85, 7, 12, 0, 0, }, /* 527 */ - { 85, 6, 12, 0, 0, }, /* 528 */ - { 85, 21, 12, 0, 0, }, /* 529 */ - { 76, 7, 12, 0, 0, }, /* 530 */ - { 76, 6, 12, 0, 0, }, /* 531 */ - { 76, 21, 12, 0, 0, }, /* 532 */ - { 76, 13, 12, 0, 0, }, /* 533 */ - { 12, 9, 12, 108, 1, }, /* 534 */ - { 12, 5, 12, 108, -35267, }, /* 535 */ - { 12, 7, 12, 0, 0, }, /* 536 */ - { 12, 21, 12, 0, 0, }, /* 537 */ - { 78, 7, 12, 0, 0, }, /* 538 */ - { 78, 14, 12, 0, 0, }, /* 539 */ - { 78, 12, 3, 0, 0, }, /* 540 */ - { 78, 21, 12, 0, 0, }, /* 541 */ - { 33, 9, 12, 0, -35332, }, /* 542 */ - { 33, 9, 12, 0, -42280, }, /* 543 */ - { 33, 9, 12, 0, -42308, }, /* 544 */ - { 33, 9, 12, 0, -42319, }, /* 545 */ - { 33, 9, 12, 0, -42315, }, /* 546 */ - { 33, 9, 12, 0, -42305, }, /* 547 */ - { 33, 9, 12, 0, -42258, }, /* 548 */ - { 33, 9, 12, 0, -42282, }, /* 549 */ - { 33, 9, 12, 0, -42261, }, /* 550 */ - { 33, 9, 12, 0, 928, }, /* 551 */ - { 48, 7, 12, 0, 0, }, /* 552 */ - { 48, 12, 3, 0, 0, }, /* 553 */ - { 48, 10, 5, 0, 0, }, /* 554 */ - { 48, 26, 12, 0, 0, }, /* 555 */ - { 64, 7, 12, 0, 0, }, /* 556 */ - { 64, 21, 12, 0, 0, }, /* 557 */ - { 74, 10, 5, 0, 0, }, /* 558 */ - { 74, 7, 12, 0, 0, }, /* 559 */ - { 74, 12, 3, 0, 0, }, /* 560 */ - { 74, 21, 12, 0, 0, }, /* 561 */ - { 74, 13, 12, 0, 0, }, /* 562 */ - { 68, 13, 12, 0, 0, }, /* 563 */ - { 68, 7, 12, 0, 0, }, /* 564 */ - { 68, 12, 3, 0, 0, }, /* 565 */ - { 68, 21, 12, 0, 0, }, /* 566 */ - { 73, 7, 12, 0, 0, }, /* 567 */ - { 73, 12, 3, 0, 0, }, /* 568 */ - { 73, 10, 5, 0, 0, }, /* 569 */ - { 73, 21, 12, 0, 0, }, /* 570 */ - { 83, 12, 3, 0, 0, }, /* 571 */ - { 83, 10, 5, 0, 0, }, /* 572 */ - { 83, 7, 12, 0, 0, }, /* 573 */ - { 83, 21, 12, 0, 0, }, /* 574 */ - { 83, 13, 12, 0, 0, }, /* 575 */ - { 38, 6, 12, 0, 0, }, /* 576 */ - { 67, 7, 12, 0, 0, }, /* 577 */ - { 67, 12, 3, 0, 0, }, /* 578 */ - { 67, 10, 5, 0, 0, }, /* 579 */ - { 67, 13, 12, 0, 0, }, /* 580 */ - { 67, 21, 12, 0, 0, }, /* 581 */ - { 91, 7, 12, 0, 0, }, /* 582 */ - { 91, 12, 3, 0, 0, }, /* 583 */ - { 91, 6, 12, 0, 0, }, /* 584 */ - { 91, 21, 12, 0, 0, }, /* 585 */ - { 86, 7, 12, 0, 0, }, /* 586 */ - { 86, 10, 5, 0, 0, }, /* 587 */ - { 86, 12, 3, 0, 0, }, /* 588 */ - { 86, 21, 12, 0, 0, }, /* 589 */ - { 86, 6, 12, 0, 0, }, /* 590 */ - { 33, 5, 12, 0, -928, }, /* 591 */ - { 8, 5, 12, 0, -38864, }, /* 592 */ - { 86, 13, 12, 0, 0, }, /* 593 */ - { 23, 7, 9, 0, 0, }, /* 594 */ - { 23, 7, 10, 0, 0, }, /* 595 */ - { 9, 4, 2, 0, 0, }, /* 596 */ - { 9, 3, 12, 0, 0, }, /* 597 */ - { 25, 25, 12, 0, 0, }, /* 598 */ - { 0, 24, 12, 0, 0, }, /* 599 */ - { 9, 6, 3, 0, 0, }, /* 600 */ - { 35, 7, 12, 0, 0, }, /* 601 */ - { 19, 14, 12, 0, 0, }, /* 602 */ - { 19, 15, 12, 0, 0, }, /* 603 */ - { 19, 26, 12, 0, 0, }, /* 604 */ - { 70, 7, 12, 0, 0, }, /* 605 */ - { 66, 7, 12, 0, 0, }, /* 606 */ - { 41, 7, 12, 0, 0, }, /* 607 */ - { 41, 15, 12, 0, 0, }, /* 608 */ - { 18, 7, 12, 0, 0, }, /* 609 */ - { 18, 14, 12, 0, 0, }, /* 610 */ - { 117, 7, 12, 0, 0, }, /* 611 */ - { 117, 12, 3, 0, 0, }, /* 612 */ - { 59, 7, 12, 0, 0, }, /* 613 */ - { 59, 21, 12, 0, 0, }, /* 614 */ - { 42, 7, 12, 0, 0, }, /* 615 */ - { 42, 21, 12, 0, 0, }, /* 616 */ - { 42, 14, 12, 0, 0, }, /* 617 */ - { 13, 9, 12, 0, 40, }, /* 618 */ - { 13, 5, 12, 0, -40, }, /* 619 */ - { 46, 7, 12, 0, 0, }, /* 620 */ - { 44, 7, 12, 0, 0, }, /* 621 */ - { 44, 13, 12, 0, 0, }, /* 622 */ - { 135, 9, 12, 0, 40, }, /* 623 */ - { 135, 5, 12, 0, -40, }, /* 624 */ - { 105, 7, 12, 0, 0, }, /* 625 */ - { 103, 7, 12, 0, 0, }, /* 626 */ - { 103, 21, 12, 0, 0, }, /* 627 */ - { 109, 7, 12, 0, 0, }, /* 628 */ - { 11, 7, 12, 0, 0, }, /* 629 */ - { 80, 7, 12, 0, 0, }, /* 630 */ - { 80, 21, 12, 0, 0, }, /* 631 */ - { 80, 15, 12, 0, 0, }, /* 632 */ - { 119, 7, 12, 0, 0, }, /* 633 */ - { 119, 26, 12, 0, 0, }, /* 634 */ - { 119, 15, 12, 0, 0, }, /* 635 */ - { 115, 7, 12, 0, 0, }, /* 636 */ - { 115, 15, 12, 0, 0, }, /* 637 */ - { 127, 7, 12, 0, 0, }, /* 638 */ - { 127, 15, 12, 0, 0, }, /* 639 */ - { 65, 7, 12, 0, 0, }, /* 640 */ - { 65, 15, 12, 0, 0, }, /* 641 */ - { 65, 21, 12, 0, 0, }, /* 642 */ - { 71, 7, 12, 0, 0, }, /* 643 */ - { 71, 21, 12, 0, 0, }, /* 644 */ - { 97, 7, 12, 0, 0, }, /* 645 */ - { 96, 7, 12, 0, 0, }, /* 646 */ - { 96, 15, 12, 0, 0, }, /* 647 */ - { 30, 7, 12, 0, 0, }, /* 648 */ - { 30, 12, 3, 0, 0, }, /* 649 */ - { 30, 15, 12, 0, 0, }, /* 650 */ - { 30, 21, 12, 0, 0, }, /* 651 */ - { 87, 7, 12, 0, 0, }, /* 652 */ - { 87, 15, 12, 0, 0, }, /* 653 */ - { 87, 21, 12, 0, 0, }, /* 654 */ - { 116, 7, 12, 0, 0, }, /* 655 */ - { 116, 15, 12, 0, 0, }, /* 656 */ - { 111, 7, 12, 0, 0, }, /* 657 */ - { 111, 26, 12, 0, 0, }, /* 658 */ - { 111, 12, 3, 0, 0, }, /* 659 */ - { 111, 15, 12, 0, 0, }, /* 660 */ - { 111, 21, 12, 0, 0, }, /* 661 */ - { 77, 7, 12, 0, 0, }, /* 662 */ - { 77, 21, 12, 0, 0, }, /* 663 */ - { 82, 7, 12, 0, 0, }, /* 664 */ - { 82, 15, 12, 0, 0, }, /* 665 */ - { 81, 7, 12, 0, 0, }, /* 666 */ - { 81, 15, 12, 0, 0, }, /* 667 */ - { 120, 7, 12, 0, 0, }, /* 668 */ - { 120, 21, 12, 0, 0, }, /* 669 */ - { 120, 15, 12, 0, 0, }, /* 670 */ - { 88, 7, 12, 0, 0, }, /* 671 */ - { 129, 9, 12, 0, 64, }, /* 672 */ - { 129, 5, 12, 0, -64, }, /* 673 */ - { 129, 15, 12, 0, 0, }, /* 674 */ - { 143, 7, 12, 0, 0, }, /* 675 */ - { 143, 12, 3, 0, 0, }, /* 676 */ - { 143, 13, 12, 0, 0, }, /* 677 */ - { 0, 15, 12, 0, 0, }, /* 678 */ - { 146, 7, 12, 0, 0, }, /* 679 */ - { 146, 15, 12, 0, 0, }, /* 680 */ - { 147, 7, 12, 0, 0, }, /* 681 */ - { 147, 12, 3, 0, 0, }, /* 682 */ - { 147, 15, 12, 0, 0, }, /* 683 */ - { 147, 21, 12, 0, 0, }, /* 684 */ - { 93, 10, 5, 0, 0, }, /* 685 */ - { 93, 12, 3, 0, 0, }, /* 686 */ - { 93, 7, 12, 0, 0, }, /* 687 */ - { 93, 21, 12, 0, 0, }, /* 688 */ - { 93, 15, 12, 0, 0, }, /* 689 */ - { 93, 13, 12, 0, 0, }, /* 690 */ - { 84, 12, 3, 0, 0, }, /* 691 */ - { 84, 10, 5, 0, 0, }, /* 692 */ - { 84, 7, 12, 0, 0, }, /* 693 */ - { 84, 21, 12, 0, 0, }, /* 694 */ - { 84, 1, 4, 0, 0, }, /* 695 */ - { 100, 7, 12, 0, 0, }, /* 696 */ - { 100, 13, 12, 0, 0, }, /* 697 */ - { 95, 12, 3, 0, 0, }, /* 698 */ - { 95, 7, 12, 0, 0, }, /* 699 */ - { 95, 10, 5, 0, 0, }, /* 700 */ - { 95, 13, 12, 0, 0, }, /* 701 */ - { 95, 21, 12, 0, 0, }, /* 702 */ - { 110, 7, 12, 0, 0, }, /* 703 */ - { 110, 12, 3, 0, 0, }, /* 704 */ - { 110, 21, 12, 0, 0, }, /* 705 */ - { 99, 12, 3, 0, 0, }, /* 706 */ - { 99, 10, 5, 0, 0, }, /* 707 */ - { 99, 7, 12, 0, 0, }, /* 708 */ - { 99, 7, 4, 0, 0, }, /* 709 */ - { 99, 21, 12, 0, 0, }, /* 710 */ - { 99, 13, 12, 0, 0, }, /* 711 */ - { 47, 15, 12, 0, 0, }, /* 712 */ - { 107, 7, 12, 0, 0, }, /* 713 */ - { 107, 10, 5, 0, 0, }, /* 714 */ - { 107, 12, 3, 0, 0, }, /* 715 */ - { 107, 21, 12, 0, 0, }, /* 716 */ - { 128, 7, 12, 0, 0, }, /* 717 */ - { 128, 21, 12, 0, 0, }, /* 718 */ - { 108, 7, 12, 0, 0, }, /* 719 */ - { 108, 12, 3, 0, 0, }, /* 720 */ - { 108, 10, 5, 0, 0, }, /* 721 */ - { 108, 13, 12, 0, 0, }, /* 722 */ - { 106, 12, 3, 0, 0, }, /* 723 */ - { 106, 10, 5, 0, 0, }, /* 724 */ - { 106, 7, 12, 0, 0, }, /* 725 */ - { 106, 10, 3, 0, 0, }, /* 726 */ - { 134, 7, 12, 0, 0, }, /* 727 */ - { 134, 10, 5, 0, 0, }, /* 728 */ - { 134, 12, 3, 0, 0, }, /* 729 */ - { 134, 21, 12, 0, 0, }, /* 730 */ - { 134, 13, 12, 0, 0, }, /* 731 */ - { 123, 7, 12, 0, 0, }, /* 732 */ - { 123, 10, 3, 0, 0, }, /* 733 */ - { 123, 10, 5, 0, 0, }, /* 734 */ - { 123, 12, 3, 0, 0, }, /* 735 */ - { 123, 21, 12, 0, 0, }, /* 736 */ - { 123, 13, 12, 0, 0, }, /* 737 */ - { 122, 7, 12, 0, 0, }, /* 738 */ - { 122, 10, 3, 0, 0, }, /* 739 */ - { 122, 10, 5, 0, 0, }, /* 740 */ - { 122, 12, 3, 0, 0, }, /* 741 */ - { 122, 21, 12, 0, 0, }, /* 742 */ - { 113, 7, 12, 0, 0, }, /* 743 */ - { 113, 10, 5, 0, 0, }, /* 744 */ - { 113, 12, 3, 0, 0, }, /* 745 */ - { 113, 21, 12, 0, 0, }, /* 746 */ - { 113, 13, 12, 0, 0, }, /* 747 */ - { 101, 7, 12, 0, 0, }, /* 748 */ - { 101, 12, 3, 0, 0, }, /* 749 */ - { 101, 10, 5, 0, 0, }, /* 750 */ - { 101, 13, 12, 0, 0, }, /* 751 */ - { 125, 7, 12, 0, 0, }, /* 752 */ - { 125, 12, 3, 0, 0, }, /* 753 */ - { 125, 10, 5, 0, 0, }, /* 754 */ - { 125, 13, 12, 0, 0, }, /* 755 */ - { 125, 15, 12, 0, 0, }, /* 756 */ - { 125, 21, 12, 0, 0, }, /* 757 */ - { 125, 26, 12, 0, 0, }, /* 758 */ - { 141, 7, 12, 0, 0, }, /* 759 */ - { 141, 10, 5, 0, 0, }, /* 760 */ - { 141, 12, 3, 0, 0, }, /* 761 */ - { 141, 21, 12, 0, 0, }, /* 762 */ - { 124, 9, 12, 0, 32, }, /* 763 */ - { 124, 5, 12, 0, -32, }, /* 764 */ - { 124, 13, 12, 0, 0, }, /* 765 */ - { 124, 15, 12, 0, 0, }, /* 766 */ - { 124, 7, 12, 0, 0, }, /* 767 */ - { 140, 7, 12, 0, 0, }, /* 768 */ - { 140, 12, 3, 0, 0, }, /* 769 */ - { 140, 10, 5, 0, 0, }, /* 770 */ - { 140, 7, 4, 0, 0, }, /* 771 */ - { 140, 21, 12, 0, 0, }, /* 772 */ - { 139, 7, 12, 0, 0, }, /* 773 */ - { 139, 12, 3, 0, 0, }, /* 774 */ - { 139, 10, 5, 0, 0, }, /* 775 */ - { 139, 7, 4, 0, 0, }, /* 776 */ - { 139, 21, 12, 0, 0, }, /* 777 */ - { 121, 7, 12, 0, 0, }, /* 778 */ - { 132, 7, 12, 0, 0, }, /* 779 */ - { 132, 10, 5, 0, 0, }, /* 780 */ - { 132, 12, 3, 0, 0, }, /* 781 */ - { 132, 21, 12, 0, 0, }, /* 782 */ - { 132, 13, 12, 0, 0, }, /* 783 */ - { 132, 15, 12, 0, 0, }, /* 784 */ - { 133, 21, 12, 0, 0, }, /* 785 */ - { 133, 7, 12, 0, 0, }, /* 786 */ - { 133, 12, 3, 0, 0, }, /* 787 */ - { 133, 10, 5, 0, 0, }, /* 788 */ - { 137, 7, 12, 0, 0, }, /* 789 */ - { 137, 12, 3, 0, 0, }, /* 790 */ - { 137, 7, 4, 0, 0, }, /* 791 */ - { 137, 13, 12, 0, 0, }, /* 792 */ - { 142, 7, 12, 0, 0, }, /* 793 */ - { 142, 10, 5, 0, 0, }, /* 794 */ - { 142, 12, 3, 0, 0, }, /* 795 */ - { 142, 13, 12, 0, 0, }, /* 796 */ - { 144, 7, 12, 0, 0, }, /* 797 */ - { 144, 12, 3, 0, 0, }, /* 798 */ - { 144, 10, 5, 0, 0, }, /* 799 */ - { 144, 21, 12, 0, 0, }, /* 800 */ - { 62, 7, 12, 0, 0, }, /* 801 */ - { 62, 14, 12, 0, 0, }, /* 802 */ - { 62, 21, 12, 0, 0, }, /* 803 */ - { 79, 7, 12, 0, 0, }, /* 804 */ - { 126, 7, 12, 0, 0, }, /* 805 */ - { 114, 7, 12, 0, 0, }, /* 806 */ - { 114, 13, 12, 0, 0, }, /* 807 */ - { 114, 21, 12, 0, 0, }, /* 808 */ - { 102, 7, 12, 0, 0, }, /* 809 */ - { 102, 12, 3, 0, 0, }, /* 810 */ - { 102, 21, 12, 0, 0, }, /* 811 */ - { 118, 7, 12, 0, 0, }, /* 812 */ - { 118, 12, 3, 0, 0, }, /* 813 */ - { 118, 21, 12, 0, 0, }, /* 814 */ - { 118, 26, 12, 0, 0, }, /* 815 */ - { 118, 6, 12, 0, 0, }, /* 816 */ - { 118, 13, 12, 0, 0, }, /* 817 */ - { 118, 15, 12, 0, 0, }, /* 818 */ - { 145, 9, 12, 0, 32, }, /* 819 */ - { 145, 5, 12, 0, -32, }, /* 820 */ - { 145, 15, 12, 0, 0, }, /* 821 */ - { 145, 21, 12, 0, 0, }, /* 822 */ - { 98, 7, 12, 0, 0, }, /* 823 */ - { 98, 10, 5, 0, 0, }, /* 824 */ - { 98, 12, 3, 0, 0, }, /* 825 */ - { 98, 6, 12, 0, 0, }, /* 826 */ - { 136, 6, 12, 0, 0, }, /* 827 */ - { 138, 6, 12, 0, 0, }, /* 828 */ - { 136, 7, 12, 0, 0, }, /* 829 */ - { 138, 7, 12, 0, 0, }, /* 830 */ - { 104, 7, 12, 0, 0, }, /* 831 */ - { 104, 26, 12, 0, 0, }, /* 832 */ - { 104, 12, 3, 0, 0, }, /* 833 */ - { 104, 21, 12, 0, 0, }, /* 834 */ - { 9, 10, 3, 0, 0, }, /* 835 */ - { 19, 12, 3, 0, 0, }, /* 836 */ - { 130, 26, 12, 0, 0, }, /* 837 */ - { 130, 12, 3, 0, 0, }, /* 838 */ - { 130, 21, 12, 0, 0, }, /* 839 */ - { 17, 12, 3, 0, 0, }, /* 840 */ - { 112, 7, 12, 0, 0, }, /* 841 */ - { 112, 15, 12, 0, 0, }, /* 842 */ - { 112, 12, 3, 0, 0, }, /* 843 */ - { 131, 9, 12, 0, 34, }, /* 844 */ - { 131, 5, 12, 0, -34, }, /* 845 */ - { 131, 12, 3, 0, 0, }, /* 846 */ - { 131, 13, 12, 0, 0, }, /* 847 */ - { 131, 21, 12, 0, 0, }, /* 848 */ - { 9, 2, 14, 0, 0, }, /* 849 */ - { 9, 26, 11, 0, 0, }, /* 850 */ - { 26, 26, 12, 0, 0, }, /* 851 */ - { 9, 24, 3, 0, 0, }, /* 852 */ - { 9, 1, 3, 0, 0, }, /* 853 */ +/* This table lists the code points for the '9' characters in each +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)[] = { + 61, /* 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, 0x1e959, +}; + +/* This vector is a list of lists of scripts for the Script Extension +property. Each sublist is zero-terminated. */ + +const uint8_t PRIV(ucd_script_sets)[] = { + /* 0 */ 0, + /* 1 */ 1, 11, 0, + /* 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, + /* 37 */ 15, 107, 0, + /* 40 */ 15, 100, 0, + /* 43 */ 15, 54, 0, + /* 46 */ 17, 34, 0, + /* 49 */ 107, 54, 0, + /* 52 */ 21, 108, 0, + /* 55 */ 22, 129, 0, + /* 58 */ 27, 30, 0, + /* 61 */ 38, 65, 0, + /* 64 */ 1, 50, 56, 0, + /* 68 */ 3, 96, 49, 0, + /* 72 */ 96, 39, 53, 0, + /* 76 */ 12, 110, 36, 0, + /* 80 */ 15, 107, 29, 0, + /* 84 */ 15, 107, 34, 0, + /* 88 */ 23, 27, 30, 0, + /* 92 */ 69, 34, 39, 0, + /* 96 */ 1, 144, 50, 56, 0, + /* 101 */ 3, 15, 107, 29, 0, + /* 106 */ 7, 25, 52, 51, 0, + /* 111 */ 15, 142, 85, 111, 0, + /* 116 */ 4, 24, 23, 27, 30, 0, + /* 122 */ 4, 24, 23, 27, 30, 61, 0, + /* 129 */ 15, 29, 37, 44, 54, 55, 0, + /* 136 */ 132, 1, 95, 112, 121, 144, 148, 50, 0, + /* 145 */ 15, 142, 21, 22, 108, 85, 111, 114, 109, 102, 124, 0, + /* 157 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 54, 55, 124, 0, + /* 170 */ 15, 142, 21, 22, 108, 29, 85, 111, 114, 109, 102, 124, 0, + /* 183 */ 3, 15, 107, 21, 22, 29, 34, 37, 44, 100, 54, 55, 124, 0, + /* 197 */ 15, 142, 21, 22, 108, 29, 85, 111, 37, 114, 109, 102, 124, 0, + /* 211 */ 3, 15, 142, 143, 107, 21, 22, 29, 111, 37, 44, 109, 48, 49, 102, 54, 55, 124, 0, + /* 230 */ 3, 15, 142, 143, 107, 21, 22, 29, 35, 111, 37, 44, 109, 48, 49, 102, 54, 55, 124, 0, + /* 250 */ +}; + +/* These are the main two-stage UCD tables. The fields in each record are: +script (8 bits), character type (8 bits), grapheme break property (8 bits), +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)[] = { /* 11136 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 */ + { 10, 0, 0, 0, 0, 10, 0, }, /* 3 */ + { 10, 29, 12, 0, 0, 10, 0, }, /* 4 */ + { 10, 21, 12, 0, 0, 10, 0, }, /* 5 */ + { 10, 23, 12, 0, 0, 10, 0, }, /* 6 */ + { 10, 22, 12, 0, 0, 10, 0, }, /* 7 */ + { 10, 18, 12, 0, 0, 10, 0, }, /* 8 */ + { 10, 25, 12, 0, 0, 10, 0, }, /* 9 */ + { 10, 17, 12, 0, 0, 10, 0, }, /* 10 */ + { 10, 13, 12, 0, 0, 10, 0, }, /* 11 */ + { 34, 9, 12, 0, 32, 34, 0, }, /* 12 */ + { 34, 9, 12, 100, 32, 34, 0, }, /* 13 */ + { 34, 9, 12, 1, 32, 34, 0, }, /* 14 */ + { 10, 24, 12, 0, 0, 10, 0, }, /* 15 */ + { 10, 16, 12, 0, 0, 10, 0, }, /* 16 */ + { 34, 5, 12, 0, -32, 34, 0, }, /* 17 */ + { 34, 5, 12, 100, -32, 34, 0, }, /* 18 */ + { 34, 5, 12, 1, -32, 34, 0, }, /* 19 */ + { 10, 26, 12, 0, 0, 10, 0, }, /* 20 */ + { 10, 26, 14, 0, 0, 10, 0, }, /* 21 */ + { 34, 7, 12, 0, 0, 34, 0, }, /* 22 */ + { 10, 20, 12, 0, 0, 10, 0, }, /* 23 */ + { 10, 1, 2, 0, 0, 10, 0, }, /* 24 */ + { 10, 15, 12, 0, 0, 10, 0, }, /* 25 */ + { 10, 5, 12, 26, 775, 10, 0, }, /* 26 */ + { 10, 19, 12, 0, 0, 10, 0, }, /* 27 */ + { 34, 9, 12, 104, 32, 34, 0, }, /* 28 */ + { 34, 5, 12, 0, 7615, 34, 0, }, /* 29 */ + { 34, 5, 12, 104, -32, 34, 0, }, /* 30 */ + { 34, 5, 12, 0, 121, 34, 0, }, /* 31 */ + { 34, 9, 12, 0, 1, 34, 0, }, /* 32 */ + { 34, 5, 12, 0, -1, 34, 0, }, /* 33 */ + { 34, 9, 12, 0, 0, 34, 0, }, /* 34 */ + { 34, 5, 12, 0, 0, 34, 0, }, /* 35 */ + { 34, 9, 12, 0, -121, 34, 0, }, /* 36 */ + { 34, 5, 12, 1, -268, 34, 0, }, /* 37 */ + { 34, 5, 12, 0, 195, 34, 0, }, /* 38 */ + { 34, 9, 12, 0, 210, 34, 0, }, /* 39 */ + { 34, 9, 12, 0, 206, 34, 0, }, /* 40 */ + { 34, 9, 12, 0, 205, 34, 0, }, /* 41 */ + { 34, 9, 12, 0, 79, 34, 0, }, /* 42 */ + { 34, 9, 12, 0, 202, 34, 0, }, /* 43 */ + { 34, 9, 12, 0, 203, 34, 0, }, /* 44 */ + { 34, 9, 12, 0, 207, 34, 0, }, /* 45 */ + { 34, 5, 12, 0, 97, 34, 0, }, /* 46 */ + { 34, 9, 12, 0, 211, 34, 0, }, /* 47 */ + { 34, 9, 12, 0, 209, 34, 0, }, /* 48 */ + { 34, 5, 12, 0, 163, 34, 0, }, /* 49 */ + { 34, 9, 12, 0, 213, 34, 0, }, /* 50 */ + { 34, 5, 12, 0, 130, 34, 0, }, /* 51 */ + { 34, 9, 12, 0, 214, 34, 0, }, /* 52 */ + { 34, 9, 12, 0, 218, 34, 0, }, /* 53 */ + { 34, 9, 12, 0, 217, 34, 0, }, /* 54 */ + { 34, 9, 12, 0, 219, 34, 0, }, /* 55 */ + { 34, 5, 12, 0, 56, 34, 0, }, /* 56 */ + { 34, 9, 12, 5, 2, 34, 0, }, /* 57 */ + { 34, 8, 12, 5, 1, 34, 0, }, /* 58 */ + { 34, 5, 12, 5, -2, 34, 0, }, /* 59 */ + { 34, 9, 12, 9, 2, 34, 0, }, /* 60 */ + { 34, 8, 12, 9, 1, 34, 0, }, /* 61 */ + { 34, 5, 12, 9, -2, 34, 0, }, /* 62 */ + { 34, 9, 12, 13, 2, 34, 0, }, /* 63 */ + { 34, 8, 12, 13, 1, 34, 0, }, /* 64 */ + { 34, 5, 12, 13, -2, 34, 0, }, /* 65 */ + { 34, 5, 12, 0, -79, 34, 0, }, /* 66 */ + { 34, 9, 12, 17, 2, 34, 0, }, /* 67 */ + { 34, 8, 12, 17, 1, 34, 0, }, /* 68 */ + { 34, 5, 12, 17, -2, 34, 0, }, /* 69 */ + { 34, 9, 12, 0, -97, 34, 0, }, /* 70 */ + { 34, 9, 12, 0, -56, 34, 0, }, /* 71 */ + { 34, 9, 12, 0, -130, 34, 0, }, /* 72 */ + { 34, 9, 12, 0, 10795, 34, 0, }, /* 73 */ + { 34, 9, 12, 0, -163, 34, 0, }, /* 74 */ + { 34, 9, 12, 0, 10792, 34, 0, }, /* 75 */ + { 34, 5, 12, 0, 10815, 34, 0, }, /* 76 */ + { 34, 9, 12, 0, -195, 34, 0, }, /* 77 */ + { 34, 9, 12, 0, 69, 34, 0, }, /* 78 */ + { 34, 9, 12, 0, 71, 34, 0, }, /* 79 */ + { 34, 5, 12, 0, 10783, 34, 0, }, /* 80 */ + { 34, 5, 12, 0, 10780, 34, 0, }, /* 81 */ + { 34, 5, 12, 0, 10782, 34, 0, }, /* 82 */ + { 34, 5, 12, 0, -210, 34, 0, }, /* 83 */ + { 34, 5, 12, 0, -206, 34, 0, }, /* 84 */ + { 34, 5, 12, 0, -205, 34, 0, }, /* 85 */ + { 34, 5, 12, 0, -202, 34, 0, }, /* 86 */ + { 34, 5, 12, 0, -203, 34, 0, }, /* 87 */ + { 34, 5, 12, 0, 42319, 34, 0, }, /* 88 */ + { 34, 5, 12, 0, 42315, 34, 0, }, /* 89 */ + { 34, 5, 12, 0, -207, 34, 0, }, /* 90 */ + { 34, 5, 12, 0, 42280, 34, 0, }, /* 91 */ + { 34, 5, 12, 0, 42308, 34, 0, }, /* 92 */ + { 34, 5, 12, 0, -209, 34, 0, }, /* 93 */ + { 34, 5, 12, 0, -211, 34, 0, }, /* 94 */ + { 34, 5, 12, 0, 10743, 34, 0, }, /* 95 */ + { 34, 5, 12, 0, 42305, 34, 0, }, /* 96 */ + { 34, 5, 12, 0, 10749, 34, 0, }, /* 97 */ + { 34, 5, 12, 0, -213, 34, 0, }, /* 98 */ + { 34, 5, 12, 0, -214, 34, 0, }, /* 99 */ + { 34, 5, 12, 0, 10727, 34, 0, }, /* 100 */ + { 34, 5, 12, 0, -218, 34, 0, }, /* 101 */ + { 34, 5, 12, 0, 42282, 34, 0, }, /* 102 */ + { 34, 5, 12, 0, -69, 34, 0, }, /* 103 */ + { 34, 5, 12, 0, -217, 34, 0, }, /* 104 */ + { 34, 5, 12, 0, -71, 34, 0, }, /* 105 */ + { 34, 5, 12, 0, -219, 34, 0, }, /* 106 */ + { 34, 5, 12, 0, 42261, 34, 0, }, /* 107 */ + { 34, 5, 12, 0, 42258, 34, 0, }, /* 108 */ + { 34, 6, 12, 0, 0, 34, 0, }, /* 109 */ + { 10, 6, 12, 0, 0, 10, 0, }, /* 110 */ + { 4, 24, 12, 0, 0, 4, 0, }, /* 111 */ + { 28, 12, 3, 0, 0, 28, 0, }, /* 112 */ + { 28, 12, 3, 0, 0, 20, 0, }, /* 113 */ + { 28, 12, 3, 21, 116, 20, 0, }, /* 114 */ + { 28, 12, 3, 0, 0, 34, 0, }, /* 115 */ + { 20, 9, 12, 0, 1, 20, 0, }, /* 116 */ + { 20, 5, 12, 0, -1, 20, 0, }, /* 117 */ + { 20, 24, 12, 0, 0, 20, 0, }, /* 118 */ + { 0, 2, 12, 0, 0, 0, 0, }, /* 119 */ + { 20, 6, 12, 0, 0, 20, 0, }, /* 120 */ + { 20, 5, 12, 0, 130, 20, 0, }, /* 121 */ + { 20, 9, 12, 0, 116, 20, 0, }, /* 122 */ + { 20, 9, 12, 0, 38, 20, 0, }, /* 123 */ + { 20, 9, 12, 0, 37, 20, 0, }, /* 124 */ + { 20, 9, 12, 0, 64, 20, 0, }, /* 125 */ + { 20, 9, 12, 0, 63, 20, 0, }, /* 126 */ + { 20, 5, 12, 0, 0, 20, 0, }, /* 127 */ + { 20, 9, 12, 0, 32, 20, 0, }, /* 128 */ + { 20, 9, 12, 34, 32, 20, 0, }, /* 129 */ + { 20, 9, 12, 59, 32, 20, 0, }, /* 130 */ + { 20, 9, 12, 38, 32, 20, 0, }, /* 131 */ + { 20, 9, 12, 21, 32, 20, 0, }, /* 132 */ + { 20, 9, 12, 51, 32, 20, 0, }, /* 133 */ + { 20, 9, 12, 26, 32, 20, 0, }, /* 134 */ + { 20, 9, 12, 47, 32, 20, 0, }, /* 135 */ + { 20, 9, 12, 55, 32, 20, 0, }, /* 136 */ + { 20, 9, 12, 30, 32, 20, 0, }, /* 137 */ + { 20, 9, 12, 43, 32, 20, 0, }, /* 138 */ + { 20, 9, 12, 96, 32, 20, 0, }, /* 139 */ + { 20, 5, 12, 0, -38, 20, 0, }, /* 140 */ + { 20, 5, 12, 0, -37, 20, 0, }, /* 141 */ + { 20, 5, 12, 0, -32, 20, 0, }, /* 142 */ + { 20, 5, 12, 34, -32, 20, 0, }, /* 143 */ + { 20, 5, 12, 59, -32, 20, 0, }, /* 144 */ + { 20, 5, 12, 38, -32, 20, 0, }, /* 145 */ + { 20, 5, 12, 21, -116, 20, 0, }, /* 146 */ + { 20, 5, 12, 51, -32, 20, 0, }, /* 147 */ + { 20, 5, 12, 26, -775, 20, 0, }, /* 148 */ + { 20, 5, 12, 47, -32, 20, 0, }, /* 149 */ + { 20, 5, 12, 55, -32, 20, 0, }, /* 150 */ + { 20, 5, 12, 30, 1, 20, 0, }, /* 151 */ + { 20, 5, 12, 30, -32, 20, 0, }, /* 152 */ + { 20, 5, 12, 43, -32, 20, 0, }, /* 153 */ + { 20, 5, 12, 96, -32, 20, 0, }, /* 154 */ + { 20, 5, 12, 0, -64, 20, 0, }, /* 155 */ + { 20, 5, 12, 0, -63, 20, 0, }, /* 156 */ + { 20, 9, 12, 0, 8, 20, 0, }, /* 157 */ + { 20, 5, 12, 34, -30, 20, 0, }, /* 158 */ + { 20, 5, 12, 38, -25, 20, 0, }, /* 159 */ + { 20, 9, 12, 0, 0, 20, 0, }, /* 160 */ + { 20, 5, 12, 43, -15, 20, 0, }, /* 161 */ + { 20, 5, 12, 47, -22, 20, 0, }, /* 162 */ + { 20, 5, 12, 0, -8, 20, 0, }, /* 163 */ + { 11, 9, 12, 0, 1, 11, 0, }, /* 164 */ + { 11, 5, 12, 0, -1, 11, 0, }, /* 165 */ + { 20, 5, 12, 51, -54, 20, 0, }, /* 166 */ + { 20, 5, 12, 55, -48, 20, 0, }, /* 167 */ + { 20, 5, 12, 0, 7, 20, 0, }, /* 168 */ + { 20, 5, 12, 0, -116, 20, 0, }, /* 169 */ + { 20, 9, 12, 38, -60, 20, 0, }, /* 170 */ + { 20, 5, 12, 59, -64, 20, 0, }, /* 171 */ + { 20, 25, 12, 0, 0, 20, 0, }, /* 172 */ + { 20, 9, 12, 0, -7, 20, 0, }, /* 173 */ + { 20, 9, 12, 0, -130, 20, 0, }, /* 174 */ + { 13, 9, 12, 0, 80, 13, 0, }, /* 175 */ + { 13, 9, 12, 0, 32, 13, 0, }, /* 176 */ + { 13, 9, 12, 63, 32, 13, 0, }, /* 177 */ + { 13, 9, 12, 67, 32, 13, 0, }, /* 178 */ + { 13, 9, 12, 71, 32, 13, 0, }, /* 179 */ + { 13, 9, 12, 75, 32, 13, 0, }, /* 180 */ + { 13, 9, 12, 79, 32, 13, 0, }, /* 181 */ + { 13, 9, 12, 84, 32, 13, 0, }, /* 182 */ + { 13, 5, 12, 0, -32, 13, 0, }, /* 183 */ + { 13, 5, 12, 63, -32, 13, 0, }, /* 184 */ + { 13, 5, 12, 67, -32, 13, 0, }, /* 185 */ + { 13, 5, 12, 71, -32, 13, 0, }, /* 186 */ + { 13, 5, 12, 75, -32, 13, 0, }, /* 187 */ + { 13, 5, 12, 79, -32, 13, 0, }, /* 188 */ + { 13, 5, 12, 84, -32, 13, 0, }, /* 189 */ + { 13, 5, 12, 0, -80, 13, 0, }, /* 190 */ + { 13, 9, 12, 0, 1, 13, 0, }, /* 191 */ + { 13, 5, 12, 0, -1, 13, 0, }, /* 192 */ + { 13, 9, 12, 88, 1, 13, 0, }, /* 193 */ + { 13, 5, 12, 88, -1, 13, 0, }, /* 194 */ + { 13, 26, 12, 0, 0, 13, 0, }, /* 195 */ + { 13, 12, 3, 0, 0, -34, 0, }, /* 196 */ + { 13, 12, 3, 0, 0, -28, 0, }, /* 197 */ + { 28, 12, 3, 0, 0, -31, 0, }, /* 198 */ + { 13, 11, 3, 0, 0, 13, 0, }, /* 199 */ + { 13, 9, 12, 0, 15, 13, 0, }, /* 200 */ + { 13, 5, 12, 0, -15, 13, 0, }, /* 201 */ + { 2, 9, 12, 0, 48, 2, 0, }, /* 202 */ + { 2, 6, 12, 0, 0, 2, 0, }, /* 203 */ + { 2, 21, 12, 0, 0, 2, 0, }, /* 204 */ + { 2, 5, 12, 0, 0, 2, 0, }, /* 205 */ + { 2, 5, 12, 0, -48, 2, 0, }, /* 206 */ + { 10, 21, 12, 0, 0, -13, 0, }, /* 207 */ + { 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, -96, 0, }, /* 220 */ + { 1, 26, 12, 0, 0, 1, 0, }, /* 221 */ + { 1, 12, 3, 0, 0, 1, 0, }, /* 222 */ + { 1, 1, 2, 0, 0, -64, 0, }, /* 223 */ + { 1, 7, 12, 0, 0, 1, 0, }, /* 224 */ + { 10, 6, 12, 0, 0, -136, 0, }, /* 225 */ + { 28, 12, 3, 0, 0, -7, 0, }, /* 226 */ + { 1, 13, 12, 0, 0, -10, 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, -183, 0, }, /* 254 */ + { 28, 12, 3, 0, 0, -157, 0, }, /* 255 */ + { 10, 21, 12, 0, 0, -211, 0, }, /* 256 */ + { 10, 21, 12, 0, 0, -230, 0, }, /* 257 */ + { 15, 13, 12, 0, 0, -111, 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, -68, 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, -55, 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, -52, 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, -49, 0, }, /* 292 */ + { 54, 15, 12, 0, 0, -49, 0, }, /* 293 */ + { 54, 26, 12, 0, 0, -49, 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, 15, 12, 0, 0, 55, 0, }, /* 301 */ + { 55, 26, 12, 0, 0, 55, 0, }, /* 302 */ + { 29, 7, 12, 0, 0, 29, 0, }, /* 303 */ + { 29, 12, 3, 0, 0, 29, 0, }, /* 304 */ + { 29, 10, 5, 0, 0, 29, 0, }, /* 305 */ + { 29, 21, 12, 0, 0, 29, 0, }, /* 306 */ + { 29, 10, 3, 0, 0, 29, 0, }, /* 307 */ + { 29, 13, 12, 0, 0, 29, 0, }, /* 308 */ + { 37, 12, 3, 0, 0, 37, 0, }, /* 309 */ + { 37, 10, 5, 0, 0, 37, 0, }, /* 310 */ + { 37, 7, 12, 0, 0, 37, 0, }, /* 311 */ + { 37, 10, 3, 0, 0, 37, 0, }, /* 312 */ + { 37, 7, 4, 0, 0, 37, 0, }, /* 313 */ + { 37, 26, 12, 0, 0, 37, 0, }, /* 314 */ + { 37, 15, 12, 0, 0, 37, 0, }, /* 315 */ + { 37, 13, 12, 0, 0, 37, 0, }, /* 316 */ + { 48, 10, 5, 0, 0, 48, 0, }, /* 317 */ + { 48, 7, 12, 0, 0, 48, 0, }, /* 318 */ + { 48, 12, 3, 0, 0, 48, 0, }, /* 319 */ + { 48, 10, 3, 0, 0, 48, 0, }, /* 320 */ + { 48, 13, 12, 0, 0, 48, 0, }, /* 321 */ + { 48, 21, 12, 0, 0, 48, 0, }, /* 322 */ + { 57, 7, 12, 0, 0, 57, 0, }, /* 323 */ + { 57, 12, 3, 0, 0, 57, 0, }, /* 324 */ + { 57, 7, 5, 0, 0, 57, 0, }, /* 325 */ + { 57, 6, 12, 0, 0, 57, 0, }, /* 326 */ + { 57, 21, 12, 0, 0, 57, 0, }, /* 327 */ + { 57, 13, 12, 0, 0, 57, 0, }, /* 328 */ + { 33, 7, 12, 0, 0, 33, 0, }, /* 329 */ + { 33, 12, 3, 0, 0, 33, 0, }, /* 330 */ + { 33, 7, 5, 0, 0, 33, 0, }, /* 331 */ + { 33, 6, 12, 0, 0, 33, 0, }, /* 332 */ + { 33, 13, 12, 0, 0, 33, 0, }, /* 333 */ + { 58, 7, 12, 0, 0, 58, 0, }, /* 334 */ + { 58, 26, 12, 0, 0, 58, 0, }, /* 335 */ + { 58, 21, 12, 0, 0, 58, 0, }, /* 336 */ + { 58, 12, 3, 0, 0, 58, 0, }, /* 337 */ + { 58, 13, 12, 0, 0, 58, 0, }, /* 338 */ + { 58, 15, 12, 0, 0, 58, 0, }, /* 339 */ + { 58, 22, 12, 0, 0, 58, 0, }, /* 340 */ + { 58, 18, 12, 0, 0, 58, 0, }, /* 341 */ + { 58, 10, 5, 0, 0, 58, 0, }, /* 342 */ + { 39, 7, 12, 0, 0, 39, 0, }, /* 343 */ + { 39, 10, 12, 0, 0, 39, 0, }, /* 344 */ + { 39, 12, 3, 0, 0, 39, 0, }, /* 345 */ + { 39, 10, 5, 0, 0, 39, 0, }, /* 346 */ + { 39, 13, 12, 0, 0, -72, 0, }, /* 347 */ + { 39, 21, 12, 0, 0, 39, 0, }, /* 348 */ + { 39, 13, 12, 0, 0, 39, 0, }, /* 349 */ + { 39, 26, 12, 0, 0, 39, 0, }, /* 350 */ + { 17, 9, 12, 0, 7264, 17, 0, }, /* 351 */ + { 17, 5, 12, 0, 3008, 17, 0, }, /* 352 */ + { 10, 21, 12, 0, 0, -46, 0, }, /* 353 */ + { 17, 6, 12, 0, 0, 17, 0, }, /* 354 */ + { 24, 7, 6, 0, 0, 24, 0, }, /* 355 */ + { 24, 7, 7, 0, 0, 24, 0, }, /* 356 */ + { 24, 7, 8, 0, 0, 24, 0, }, /* 357 */ + { 16, 7, 12, 0, 0, 16, 0, }, /* 358 */ + { 16, 12, 3, 0, 0, 16, 0, }, /* 359 */ + { 16, 21, 12, 0, 0, 16, 0, }, /* 360 */ + { 16, 15, 12, 0, 0, 16, 0, }, /* 361 */ + { 16, 26, 12, 0, 0, 16, 0, }, /* 362 */ + { 9, 9, 12, 0, 38864, 9, 0, }, /* 363 */ + { 9, 9, 12, 0, 8, 9, 0, }, /* 364 */ + { 9, 5, 12, 0, -8, 9, 0, }, /* 365 */ + { 8, 17, 12, 0, 0, 8, 0, }, /* 366 */ + { 8, 7, 12, 0, 0, 8, 0, }, /* 367 */ + { 8, 21, 12, 0, 0, 8, 0, }, /* 368 */ + { 41, 29, 12, 0, 0, 41, 0, }, /* 369 */ + { 41, 7, 12, 0, 0, 41, 0, }, /* 370 */ + { 41, 22, 12, 0, 0, 41, 0, }, /* 371 */ + { 41, 18, 12, 0, 0, 41, 0, }, /* 372 */ + { 46, 7, 12, 0, 0, 46, 0, }, /* 373 */ + { 46, 14, 12, 0, 0, 46, 0, }, /* 374 */ + { 51, 7, 12, 0, 0, 51, 0, }, /* 375 */ + { 51, 12, 3, 0, 0, 51, 0, }, /* 376 */ + { 25, 7, 12, 0, 0, 25, 0, }, /* 377 */ + { 25, 12, 3, 0, 0, 25, 0, }, /* 378 */ + { 10, 21, 12, 0, 0, -106, 0, }, /* 379 */ + { 7, 7, 12, 0, 0, 7, 0, }, /* 380 */ + { 7, 12, 3, 0, 0, 7, 0, }, /* 381 */ + { 52, 7, 12, 0, 0, 52, 0, }, /* 382 */ + { 52, 12, 3, 0, 0, 52, 0, }, /* 383 */ + { 32, 7, 12, 0, 0, 32, 0, }, /* 384 */ + { 32, 12, 3, 0, 0, 32, 0, }, /* 385 */ + { 32, 10, 5, 0, 0, 32, 0, }, /* 386 */ + { 32, 21, 12, 0, 0, 32, 0, }, /* 387 */ + { 32, 6, 12, 0, 0, 32, 0, }, /* 388 */ + { 32, 23, 12, 0, 0, 32, 0, }, /* 389 */ + { 32, 13, 12, 0, 0, 32, 0, }, /* 390 */ + { 32, 15, 12, 0, 0, 32, 0, }, /* 391 */ + { 38, 21, 12, 0, 0, 38, 0, }, /* 392 */ + { 10, 21, 12, 0, 0, -61, 0, }, /* 393 */ + { 38, 17, 12, 0, 0, 38, 0, }, /* 394 */ + { 38, 12, 3, 0, 0, 38, 0, }, /* 395 */ + { 38, 1, 2, 0, 0, 38, 0, }, /* 396 */ + { 38, 13, 12, 0, 0, 38, 0, }, /* 397 */ + { 38, 7, 12, 0, 0, 38, 0, }, /* 398 */ + { 38, 6, 12, 0, 0, 38, 0, }, /* 399 */ + { 35, 7, 12, 0, 0, 35, 0, }, /* 400 */ + { 35, 12, 3, 0, 0, 35, 0, }, /* 401 */ + { 35, 10, 5, 0, 0, 35, 0, }, /* 402 */ + { 35, 26, 12, 0, 0, 35, 0, }, /* 403 */ + { 35, 21, 12, 0, 0, 35, 0, }, /* 404 */ + { 35, 13, 12, 0, 0, 35, 0, }, /* 405 */ + { 53, 7, 12, 0, 0, 53, 0, }, /* 406 */ + { 40, 7, 12, 0, 0, 40, 0, }, /* 407 */ + { 40, 13, 12, 0, 0, 40, 0, }, /* 408 */ + { 40, 15, 12, 0, 0, 40, 0, }, /* 409 */ + { 40, 26, 12, 0, 0, 40, 0, }, /* 410 */ + { 32, 26, 12, 0, 0, 32, 0, }, /* 411 */ + { 6, 7, 12, 0, 0, 6, 0, }, /* 412 */ + { 6, 12, 3, 0, 0, 6, 0, }, /* 413 */ + { 6, 10, 5, 0, 0, 6, 0, }, /* 414 */ + { 6, 21, 12, 0, 0, 6, 0, }, /* 415 */ + { 91, 7, 12, 0, 0, 91, 0, }, /* 416 */ + { 91, 10, 5, 0, 0, 91, 0, }, /* 417 */ + { 91, 12, 3, 0, 0, 91, 0, }, /* 418 */ + { 91, 10, 12, 0, 0, 91, 0, }, /* 419 */ + { 91, 13, 12, 0, 0, 91, 0, }, /* 420 */ + { 91, 21, 12, 0, 0, 91, 0, }, /* 421 */ + { 91, 6, 12, 0, 0, 91, 0, }, /* 422 */ + { 28, 11, 3, 0, 0, 28, 0, }, /* 423 */ + { 62, 12, 3, 0, 0, 62, 0, }, /* 424 */ + { 62, 10, 5, 0, 0, 62, 0, }, /* 425 */ + { 62, 7, 12, 0, 0, 62, 0, }, /* 426 */ + { 62, 13, 12, 0, 0, 62, 0, }, /* 427 */ + { 62, 21, 12, 0, 0, 62, 0, }, /* 428 */ + { 62, 26, 12, 0, 0, 62, 0, }, /* 429 */ + { 76, 12, 3, 0, 0, 76, 0, }, /* 430 */ + { 76, 10, 5, 0, 0, 76, 0, }, /* 431 */ + { 76, 7, 12, 0, 0, 76, 0, }, /* 432 */ + { 76, 13, 12, 0, 0, 76, 0, }, /* 433 */ + { 93, 7, 12, 0, 0, 93, 0, }, /* 434 */ + { 93, 12, 3, 0, 0, 93, 0, }, /* 435 */ + { 93, 10, 5, 0, 0, 93, 0, }, /* 436 */ + { 93, 21, 12, 0, 0, 93, 0, }, /* 437 */ + { 70, 7, 12, 0, 0, 70, 0, }, /* 438 */ + { 70, 10, 5, 0, 0, 70, 0, }, /* 439 */ + { 70, 12, 3, 0, 0, 70, 0, }, /* 440 */ + { 70, 21, 12, 0, 0, 70, 0, }, /* 441 */ + { 70, 13, 12, 0, 0, 70, 0, }, /* 442 */ + { 73, 13, 12, 0, 0, 73, 0, }, /* 443 */ + { 73, 7, 12, 0, 0, 73, 0, }, /* 444 */ + { 73, 6, 12, 0, 0, 73, 0, }, /* 445 */ + { 73, 21, 12, 0, 0, 73, 0, }, /* 446 */ + { 13, 5, 12, 63, -6222, 13, 0, }, /* 447 */ + { 13, 5, 12, 67, -6221, 13, 0, }, /* 448 */ + { 13, 5, 12, 71, -6212, 13, 0, }, /* 449 */ + { 13, 5, 12, 75, -6210, 13, 0, }, /* 450 */ + { 13, 5, 12, 79, -6210, 13, 0, }, /* 451 */ + { 13, 5, 12, 79, -6211, 13, 0, }, /* 452 */ + { 13, 5, 12, 84, -6204, 13, 0, }, /* 453 */ + { 13, 5, 12, 88, -6180, 13, 0, }, /* 454 */ + { 13, 5, 12, 108, 35267, 13, 0, }, /* 455 */ + { 17, 9, 12, 0, -3008, 17, 0, }, /* 456 */ + { 76, 21, 12, 0, 0, 76, 0, }, /* 457 */ + { 28, 12, 3, 0, 0, -101, 0, }, /* 458 */ + { 28, 12, 3, 0, 0, 15, 0, }, /* 459 */ + { 10, 21, 12, 0, 0, -37, 0, }, /* 460 */ + { 28, 12, 3, 0, 0, -16, 0, }, /* 461 */ + { 28, 12, 3, 0, 0, -40, 0, }, /* 462 */ + { 28, 12, 3, 0, 0, -129, 0, }, /* 463 */ + { 10, 10, 5, 0, 0, -16, 0, }, /* 464 */ + { 10, 7, 12, 0, 0, 15, 0, }, /* 465 */ + { 10, 7, 12, 0, 0, -16, 0, }, /* 466 */ + { 10, 10, 5, 0, 0, -37, 0, }, /* 467 */ + { 28, 12, 3, 0, 0, -80, 0, }, /* 468 */ + { 10, 10, 5, 0, 0, 3, 0, }, /* 469 */ + { 28, 12, 3, 0, 0, -37, 0, }, /* 470 */ + { 13, 5, 12, 0, 0, 13, 0, }, /* 471 */ + { 13, 6, 12, 0, 0, 13, 0, }, /* 472 */ + { 34, 5, 12, 0, 35332, 34, 0, }, /* 473 */ + { 34, 5, 12, 0, 3814, 34, 0, }, /* 474 */ + { 34, 9, 12, 92, 1, 34, 0, }, /* 475 */ + { 34, 5, 12, 92, -1, 34, 0, }, /* 476 */ + { 34, 5, 12, 92, -58, 34, 0, }, /* 477 */ + { 34, 9, 12, 0, -7615, 34, 0, }, /* 478 */ + { 20, 5, 12, 0, 8, 20, 0, }, /* 479 */ + { 20, 9, 12, 0, -8, 20, 0, }, /* 480 */ + { 20, 5, 12, 0, 74, 20, 0, }, /* 481 */ + { 20, 5, 12, 0, 86, 20, 0, }, /* 482 */ + { 20, 5, 12, 0, 100, 20, 0, }, /* 483 */ + { 20, 5, 12, 0, 128, 20, 0, }, /* 484 */ + { 20, 5, 12, 0, 112, 20, 0, }, /* 485 */ + { 20, 5, 12, 0, 126, 20, 0, }, /* 486 */ + { 20, 8, 12, 0, -8, 20, 0, }, /* 487 */ + { 20, 5, 12, 0, 9, 20, 0, }, /* 488 */ + { 20, 9, 12, 0, -74, 20, 0, }, /* 489 */ + { 20, 8, 12, 0, -9, 20, 0, }, /* 490 */ + { 20, 5, 12, 21, -7173, 20, 0, }, /* 491 */ + { 20, 9, 12, 0, -86, 20, 0, }, /* 492 */ + { 20, 9, 12, 0, -100, 20, 0, }, /* 493 */ + { 20, 9, 12, 0, -112, 20, 0, }, /* 494 */ + { 20, 9, 12, 0, -128, 20, 0, }, /* 495 */ + { 20, 9, 12, 0, -126, 20, 0, }, /* 496 */ + { 28, 1, 3, 0, 0, 28, 0, }, /* 497 */ + { 28, 1, 13, 0, 0, 28, 0, }, /* 498 */ + { 10, 27, 2, 0, 0, 10, 0, }, /* 499 */ + { 10, 28, 2, 0, 0, 10, 0, }, /* 500 */ + { 10, 21, 14, 0, 0, 10, 0, }, /* 501 */ + { 0, 2, 2, 0, 0, 0, 0, }, /* 502 */ + { 28, 12, 3, 0, 0, -84, 0, }, /* 503 */ + { 10, 9, 12, 0, 0, 10, 0, }, /* 504 */ + { 10, 5, 12, 0, 0, 10, 0, }, /* 505 */ + { 20, 9, 12, 96, -7517, 20, 0, }, /* 506 */ + { 34, 9, 12, 100, -8383, 34, 0, }, /* 507 */ + { 34, 9, 12, 104, -8262, 34, 0, }, /* 508 */ + { 34, 9, 12, 0, 28, 34, 0, }, /* 509 */ + { 10, 7, 12, 0, 0, 10, 0, }, /* 510 */ + { 10, 5, 14, 0, 0, 10, 0, }, /* 511 */ + { 34, 5, 12, 0, -28, 34, 0, }, /* 512 */ + { 34, 14, 12, 0, 16, 34, 0, }, /* 513 */ + { 34, 14, 12, 0, -16, 34, 0, }, /* 514 */ + { 34, 14, 12, 0, 0, 34, 0, }, /* 515 */ + { 10, 25, 14, 0, 0, 10, 0, }, /* 516 */ + { 10, 26, 12, 0, 26, 10, 0, }, /* 517 */ + { 10, 26, 14, 0, 26, 10, 0, }, /* 518 */ + { 10, 26, 12, 0, -26, 10, 0, }, /* 519 */ + { 5, 26, 12, 0, 0, 5, 0, }, /* 520 */ + { 18, 9, 12, 0, 48, 18, 0, }, /* 521 */ + { 18, 5, 12, 0, -48, 18, 0, }, /* 522 */ + { 34, 9, 12, 0, -10743, 34, 0, }, /* 523 */ + { 34, 9, 12, 0, -3814, 34, 0, }, /* 524 */ + { 34, 9, 12, 0, -10727, 34, 0, }, /* 525 */ + { 34, 5, 12, 0, -10795, 34, 0, }, /* 526 */ + { 34, 5, 12, 0, -10792, 34, 0, }, /* 527 */ + { 34, 9, 12, 0, -10780, 34, 0, }, /* 528 */ + { 34, 9, 12, 0, -10749, 34, 0, }, /* 529 */ + { 34, 9, 12, 0, -10783, 34, 0, }, /* 530 */ + { 34, 9, 12, 0, -10782, 34, 0, }, /* 531 */ + { 34, 9, 12, 0, -10815, 34, 0, }, /* 532 */ + { 11, 5, 12, 0, 0, 11, 0, }, /* 533 */ + { 11, 26, 12, 0, 0, 11, 0, }, /* 534 */ + { 11, 12, 3, 0, 0, 11, 0, }, /* 535 */ + { 11, 21, 12, 0, 0, 11, 0, }, /* 536 */ + { 11, 15, 12, 0, 0, 11, 0, }, /* 537 */ + { 17, 5, 12, 0, -7264, 17, 0, }, /* 538 */ + { 59, 7, 12, 0, 0, 59, 0, }, /* 539 */ + { 59, 6, 12, 0, 0, 59, 0, }, /* 540 */ + { 59, 21, 12, 0, 0, 59, 0, }, /* 541 */ + { 59, 12, 3, 0, 0, 59, 0, }, /* 542 */ + { 13, 12, 3, 0, 0, 13, 0, }, /* 543 */ + { 10, 21, 12, 0, 0, -28, 0, }, /* 544 */ + { 23, 26, 12, 0, 0, 23, 0, }, /* 545 */ + { 10, 21, 12, 0, 0, -122, 0, }, /* 546 */ + { 10, 21, 12, 0, 0, -116, 0, }, /* 547 */ + { 23, 6, 12, 0, 0, 23, 0, }, /* 548 */ + { 10, 7, 12, 0, 0, 23, 0, }, /* 549 */ + { 23, 14, 12, 0, 0, 23, 0, }, /* 550 */ + { 10, 22, 12, 0, 0, -122, 0, }, /* 551 */ + { 10, 18, 12, 0, 0, -122, 0, }, /* 552 */ + { 10, 26, 12, 0, 0, -116, 0, }, /* 553 */ + { 10, 17, 12, 0, 0, -116, 0, }, /* 554 */ + { 10, 22, 12, 0, 0, -116, 0, }, /* 555 */ + { 10, 18, 12, 0, 0, -116, 0, }, /* 556 */ + { 28, 12, 3, 0, 0, -19, 0, }, /* 557 */ + { 24, 10, 3, 0, 0, 24, 0, }, /* 558 */ + { 10, 17, 14, 0, 0, -116, 0, }, /* 559 */ + { 10, 6, 12, 0, 0, -58, 0, }, /* 560 */ + { 10, 7, 12, 0, 0, -88, 0, }, /* 561 */ + { 10, 21, 14, 0, 0, -88, 0, }, /* 562 */ + { 10, 26, 12, 0, 0, 23, 0, }, /* 563 */ + { 27, 7, 12, 0, 0, 27, 0, }, /* 564 */ + { 28, 12, 3, 0, 0, -58, 0, }, /* 565 */ + { 10, 24, 12, 0, 0, -58, 0, }, /* 566 */ + { 27, 6, 12, 0, 0, 27, 0, }, /* 567 */ + { 10, 17, 12, 0, 0, -58, 0, }, /* 568 */ + { 30, 7, 12, 0, 0, 30, 0, }, /* 569 */ + { 30, 6, 12, 0, 0, 30, 0, }, /* 570 */ + { 4, 7, 12, 0, 0, 4, 0, }, /* 571 */ + { 24, 7, 12, 0, 0, 24, 0, }, /* 572 */ + { 10, 15, 12, 0, 0, 23, 0, }, /* 573 */ + { 24, 26, 12, 0, 0, 24, 0, }, /* 574 */ + { 10, 26, 14, 0, 0, 23, 0, }, /* 575 */ + { 30, 26, 12, 0, 0, 30, 0, }, /* 576 */ + { 23, 7, 12, 0, 0, 23, 0, }, /* 577 */ + { 61, 7, 12, 0, 0, 61, 0, }, /* 578 */ + { 61, 6, 12, 0, 0, 61, 0, }, /* 579 */ + { 61, 26, 12, 0, 0, 61, 0, }, /* 580 */ + { 86, 7, 12, 0, 0, 86, 0, }, /* 581 */ + { 86, 6, 12, 0, 0, 86, 0, }, /* 582 */ + { 86, 21, 12, 0, 0, 86, 0, }, /* 583 */ + { 77, 7, 12, 0, 0, 77, 0, }, /* 584 */ + { 77, 6, 12, 0, 0, 77, 0, }, /* 585 */ + { 77, 21, 12, 0, 0, 77, 0, }, /* 586 */ + { 77, 13, 12, 0, 0, 77, 0, }, /* 587 */ + { 13, 9, 12, 108, 1, 13, 0, }, /* 588 */ + { 13, 5, 12, 108, -35267, 13, 0, }, /* 589 */ + { 13, 7, 12, 0, 0, 13, 0, }, /* 590 */ + { 13, 21, 12, 0, 0, 13, 0, }, /* 591 */ + { 79, 7, 12, 0, 0, 79, 0, }, /* 592 */ + { 79, 14, 12, 0, 0, 79, 0, }, /* 593 */ + { 79, 12, 3, 0, 0, 79, 0, }, /* 594 */ + { 79, 21, 12, 0, 0, 79, 0, }, /* 595 */ + { 34, 9, 12, 0, -35332, 34, 0, }, /* 596 */ + { 34, 9, 12, 0, -42280, 34, 0, }, /* 597 */ + { 34, 9, 12, 0, -42308, 34, 0, }, /* 598 */ + { 34, 9, 12, 0, -42319, 34, 0, }, /* 599 */ + { 34, 9, 12, 0, -42315, 34, 0, }, /* 600 */ + { 34, 9, 12, 0, -42305, 34, 0, }, /* 601 */ + { 34, 9, 12, 0, -42258, 34, 0, }, /* 602 */ + { 34, 9, 12, 0, -42282, 34, 0, }, /* 603 */ + { 34, 9, 12, 0, -42261, 34, 0, }, /* 604 */ + { 34, 9, 12, 0, 928, 34, 0, }, /* 605 */ + { 49, 7, 12, 0, 0, 49, 0, }, /* 606 */ + { 49, 12, 3, 0, 0, 49, 0, }, /* 607 */ + { 49, 10, 5, 0, 0, 49, 0, }, /* 608 */ + { 49, 26, 12, 0, 0, 49, 0, }, /* 609 */ + { 10, 15, 12, 0, 0, -197, 0, }, /* 610 */ + { 10, 15, 12, 0, 0, -170, 0, }, /* 611 */ + { 10, 26, 12, 0, 0, -145, 0, }, /* 612 */ + { 10, 23, 12, 0, 0, -145, 0, }, /* 613 */ + { 65, 7, 12, 0, 0, 65, 0, }, /* 614 */ + { 65, 21, 12, 0, 0, 65, 0, }, /* 615 */ + { 75, 10, 5, 0, 0, 75, 0, }, /* 616 */ + { 75, 7, 12, 0, 0, 75, 0, }, /* 617 */ + { 75, 12, 3, 0, 0, 75, 0, }, /* 618 */ + { 75, 21, 12, 0, 0, 75, 0, }, /* 619 */ + { 75, 13, 12, 0, 0, 75, 0, }, /* 620 */ + { 15, 12, 3, 0, 0, -16, 0, }, /* 621 */ + { 15, 7, 12, 0, 0, -43, 0, }, /* 622 */ + { 69, 13, 12, 0, 0, 69, 0, }, /* 623 */ + { 69, 7, 12, 0, 0, 69, 0, }, /* 624 */ + { 69, 12, 3, 0, 0, 69, 0, }, /* 625 */ + { 10, 21, 12, 0, 0, -92, 0, }, /* 626 */ + { 69, 21, 12, 0, 0, 69, 0, }, /* 627 */ + { 74, 7, 12, 0, 0, 74, 0, }, /* 628 */ + { 74, 12, 3, 0, 0, 74, 0, }, /* 629 */ + { 74, 10, 5, 0, 0, 74, 0, }, /* 630 */ + { 74, 21, 12, 0, 0, 74, 0, }, /* 631 */ + { 84, 12, 3, 0, 0, 84, 0, }, /* 632 */ + { 84, 10, 5, 0, 0, 84, 0, }, /* 633 */ + { 84, 7, 12, 0, 0, 84, 0, }, /* 634 */ + { 84, 21, 12, 0, 0, 84, 0, }, /* 635 */ + { 10, 6, 12, 0, 0, -22, 0, }, /* 636 */ + { 84, 13, 12, 0, 0, 84, 0, }, /* 637 */ + { 39, 6, 12, 0, 0, 39, 0, }, /* 638 */ + { 68, 7, 12, 0, 0, 68, 0, }, /* 639 */ + { 68, 12, 3, 0, 0, 68, 0, }, /* 640 */ + { 68, 10, 5, 0, 0, 68, 0, }, /* 641 */ + { 68, 13, 12, 0, 0, 68, 0, }, /* 642 */ + { 68, 21, 12, 0, 0, 68, 0, }, /* 643 */ + { 92, 7, 12, 0, 0, 92, 0, }, /* 644 */ + { 92, 12, 3, 0, 0, 92, 0, }, /* 645 */ + { 92, 6, 12, 0, 0, 92, 0, }, /* 646 */ + { 92, 21, 12, 0, 0, 92, 0, }, /* 647 */ + { 87, 7, 12, 0, 0, 87, 0, }, /* 648 */ + { 87, 10, 5, 0, 0, 87, 0, }, /* 649 */ + { 87, 12, 3, 0, 0, 87, 0, }, /* 650 */ + { 87, 21, 12, 0, 0, 87, 0, }, /* 651 */ + { 87, 6, 12, 0, 0, 87, 0, }, /* 652 */ + { 34, 5, 12, 0, -928, 34, 0, }, /* 653 */ + { 9, 5, 12, 0, -38864, 9, 0, }, /* 654 */ + { 87, 13, 12, 0, 0, 87, 0, }, /* 655 */ + { 24, 7, 9, 0, 0, 24, 0, }, /* 656 */ + { 24, 7, 10, 0, 0, 24, 0, }, /* 657 */ + { 0, 4, 2, 0, 0, 0, 0, }, /* 658 */ + { 0, 3, 12, 0, 0, 0, 0, }, /* 659 */ + { 26, 25, 12, 0, 0, 26, 0, }, /* 660 */ + { 1, 24, 12, 0, 0, 1, 0, }, /* 661 */ + { 1, 7, 12, 0, 0, -10, 0, }, /* 662 */ + { 1, 26, 12, 0, 0, -10, 0, }, /* 663 */ + { 10, 6, 3, 0, 0, -58, 0, }, /* 664 */ + { 36, 7, 12, 0, 0, 36, 0, }, /* 665 */ + { 10, 21, 12, 0, 0, -25, 0, }, /* 666 */ + { 10, 15, 12, 0, 0, -76, 0, }, /* 667 */ + { 10, 26, 12, 0, 0, -25, 0, }, /* 668 */ + { 20, 14, 12, 0, 0, 20, 0, }, /* 669 */ + { 20, 15, 12, 0, 0, 20, 0, }, /* 670 */ + { 20, 26, 12, 0, 0, 20, 0, }, /* 671 */ + { 71, 7, 12, 0, 0, 71, 0, }, /* 672 */ + { 67, 7, 12, 0, 0, 67, 0, }, /* 673 */ + { 28, 12, 3, 0, 0, -1, 0, }, /* 674 */ + { 10, 15, 12, 0, 0, -1, 0, }, /* 675 */ + { 42, 7, 12, 0, 0, 42, 0, }, /* 676 */ + { 42, 15, 12, 0, 0, 42, 0, }, /* 677 */ + { 19, 7, 12, 0, 0, 19, 0, }, /* 678 */ + { 19, 14, 12, 0, 0, 19, 0, }, /* 679 */ + { 118, 7, 12, 0, 0, 118, 0, }, /* 680 */ + { 118, 12, 3, 0, 0, 118, 0, }, /* 681 */ + { 60, 7, 12, 0, 0, 60, 0, }, /* 682 */ + { 60, 21, 12, 0, 0, 60, 0, }, /* 683 */ + { 43, 7, 12, 0, 0, 43, 0, }, /* 684 */ + { 43, 21, 12, 0, 0, 43, 0, }, /* 685 */ + { 43, 14, 12, 0, 0, 43, 0, }, /* 686 */ + { 14, 9, 12, 0, 40, 14, 0, }, /* 687 */ + { 14, 5, 12, 0, -40, 14, 0, }, /* 688 */ + { 47, 7, 12, 0, 0, 47, 0, }, /* 689 */ + { 45, 7, 12, 0, 0, 45, 0, }, /* 690 */ + { 45, 13, 12, 0, 0, 45, 0, }, /* 691 */ + { 136, 9, 12, 0, 40, 136, 0, }, /* 692 */ + { 136, 5, 12, 0, -40, 136, 0, }, /* 693 */ + { 106, 7, 12, 0, 0, 106, 0, }, /* 694 */ + { 104, 7, 12, 0, 0, 104, 0, }, /* 695 */ + { 104, 21, 12, 0, 0, 104, 0, }, /* 696 */ + { 110, 7, 12, 0, 0, 110, 0, }, /* 697 */ + { 12, 7, 12, 0, 0, 12, 0, }, /* 698 */ + { 81, 7, 12, 0, 0, 81, 0, }, /* 699 */ + { 81, 21, 12, 0, 0, 81, 0, }, /* 700 */ + { 81, 15, 12, 0, 0, 81, 0, }, /* 701 */ + { 120, 7, 12, 0, 0, 120, 0, }, /* 702 */ + { 120, 26, 12, 0, 0, 120, 0, }, /* 703 */ + { 120, 15, 12, 0, 0, 120, 0, }, /* 704 */ + { 116, 7, 12, 0, 0, 116, 0, }, /* 705 */ + { 116, 15, 12, 0, 0, 116, 0, }, /* 706 */ + { 128, 7, 12, 0, 0, 128, 0, }, /* 707 */ + { 128, 15, 12, 0, 0, 128, 0, }, /* 708 */ + { 66, 7, 12, 0, 0, 66, 0, }, /* 709 */ + { 66, 15, 12, 0, 0, 66, 0, }, /* 710 */ + { 66, 21, 12, 0, 0, 66, 0, }, /* 711 */ + { 72, 7, 12, 0, 0, 72, 0, }, /* 712 */ + { 72, 21, 12, 0, 0, 72, 0, }, /* 713 */ + { 98, 7, 12, 0, 0, 98, 0, }, /* 714 */ + { 97, 7, 12, 0, 0, 97, 0, }, /* 715 */ + { 97, 15, 12, 0, 0, 97, 0, }, /* 716 */ + { 31, 7, 12, 0, 0, 31, 0, }, /* 717 */ + { 31, 12, 3, 0, 0, 31, 0, }, /* 718 */ + { 31, 15, 12, 0, 0, 31, 0, }, /* 719 */ + { 31, 21, 12, 0, 0, 31, 0, }, /* 720 */ + { 88, 7, 12, 0, 0, 88, 0, }, /* 721 */ + { 88, 15, 12, 0, 0, 88, 0, }, /* 722 */ + { 88, 21, 12, 0, 0, 88, 0, }, /* 723 */ + { 117, 7, 12, 0, 0, 117, 0, }, /* 724 */ + { 117, 15, 12, 0, 0, 117, 0, }, /* 725 */ + { 112, 7, 12, 0, 0, 112, 0, }, /* 726 */ + { 112, 26, 12, 0, 0, 112, 0, }, /* 727 */ + { 112, 12, 3, 0, 0, 112, 0, }, /* 728 */ + { 112, 15, 12, 0, 0, 112, 0, }, /* 729 */ + { 112, 21, 12, 0, 0, 112, 0, }, /* 730 */ + { 78, 7, 12, 0, 0, 78, 0, }, /* 731 */ + { 78, 21, 12, 0, 0, 78, 0, }, /* 732 */ + { 83, 7, 12, 0, 0, 83, 0, }, /* 733 */ + { 83, 15, 12, 0, 0, 83, 0, }, /* 734 */ + { 82, 7, 12, 0, 0, 82, 0, }, /* 735 */ + { 82, 15, 12, 0, 0, 82, 0, }, /* 736 */ + { 121, 7, 12, 0, 0, 121, 0, }, /* 737 */ + { 121, 21, 12, 0, 0, 121, 0, }, /* 738 */ + { 121, 15, 12, 0, 0, 121, 0, }, /* 739 */ + { 89, 7, 12, 0, 0, 89, 0, }, /* 740 */ + { 130, 9, 12, 0, 64, 130, 0, }, /* 741 */ + { 130, 5, 12, 0, -64, 130, 0, }, /* 742 */ + { 130, 15, 12, 0, 0, 130, 0, }, /* 743 */ + { 144, 7, 12, 0, 0, 144, 0, }, /* 744 */ + { 144, 12, 3, 0, 0, 144, 0, }, /* 745 */ + { 144, 13, 12, 0, 0, 144, 0, }, /* 746 */ + { 1, 15, 12, 0, 0, 1, 0, }, /* 747 */ + { 147, 7, 12, 0, 0, 147, 0, }, /* 748 */ + { 147, 15, 12, 0, 0, 147, 0, }, /* 749 */ + { 148, 7, 12, 0, 0, 148, 0, }, /* 750 */ + { 148, 12, 3, 0, 0, 148, 0, }, /* 751 */ + { 148, 15, 12, 0, 0, 148, 0, }, /* 752 */ + { 148, 21, 12, 0, 0, 148, 0, }, /* 753 */ + { 94, 10, 5, 0, 0, 94, 0, }, /* 754 */ + { 94, 12, 3, 0, 0, 94, 0, }, /* 755 */ + { 94, 7, 12, 0, 0, 94, 0, }, /* 756 */ + { 94, 21, 12, 0, 0, 94, 0, }, /* 757 */ + { 94, 15, 12, 0, 0, 94, 0, }, /* 758 */ + { 94, 13, 12, 0, 0, 94, 0, }, /* 759 */ + { 85, 12, 3, 0, 0, 85, 0, }, /* 760 */ + { 85, 10, 5, 0, 0, 85, 0, }, /* 761 */ + { 85, 7, 12, 0, 0, 85, 0, }, /* 762 */ + { 85, 21, 12, 0, 0, 85, 0, }, /* 763 */ + { 85, 1, 4, 0, 0, 85, 0, }, /* 764 */ + { 101, 7, 12, 0, 0, 101, 0, }, /* 765 */ + { 101, 13, 12, 0, 0, 101, 0, }, /* 766 */ + { 96, 12, 3, 0, 0, 96, 0, }, /* 767 */ + { 96, 7, 12, 0, 0, 96, 0, }, /* 768 */ + { 96, 10, 5, 0, 0, 96, 0, }, /* 769 */ + { 96, 13, 12, 0, 0, 96, 0, }, /* 770 */ + { 96, 21, 12, 0, 0, 96, 0, }, /* 771 */ + { 111, 7, 12, 0, 0, 111, 0, }, /* 772 */ + { 111, 12, 3, 0, 0, 111, 0, }, /* 773 */ + { 111, 21, 12, 0, 0, 111, 0, }, /* 774 */ + { 100, 12, 3, 0, 0, 100, 0, }, /* 775 */ + { 100, 10, 5, 0, 0, 100, 0, }, /* 776 */ + { 100, 7, 12, 0, 0, 100, 0, }, /* 777 */ + { 100, 7, 4, 0, 0, 100, 0, }, /* 778 */ + { 100, 21, 12, 0, 0, 100, 0, }, /* 779 */ + { 100, 13, 12, 0, 0, 100, 0, }, /* 780 */ + { 48, 15, 12, 0, 0, 48, 0, }, /* 781 */ + { 108, 7, 12, 0, 0, 108, 0, }, /* 782 */ + { 108, 10, 5, 0, 0, 108, 0, }, /* 783 */ + { 108, 12, 3, 0, 0, 108, 0, }, /* 784 */ + { 108, 21, 12, 0, 0, 108, 0, }, /* 785 */ + { 129, 7, 12, 0, 0, 129, 0, }, /* 786 */ + { 129, 21, 12, 0, 0, 129, 0, }, /* 787 */ + { 109, 7, 12, 0, 0, 109, 0, }, /* 788 */ + { 109, 12, 3, 0, 0, 109, 0, }, /* 789 */ + { 109, 10, 5, 0, 0, 109, 0, }, /* 790 */ + { 109, 13, 12, 0, 0, 109, 0, }, /* 791 */ + { 107, 12, 3, 0, 0, 107, 0, }, /* 792 */ + { 107, 12, 3, 0, 0, -49, 0, }, /* 793 */ + { 107, 10, 5, 0, 0, 107, 0, }, /* 794 */ + { 107, 10, 5, 0, 0, -49, 0, }, /* 795 */ + { 107, 7, 12, 0, 0, 107, 0, }, /* 796 */ + { 28, 12, 3, 0, 0, -49, 0, }, /* 797 */ + { 107, 10, 3, 0, 0, 107, 0, }, /* 798 */ + { 135, 7, 12, 0, 0, 135, 0, }, /* 799 */ + { 135, 10, 5, 0, 0, 135, 0, }, /* 800 */ + { 135, 12, 3, 0, 0, 135, 0, }, /* 801 */ + { 135, 21, 12, 0, 0, 135, 0, }, /* 802 */ + { 135, 13, 12, 0, 0, 135, 0, }, /* 803 */ + { 124, 7, 12, 0, 0, 124, 0, }, /* 804 */ + { 124, 10, 3, 0, 0, 124, 0, }, /* 805 */ + { 124, 10, 5, 0, 0, 124, 0, }, /* 806 */ + { 124, 12, 3, 0, 0, 124, 0, }, /* 807 */ + { 124, 21, 12, 0, 0, 124, 0, }, /* 808 */ + { 124, 13, 12, 0, 0, 124, 0, }, /* 809 */ + { 123, 7, 12, 0, 0, 123, 0, }, /* 810 */ + { 123, 10, 3, 0, 0, 123, 0, }, /* 811 */ + { 123, 10, 5, 0, 0, 123, 0, }, /* 812 */ + { 123, 12, 3, 0, 0, 123, 0, }, /* 813 */ + { 123, 21, 12, 0, 0, 123, 0, }, /* 814 */ + { 114, 7, 12, 0, 0, 114, 0, }, /* 815 */ + { 114, 10, 5, 0, 0, 114, 0, }, /* 816 */ + { 114, 12, 3, 0, 0, 114, 0, }, /* 817 */ + { 114, 21, 12, 0, 0, 114, 0, }, /* 818 */ + { 114, 13, 12, 0, 0, 114, 0, }, /* 819 */ + { 102, 7, 12, 0, 0, 102, 0, }, /* 820 */ + { 102, 12, 3, 0, 0, 102, 0, }, /* 821 */ + { 102, 10, 5, 0, 0, 102, 0, }, /* 822 */ + { 102, 13, 12, 0, 0, 102, 0, }, /* 823 */ + { 126, 7, 12, 0, 0, 126, 0, }, /* 824 */ + { 126, 12, 3, 0, 0, 126, 0, }, /* 825 */ + { 126, 10, 5, 0, 0, 126, 0, }, /* 826 */ + { 126, 13, 12, 0, 0, 126, 0, }, /* 827 */ + { 126, 15, 12, 0, 0, 126, 0, }, /* 828 */ + { 126, 21, 12, 0, 0, 126, 0, }, /* 829 */ + { 126, 26, 12, 0, 0, 126, 0, }, /* 830 */ + { 142, 7, 12, 0, 0, 142, 0, }, /* 831 */ + { 142, 10, 5, 0, 0, 142, 0, }, /* 832 */ + { 142, 12, 3, 0, 0, 142, 0, }, /* 833 */ + { 142, 21, 12, 0, 0, 142, 0, }, /* 834 */ + { 125, 9, 12, 0, 32, 125, 0, }, /* 835 */ + { 125, 5, 12, 0, -32, 125, 0, }, /* 836 */ + { 125, 13, 12, 0, 0, 125, 0, }, /* 837 */ + { 125, 15, 12, 0, 0, 125, 0, }, /* 838 */ + { 125, 7, 12, 0, 0, 125, 0, }, /* 839 */ + { 141, 7, 12, 0, 0, 141, 0, }, /* 840 */ + { 141, 12, 3, 0, 0, 141, 0, }, /* 841 */ + { 141, 10, 5, 0, 0, 141, 0, }, /* 842 */ + { 141, 7, 4, 0, 0, 141, 0, }, /* 843 */ + { 141, 21, 12, 0, 0, 141, 0, }, /* 844 */ + { 140, 7, 12, 0, 0, 140, 0, }, /* 845 */ + { 140, 12, 3, 0, 0, 140, 0, }, /* 846 */ + { 140, 10, 5, 0, 0, 140, 0, }, /* 847 */ + { 140, 7, 4, 0, 0, 140, 0, }, /* 848 */ + { 140, 21, 12, 0, 0, 140, 0, }, /* 849 */ + { 122, 7, 12, 0, 0, 122, 0, }, /* 850 */ + { 133, 7, 12, 0, 0, 133, 0, }, /* 851 */ + { 133, 10, 5, 0, 0, 133, 0, }, /* 852 */ + { 133, 12, 3, 0, 0, 133, 0, }, /* 853 */ + { 133, 21, 12, 0, 0, 133, 0, }, /* 854 */ + { 133, 13, 12, 0, 0, 133, 0, }, /* 855 */ + { 133, 15, 12, 0, 0, 133, 0, }, /* 856 */ + { 134, 21, 12, 0, 0, 134, 0, }, /* 857 */ + { 134, 7, 12, 0, 0, 134, 0, }, /* 858 */ + { 134, 12, 3, 0, 0, 134, 0, }, /* 859 */ + { 134, 10, 5, 0, 0, 134, 0, }, /* 860 */ + { 138, 7, 12, 0, 0, 138, 0, }, /* 861 */ + { 138, 12, 3, 0, 0, 138, 0, }, /* 862 */ + { 138, 7, 4, 0, 0, 138, 0, }, /* 863 */ + { 138, 13, 12, 0, 0, 138, 0, }, /* 864 */ + { 143, 7, 12, 0, 0, 143, 0, }, /* 865 */ + { 143, 10, 5, 0, 0, 143, 0, }, /* 866 */ + { 143, 12, 3, 0, 0, 143, 0, }, /* 867 */ + { 143, 13, 12, 0, 0, 143, 0, }, /* 868 */ + { 145, 7, 12, 0, 0, 145, 0, }, /* 869 */ + { 145, 12, 3, 0, 0, 145, 0, }, /* 870 */ + { 145, 10, 5, 0, 0, 145, 0, }, /* 871 */ + { 145, 21, 12, 0, 0, 145, 0, }, /* 872 */ + { 63, 7, 12, 0, 0, 63, 0, }, /* 873 */ + { 63, 14, 12, 0, 0, 63, 0, }, /* 874 */ + { 63, 21, 12, 0, 0, 63, 0, }, /* 875 */ + { 80, 7, 12, 0, 0, 80, 0, }, /* 876 */ + { 127, 7, 12, 0, 0, 127, 0, }, /* 877 */ + { 115, 7, 12, 0, 0, 115, 0, }, /* 878 */ + { 115, 13, 12, 0, 0, 115, 0, }, /* 879 */ + { 115, 21, 12, 0, 0, 115, 0, }, /* 880 */ + { 103, 7, 12, 0, 0, 103, 0, }, /* 881 */ + { 103, 12, 3, 0, 0, 103, 0, }, /* 882 */ + { 103, 21, 12, 0, 0, 103, 0, }, /* 883 */ + { 119, 7, 12, 0, 0, 119, 0, }, /* 884 */ + { 119, 12, 3, 0, 0, 119, 0, }, /* 885 */ + { 119, 21, 12, 0, 0, 119, 0, }, /* 886 */ + { 119, 26, 12, 0, 0, 119, 0, }, /* 887 */ + { 119, 6, 12, 0, 0, 119, 0, }, /* 888 */ + { 119, 13, 12, 0, 0, 119, 0, }, /* 889 */ + { 119, 15, 12, 0, 0, 119, 0, }, /* 890 */ + { 146, 9, 12, 0, 32, 146, 0, }, /* 891 */ + { 146, 5, 12, 0, -32, 146, 0, }, /* 892 */ + { 146, 15, 12, 0, 0, 146, 0, }, /* 893 */ + { 146, 21, 12, 0, 0, 146, 0, }, /* 894 */ + { 99, 7, 12, 0, 0, 99, 0, }, /* 895 */ + { 99, 10, 5, 0, 0, 99, 0, }, /* 896 */ + { 99, 12, 3, 0, 0, 99, 0, }, /* 897 */ + { 99, 6, 12, 0, 0, 99, 0, }, /* 898 */ + { 137, 6, 12, 0, 0, 137, 0, }, /* 899 */ + { 139, 6, 12, 0, 0, 139, 0, }, /* 900 */ + { 137, 7, 12, 0, 0, 137, 0, }, /* 901 */ + { 139, 7, 12, 0, 0, 139, 0, }, /* 902 */ + { 105, 7, 12, 0, 0, 105, 0, }, /* 903 */ + { 105, 26, 12, 0, 0, 105, 0, }, /* 904 */ + { 105, 12, 3, 0, 0, 105, 0, }, /* 905 */ + { 105, 21, 12, 0, 0, 105, 0, }, /* 906 */ + { 10, 1, 2, 0, 0, 105, 0, }, /* 907 */ + { 10, 10, 3, 0, 0, 10, 0, }, /* 908 */ + { 10, 10, 5, 0, 0, 10, 0, }, /* 909 */ + { 20, 12, 3, 0, 0, 20, 0, }, /* 910 */ + { 131, 26, 12, 0, 0, 131, 0, }, /* 911 */ + { 131, 12, 3, 0, 0, 131, 0, }, /* 912 */ + { 131, 21, 12, 0, 0, 131, 0, }, /* 913 */ + { 18, 12, 3, 0, 0, 18, 0, }, /* 914 */ + { 113, 7, 12, 0, 0, 113, 0, }, /* 915 */ + { 113, 15, 12, 0, 0, 113, 0, }, /* 916 */ + { 113, 12, 3, 0, 0, 113, 0, }, /* 917 */ + { 132, 9, 12, 0, 34, 132, 0, }, /* 918 */ + { 132, 5, 12, 0, -34, 132, 0, }, /* 919 */ + { 132, 12, 3, 0, 0, 132, 0, }, /* 920 */ + { 132, 13, 12, 0, 0, 132, 0, }, /* 921 */ + { 132, 21, 12, 0, 0, 132, 0, }, /* 922 */ + { 0, 2, 14, 0, 0, 0, 0, }, /* 923 */ + { 10, 26, 11, 0, 0, 10, 0, }, /* 924 */ + { 27, 26, 12, 0, 0, 27, 0, }, /* 925 */ + { 10, 24, 3, 0, 0, 10, 0, }, /* 926 */ + { 10, 1, 3, 0, 0, 10, 0, }, /* 927 */ }; const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ @@ -968,3216 +1123,3226 @@ const uint16_t PRIV(ucd_stage1)[] = { /* 17408 bytes */ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, /* U+1800 */ 62, 63, 64, 65, 66, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, /* U+2000 */ 77, 77, 78, 79, 66, 66, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, /* U+2800 */ - 90, 91, 92, 93, 94, 95, 96, 71, 97, 97, 97, 97, 97, 97, 97, 97, /* U+3000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+3800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+4000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, 97, 97, 97, 97, /* U+4800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+5000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+5800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+6000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+6800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+7000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+7800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+8000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+8800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+9000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 99, /* U+9800 */ -100,101,101,101,101,101,101,101,101,102,103,103,104,105,106,107, /* U+A000 */ -108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,116, /* U+A800 */ -117,118,119,120,121,122,116,117,118,119,120,121,122,116,117,118, /* U+B000 */ -119,120,121,122,116,117,118,119,120,121,122,116,117,118,119,120, /* U+B800 */ -121,122,116,117,118,119,120,121,122,116,117,118,119,120,121,122, /* U+C000 */ -116,117,118,119,120,121,122,116,117,118,119,120,121,122,116,117, /* U+C800 */ -118,119,120,121,122,116,117,118,119,120,121,122,116,117,118,123, /* U+D000 */ -124,124,124,124,124,124,124,124,124,124,124,124,124,124,124,124, /* U+D800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+E000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+E800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F000 */ -125,125, 97, 97,126,127,128,129,130,130,131,132,133,134,135,136, /* U+F800 */ -137,138,139,140,141,142,143,144,145,146,147,141,148,148,149,141, /* U+10000 */ -150,151,152,153,154,155,156,157,158,159,160,141,161,141,162,141, /* U+10800 */ -163,164,165,166,167,168,169,141,170,171,141,172,173,174,175,141, /* U+11000 */ -176,177,141,141,178,179,141,141,180,181,182,183,141,184,141,141, /* U+11800 */ -185,185,185,185,185,185,185,186,187,185,188,141,141,141,141,141, /* U+12000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+12800 */ -189,189,189,189,189,189,189,189,190,141,141,141,141,141,141,141, /* U+13000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+13800 */ -141,141,141,141,141,141,141,141,191,191,191,191,192,141,141,141, /* U+14000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+14800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+15000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+15800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+16000 */ -193,193,193,193,194,195,196,197,141,141,141,141,198,199,200,201, /* U+16800 */ -202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, /* U+17000 */ -202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, /* U+17800 */ -202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,203, /* U+18000 */ -202,202,202,202,202,204,141,141,141,141,141,141,141,141,141,141, /* U+18800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+19000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+19800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+1A000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+1A800 */ -205,206,207,208,208,209,141,141,141,141,141,141,141,141,141,141, /* U+1B000 */ -141,141,141,141,141,141,141,141,210,211,141,141,141,141,141,141, /* U+1B800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+1C000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+1C800 */ - 71,212,213,214,215,216,217,141,218,219,220,221,222,223,224,225, /* U+1D000 */ -226,226,226,226,227,228,141,141,141,141,141,141,141,141,141,141, /* U+1D800 */ -229,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+1E000 */ -230,231,232,141,141,141,141,141,233,234,141,141,235,236,141,141, /* U+1E800 */ -237,238,239,240,241,242,243,244,243,243,245,243,246,247,248,249, /* U+1F000 */ -250,251,252,253,254,242,242,242,242,242,242,242,242,242,242,255, /* U+1F800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+20000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+20800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+21000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+21800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+22000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+22800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+23000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+23800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+24000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+24800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+25000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+25800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+26000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+26800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+27000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+27800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+28000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+28800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+29000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+29800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,256, 97, 97, /* U+2A000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+2A800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,257, 97, /* U+2B000 */ -258, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+2B800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+2C000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,259, 97, 97, /* U+2C800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+2D000 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+2D800 */ - 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, /* U+2E000 */ - 97, 97, 97, 97, 97, 97, 97,260,141,141,141,141,141,141,141,141, /* U+2E800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+2F000 */ - 97, 97, 97, 97,261,141,141,141,141,141,141,141,141,141,141,141, /* U+2F800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+30000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+30800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+31000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+31800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+32000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+32800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+33000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+33800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+34000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+34800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+35000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+35800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+36000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+36800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+37000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+37800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+38000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+38800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+39000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+39800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3A000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3A800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3B000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3B800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3C000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3C800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3D000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3D800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3E000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3E800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3F000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+3F800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+40000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+40800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+41000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+41800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+42000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+42800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+43000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+43800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+44000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+44800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+45000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+45800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+46000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+46800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+47000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+47800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+48000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+48800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+49000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+49800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4A000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4A800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4B000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4B800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4C000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4C800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4D000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4D800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4E000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4E800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4F000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+4F800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+50000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+50800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+51000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+51800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+52000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+52800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+53000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+53800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+54000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+54800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+55000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+55800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+56000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+56800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+57000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+57800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+58000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+58800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+59000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+59800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5A000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5A800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5B000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5B800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5C000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5C800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5D000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5D800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5E000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5E800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5F000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+5F800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+60000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+60800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+61000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+61800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+62000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+62800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+63000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+63800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+64000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+64800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+65000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+65800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+66000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+66800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+67000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+67800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+68000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+68800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+69000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+69800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6A000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6A800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6B000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6B800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6C000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6C800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6D000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6D800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6E000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6E800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6F000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+6F800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+70000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+70800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+71000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+71800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+72000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+72800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+73000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+73800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+74000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+74800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+75000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+75800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+76000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+76800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+77000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+77800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+78000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+78800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+79000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+79800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7A000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7A800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7B000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7B800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7C000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7C800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7D000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7D800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7E000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7E800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7F000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+7F800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+80000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+80800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+81000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+81800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+82000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+82800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+83000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+83800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+84000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+84800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+85000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+85800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+86000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+86800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+87000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+87800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+88000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+88800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+89000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+89800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8A000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8A800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8B000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8B800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8C000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8C800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8D000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8D800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8E000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8E800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8F000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+8F800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+90000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+90800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+91000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+91800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+92000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+92800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+93000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+93800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+94000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+94800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+95000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+95800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+96000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+96800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+97000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+97800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+98000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+98800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+99000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+99800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9A000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9A800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9B000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9B800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9C000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9C800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9D000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9D800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9E000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9E800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9F000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+9F800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A0000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A0800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A1000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A1800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A2000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A2800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A3000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A3800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A4000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A4800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A5000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A5800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A6000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A6800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A7000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A7800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A8000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A8800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A9000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+A9800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AA000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AA800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AB000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AB800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AC000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AC800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AD000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AD800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AE000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AE800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AF000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+AF800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B0000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B0800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B1000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B1800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B2000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B2800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B3000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B3800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B4000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B4800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B5000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B5800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B6000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B6800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B7000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B7800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B8000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B8800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B9000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+B9800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BA000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BA800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BB000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BB800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BC000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BC800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BD000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BD800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BE000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BE800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BF000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+BF800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C0000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C0800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C1000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C1800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C2000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C2800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C3000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C3800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C4000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C4800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C5000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C5800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C6000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C6800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C7000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C7800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C8000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C8800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C9000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+C9800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CA000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CA800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CB000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CB800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CC000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CC800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CD000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CD800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CE000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CE800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CF000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+CF800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D0000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D0800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D1000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D1800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D2000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D2800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D3000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D3800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D4000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D4800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D5000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D5800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D6000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D6800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D7000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D7800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D8000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D8800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D9000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+D9800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DA000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DA800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DB000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DB800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DC000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DC800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DD000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DD800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DE000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DE800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DF000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+DF800 */ -262,263,264,265,263,263,263,263,263,263,263,263,263,263,263,263, /* U+E0000 */ -263,263,263,263,263,263,263,263,263,263,263,263,263,263,263,263, /* U+E0800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E1000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E1800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E2000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E2800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E3000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E3800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E4000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E4800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E5000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E5800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E6000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E6800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E7000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E7800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E8000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E8800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E9000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+E9800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+EA000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+EA800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+EB000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+EB800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+EC000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+EC800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+ED000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+ED800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+EE000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+EE800 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+EF000 */ -141,141,141,141,141,141,141,141,141,141,141,141,141,141,141,141, /* U+EF800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F0000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F0800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F1000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F1800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F2000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F2800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F3000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F3800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F4000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F4800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F5000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F5800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F6000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F6800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F7000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F7800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F8000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F8800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F9000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+F9800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FA000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FA800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FB000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FB800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FC000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FC800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FD000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FD800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FE000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FE800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+FF000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,266, /* U+FF800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+100000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+100800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+101000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+101800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+102000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+102800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+103000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+103800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+104000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+104800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+105000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+105800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+106000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+106800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+107000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+107800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+108000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+108800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+109000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+109800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10A000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10A800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10B000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10B800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10C000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10C800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10D000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10D800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10E000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10E800 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+10F000 */ -125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,266, /* U+10F800 */ + 90, 91, 92, 93, 94, 95, 96, 97, 98, 98, 98, 98, 98, 98, 98, 98, /* U+3000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+3800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+4000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 99, 98, 98, 98, 98, /* U+4800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+5000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+5800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+6000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+6800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+7000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+7800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+8000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+8800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+9000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,100, /* U+9800 */ +101,102,102,102,102,102,102,102,102,103,104,104,105,106,107,108, /* U+A000 */ +109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,117, /* U+A800 */ +118,119,120,121,122,123,117,118,119,120,121,122,123,117,118,119, /* U+B000 */ +120,121,122,123,117,118,119,120,121,122,123,117,118,119,120,121, /* U+B800 */ +122,123,117,118,119,120,121,122,123,117,118,119,120,121,122,123, /* U+C000 */ +117,118,119,120,121,122,123,117,118,119,120,121,122,123,117,118, /* U+C800 */ +119,120,121,122,123,117,118,119,120,121,122,123,117,118,119,124, /* U+D000 */ +125,125,125,125,125,125,125,125,125,125,125,125,125,125,125,125, /* U+D800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+E000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+E800 */ +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,142, /* U+10800 */ +164,165,166,167,168,169,170,142,171,172,142,173,174,175,176,142, /* U+11000 */ +177,178,142,142,179,180,142,142,181,182,183,184,142,185,142,142, /* U+11800 */ +186,186,186,186,186,186,186,187,188,186,189,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 */ +190,190,190,190,190,190,190,190,191,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,192,192,192,192,193,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 */ +194,194,194,194,195,196,197,198,142,142,142,142,199,200,201,202, /* U+16800 */ +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, /* U+17000 */ +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,203, /* U+17800 */ +203,203,203,203,203,203,203,203,203,203,203,203,203,203,203,204, /* U+18000 */ +203,203,203,203,203,205,142,142,142,142,142,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 */ +206,207,208,209,209,210,142,142,142,142,142,142,142,142,142,142, /* U+1B000 */ +142,142,142,142,142,142,142,142,211,212,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,213,214,215,216,217,218,142,219,220,221,222,223,224,225,226, /* U+1D000 */ +227,227,227,227,228,229,142,142,142,142,142,142,142,142,142,142, /* U+1D800 */ +230,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+1E000 */ +231,232,233,142,142,142,142,142,234,235,142,142,236,237,142,142, /* U+1E800 */ +238,239,240,241,242,243,244,245,244,244,246,244,247,248,249,250, /* U+1F000 */ +251,252,253,254,255,243,243,243,243,243,243,243,243,243,243,256, /* 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 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+21800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+22000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+22800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+23000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+23800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+24000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+24800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+25000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+25800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+26000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+26800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+27000 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+27800 */ + 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, 98, /* U+28000 */ + 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,257, 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,258, 98, /* U+2B000 */ +259, 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,260, 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,261,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,262,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 */ +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 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+33000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+33800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+34000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+34800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+35000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+35800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+36000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+36800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+37000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+37800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+38000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+38800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+39000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+39800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3A000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3A800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3B000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3B800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3C000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3C800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3D000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3D800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3E000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3E800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3F000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+3F800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+40000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+40800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+41000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+41800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+42000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+42800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+43000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+43800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+44000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+44800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+45000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+45800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+46000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+46800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+47000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+47800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+48000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+48800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+49000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+49800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4A000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4A800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4B000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4B800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4C000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4C800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4D000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4D800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4E000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4E800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4F000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+4F800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+50000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+50800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+51000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+51800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+52000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+52800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+53000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+53800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+54000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+54800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+55000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+55800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+56000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+56800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+57000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+57800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+58000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+58800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+59000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+59800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5A000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5A800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5B000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5B800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5C000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5C800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5D000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5D800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5E000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5E800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5F000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+5F800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+60000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+60800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+61000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+61800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+62000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+62800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+63000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+63800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+64000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+64800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+65000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+65800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+66000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+66800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+67000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+67800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+68000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+68800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+69000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+69800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6A000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6A800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6B000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6B800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6C000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6C800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6D000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6D800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6E000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6E800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6F000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+6F800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+70000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+70800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+71000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+71800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+72000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+72800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+73000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+73800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+74000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+74800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+75000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+75800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+76000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+76800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+77000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+77800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+78000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+78800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+79000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+79800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7A000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7A800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7B000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7B800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7C000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7C800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7D000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7D800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7E000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7E800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7F000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+7F800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+80000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+80800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+81000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+81800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+82000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+82800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+83000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+83800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+84000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+84800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+85000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+85800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+86000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+86800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+87000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+87800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+88000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+88800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+89000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+89800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8A000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8A800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8B000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8B800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8C000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8C800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8D000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8D800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8E000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8E800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8F000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+8F800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+90000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+90800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+91000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+91800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+92000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+92800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+93000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+93800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+94000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+94800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+95000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+95800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+96000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+96800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+97000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+97800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+98000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+98800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+99000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+99800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9A000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9A800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9B000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9B800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9C000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9C800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9D000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9D800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9E000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9E800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9F000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+9F800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A0000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A0800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A1000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A1800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A2000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A2800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A3000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A3800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A4000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A4800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A5000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A5800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A6000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A6800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A7000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A7800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A8000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A8800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A9000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+A9800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AA000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AA800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AB000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AB800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AC000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AC800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AD000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AD800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AE000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AE800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AF000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+AF800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B0000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B0800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B1000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B1800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B2000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B2800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B3000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B3800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B4000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B4800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B5000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B5800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B6000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B6800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B7000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B7800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B8000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B8800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B9000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+B9800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BA000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BA800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BB000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BB800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BC000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BC800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BD000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BD800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BE000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BE800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BF000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+BF800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C0000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C0800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C1000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C1800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C2000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C2800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C3000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C3800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C4000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C4800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C5000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C5800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C6000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C6800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C7000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C7800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C8000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C8800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C9000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+C9800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CA000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CA800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CB000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CB800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CC000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CC800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CD000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CD800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CE000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CE800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CF000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+CF800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D0000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D0800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D1000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D1800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D2000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D2800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D3000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D3800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D4000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D4800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D5000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D5800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D6000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D6800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D7000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D7800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D8000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D8800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D9000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+D9800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DA000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DA800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DB000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DB800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DC000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DC800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DD000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DD800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+DE000 */ +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 */ +263,264,265,266,264,264,264,264,264,264,264,264,264,264,264,264, /* U+E0000 */ +264,264,264,264,264,264,264,264,264,264,264,264,264,264,264,264, /* 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 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E2800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E3000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E3800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E4000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E4800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E5000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E5800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E6000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E6800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E7000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E7800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E8000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E8800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E9000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+E9800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EA000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EA800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EB000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EB800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EC000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EC800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+ED000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+ED800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EE000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EE800 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EF000 */ +142,142,142,142,142,142,142,142,142,142,142,142,142,142,142,142, /* U+EF800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F0000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F0800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F1000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F1800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F2000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F2800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F3000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F3800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F4000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F4800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F5000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F5800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F6000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F6800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F7000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F7800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F8000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F8800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F9000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+F9800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FA000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FA800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FB000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FB800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FC000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FC800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FD000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+FD800 */ +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,267, /* 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 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+101800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+102000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+102800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+103000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+103800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+104000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+104800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+105000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+105800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+106000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+106800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+107000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+107800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+108000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+108800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+109000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+109800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10A000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10A800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10B000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10B800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10C000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10C800 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10D000 */ +126,126,126,126,126,126,126,126,126,126,126,126,126,126,126,126, /* U+10D800 */ +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,267, /* U+10F800 */ }; -const uint16_t PRIV(ucd_stage2)[] = { /* 68352 bytes, block = 128 */ +const uint16_t PRIV(ucd_stage2)[] = { /* 68608 bytes, block = 128 */ /* block 0 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 3, 4, 4, 4, 5, 4, 4, 4, 6, 7, 4, 8, 4, 9, 4, 4, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 4, 8, 8, 8, 4, - 4, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 11, 11, 11, 11, - 11, 11, 11, 13, 11, 11, 11, 11, 11, 11, 11, 6, 4, 7, 14, 15, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 16, 16, 16, 16, - 16, 16, 16, 18, 16, 16, 16, 16, 16, 16, 16, 6, 8, 7, 8, 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, + 4, 5, 5, 5, 6, 5, 5, 5, 7, 8, 5, 9, 5, 10, 5, 5, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 5, 5, 9, 9, 9, 5, + 5, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 12, 12, 12, 12, + 12, 12, 12, 14, 12, 12, 12, 12, 12, 12, 12, 7, 5, 8, 15, 16, + 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 17, 17, 17, 17, + 17, 17, 17, 19, 17, 17, 17, 17, 17, 17, 17, 7, 9, 8, 9, 1, /* block 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, - 3, 4, 5, 5, 5, 5, 19, 4, 14, 20, 21, 22, 8, 23, 20, 14, - 19, 8, 24, 24, 14, 25, 4, 4, 14, 24, 21, 26, 24, 24, 24, 4, - 11, 11, 11, 11, 11, 27, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 8, 11, 11, 11, 11, 11, 11, 11, 28, - 16, 16, 16, 16, 16, 29, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 8, 16, 16, 16, 16, 16, 16, 16, 30, + 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, + 4, 5, 6, 6, 6, 6, 20, 5, 15, 21, 22, 23, 9, 24, 21, 15, + 20, 9, 25, 25, 15, 26, 5, 5, 15, 25, 22, 27, 25, 25, 25, 5, + 12, 12, 12, 12, 12, 28, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 9, 12, 12, 12, 12, 12, 12, 12, 29, + 17, 17, 17, 17, 17, 30, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 9, 17, 17, 17, 17, 17, 17, 17, 31, /* block 2 */ - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 33, 34, 31, 32, 31, 32, 31, 32, 34, 31, 32, 31, 32, 31, 32, 31, - 32, 31, 32, 31, 32, 31, 32, 31, 32, 34, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 35, 31, 32, 31, 32, 31, 32, 36, + 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, + 34, 35, 32, 33, 32, 33, 32, 33, 35, 32, 33, 32, 33, 32, 33, 32, + 33, 32, 33, 32, 33, 32, 33, 32, 33, 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, 36, 32, 33, 32, 33, 32, 33, 37, /* block 3 */ - 37, 38, 31, 32, 31, 32, 39, 31, 32, 40, 40, 31, 32, 34, 41, 42, - 43, 31, 32, 40, 44, 45, 46, 47, 31, 32, 48, 34, 46, 49, 50, 51, - 31, 32, 31, 32, 31, 32, 52, 31, 32, 52, 34, 34, 31, 32, 52, 31, - 32, 53, 53, 31, 32, 31, 32, 54, 31, 32, 34, 21, 31, 32, 34, 55, - 21, 21, 21, 21, 56, 57, 58, 59, 60, 61, 62, 63, 64, 31, 32, 31, - 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 65, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 34, 66, 67, 68, 31, 32, 69, 70, 31, 32, 31, 32, 31, 32, 31, 32, + 38, 39, 32, 33, 32, 33, 40, 32, 33, 41, 41, 32, 33, 35, 42, 43, + 44, 32, 33, 41, 45, 46, 47, 48, 32, 33, 49, 35, 47, 50, 51, 52, + 32, 33, 32, 33, 32, 33, 53, 32, 33, 53, 35, 35, 32, 33, 53, 32, + 33, 54, 54, 32, 33, 32, 33, 55, 32, 33, 35, 22, 32, 33, 35, 56, + 22, 22, 22, 22, 57, 58, 59, 60, 61, 62, 63, 64, 65, 32, 33, 32, + 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 66, 32, 33, + 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, + 35, 67, 68, 69, 32, 33, 70, 71, 32, 33, 32, 33, 32, 33, 32, 33, /* block 4 */ - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 71, 34, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 34, 34, 34, 34, 34, 34, 72, 31, 32, 73, 74, 75, - 75, 31, 32, 76, 77, 78, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 79, 80, 81, 82, 83, 34, 84, 84, 34, 85, 34, 86, 87, 34, 34, 34, - 84, 88, 34, 89, 34, 90, 91, 34, 92, 93, 91, 94, 95, 34, 34, 93, - 34, 96, 97, 34, 34, 98, 34, 34, 34, 34, 34, 34, 34, 99, 34, 34, + 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, + 72, 35, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, + 32, 33, 32, 33, 35, 35, 35, 35, 35, 35, 73, 32, 33, 74, 75, 76, + 76, 32, 33, 77, 78, 79, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, + 80, 81, 82, 83, 84, 35, 85, 85, 35, 86, 35, 87, 88, 35, 35, 35, + 85, 89, 35, 90, 35, 91, 92, 35, 93, 94, 92, 95, 96, 35, 35, 94, + 35, 97, 98, 35, 35, 99, 35, 35, 35, 35, 35, 35, 35,100, 35, 35, /* block 5 */ -100, 34, 34,100, 34, 34, 34,101,100,102,103,103,104, 34, 34, 34, - 34, 34,105, 34, 21, 34, 34, 34, 34, 34, 34, 34, 34,106,107, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, -108,108,108,108,108,108,108,108,108,109,109,109,109,109,109,109, -109,109, 14, 14, 14, 14,109,109,109,109,109,109,109,109,109,109, -109,109, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -108,108,108,108,108, 14, 14, 14, 14, 14,110,110,109, 14,109, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, +101, 35, 35,101, 35, 35, 35,102,101,103,104,104,105, 35, 35, 35, + 35, 35,106, 35, 22, 35, 35, 35, 35, 35, 35, 35, 35,107,108, 35, + 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, 35, +109,109,109,109,109,109,109,109,109,110,110,110,110,110,110,110, +110,110, 15, 15, 15, 15,110,110,110,110,110,110,110,110,110,110, +110,110, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, +109,109,109,109,109, 15, 15, 15, 15, 15,111,111,110, 15,110, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, /* block 6 */ -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,112,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -113,114,113,114,109,115,113,114,116,116,117,118,118,118, 4,119, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,113,112,112,114,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,115,115,115,115,115,115,115,115,115,115,115,115,115, +116,117,116,117,110,118,116,117,119,119,120,121,121,121, 5,122, /* block 7 */ -116,116,116,116,115, 14,120, 4,121,121,121,116,122,116,123,123, -124,125,126,125,125,127,125,125,128,129,130,125,131,125,125,125, -132,133,116,134,125,125,135,125,125,136,125,125,137,138,138,138, -124,139,140,139,139,141,139,139,142,143,144,139,145,139,139,139, -146,147,148,149,139,139,150,139,139,151,139,139,152,153,153,154, -155,156,157,157,157,158,159,160,113,114,113,114,113,114,113,114, -113,114,161,162,161,162,161,162,161,162,161,162,161,162,161,162, -163,164,165,166,167,168,169,113,114,170,113,114,124,171,171,171, +119,119,119,119,118, 15,123, 5,124,124,124,119,125,119,126,126, +127,128,129,128,128,130,128,128,131,132,133,128,134,128,128,128, +135,136,119,137,128,128,138,128,128,139,128,128,140,141,141,141, +127,142,143,142,142,144,142,142,145,146,147,142,148,142,142,142, +149,150,151,152,142,142,153,142,142,154,142,142,155,156,156,157, +158,159,160,160,160,161,162,163,116,117,116,117,116,117,116,117, +116,117,164,165,164,165,164,165,164,165,164,165,164,165,164,165, +166,167,168,169,170,171,172,116,117,173,116,117,127,174,174,174, /* block 8 */ -172,172,172,172,172,172,172,172,172,172,172,172,172,172,172,172, -173,173,174,173,175,173,173,173,173,173,173,173,173,173,176,173, -173,177,178,173,173,173,173,173,173,173,179,173,173,173,173,173, -180,180,181,180,182,180,180,180,180,180,180,180,180,180,183,180, -180,184,185,180,180,180,180,180,180,180,186,180,180,180,180,180, -187,187,187,187,187,187,187,187,187,187,187,187,187,187,187,187, -188,189,190,191,188,189,188,189,188,189,188,189,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, +175,175,175,175,175,175,175,175,175,175,175,175,175,175,175,175, +176,176,177,176,178,176,176,176,176,176,176,176,176,176,179,176, +176,180,181,176,176,176,176,176,176,176,182,176,176,176,176,176, +183,183,184,183,185,183,183,183,183,183,183,183,183,183,186,183, +183,187,188,183,183,183,183,183,183,183,189,183,183,183,183,183, +190,190,190,190,190,190,190,190,190,190,190,190,190,190,190,190, +191,192,193,194,191,192,191,192,191,192,191,192,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, /* block 9 */ -188,189,192,193,193,111,111,193,194,194,188,189,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, -195,188,189,188,189,188,189,188,189,188,189,188,189,188,189,196, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, +191,192,195,196,197,198,198,197,199,199,191,192,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +200,191,192,191,192,191,192,191,192,191,192,191,192,191,192,201, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, /* block 10 */ -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, -116,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, -197,197,197,197,197,197,197,197,197,197,197,197,197,197,197,197, -197,197,197,197,197,197,197,116,116,198,199,199,199,199,199,199, -200,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, -201,201,201,201,201,201,201,201,201,201,201,201,201,201,201,201, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +119,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,202,202,202,202,202,202,202,202,202, +202,202,202,202,202,202,202,119,119,203,204,204,204,204,204,204, +205,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, +206,206,206,206,206,206,206,206,206,206,206,206,206,206,206,206, /* block 11 */ -201,201,201,201,201,201,201,200,200, 4,202,116,116,203,203,204, -116,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, -205,205,205,205,205,205,205,205,205,205,205,205,205,205,205,205, -205,205,205,205,205,205,205,205,205,205,205,205,205,205,206,205, -207,205,205,207,205,205,207,205,116,116,116,116,116,116,116,116, -208,208,208,208,208,208,208,208,208,208,208,208,208,208,208,208, -208,208,208,208,208,208,208,208,208,208,208,116,116,116,116,208, -208,208,208,207,207,116,116,116,116,116,116,116,116,116,116,116, +206,206,206,206,206,206,206,205,205,207,208,119,119,209,209,210, +119,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,119,119,119,119,119,119,119,119, +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,119,119,119,119,214, +214,214,214,213,213,119,119,119,119,119,119,119,119,119,119,119, /* block 12 */ -209,209,209,209,209,210,211,211,211,212,212,213, 4,212,214,214, -215,215,215,215,215,215,215,215,215,215,215, 4,216,116,212, 4, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -109,217,217,217,217,217,217,217,217,217,217,111,111,111,111,111, -111,111,111,111,111,111,215,215,215,215,215,215,215,215,215,215, -218,218,218,218,218,218,218,218,218,218,212,212,212,212,217,217, -111,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +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,119,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 */ -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,212,217,215,215,215,215,215,215,215,210,214,215, -215,215,215,215,215,219,219,215,215,214,215,215,215,215,217,217, -218,218,218,218,218,218,218,218,218,218,217,217,217,214,214,217, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,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 */ -220,220,220,220,220,220,220,220,220,220,220,220,220,220,116,221, -222,223,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,222, -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,116,116,222,222,222, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, - -/* block 15 */ +231,231,231,231,231,231,231,231,231,231,231,231,231,231,119,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, +234,234,234,234,234,234,234,234,234,234,234,119,119,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, -224,224,224,224,224,224,225,225,225,225,225,225,225,225,225,225, -225,224,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -226,226,226,226,226,226,226,226,226,226,227,227,227,227,227,227, -227,227,227,227,227,227,227,227,227,227,227,227,227,227,227,227, -227,227,227,227,227,227,227,227,227,227,227,228,228,228,228,228, -228,228,228,228,229,229,230,231,231,231,229,116,116,228,232,232, + +/* block 15 */ +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,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +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,119,119,239,243,243, /* block 16 */ -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,235,234,234,234,234,234, -234,234,234,234,235,234,234,234,235,234,234,234,234,234,116,116, -236,236,236,236,236,236,236,236,236,236,236,236,236,236,236,116, -237,237,237,237,237,237,237,237,237,237,237,237,237,237,237,237, -237,237,237,237,237,237,237,237,237,238,238,238,116,116,239,116, -222,222,222,222,222,222,222,222,222,222,222,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +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,119,119, +247,247,247,247,247,247,247,247,247,247,247,247,247,247,247,119, +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,119,119,250,119, +233,233,233,233,233,233,233,233,233,233,233,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 17 */ -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,116,217,217,217,217,217,217,217,217,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,215,215,215,215,215,215,215,215,215,215,215,215,215, -215,215,210,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,215,215, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,119,224,224,224,224,224,224,224,224,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,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 */ -240,240,240,241,242,242,242,242,242,242,242,242,242,242,242,242, -242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, -242,242,242,242,242,242,242,242,242,242,242,242,242,242,242,242, -242,242,242,242,242,242,242,242,242,242,240,241,240,242,241,241, -241,240,240,240,240,240,240,240,240,241,241,241,241,240,241,241, -242,111,111,240,240,240,240,240,242,242,242,242,242,242,242,242, -242,242,240,240, 4, 4,243,243,243,243,243,243,243,243,243,243, -244,245,242,242,242,242,242,242,242,242,242,242,242,242,242,242, +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,251,251,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 */ -246,247,248,248,116,246,246,246,246,246,246,246,246,116,116,246, -246,116,116,246,246,246,246,246,246,246,246,246,246,246,246,246, -246,246,246,246,246,246,246,246,246,116,246,246,246,246,246,246, -246,116,246,116,116,116,246,246,246,246,116,116,247,246,249,248, -248,247,247,247,247,116,116,248,248,116,116,248,248,247,246,116, -116,116,116,116,116,116,116,249,116,116,116,116,246,246,116,246, -246,246,247,247,116,116,250,250,250,250,250,250,250,250,250,250, -246,246,251,251,252,252,252,252,252,252,253,251,246,254,247,116, +261,262,263,263,119,261,261,261,261,261,261,261,261,119,119,261, +261,119,119,261,261,261,261,261,261,261,261,261,261,261,261,261, +261,261,261,261,261,261,261,261,261,119,261,261,261,261,261,261, +261,119,261,119,119,119,261,261,261,261,119,119,262,261,264,263, +263,262,262,262,262,119,119,263,263,119,119,263,263,262,261,119, +119,119,119,119,119,119,119,264,119,119,119,119,261,261,119,261, +261,261,262,262,119,119,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,119, /* block 20 */ -116,255,255,256,116,257,257,257,257,257,257,116,116,116,116,257, -257,116,116,257,257,257,257,257,257,257,257,257,257,257,257,257, -257,257,257,257,257,257,257,257,257,116,257,257,257,257,257,257, -257,116,257,257,116,257,257,116,257,257,116,116,255,116,256,256, -256,255,255,116,116,116,116,255,255,116,116,255,255,255,116,116, -116,255,116,116,116,116,116,116,116,257,257,257,257,116,257,116, -116,116,116,116,116,116,258,258,258,258,258,258,258,258,258,258, -255,255,257,257,257,255,259,116,116,116,116,116,116,116,116,116, +119,270,270,271,119,272,272,272,272,272,272,119,119,119,119,272, +272,119,119,272,272,272,272,272,272,272,272,272,272,272,272,272, +272,272,272,272,272,272,272,272,272,119,272,272,272,272,272,272, +272,119,272,272,119,272,272,119,272,272,119,119,270,119,271,271, +271,270,270,119,119,119,119,270,270,119,119,270,270,270,119,119, +119,270,119,119,119,119,119,119,119,272,272,272,272,119,272,119, +119,119,119,119,119,119,273,273,273,273,273,273,273,273,273,273, +270,270,272,272,272,270,274,119,119,119,119,119,119,119,119,119, /* block 21 */ -116,260,260,261,116,262,262,262,262,262,262,262,262,262,116,262, -262,262,116,262,262,262,262,262,262,262,262,262,262,262,262,262, -262,262,262,262,262,262,262,262,262,116,262,262,262,262,262,262, -262,116,262,262,116,262,262,262,262,262,116,116,260,262,261,261, -261,260,260,260,260,260,116,260,260,261,116,261,261,260,116,116, -262,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -262,262,260,260,116,116,263,263,263,263,263,263,263,263,263,263, -264,265,116,116,116,116,116,116,116,262,260,260,260,260,260,260, +119,275,275,276,119,277,277,277,277,277,277,277,277,277,119,277, +277,277,119,277,277,277,277,277,277,277,277,277,277,277,277,277, +277,277,277,277,277,277,277,277,277,119,277,277,277,277,277,277, +277,119,277,277,119,277,277,277,277,277,119,119,275,277,276,276, +276,275,275,275,275,275,119,275,275,276,119,276,276,275,119,119, +277,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +277,277,275,275,119,119,278,278,278,278,278,278,278,278,278,278, +279,280,119,119,119,119,119,119,119,277,275,275,275,275,275,275, /* block 22 */ -116,266,267,267,116,268,268,268,268,268,268,268,268,116,116,268, -268,116,116,268,268,268,268,268,268,268,268,268,268,268,268,268, -268,268,268,268,268,268,268,268,268,116,268,268,268,268,268,268, -268,116,268,268,116,268,268,268,268,268,116,116,266,268,269,266, -267,266,266,266,266,116,116,267,267,116,116,267,267,266,116,116, -116,116,116,116,116,116,266,269,116,116,116,116,268,268,116,268, -268,268,266,266,116,116,270,270,270,270,270,270,270,270,270,270, -271,268,272,272,272,272,272,272,116,116,116,116,116,116,116,116, +119,281,282,282,119,283,283,283,283,283,283,283,283,119,119,283, +283,119,119,283,283,283,283,283,283,283,283,283,283,283,283,283, +283,283,283,283,283,283,283,283,283,119,283,283,283,283,283,283, +283,119,283,283,119,283,283,283,283,283,119,119,281,283,284,281, +282,281,281,281,281,119,119,282,282,119,119,282,282,281,119,119, +119,119,119,119,119,119,281,284,119,119,119,119,283,283,119,283, +283,283,281,281,119,119,285,285,285,285,285,285,285,285,285,285, +286,283,287,287,287,287,287,287,119,119,119,119,119,119,119,119, /* block 23 */ -116,116,273,274,116,274,274,274,274,274,274,116,116,116,274,274, -274,116,274,274,274,274,116,116,116,274,274,116,274,116,274,274, -116,116,116,274,274,116,116,116,274,274,274,116,116,116,274,274, -274,274,274,274,274,274,274,274,274,274,116,116,116,116,275,276, -273,276,276,116,116,116,276,276,276,116,276,276,276,273,116,116, -274,116,116,116,116,116,116,275,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,277,277,277,277,277,277,277,277,277,277, -278,278,278,279,279,279,279,279,279,280,279,116,116,116,116,116, +119,119,288,289,119,289,289,289,289,289,289,119,119,119,289,289, +289,119,289,289,289,289,119,119,119,289,289,119,289,119,289,289, +119,119,119,289,289,119,119,119,289,289,289,119,119,119,289,289, +289,289,289,289,289,289,289,289,289,289,119,119,119,119,290,291, +288,291,291,119,119,119,291,291,291,119,291,291,291,288,119,119, +289,119,119,119,119,119,119,290,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,292,292,292,292,292,292,292,292,292,292, +293,293,293,294,295,295,295,295,295,296,295,119,119,119,119,119, /* block 24 */ -281,282,282,282,281,283,283,283,283,283,283,283,283,116,283,283, -283,116,283,283,283,283,283,283,283,283,283,283,283,283,283,283, -283,283,283,283,283,283,283,283,283,116,283,283,283,283,283,283, -283,283,283,283,283,283,283,283,283,283,116,116,116,283,281,281, -281,282,282,282,282,116,281,281,281,116,281,281,281,281,116,116, -116,116,116,116,116,281,281,116,283,283,283,116,116,116,116,116, -283,283,281,281,116,116,284,284,284,284,284,284,284,284,284,284, -116,116,116,116,116,116,116,116,285,285,285,285,285,285,285,286, +297,298,298,298,297,299,299,299,299,299,299,299,299,119,299,299, +299,119,299,299,299,299,299,299,299,299,299,299,299,299,299,299, +299,299,299,299,299,299,299,299,299,119,299,299,299,299,299,299, +299,299,299,299,299,299,299,299,299,299,119,119,119,299,297,297, +297,298,298,298,298,119,297,297,297,119,297,297,297,297,119,119, +119,119,119,119,119,297,297,119,299,299,299,119,119,119,119,119, +299,299,297,297,119,119,300,300,300,300,300,300,300,300,300,300, +119,119,119,119,119,119,119,119,301,301,301,301,301,301,301,302, /* block 25 */ -287,288,289,289,290,287,287,287,287,287,287,287,287,116,287,287, -287,116,287,287,287,287,287,287,287,287,287,287,287,287,287,287, -287,287,287,287,287,287,287,287,287,116,287,287,287,287,287,287, -287,287,287,287,116,287,287,287,287,287,116,116,288,287,289,288, -289,289,291,289,289,116,288,289,289,116,289,289,288,288,116,116, -116,116,116,116,116,291,291,116,116,116,116,116,116,116,287,116, -287,287,288,288,116,116,292,292,292,292,292,292,292,292,292,292, -116,287,287,116,116,116,116,116,116,116,116,116,116,116,116,116, +303,304,305,305,306,303,303,303,303,303,303,303,303,119,303,303, +303,119,303,303,303,303,303,303,303,303,303,303,303,303,303,303, +303,303,303,303,303,303,303,303,303,119,303,303,303,303,303,303, +303,303,303,303,119,303,303,303,303,303,119,119,304,303,305,304, +305,305,307,305,305,119,304,305,305,119,305,305,304,304,119,119, +119,119,119,119,119,307,307,119,119,119,119,119,119,119,303,119, +303,303,304,304,119,119,308,308,308,308,308,308,308,308,308,308, +119,303,303,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 26 */ -293,293,294,294,116,295,295,295,295,295,295,295,295,116,295,295, -295,116,295,295,295,295,295,295,295,295,295,295,295,295,295,295, -295,295,295,295,295,295,295,295,295,295,295,295,295,295,295,295, -295,295,295,295,295,295,295,295,295,295,295,293,293,295,296,294, -294,293,293,293,293,116,294,294,294,116,294,294,294,293,297,298, -116,116,116,116,295,295,295,296,299,299,299,299,299,299,299,295, -295,295,293,293,116,116,300,300,300,300,300,300,300,300,300,300, -299,299,299,299,299,299,299,299,299,298,295,295,295,295,295,295, +309,309,310,310,119,311,311,311,311,311,311,311,311,119,311,311, +311,119,311,311,311,311,311,311,311,311,311,311,311,311,311,311, +311,311,311,311,311,311,311,311,311,311,311,311,311,311,311,311, +311,311,311,311,311,311,311,311,311,311,311,309,309,311,312,310, +310,309,309,309,309,119,310,310,310,119,310,310,310,309,313,314, +119,119,119,119,311,311,311,312,315,315,315,315,315,315,315,311, +311,311,309,309,119,119,316,316,316,316,316,316,316,316,316,316, +315,315,315,315,315,315,315,315,315,314,311,311,311,311,311,311, /* block 27 */ -116,116,301,301,116,302,302,302,302,302,302,302,302,302,302,302, -302,302,302,302,302,302,302,116,116,116,302,302,302,302,302,302, -302,302,302,302,302,302,302,302,302,302,302,302,302,302,302,302, -302,302,116,302,302,302,302,302,302,302,302,302,116,302,116,116, -302,302,302,302,302,302,302,116,116,116,303,116,116,116,116,304, -301,301,303,303,303,116,303,116,301,301,301,301,301,301,301,304, -116,116,116,116,116,116,305,305,305,305,305,305,305,305,305,305, -116,116,301,301,306,116,116,116,116,116,116,116,116,116,116,116, +119,119,317,317,119,318,318,318,318,318,318,318,318,318,318,318, +318,318,318,318,318,318,318,119,119,119,318,318,318,318,318,318, +318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318, +318,318,119,318,318,318,318,318,318,318,318,318,119,318,119,119, +318,318,318,318,318,318,318,119,119,119,319,119,119,119,119,320, +317,317,319,319,319,119,319,119,317,317,317,317,317,317,317,320, +119,119,119,119,119,119,321,321,321,321,321,321,321,321,321,321, +119,119,317,317,322,119,119,119,119,119,119,119,119,119,119,119, /* block 28 */ -116,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307, -307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307, -307,307,307,307,307,307,307,307,307,307,307,307,307,307,307,307, -307,308,307,309,308,308,308,308,308,308,308,116,116,116,116, 5, -307,307,307,307,307,307,310,308,308,308,308,308,308,308,308,311, -312,312,312,312,312,312,312,312,312,312,311,311,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +119,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323, +323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323, +323,323,323,323,323,323,323,323,323,323,323,323,323,323,323,323, +323,324,323,325,324,324,324,324,324,324,324,119,119,119,119, 6, +323,323,323,323,323,323,326,324,324,324,324,324,324,324,324,327, +328,328,328,328,328,328,328,328,328,328,327,327,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 29 */ -116,313,313,116,313,116,116,313,313,116,313,116,116,313,116,116, -116,116,116,116,313,313,313,313,116,313,313,313,313,313,313,313, -116,313,313,313,116,313,116,313,116,116,313,313,116,313,313,313, -313,314,313,315,314,314,314,314,314,314,116,314,314,313,116,116, -313,313,313,313,313,116,316,116,314,314,314,314,314,314,116,116, -317,317,317,317,317,317,317,317,317,317,116,116,313,313,313,313, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +119,329,329,119,329,119,119,329,329,119,329,119,119,329,119,119, +119,119,119,119,329,329,329,329,119,329,329,329,329,329,329,329, +119,329,329,329,119,329,119,329,119,119,329,329,119,329,329,329, +329,330,329,331,330,330,330,330,330,330,119,330,330,329,119,119, +329,329,329,329,329,119,332,119,330,330,330,330,330,330,119,119, +333,333,333,333,333,333,333,333,333,333,119,119,329,329,329,329, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 30 */ -318,319,319,319,320,320,320,320,320,320,320,320,320,320,320,320, -320,320,320,319,320,319,319,319,321,321,319,319,319,319,319,319, -322,322,322,322,322,322,322,322,322,322,323,323,323,323,323,323, -323,323,323,323,319,321,319,321,319,321,324,325,324,325,326,326, -318,318,318,318,318,318,318,318,116,318,318,318,318,318,318,318, -318,318,318,318,318,318,318,318,318,318,318,318,318,318,318,318, -318,318,318,318,318,318,318,318,318,318,318,318,318,116,116,116, -116,321,321,321,321,321,321,321,321,321,321,321,321,321,321,326, +334,335,335,335,336,336,336,336,336,336,336,336,336,336,336,336, +336,336,336,335,336,335,335,335,337,337,335,335,335,335,335,335, +338,338,338,338,338,338,338,338,338,338,339,339,339,339,339,339, +339,339,339,339,335,337,335,337,335,337,340,341,340,341,342,342, +334,334,334,334,334,334,334,334,119,334,334,334,334,334,334,334, +334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334, +334,334,334,334,334,334,334,334,334,334,334,334,334,119,119,119, +119,337,337,337,337,337,337,337,337,337,337,337,337,337,337,342, /* block 31 */ -321,321,321,321,321,320,321,321,318,318,318,318,318,321,321,321, -321,321,321,321,321,321,321,321,116,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,321,321,321, -321,321,321,321,321,321,321,321,321,321,321,321,321,116,319,319, -319,319,319,319,319,319,321,319,319,319,319,319,319,116,319,319, -320,320,320,320,320, 19, 19, 19, 19,320,320,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +337,337,337,337,337,336,337,337,334,334,334,334,334,337,337,337, +337,337,337,337,337,337,337,337,119,337,337,337,337,337,337,337, +337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337, +337,337,337,337,337,337,337,337,337,337,337,337,337,119,335,335, +335,335,335,335,335,335,337,335,335,335,335,335,335,119,335,335, +336,336,336,336,336, 20, 20, 20, 20,336,336,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 32 */ -327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327, -327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327, -327,327,327,327,327,327,327,327,327,327,327,328,328,329,329,329, -329,330,329,329,329,329,329,329,328,329,329,330,330,329,329,327, -331,331,331,331,331,331,331,331,331,331,332,332,332,332,332,332, -327,327,327,327,327,327,330,330,329,329,327,327,327,327,329,329, -329,327,328,328,328,327,327,328,328,328,328,328,328,328,327,327, -327,329,329,329,329,327,327,327,327,327,327,327,327,327,327,327, +343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343, +343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343, +343,343,343,343,343,343,343,343,343,343,343,344,344,345,345,345, +345,346,345,345,345,345,345,345,344,345,345,346,346,345,345,343, +347,347,347,347,347,347,347,347,347,347,348,348,348,348,348,348, +343,343,343,343,343,343,346,346,345,345,343,343,343,343,345,345, +345,343,344,344,344,343,343,344,344,344,344,344,344,344,343,343, +343,345,345,345,345,343,343,343,343,343,343,343,343,343,343,343, /* block 33 */ -327,327,329,328,330,329,329,328,328,328,328,328,328,329,327,328, -331,331,331,331,331,331,331,331,331,331,328,328,328,329,333,333, -334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334, -334,334,334,334,334,334,334,334,334,334,334,334,334,334,334,334, -334,334,334,334,334,334,116,334,116,116,116,116,116,334,116,116, -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,335,335,335,335,335,335,335, 4,336,335,335,335, +343,343,345,344,346,345,345,344,344,344,344,344,344,345,343,344, +349,349,349,349,349,349,349,349,349,349,344,344,344,345,350,350, +351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351, +351,351,351,351,351,351,351,351,351,351,351,351,351,351,351,351, +351,351,351,351,351,351,119,351,119,119,119,119,119,351,119,119, +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,352,352,352,352,352,353,354,352,352,352, /* block 34 */ -337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337, -337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337, -337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337, -337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337, -337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337, -337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337, -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, +355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, +355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, +355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, +355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, +355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, +355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, +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, /* block 35 */ -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,338,338,338,338,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,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, -339,339,339,339,339,339,339,339,339,339,339,339,339,339,339,339, +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,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, /* block 36 */ -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,116,340,340,340,340,116,116, -340,340,340,340,340,340,340,116,340,116,340,340,340,340,116,116, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +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,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +358,358,358,358,358,358,358,358,358,119,358,358,358,358,119,119, +358,358,358,358,358,358,358,119,358,119,358,358,358,358,119,119, +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 37 */ -340,340,340,340,340,340,340,340,340,116,340,340,340,340,116,116, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,116,340,340,340,340,116,116,340,340,340,340,340,340,340,116, -340,116,340,340,340,340,116,116,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,116,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, +358,358,358,358,358,358,358,358,358,119,358,358,358,358,119,119, +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,119,358,358,358,358,119,119,358,358,358,358,358,358,358,119, +358,119,358,358,358,358,119,119,358,358,358,358,358,358,358,358, +358,358,358,358,358,358,358,119,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 38 */ -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,116,340,340,340,340,116,116,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,340,340,340,340,116,116,341,341,341, -342,342,342,342,342,342,342,342,342,343,343,343,343,343,343,343, -343,343,343,343,343,343,343,343,343,343,343,343,343,116,116,116, +358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +358,119,358,358,358,358,119,119,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,358,358,358,358,358,358,358, +358,358,358,358,358,358,358,358,358,358,358,119,119,359,359,359, +360,360,360,360,360,360,360,360,360,361,361,361,361,361,361,361, +361,361,361,361,361,361,361,361,361,361,361,361,361,119,119,119, /* block 39 */ -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -344,344,344,344,344,344,344,344,344,344,116,116,116,116,116,116, -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,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,346,346,346,346,116,116,347,347,347,347,347,347,116,116, +358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +362,362,362,362,362,362,362,362,362,362,119,119,119,119,119,119, +363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363, +363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363, +363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363, +363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363, +363,363,363,363,363,363,363,363,363,363,363,363,363,363,363,363, +364,364,364,364,364,364,119,119,365,365,365,365,365,365,119,119, /* block 40 */ -348,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, +366,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, /* block 41 */ -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, /* block 42 */ -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,350,350,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,368,368,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, /* block 43 */ -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,353,354,116,116,116, -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, -355,355,355,355,355,355,355,355,355,355,355, 4, 4, 4,356,356, -356,355,355,355,355,355,355,355,355,116,116,116,116,116,116,116, +369,370,370,370,370,370,370,370,370,370,370,370,370,370,370,370, +370,370,370,370,370,370,370,370,370,370,370,371,372,119,119,119, +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,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,373,373,373,373,373,373,373,373,373,373,373,373, +373,373,373,373,373,373,373,373,373,373,373, 5, 5, 5,374,374, +374,373,373,373,373,373,373,373,373,119,119,119,119,119,119,119, /* block 44 */ -357,357,357,357,357,357,357,357,357,357,357,357,357,116,357,357, -357,357,358,358,358,116,116,116,116,116,116,116,116,116,116,116, -359,359,359,359,359,359,359,359,359,359,359,359,359,359,359,359, -359,359,360,360,360, 4, 4,116,116,116,116,116,116,116,116,116, -361,361,361,361,361,361,361,361,361,361,361,361,361,361,361,361, -361,361,362,362,116,116,116,116,116,116,116,116,116,116,116,116, -363,363,363,363,363,363,363,363,363,363,363,363,363,116,363,363, -363,116,364,364,116,116,116,116,116,116,116,116,116,116,116,116, +375,375,375,375,375,375,375,375,375,375,375,375,375,119,375,375, +375,375,376,376,376,119,119,119,119,119,119,119,119,119,119,119, +377,377,377,377,377,377,377,377,377,377,377,377,377,377,377,377, +377,377,378,378,378,379,379,119,119,119,119,119,119,119,119,119, +380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380, +380,380,381,381,119,119,119,119,119,119,119,119,119,119,119,119, +382,382,382,382,382,382,382,382,382,382,382,382,382,119,382,382, +382,119,383,383,119,119,119,119,119,119,119,119,119,119,119,119, /* block 45 */ -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,367,366,366,366,366,366,366,366,367,367, -367,367,367,367,367,367,366,367,367,366,366,366,366,366,366,366, -366,366,366,366,368,368,368,369,368,368,368,370,365,366,116,116, -371,371,371,371,371,371,371,371,371,371,116,116,116,116,116,116, -372,372,372,372,372,372,372,372,372,372,116,116,116,116,116,116, +384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384, +384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384, +384,384,384,384,384,384,384,384,384,384,384,384,384,384,384,384, +384,384,384,384,385,385,386,385,385,385,385,385,385,385,386,386, +386,386,386,386,386,386,385,386,386,385,385,385,385,385,385,385, +385,385,385,385,387,387,387,388,387,387,387,389,384,385,119,119, +390,390,390,390,390,390,390,390,390,390,119,119,119,119,119,119, +391,391,391,391,391,391,391,391,391,391,119,119,119,119,119,119, /* block 46 */ -373,373, 4, 4,373, 4,374,373,373,373,373,375,375,375,376,116, -377,377,377,377,377,377,377,377,377,377,116,116,116,116,116,116, -378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, -378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, -378,378,378,379,378,378,378,378,378,378,378,378,378,378,378,378, -378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, -378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, -378,378,378,378,378,378,378,378,378,116,116,116,116,116,116,116, +392,392,393,393,392,393,394,392,392,392,392,395,395,395,396,119, +397,397,397,397,397,397,397,397,397,397,119,119,119,119,119,119, +398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, +398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, +398,398,398,399,398,398,398,398,398,398,398,398,398,398,398,398, +398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, +398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, +398,398,398,398,398,398,398,398,398,119,119,119,119,119,119,119, /* block 47 */ -378,378,378,378,378,375,375,378,378,378,378,378,378,378,378,378, -378,378,378,378,378,378,378,378,378,378,378,378,378,378,378,378, -378,378,378,378,378,378,378,378,378,375,378,116,116,116,116,116, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,349,349,349,349,349,349,349,349,349,349, -349,349,349,349,349,349,116,116,116,116,116,116,116,116,116,116, +398,398,398,398,398,395,395,398,398,398,398,398,398,398,398,398, +398,398,398,398,398,398,398,398,398,398,398,398,398,398,398,398, +398,398,398,398,398,398,398,398,398,395,398,119,119,119,119,119, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,367,367,367,367,367,367,367,367,367,367, +367,367,367,367,367,367,119,119,119,119,119,119,119,119,119,119, /* block 48 */ -380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,380, -380,380,380,380,380,380,380,380,380,380,380,380,380,380,380,116, -381,381,381,382,382,382,382,381,381,382,382,382,116,116,116,116, -382,382,381,382,382,382,382,382,382,381,381,381,116,116,116,116, -383,116,116,116,384,384,385,385,385,385,385,385,385,385,385,385, -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,116,116, -386,386,386,386,386,116,116,116,116,116,116,116,116,116,116,116, +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,119, +401,401,401,402,402,402,402,401,401,402,402,402,119,119,119,119, +402,402,401,402,402,402,402,402,402,401,401,401,119,119,119,119, +403,119,119,119,404,404,405,405,405,405,405,405,405,405,405,405, +406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406, +406,406,406,406,406,406,406,406,406,406,406,406,406,406,119,119, +406,406,406,406,406,119,119,119,119,119,119,119,119,119,119,119, /* block 49 */ -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,116,116,116,116, -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,116,116,116,116,116,116, -388,388,388,388,388,388,388,388,388,388,389,116,116,116,390,390, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, -391,391,391,391,391,391,391,391,391,391,391,391,391,391,391,391, +407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407, +407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407, +407,407,407,407,407,407,407,407,407,407,407,407,119,119,119,119, +407,407,407,407,407,407,407,407,407,407,407,407,407,407,407,407, +407,407,407,407,407,407,407,407,407,407,119,119,119,119,119,119, +408,408,408,408,408,408,408,408,408,408,409,119,119,119,410,410, +411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411, +411,411,411,411,411,411,411,411,411,411,411,411,411,411,411,411, /* block 50 */ -392,392,392,392,392,392,392,392,392,392,392,392,392,392,392,392, -392,392,392,392,392,392,392,393,393,394,394,393,116,116,395,395, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,396,396,396,396,396,396,396,396,396,396,396, -396,396,396,396,396,397,398,397,398,398,398,398,398,398,398,116, -398,399,398,399,399,398,398,398,398,398,398,398,398,397,397,397, -397,397,397,398,398,398,398,398,398,398,398,398,398,116,116,398, +412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, +412,412,412,412,412,412,412,413,413,414,414,413,119,119,415,415, +416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, +416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, +416,416,416,416,416,416,416,416,416,416,416,416,416,416,416,416, +416,416,416,416,416,417,418,417,418,418,418,418,418,418,418,119, +418,419,418,419,419,418,418,418,418,418,418,418,418,417,417,417, +417,417,417,418,418,418,418,418,418,418,418,418,418,119,119,418, /* block 51 */ -400,400,400,400,400,400,400,400,400,400,116,116,116,116,116,116, -400,400,400,400,400,400,400,400,400,400,116,116,116,116,116,116, -401,401,401,401,401,401,401,402,401,401,401,401,401,401,116,116, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,403,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +420,420,420,420,420,420,420,420,420,420,119,119,119,119,119,119, +420,420,420,420,420,420,420,420,420,420,119,119,119,119,119,119, +421,421,421,421,421,421,421,422,421,421,421,421,421,421,119,119, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,423,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 52 */ -404,404,404,404,405,406,406,406,406,406,406,406,406,406,406,406, -406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406, -406,406,406,406,406,406,406,406,406,406,406,406,406,406,406,406, -406,406,406,406,404,405,404,404,404,404,404,405,404,405,405,405, -405,405,404,405,405,406,406,406,406,406,406,406,116,116,116,116, -407,407,407,407,407,407,407,407,407,407,408,408,408,408,408,408, -408,409,409,409,409,409,409,409,409,409,409,404,404,404,404,404, -404,404,404,404,409,409,409,409,409,409,409,409,409,116,116,116, +424,424,424,424,425,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,426,426,426,426,426,426,426,426,426,426,426,426, +426,426,426,426,424,425,424,424,424,424,424,425,424,425,425,425, +425,425,424,425,425,426,426,426,426,426,426,426,119,119,119,119, +427,427,427,427,427,427,427,427,427,427,428,428,428,428,428,428, +428,429,429,429,429,429,429,429,429,429,429,424,424,424,424,424, +424,424,424,424,429,429,429,429,429,429,429,429,429,119,119,119, /* block 53 */ -410,410,411,412,412,412,412,412,412,412,412,412,412,412,412,412, -412,412,412,412,412,412,412,412,412,412,412,412,412,412,412,412, -412,411,410,410,410,410,411,411,410,410,411,410,410,410,412,412, -413,413,413,413,413,413,413,413,413,413,412,412,412,412,412,412, -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, -414,414,414,414,414,414,415,416,415,415,416,416,416,415,416,415, -415,415,416,416,116,116,116,116,116,116,116,116,417,417,417,417, +430,430,431,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,432,432,432,432,432,432,432,432,432,432,432,432,432,432,432, +432,431,430,430,430,430,431,431,430,430,431,430,430,430,432,432, +433,433,433,433,433,433,433,433,433,433,432,432,432,432,432,432, +434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434, +434,434,434,434,434,434,434,434,434,434,434,434,434,434,434,434, +434,434,434,434,434,434,435,436,435,435,436,436,436,435,436,435, +435,435,436,436,119,119,119,119,119,119,119,119,437,437,437,437, /* block 54 */ -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,419,419,419,419,419,419,419,420,420,420,420, -420,420,420,420,419,419,420,420,116,116,116,421,421,421,421,421, -422,422,422,422,422,422,422,422,422,422,116,116,116,418,418,418, -423,423,423,423,423,423,423,423,423,423,424,424,424,424,424,424, -424,424,424,424,424,424,424,424,424,424,424,424,424,424,424,424, -424,424,424,424,424,424,424,424,425,425,425,425,425,425,426,426, +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,439,439,439,439,439,439,439,440,440,440,440, +440,440,440,440,439,439,440,440,119,119,119,441,441,441,441,441, +442,442,442,442,442,442,442,442,442,442,119,119,119,438,438,438, +443,443,443,443,443,443,443,443,443,443,444,444,444,444,444,444, +444,444,444,444,444,444,444,444,444,444,444,444,444,444,444,444, +444,444,444,444,444,444,444,444,445,445,445,445,445,445,446,446, /* block 55 */ -427,428,429,430,431,432,433,434,435,116,116,116,116,116,116,116, -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,436,436, -436,436,436,436,436,436,436,436,436,436,436,116,116,436,436,436, -437,437,437,437,437,437,437,437,116,116,116,116,116,116,116,116, -111,111,111, 4,111,111,111,111,111,111,111,111,111,111,111,111, -111,438,111,111,111,111,111,111,111,439,439,439,439,111,439,439, -439,439,438,438,111,439,439,438,111,111,116,116,116,116,116,116, +447,448,449,450,451,452,453,454,455,119,119,119,119,119,119,119, +456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, +456,456,456,456,456,456,456,456,456,456,456,456,456,456,456,456, +456,456,456,456,456,456,456,456,456,456,456,119,119,456,456,456, +457,457,457,457,457,457,457,457,119,119,119,119,119,119,119,119, +458,459,458,460,459,461,461,462,461,462,463,459,462,462,459,459, +462,464,459,459,459,459,459,459,459,465,466,465,465,461,465,465, +465,465,467,467,468,466,466,469,470,470,119,119,119,119,119,119, /* block 56 */ - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34,124,124,124,124,124,440,108,108,108,108, -108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, -108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, -108,108,108,108,108,108,108,108,108,108,108,108,108,117,117,117, -117,117,108,108,108,108,117,117,117,117,117, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34,441,442, 34, 34, 34,443, 34, 34, + 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,127,127,127,127,127,471,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,120,120,120, +120,120,109,109,109,109,120,120,120,120,120, 35, 35, 35, 35, 35, + 35, 35, 35, 35, 35, 35, 35, 35,472,473, 35, 35, 35,474, 35, 35, /* block 57 */ - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,108,108,108,108,108, -108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,108, -108,108,108,108,108,108,108,108,108,108,108,108,108,108,108,117, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,116,111,111,111,111,111, + 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,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,109, +109,109,109,109,109,109,109,109,109,109,109,109,109,109,109,120, +113,113,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,119,112,112,112,112,112, /* block 58 */ - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, -444,445, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, + 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, 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, +475,476, 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, /* block 59 */ - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 34, 34, 34, 34, 34,446, 34, 34,447, 34, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, + 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, 32, 33, + 32, 33, 32, 33, 32, 33, 35, 35, 35, 35, 35,477, 35, 35,478, 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, 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, /* block 60 */ -448,448,448,448,448,448,448,448,449,449,449,449,449,449,449,449, -448,448,448,448,448,448,116,116,449,449,449,449,449,449,116,116, -448,448,448,448,448,448,448,448,449,449,449,449,449,449,449,449, -448,448,448,448,448,448,448,448,449,449,449,449,449,449,449,449, -448,448,448,448,448,448,116,116,449,449,449,449,449,449,116,116, -124,448,124,448,124,448,124,448,116,449,116,449,116,449,116,449, -448,448,448,448,448,448,448,448,449,449,449,449,449,449,449,449, -450,450,451,451,451,451,452,452,453,453,454,454,455,455,116,116, +479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480, +479,479,479,479,479,479,119,119,480,480,480,480,480,480,119,119, +479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480, +479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480, +479,479,479,479,479,479,119,119,480,480,480,480,480,480,119,119, +127,479,127,479,127,479,127,479,119,480,119,480,119,480,119,480, +479,479,479,479,479,479,479,479,480,480,480,480,480,480,480,480, +481,481,482,482,482,482,483,483,484,484,485,485,486,486,119,119, /* block 61 */ -448,448,448,448,448,448,448,448,456,456,456,456,456,456,456,456, -448,448,448,448,448,448,448,448,456,456,456,456,456,456,456,456, -448,448,448,448,448,448,448,448,456,456,456,456,456,456,456,456, -448,448,124,457,124,116,124,124,449,449,458,458,459,115,460,115, -115,115,124,457,124,116,124,124,461,461,461,461,459,115,115,115, -448,448,124,124,116,116,124,124,449,449,462,462,116,115,115,115, -448,448,124,124,124,165,124,124,449,449,463,463,170,115,115,115, -116,116,124,457,124,116,124,124,464,464,465,465,459,115,115,116, +479,479,479,479,479,479,479,479,487,487,487,487,487,487,487,487, +479,479,479,479,479,479,479,479,487,487,487,487,487,487,487,487, +479,479,479,479,479,479,479,479,487,487,487,487,487,487,487,487, +479,479,127,488,127,119,127,127,480,480,489,489,490,118,491,118, +118,118,127,488,127,119,127,127,492,492,492,492,490,118,118,118, +479,479,127,127,119,119,127,127,480,480,493,493,119,118,118,118, +479,479,127,127,127,168,127,127,480,480,494,494,173,118,118,118, +119,119,127,488,127,119,127,127,495,495,496,496,490,118,118,119, /* block 62 */ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 23,466,467, 23, 23, - 9, 9, 9, 9, 9, 9, 4, 4, 22, 26, 6, 22, 22, 26, 6, 22, - 4, 4, 4, 4, 4, 4, 4, 4,468,469, 23, 23, 23, 23, 23, 3, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 22, 26, 4,470, 4, 4, 15, - 15, 4, 4, 4, 8, 6, 7, 4, 4,470, 4, 4, 4, 4, 4, 4, - 4, 4, 8, 4, 15, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, - 23, 23, 23, 23, 23,471, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 24,108,116,116, 24, 24, 24, 24, 24, 24, 8, 8, 8, 6, 7,108, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 24,497,498, 24, 24, + 10, 10, 10, 10, 10, 10, 5, 5, 23, 27, 7, 23, 23, 27, 7, 23, + 5, 5, 5, 5, 5, 5, 5, 5,499,500, 24, 24, 24, 24, 24, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 23, 27, 5,501, 5, 5, 16, + 16, 5, 5, 5, 9, 7, 8, 5, 5,501, 5, 5, 5, 5, 5, 5, + 5, 5, 9, 5, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, + 24, 24, 24, 24, 24,502, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25,109,119,119, 25, 25, 25, 25, 25, 25, 9, 9, 9, 7, 8,109, /* block 63 */ - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 8, 8, 8, 6, 7,116, -108,108,108,108,108,108,108,108,108,108,108,108,108,116,116,116, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -111,111,111,111,111,111,111,111,111,111,111,111,111,403,403,403, -403,111,403,403,403,111,111,111,111,111,111,111,111,111,111,111, -111,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 9, 9, 9, 7, 8,119, +109,109,109,109,109,109,109,109,109,109,109,109,109,119,119,119, + 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, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +112,112,112,112,112,112,112,112,112,112,112,112,112,423,423,423, +423,112,423,423,423,112,112,112,112,112,112,112,112,112,112,112, +503,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 64 */ - 19, 19,472, 19, 19, 19, 19,472, 19, 19,473,472,472,472,473,473, -472,472,472,473, 19,472, 19, 19, 8,472,472,472,472,472, 19, 19, - 19, 19, 20, 19,472, 19,474, 19,472, 19,475,476,472,472, 19,473, -472,472,477,472,473,439,439,439,439,478, 19, 19,473,473,472,472, - 8, 8, 8, 8, 8,472,473,473,473,473, 19, 8, 19, 19,479, 19, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -480,480,480,480,480,480,480,480,480,480,480,480,480,480,480,480, -481,481,481,481,481,481,481,481,481,481,481,481,481,481,481,481, + 20, 20,504, 20, 20, 20, 20,504, 20, 20,505,504,504,504,505,505, +504,504,504,505, 20,504, 20, 20, 9,504,504,504,504,504, 20, 20, + 20, 20, 21, 20,504, 20,506, 20,504, 20,507,508,504,504, 20,505, +504,504,509,504,505,510,510,510,510,511, 20, 20,505,505,504,504, + 9, 9, 9, 9, 9,504,505,505,505,505, 20, 9, 20, 20,512, 20, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +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, /* block 65 */ -482,482,482, 31, 32,482,482,482,482, 24, 19, 19,116,116,116,116, - 8, 8, 8, 8,483, 20, 20, 20, 20, 20, 8, 8, 19, 19, 19, 19, - 8, 19, 19, 8, 19, 19, 8, 19, 19, 20, 20, 19, 19, 19, 8, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, - 19, 19, 8, 19, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, +515,515,515, 32, 33,515,515,515,515, 25, 20, 20,119,119,119,119, + 9, 9, 9, 9,516, 21, 21, 21, 21, 21, 9, 9, 20, 20, 20, 20, + 9, 20, 20, 9, 20, 20, 9, 20, 20, 21, 21, 20, 20, 20, 9, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 9, 9, + 20, 20, 9, 20, 9, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* block 66 */ - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* block 67 */ - 19, 19, 19, 19, 19, 19, 19, 19, 6, 7, 6, 7, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 19, 19, 19, 19, - 8, 8, 19, 19, 19, 19, 19, 19, 20, 6, 7, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 19, 19, 19, + 20, 20, 20, 20, 20, 20, 20, 20, 7, 8, 7, 8, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 20, 20, 20, 20, + 9, 9, 20, 20, 20, 20, 20, 20, 21, 7, 8, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 9, 20, 20, 20, /* block 68 */ - 19, 19, 19, 19, 19, 19, 19, 19, 20, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8, 8, - 8, 8, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 19, 19, 19, 19, 20, 20, 20, 19, 19, 19, 19, 19, + 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, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 20, 20, 20, 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, 9, 9, 9, 9, + 9, 9, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 20, 20, 20, 20, 21, 21, 21, 20, 20, 20, 20, 20, /* block 69 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 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, /* block 70 */ - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19,484,484,484,484,484,484,484,484,484,484, -484,484,485,484,484,484,484,484,484,484,484,484,484,484,484,484, -486,486,486,486,486,486,486,486,486,486,486,486,486,486,486,486, -486,486,486,486,486,486,486,486,486,486, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 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, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20,517,517,517,517,517,517,517,517,517,517, +517,517,518,517,517,517,517,517,517,517,517,517,517,517,517,517, +519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, +519,519,519,519,519,519,519,519,519,519, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, /* block 71 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - -/* block 72 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 20, 8, 19, 19, 19, 19, 19, 19, 19, 19, - 20, 8, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 8, 8, 8,483,483,483,483, 8, - -/* block 73 */ - 20, 20, 20, 20, 20, 20, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,483, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - -/* block 74 */ - 20, 20, 20, 20, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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 72 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 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, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 21, 9, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 9, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 9, 9, 9,516,516,516,516, 9, + +/* block 73 */ + 21, 21, 21, 21, 21, 21, 20, 21, 21, 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, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,516, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + +/* block 74 */ + 21, 21, 21, 21, 21, 21, 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, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 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 75 */ - 20, 20, 20, 20, 20, 20, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 19, 20, 19, 20, 19, 19, 19, 19, 19, 19, 20, 19, 19, - 19, 20, 19, 19, 19, 19, 19, 19, 20, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 20, 19, 19, 20, 19, 19, 19, 19, 20, 19, 20, 19, - 19, 19, 19, 20, 20, 20, 19, 20, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 20, 20, 20, 20, 20, 6, 7, 6, 7, 6, 7, 6, 7, - 6, 7, 6, 7, 6, 7, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 21, 21, 21, 21, 21, 21, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 20, 21, 20, 21, 20, 20, 20, 20, 20, 20, 21, 20, 20, + 20, 21, 20, 20, 20, 20, 20, 20, 21, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 21, 20, 20, 21, 20, 20, 20, 20, 21, 20, 21, 20, + 20, 20, 20, 21, 21, 21, 20, 21, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 21, 21, 21, 21, 21, 7, 8, 7, 8, 7, 8, 7, 8, + 7, 8, 7, 8, 7, 8, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, /* block 76 */ - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 19, 20, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 20, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 20, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, - 8, 8, 8, 8, 8, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 20, 21, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 21, 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, 21, + 9, 9, 9, 9, 9, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* block 77 */ -487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, -487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, -487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, -487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, -487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, -487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, -487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, -487,487,487,487,487,487,487,487,487,487,487,487,487,487,487,487, +520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, +520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, +520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, +520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, +520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, +520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, +520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, +520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, /* block 78 */ - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8,483,483, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9,516,516, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, /* block 79 */ - 8, 8, 8, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, - 7, 6, 7, 6, 7, 6, 7, 6, 7, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 6, 7, 6, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 7, 8, 8, + 9, 9, 9, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, + 8, 7, 8, 7, 8, 7, 8, 7, 8, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 7, 8, 7, 8, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 8, 9, 9, /* block 80 */ - 19, 19, 19, 19, 19, 20, 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 19, 19, 8, 8, 8, 8, 8, 8, 19, 19, 19, - 20, 19, 19, 19, 19, 20, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19,116,116, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 20, 20, 20, 20, 20, 21, 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 20, 20, 9, 9, 9, 9, 9, 9, 20, 20, 20, + 21, 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,119,119, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, /* block 81 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19,116,116, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19,116, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,116, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20,119,119, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20,119, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119, /* block 82 */ -488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488, -488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,488, -488,488,488,488,488,488,488,488,488,488,488,488,488,488,488,116, -489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, -489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,489, -489,489,489,489,489,489,489,489,489,489,489,489,489,489,489,116, - 31, 32,490,491,492,493,494, 31, 32, 31, 32, 31, 32,495,496,497, -498, 34, 31, 32, 34, 31, 32, 34, 34, 34, 34, 34,108,108,499,499, +521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, +521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, +521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,119, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, +522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,119, + 32, 33,523,524,525,526,527, 32, 33, 32, 33, 32, 33,528,529,530, +531, 35, 32, 33, 35, 32, 33, 35, 35, 35, 35, 35,109,109,532,532, /* block 83 */ -161,162,161,162,161,162,161,162,161,162,161,162,161,162,161,162, -161,162,161,162,161,162,161,162,161,162,161,162,161,162,161,162, -161,162,161,162,161,162,161,162,161,162,161,162,161,162,161,162, -161,162,161,162,161,162,161,162,161,162,161,162,161,162,161,162, -161,162,161,162,161,162,161,162,161,162,161,162,161,162,161,162, -161,162,161,162,161,162,161,162,161,162,161,162,161,162,161,162, -161,162,161,162,500,501,501,501,501,501,501,161,162,161,162,502, -502,502,161,162,116,116,116,116,116,503,503,503,503,504,503,503, +164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, +164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, +164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, +164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, +164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, +164,165,164,165,164,165,164,165,164,165,164,165,164,165,164,165, +164,165,164,165,533,534,534,534,534,534,534,164,165,164,165,535, +535,535,164,165,119,119,119,119,119,536,536,536,536,537,536,536, /* block 84 */ -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, -505,505,505,505,505,505,116,505,116,116,116,116,116,505,116,116, -506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, -506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, -506,506,506,506,506,506,506,506,506,506,506,506,506,506,506,506, -506,506,506,506,506,506,506,506,116,116,116,116,116,116,116,507, -508,116,116,116,116,116,116,116,116,116,116,116,116,116,116,509, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +538,538,538,538,538,538,119,538,119,119,119,119,119,538,119,119, +539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, +539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, +539,539,539,539,539,539,539,539,539,539,539,539,539,539,539,539, +539,539,539,539,539,539,539,539,119,119,119,119,119,119,119,540, +541,119,119,119,119,119,119,119,119,119,119,119,119,119,119,542, /* block 85 */ -340,340,340,340,340,340,340,340,340,340,340,340,340,340,340,340, -340,340,340,340,340,340,340,116,116,116,116,116,116,116,116,116, -340,340,340,340,340,340,340,116,340,340,340,340,340,340,340,116, -340,340,340,340,340,340,340,116,340,340,340,340,340,340,340,116, -340,340,340,340,340,340,340,116,340,340,340,340,340,340,340,116, -340,340,340,340,340,340,340,116,340,340,340,340,340,340,340,116, -193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, -193,193,193,193,193,193,193,193,193,193,193,193,193,193,193,193, +358,358,358,358,358,358,358,358,358,358,358,358,358,358,358,358, +358,358,358,358,358,358,358,119,119,119,119,119,119,119,119,119, +358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119, +358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119, +358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119, +358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119, +543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, +543,543,543,543,543,543,543,543,543,543,543,543,543,543,543,543, /* block 86 */ - 4, 4, 22, 26, 22, 26, 4, 4, 4, 22, 26, 4, 22, 26, 4, 4, - 4, 4, 4, 4, 4, 4, 4, 9, 4, 4, 9, 4, 22, 26, 4, 4, - 22, 26, 6, 7, 6, 7, 6, 7, 6, 7, 4, 4, 4, 4, 4,109, - 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 9, 9, 4, 4, 4, 4, - 9, 4, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, + 5, 5, 23, 27, 23, 27, 5, 5, 5, 23, 27, 5, 23, 27, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 10, 5, 5, 10, 5, 23, 27, 5, 5, + 23, 27, 7, 8, 7, 8, 7, 8, 7, 8, 5, 5, 5, 5, 5,110, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 5, 5, 5, 5, + 10, 5, 7,544, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 87 */ -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,116,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,116,116,116,116,116,116,116,116,116,116,116,116, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,119,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,119,119,119,119,119,119,119,119,119,119,119,119, /* block 88 */ -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, /* block 89 */ -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,510,510,510,510,510,510,510,510,510,510, -510,510,510,510,510,510,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,116,116,116,116, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,545,545,545,545,545,545,545,545,545,545, +545,545,545,545,545,545,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119, /* block 90 */ - 3, 4, 4, 4, 19,511,439,512, 6, 7, 6, 7, 6, 7, 6, 7, - 6, 7, 19, 19, 6, 7, 6, 7, 6, 7, 6, 7, 9, 6, 7, 7, - 19,512,512,512,512,512,512,512,512,512,111,111,111,111,513,513, -514,109,109,109,109,109, 19, 19,512,512,512,511,439,470, 19, 19, -116,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, + 4,546,546,547, 20,548,549,550,551,552,551,552,551,552,551,552, +551,552, 20,553,551,552,551,552,551,552,551,552,554,555,556,556, + 20,550,550,550,550,550,550,550,550,550,557,557,557,557,558,558, +559,560,560,560,560,560, 20,553,550,550,550,548,561,562,563,563, +119,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, /* block 91 */ -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,116,116,111,111, 14, 14,516,516,515, - 9,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,517,517,517,517,517,517,517,517, 4,109,518,518,517, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,119,119,565,565,566,566,567,567,564, +568,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, +569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, +569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, +569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, +569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, +569,569,569,569,569,569,569,569,569,569,569,546,560,570,570,569, /* block 92 */ -116,116,116,116,116,519,519,519,519,519,519,519,519,519,519,519, -519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, -519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, -116,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, +119,119,119,119,119,571,571,571,571,571,571,571,571,571,571,571, +571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571, +571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571, +119,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,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,572,572,572,572,572,572,572, /* block 93 */ -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,116, - 19, 19, 24, 24, 24, 24, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, -519,519,519,519,519,519,519,519,519,519,519,519,519,519,519,519, -519,519,519,519,519,519,519,519,519,519,519,116,116,116,116,116, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19,116,116,116,116,116,116,116,116,116,116,116,116, -517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, +572,572,572,572,572,572,572,572,572,572,572,572,572,572,572,119, +563,563,573,573,573,573,563,563,563,563,563,563,563,563,563,563, +571,571,571,571,571,571,571,571,571,571,571,571,571,571,571,571, +571,571,571,571,571,571,571,571,571,571,571,119,119,119,119,119, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,119,119,119,119,119,119,119,119,119,119,119,119, +569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, /* block 94 */ -521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, -521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,116, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 24, 24, 24, 24, 24, 24, 24, 24, - 19, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -521,521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, -521,521,521,521,521,521,521,521,521,521,521,521,521,521,521, 19, +574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574, +574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,119, +573,573,573,573,573,573,573,573,573,573,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,563,563,563, 25, 25, 25, 25, 25, 25, 25, 25, + 20, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +574,574,574,574,574,574,574,574,574,574,574,574,574,574,574,574, +574,574,574,574,574,574,574,574,574,574,574,574,574,574,574, 20, /* block 95 */ - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 20, 19, 20, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,116, +573,573,573,573,573,573,573,573,573,573,563,563,563,563,563,563, +563,563,563,563,563,563,563,575,563,575,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, +563,563,563,563,563,563,563,563,563,563,563,563, 20, 20, 20, 20, +576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, +576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, +576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,119, /* block 96 */ -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, -522,522,522,522,522,522,522,522,522,522,522,522,522,522,522,522, -522,522,522,522,522,522,522,522, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, +576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, +576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, +576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, +576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, +576,576,576,576,576,576,576,576,576,576,576,576,576,576,576,576, +576,576,576,576,576,576,576,576,563,563,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,563,563,563,563,563, /* block 97 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, +563,563,563,563,563,563,563,563,563,563,563,563,563,563,563, 20, /* block 98 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,116,116,116,116,116,116,116,116,116,116, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, /* block 99 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,119,119,119,119,119,119,119,119,119,119, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 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 100 */ -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,525,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 101 */ -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, -524,524,524,524,524,524,524,524,524,524,524,524,524,524,524,524, +578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, +578,578,578,578,578,579,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,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,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, +578,578,578,578,578,578,578,578,578,578,578,578,578,578,578,578, /* block 102 */ -524,524,524,524,524,524,524,524,524,524,524,524,524,116,116,116, -526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526, -526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526, -526,526,526,526,526,526,526,526,526,526,526,526,526,526,526,526, -526,526,526,526,526,526,526,116,116,116,116,116,116,116,116,116, -527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527, -527,527,527,527,527,527,527,527,527,527,527,527,527,527,527,527, -527,527,527,527,527,527,527,527,528,528,528,528,528,528,529,529, +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,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,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,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,578,578,578,578,578,578,578,578, /* block 103 */ -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, +578,578,578,578,578,578,578,578,578,578,578,578,578,119,119,119, +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,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,580,119,119,119,119,119,119,119,119,119, +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,581, +581,581,581,581,581,581,581,581,582,582,582,582,582,582,583,583, /* block 104 */ -530,530,530,530,530,530,530,530,530,530,530,530,531,532,532,532, -530,530,530,530,530,530,530,530,530,530,530,530,530,530,530,530, -533,533,533,533,533,533,533,533,533,533,530,530,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -188,189,188,189,188,189,188,189,188,189,534,535,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,188,189,536,193, -194,194,194,537,193,193,193,193,193,193,193,193,193,193,537,441, +584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, +584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, +584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, +584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, +584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, +584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, +584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, +584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, /* block 105 */ -188,189,188,189,188,189,188,189,188,189,188,189,188,189,188,189, -188,189,188,189,188,189,188,189,188,189,188,189,441,441,193,193, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,539,539,539,539,539,539,539,539,539,539, -540,540,541,541,541,541,541,541,116,116,116,116,116,116,116,116, +584,584,584,584,584,584,584,584,584,584,584,584,585,586,586,586, +584,584,584,584,584,584,584,584,584,584,584,584,584,584,584,584, +587,587,587,587,587,587,587,587,587,587,584,584,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +191,192,191,192,191,192,191,192,191,192,588,589,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,590,197, +199,199,199,591,543,543,543,543,543,543,543,543,543,543,591,472, /* block 106 */ - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14,109,109,109,109,109,109,109,109,109, - 14, 14, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 34, 34, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, -108, 34, 34, 34, 34, 34, 34, 34, 34, 31, 32, 31, 32,542, 31, 32, +191,192,191,192,191,192,191,192,191,192,191,192,191,192,191,192, +191,192,191,192,191,192,191,192,191,192,191,192,472,472,543,543, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,593,593,593,593,593,593,593,593,593,593, +594,594,595,595,595,595,595,595,119,119,119,119,119,119,119,119, /* block 107 */ - 31, 32, 31, 32, 31, 32, 31, 32,109, 14, 14, 31, 32,543, 34, 21, - 31, 32, 31, 32, 34, 34, 31, 32, 31, 32, 31, 32, 31, 32, 31, 32, - 31, 32, 31, 32, 31, 32, 31, 32, 31, 32,544,545,546,547,544, 34, -548,549,550,551, 31, 32, 31, 32, 31, 32,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116, 21,108,108, 34, 21, 21, 21, 21, 21, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15,110,110,110,110,110,110,110,110,110, + 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, +109, 35, 35, 35, 35, 35, 35, 35, 35, 32, 33, 32, 33,596, 32, 33, /* block 108 */ -552,552,553,552,552,552,553,552,552,552,552,553,552,552,552,552, -552,552,552,552,552,552,552,552,552,552,552,552,552,552,552,552, -552,552,552,554,554,553,553,554,555,555,555,555,116,116,116,116, - 24, 24, 24, 24, 24, 24, 19, 19, 5, 19,116,116,116,116,116,116, -556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556, -556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556, -556,556,556,556,556,556,556,556,556,556,556,556,556,556,556,556, -556,556,556,556,557,557,557,557,116,116,116,116,116,116,116,116, + 32, 33, 32, 33, 32, 33, 32, 33,110, 15, 15, 32, 33,597, 35, 22, + 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,598,599,600,601,598, 35, +602,603,604,605, 32, 33, 32, 33, 32, 33,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119, 22,109,109, 35, 22, 22, 22, 22, 22, /* block 109 */ -558,558,559,559,559,559,559,559,559,559,559,559,559,559,559,559, -559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, -559,559,559,559,559,559,559,559,559,559,559,559,559,559,559,559, -559,559,559,559,558,558,558,558,558,558,558,558,558,558,558,558, -558,558,558,558,560,560,116,116,116,116,116,116,116,116,561,561, -562,562,562,562,562,562,562,562,562,562,116,116,116,116,116,116, -240,240,240,240,240,240,240,240,240,240,240,240,240,240,240,240, -240,240,242,242,242,242,242,242,244,244,244,242,244,242,242,240, +606,606,607,606,606,606,607,606,606,606,606,607,606,606,606,606, +606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606, +606,606,606,608,608,607,607,608,609,609,609,609,119,119,119,119, +610,610,610,611,611,611,612,612,613,612,119,119,119,119,119,119, +614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614, +614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614, +614,614,614,614,614,614,614,614,614,614,614,614,614,614,614,614, +614,614,614,614,615,615,615,615,119,119,119,119,119,119,119,119, /* block 110 */ -563,563,563,563,563,563,563,563,563,563,564,564,564,564,564,564, -564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, -564,564,564,564,564,564,565,565,565,565,565,565,565,565, 4,566, -567,567,567,567,567,567,567,567,567,567,567,567,567,567,567,567, -567,567,567,567,567,567,567,568,568,568,568,568,568,568,568,568, -568,568,569,569,116,116,116,116,116,116,116,116,116,116,116,570, -337,337,337,337,337,337,337,337,337,337,337,337,337,337,337,337, -337,337,337,337,337,337,337,337,337,337,337,337,337,116,116,116, +616,616,617,617,617,617,617,617,617,617,617,617,617,617,617,617, +617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617, +617,617,617,617,617,617,617,617,617,617,617,617,617,617,617,617, +617,617,617,617,616,616,616,616,616,616,616,616,616,616,616,616, +616,616,616,616,618,618,119,119,119,119,119,119,119,119,619,619, +620,620,620,620,620,620,620,620,620,620,119,119,119,119,119,119, +251,251,251,251,251,251,251,251,251,251,251,251,251,251,251,251, +251,621,253,622,253,253,253,253,259,259,259,253,259,253,253,251, /* block 111 */ -571,571,571,572,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,571,572,572,571,571,571,571,572,572,571,572,572,572, -572,574,574,574,574,574,574,574,574,574,574,574,574,574,116,109, -575,575,575,575,575,575,575,575,575,575,116,116,116,116,574,574, -327,327,327,327,327,329,576,327,327,327,327,327,327,327,327,327, -331,331,331,331,331,331,331,331,331,331,327,327,327,327,327,116, +623,623,623,623,623,623,623,623,623,623,624,624,624,624,624,624, +624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624, +624,624,624,624,624,624,625,625,625,625,625,625,625,625,626,627, +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,629,629,629,629,629, +629,629,630,630,119,119,119,119,119,119,119,119,119,119,119,631, +355,355,355,355,355,355,355,355,355,355,355,355,355,355,355,355, +355,355,355,355,355,355,355,355,355,355,355,355,355,119,119,119, /* block 112 */ -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, -577,577,577,577,577,577,577,577,577,578,578,578,578,578,578,579, -579,578,578,579,579,578,578,116,116,116,116,116,116,116,116,116, -577,577,577,578,577,577,577,577,577,577,577,577,578,579,116,116, -580,580,580,580,580,580,580,580,580,580,116,116,581,581,581,581, -327,327,327,327,327,327,327,327,327,327,327,327,327,327,327,327, -576,327,327,327,327,327,327,333,333,333,327,328,329,328,327,327, +632,632,632,633,634,634,634,634,634,634,634,634,634,634,634,634, +634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634, +634,634,634,634,634,634,634,634,634,634,634,634,634,634,634,634, +634,634,634,632,633,633,632,632,632,632,633,633,632,633,633,633, +633,635,635,635,635,635,635,635,635,635,635,635,635,635,119,636, +637,637,637,637,637,637,637,637,637,637,119,119,119,119,635,635, +343,343,343,343,343,345,638,343,343,343,343,343,343,343,343,343, +349,349,349,349,349,349,349,349,349,349,343,343,343,343,343,119, /* block 113 */ -582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582, -582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582, -582,582,582,582,582,582,582,582,582,582,582,582,582,582,582,582, -583,582,583,583,583,582,582,583,583,582,582,582,582,582,583,583, -582,583,582,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,582,582,584,585,585, -586,586,586,586,586,586,586,586,586,586,586,587,588,588,587,587, -589,589,586,590,590,587,588,116,116,116,116,116,116,116,116,116, +639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639, +639,639,639,639,639,639,639,639,639,639,639,639,639,639,639,639, +639,639,639,639,639,639,639,639,639,640,640,640,640,640,640,641, +641,640,640,641,641,640,640,119,119,119,119,119,119,119,119,119, +639,639,639,640,639,639,639,639,639,639,639,639,640,641,119,119, +642,642,642,642,642,642,642,642,642,642,119,119,643,643,643,643, +343,343,343,343,343,343,343,343,343,343,343,343,343,343,343,343, +638,343,343,343,343,343,343,350,350,350,343,344,345,344,343,343, /* block 114 */ -116,340,340,340,340,340,340,116,116,340,340,340,340,340,340,116, -116,340,340,340,340,340,340,116,116,116,116,116,116,116,116,116, -340,340,340,340,340,340,340,116,340,340,340,340,340,340,340,116, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, - 34, 34, 34,591, 34, 34, 34, 34, 34, 34, 34, 14,108,108,108,108, - 34, 34, 34, 34, 34,124,116,116,116,116,116,116,116,116,116,116, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644, +644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644, +644,644,644,644,644,644,644,644,644,644,644,644,644,644,644,644, +645,644,645,645,645,644,644,645,645,644,644,644,644,644,645,645, +644,645,644,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,644,644,646,647,647, +648,648,648,648,648,648,648,648,648,648,648,649,650,650,649,649, +651,651,648,652,652,649,650,119,119,119,119,119,119,119,119,119, /* block 115 */ -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, -586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, -586,586,586,586,586,586,586,586,586,586,586,586,586,586,586,586, -586,586,586,587,587,588,587,587,588,587,587,589,587,588,116,116, -593,593,593,593,593,593,593,593,593,593,116,116,116,116,116,116, +119,358,358,358,358,358,358,119,119,358,358,358,358,358,358,119, +119,358,358,358,358,358,358,119,119,119,119,119,119,119,119,119, +358,358,358,358,358,358,358,119,358,358,358,358,358,358,358,119, + 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,653, 35, 35, 35, 35, 35, 35, 35, 15,109,109,109,109, + 35, 35, 35, 35, 35,127,119,119,119,119,119,119,119,119,119,119, +654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654, /* block 116 */ -594,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,594,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,594,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,594,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -594,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, +654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654, +654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654, +654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654, +654,654,654,654,654,654,654,654,654,654,654,654,654,654,654,654, +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,649,649,650,649,649,650,649,649,651,649,650,119,119, +655,655,655,655,655,655,655,655,655,655,119,119,119,119,119,119, /* block 117 */ -595,595,595,595,595,595,595,595,595,595,595,595,594,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,594,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,594,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -594,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,594,595,595,595, +656,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,656,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,656,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,656,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, +656,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, /* block 118 */ -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,594,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,594,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -594,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,594,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, +657,657,657,657,657,657,657,657,657,657,657,657,656,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,656,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,656,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, +656,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,656,657,657,657, /* block 119 */ -595,595,595,595,595,595,595,595,594,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,594,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -594,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,594,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,594,595,595,595,595,595,595,595, +657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +657,657,657,657,657,657,657,657,656,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,656,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, +656,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,656,657,657,657, +657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, /* block 120 */ -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,594,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -594,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,594,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,594,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, +657,657,657,657,657,657,657,657,656,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,656,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, +656,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,656,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,656,657,657,657,657,657,657,657, /* block 121 */ -595,595,595,595,594,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -594,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,594,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,594,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,594,595,595,595,595,595,595,595,595,595,595,595, +657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +657,657,657,657,656,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, +656,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,656,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,656,657,657,657,657,657,657,657, +657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, /* block 122 */ -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -594,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,594,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,594,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,594,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, +657,657,657,657,656,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, +656,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,656,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,656,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,656,657,657,657,657,657,657,657,657,657,657,657, /* block 123 */ -595,595,595,595,595,595,595,595,594,595,595,595,595,595,595,595, -595,595,595,595,595,595,595,595,595,595,595,595,595,595,595,595, -595,595,595,595,116,116,116,116,116,116,116,116,116,116,116,116, -338,338,338,338,338,338,338,338,338,338,338,338,338,338,338,338, -338,338,338,338,338,338,338,116,116,116,116,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,339, -339,339,339,339,339,339,339,339,339,339,339,339,116,116,116,116, +657,657,657,657,657,657,657,657,657,657,657,657,657,657,657,657, +656,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,656,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,656,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,656,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, /* block 124 */ -596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596, -596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596, -596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596, -596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596, -596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596, -596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596, -596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596, -596,596,596,596,596,596,596,596,596,596,596,596,596,596,596,596, +657,657,657,657,657,657,657,657,656,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,119,119,119,119,119,119,119,119,119,119,119,119, +356,356,356,356,356,356,356,356,356,356,356,356,356,356,356,356, +356,356,356,356,356,356,356,119,119,119,119,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,119,119,119,119, /* block 125 */ -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, +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, +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, +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, /* block 126 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,116,116, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, /* block 127 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,119,119, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, /* block 128 */ - 34, 34, 34, 34, 34, 34, 34,116,116,116,116,116,116,116,116,116, -116,116,116,200,200,200,200,200,116,116,116,116,116,208,205,208, -208,208,208,208,208,208,208,208,208,598,208,208,208,208,208,208, -208,208,208,208,208,208,208,116,208,208,208,208,208,116,208,116, -208,208,116,208,208,116,208,208,208,208,208,208,208,208,208,208, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 129 */ -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,599,599,599,599,599,599,599,599,599,599,599,599,599,599, -599,599,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, + 35, 35, 35, 35, 35, 35, 35,119,119,119,119,119,119,119,119,119, +119,119,119,205,205,205,205,205,119,119,119,119,119,214,211,214, +214,214,214,214,214,214,214,214,214,660,214,214,214,214,214,214, +214,214,214,214,214,214,214,119,214,214,214,214,214,119,214,119, +214,214,119,214,214,119,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 */ -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,661,661,661,661,661,661,661,661,661,661,661,661,661,661, +661,661,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,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 */ -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217, 7, 6, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,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 */ -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -116,116,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -217,217,217,217,217,217,217,217,217,217,217,217,213,214,116,116, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,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, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,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 */ -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, - 4, 4, 4, 4, 4, 4, 4, 6, 7, 4,116,116,116,116,116,116, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,193,193, - 4, 9, 9, 15, 15, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, - 7, 6, 7, 6, 7, 4, 4, 6, 7, 4, 4, 4, 4, 15, 15, 15, - 4, 4, 4,116, 4, 4, 4, 4, 9, 6, 7, 6, 7, 6, 7, 4, - 4, 4, 8, 9, 8, 8, 8,116, 4, 5, 4, 4,116,116,116,116, -217,217,217,217,217,116,217,217,217,217,217,217,217,217,217,217, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +119,119,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +224,224,662,224,224,224,224,224,224,224,224,224,219,663,119,119, /* block 134 */ -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,116,116, 23, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, + 5, 5, 5, 5, 5, 5, 5, 7, 8, 5,119,119,119,119,119,119, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,543,543, + 5, 10, 10, 16, 16, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, + 8, 7, 8, 7, 8,547,547, 7, 8, 5, 5, 5, 5, 16, 16, 16, + 5, 5, 5,119, 5, 5, 5, 5, 10, 7, 8, 7, 8, 7, 8, 5, + 5, 5, 9, 10, 9, 9, 9,119, 5, 6, 5, 5,119,119,119,119, +224,224,224,224,224,119,224,224,224,224,224,224,224,224,224,224, /* block 135 */ -116, 4, 4, 4, 5, 4, 4, 4, 6, 7, 4, 8, 4, 9, 4, 4, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 4, 4, 8, 8, 8, 4, - 4, 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, 6, 4, 7, 14, 15, - 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 6, 8, 7, 8, 6, - 7, 4, 6, 7, 4, 4,517,517,517,517,517,517,517,517,517,517, -109,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,119,119, 24, /* block 136 */ -517,517,517,517,517,517,517,517,517,517,517,517,517,517,517,517, -517,517,517,517,517,517,517,517,517,517,517,517,517,517,600,600, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,520, -520,520,520,520,520,520,520,520,520,520,520,520,520,520,520,116, -116,116,520,520,520,520,520,520,116,116,520,520,520,520,520,520, -116,116,520,520,520,520,520,520,116,116,520,520,520,116,116,116, - 5, 5, 8, 14, 19, 5, 5,116, 19, 8, 8, 8, 8, 19, 19,116, -471,471,471,471,471,471,471,471,471, 23, 23, 23, 19, 19,116,116, +119, 5, 5, 5, 6, 5, 5, 5, 7, 8, 5, 9, 5, 10, 5, 5, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 5, 5, 9, 9, 9, 5, + 5, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 7, 5, 8, 15, 16, + 15, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, + 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 7, 9, 8, 9, 7, + 8,546,551,552,546,546,569,569,569,569,569,569,569,569,569,569, +560,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, /* block 137 */ -601,601,601,601,601,601,601,601,601,601,601,601,116,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,116,601,601,601,601,601,601,601,601, -601,601,601,601,601,601,601,601,601,601,601,116,601,601,116,601, -601,601,601,601,601,601,601,601,601,601,601,601,601,601,116,116, -601,601,601,601,601,601,601,601,601,601,601,601,601,601,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +569,569,569,569,569,569,569,569,569,569,569,569,569,569,569,569, +569,569,569,569,569,569,569,569,569,569,569,569,569,569,664,664, +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,119, +119,119,572,572,572,572,572,572,119,119,572,572,572,572,572,572, +119,119,572,572,572,572,572,572,119,119,572,572,572,119,119,119, + 6, 6, 9, 15, 20, 6, 6,119, 20, 9, 9, 9, 9, 20, 20,119, +502,502,502,502,502,502,502,502,502, 24, 24, 24, 20, 20,119,119, /* block 138 */ -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,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,601,601,601,601,601,601,601,601,601,116,116,116,116,116, +665,665,665,665,665,665,665,665,665,665,665,665,119,665,665,665, +665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, +665,665,665,665,665,665,665,119,665,665,665,665,665,665,665,665, +665,665,665,665,665,665,665,665,665,665,665,119,665,665,119,665, +665,665,665,665,665,665,665,665,665,665,665,665,665,665,119,119, +665,665,665,665,665,665,665,665,665,665,665,665,665,665,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 139 */ - 4, 4, 4,116,116,116,116, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24,116,116,116, 19, 19, 19, 19, 19, 19, 19, 19, 19, -602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602, -602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602, -602,602,602,602,602,602,602,602,602,602,602,602,602,602,602,602, -602,602,602,602,602,603,603,603,603,604,604,604,604,604,604,604, +665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, +665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, +665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, +665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, +665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, +665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, +665,665,665,665,665,665,665,665,665,665,665,665,665,665,665,665, +665,665,665,665,665,665,665,665,665,665,665,119,119,119,119,119, /* block 140 */ -604,604,604,604,604,604,604,604,604,604,603,603,604,604,604,116, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,116,116,116,116, -604,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,111,116,116, +666,666,666,119,119,119,119,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,119,119,119,668,668,668,668,668,668,668,668,668, +669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669, +669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669, +669,669,669,669,669,669,669,669,669,669,669,669,669,669,669,669, +669,669,669,669,669,670,670,670,670,671,671,671,671,671,671,671, /* block 141 */ -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +671,671,671,671,671,671,671,671,671,671,670,670,671,671,671,119, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119, +671,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,112,119,119, /* block 142 */ -605,605,605,605,605,605,605,605,605,605,605,605,605,605,605,605, -605,605,605,605,605,605,605,605,605,605,605,605,605,116,116,116, -606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606, -606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606, -606,606,606,606,606,606,606,606,606,606,606,606,606,606,606,606, -606,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -111, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,116,116,116,116, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 143 */ -607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607, -607,607,607,607,607,607,607,607,607,607,607,607,607,607,607,607, -608,608,608,608,116,116,116,116,116,116,116,116,116,607,607,607, -609,609,609,609,609,609,609,609,609,609,609,609,609,609,609,609, -609,610,609,609,609,609,609,609,609,609,610,116,116,116,116,116, -611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611, -611,611,611,611,611,611,611,611,611,611,611,611,611,611,611,611, -611,611,611,611,611,611,612,612,612,612,612,116,116,116,116,116, +672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, +672,672,672,672,672,672,672,672,672,672,672,672,672,119,119,119, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, +673,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +674,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675, +675,675,675,675,675,675,675,675,675,675,675,675,119,119,119,119, /* block 144 */ -613,613,613,613,613,613,613,613,613,613,613,613,613,613,613,613, -613,613,613,613,613,613,613,613,613,613,613,613,613,613,116,614, -615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, -615,615,615,615,615,615,615,615,615,615,615,615,615,615,615,615, -615,615,615,615,116,116,116,116,615,615,615,615,615,615,615,615, -616,617,617,617,617,617,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676, +676,676,676,676,676,676,676,676,676,676,676,676,676,676,676,676, +677,677,677,677,119,119,119,119,119,119,119,119,119,676,676,676, +678,678,678,678,678,678,678,678,678,678,678,678,678,678,678,678, +678,679,678,678,678,678,678,678,678,678,679,119,119,119,119,119, +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,681,681,681,681,681,119,119,119,119,119, /* block 145 */ -618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, -618,618,618,618,618,618,618,618,618,618,618,618,618,618,618,618, -618,618,618,618,618,618,618,618,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -619,619,619,619,619,619,619,619,619,619,619,619,619,619,619,619, -620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, -620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, -620,620,620,620,620,620,620,620,620,620,620,620,620,620,620,620, +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,119,683, +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,119,119,119,119,684,684,684,684,684,684,684,684, +685,686,686,686,686,686,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 146 */ -621,621,621,621,621,621,621,621,621,621,621,621,621,621,621,621, -621,621,621,621,621,621,621,621,621,621,621,621,621,621,116,116, -622,622,622,622,622,622,622,622,622,622,116,116,116,116,116,116, -623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623, -623,623,623,623,623,623,623,623,623,623,623,623,623,623,623,623, -623,623,623,623,116,116,116,116,624,624,624,624,624,624,624,624, -624,624,624,624,624,624,624,624,624,624,624,624,624,624,624,624, -624,624,624,624,624,624,624,624,624,624,624,624,116,116,116,116, +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,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,688,688,688,688,688,688,688,688,688,688,688,688,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,689,689,689,689,689, +689,689,689,689,689,689,689,689,689,689,689,689,689,689,689,689, /* block 147 */ -625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625, -625,625,625,625,625,625,625,625,625,625,625,625,625,625,625,625, -625,625,625,625,625,625,625,625,116,116,116,116,116,116,116,116, -626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626, -626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626, -626,626,626,626,626,626,626,626,626,626,626,626,626,626,626,626, -626,626,626,626,116,116,116,116,116,116,116,116,116,116,116,627, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +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,119,119, +691,691,691,691,691,691,691,691,691,691,119,119,119,119,119,119, +692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692, +692,692,692,692,692,692,692,692,692,692,692,692,692,692,692,692, +692,692,692,692,119,119,119,119,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,119,119,119,119, /* block 148 */ -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,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,628,628,628,628,628,628,628,628, -628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628, +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,694,694,119,119,119,119,119,119,119,119, +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,695,695, +695,695,695,695,695,695,695,695,695,695,695,695,695,695,695,695, +695,695,695,695,119,119,119,119,119,119,119,119,119,119,119,696, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 149 */ -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,628,628,628,116,116,116,116,116,116,116,116,116, -628,628,628,628,628,628,628,628,628,628,628,628,628,628,628,628, -628,628,628,628,628,628,116,116,116,116,116,116,116,116,116,116, -628,628,628,628,628,628,628,628,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +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,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,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,697,697,697,697, +697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, /* block 150 */ -629,629,629,629,629,629,116,116,629,116,629,629,629,629,629,629, -629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629, -629,629,629,629,629,629,629,629,629,629,629,629,629,629,629,629, -629,629,629,629,629,629,116,629,629,116,116,116,629,116,116,629, -630,630,630,630,630,630,630,630,630,630,630,630,630,630,630,630, -630,630,630,630,630,630,116,631,632,632,632,632,632,632,632,632, -633,633,633,633,633,633,633,633,633,633,633,633,633,633,633,633, -633,633,633,633,633,633,633,634,634,635,635,635,635,635,635,635, +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,697,697,697,697,697,697,697,697,697,697,697,697, +697,697,697,697,697,697,697,119,119,119,119,119,119,119,119,119, +697,697,697,697,697,697,697,697,697,697,697,697,697,697,697,697, +697,697,697,697,697,697,119,119,119,119,119,119,119,119,119,119, +697,697,697,697,697,697,697,697,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 151 */ -636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,636, -636,636,636,636,636,636,636,636,636,636,636,636,636,636,636,116, -116,116,116,116,116,116,116,637,637,637,637,637,637,637,637,637, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -638,638,638,638,638,638,638,638,638,638,638,638,638,638,638,638, -638,638,638,116,638,638,116,116,116,116,116,639,639,639,639,639, +698,698,698,698,698,698,119,119,698,119,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,698,698, +698,698,698,698,698,698,119,698,698,119,119,119,698,119,119,698, +699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699, +699,699,699,699,699,699,119,700,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,703,703,704,704,704,704,704,704,704, /* block 152 */ -640,640,640,640,640,640,640,640,640,640,640,640,640,640,640,640, -640,640,640,640,640,640,641,641,641,641,641,641,116,116,116,642, -643,643,643,643,643,643,643,643,643,643,643,643,643,643,643,643, -643,643,643,643,643,643,643,643,643,643,116,116,116,116,116,644, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +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,119, +119,119,119,119,119,119,119,706,706,706,706,706,706,706,706,706, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +707,707,707,707,707,707,707,707,707,707,707,707,707,707,707,707, +707,707,707,119,707,707,119,119,119,119,119,708,708,708,708,708, /* block 153 */ -645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645, -645,645,645,645,645,645,645,645,645,645,645,645,645,645,645,645, -646,646,646,646,646,646,646,646,646,646,646,646,646,646,646,646, -646,646,646,646,646,646,646,646,116,116,116,116,647,647,646,646, -647,647,647,647,647,647,647,647,647,647,647,647,647,647,647,647, -116,116,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, +709,709,709,709,709,709,709,709,709,709,709,709,709,709,709,709, +709,709,709,709,709,709,710,710,710,710,710,710,119,119,119,711, +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,119,119,119,119,119,713, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 154 */ -648,649,649,649,116,649,649,116,116,116,116,116,649,649,649,649, -648,648,648,648,116,648,648,648,116,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,116,116,649,649,649,116,116,116,116,649, -650,650,650,650,650,650,650,650,650,116,116,116,116,116,116,116, -651,651,651,651,651,651,651,651,651,116,116,116,116,116,116,116, -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,654, +714,714,714,714,714,714,714,714,714,714,714,714,714,714,714,714, +714,714,714,714,714,714,714,714,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,715,119,119,119,119,716,716,715,715, +716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716, +119,119,716,716,716,716,716,716,716,716,716,716,716,716,716,716, +716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716, +716,716,716,716,716,716,716,716,716,716,716,716,716,716,716,716, /* block 155 */ -655,655,655,655,655,655,655,655,655,655,655,655,655,655,655,655, -655,655,655,655,655,655,655,655,655,655,655,655,655,656,656,656, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -657,657,657,657,657,657,657,657,658,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,659,659,116,116,116,116,660,660,660,660,660, -661,661,661,661,661,661,661,116,116,116,116,116,116,116,116,116, +717,718,718,718,119,718,718,119,119,119,119,119,718,718,718,718, +717,717,717,717,119,717,717,717,119,717,717,717,717,717,717,717, +717,717,717,717,717,717,717,717,717,717,717,717,717,717,717,717, +717,717,717,717,717,717,119,119,718,718,718,119,119,119,119,718, +719,719,719,719,719,719,719,719,719,119,119,119,119,119,119,119, +720,720,720,720,720,720,720,720,720,119,119,119,119,119,119,119, +721,721,721,721,721,721,721,721,721,721,721,721,721,721,721,721, +721,721,721,721,721,721,721,721,721,721,721,721,721,722,722,723, /* block 156 */ -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,662,662,662,662,662,662,662,662,662,662,662,662,662, -662,662,662,662,662,662,116,116,116,663,663,663,663,663,663,663, -664,664,664,664,664,664,664,664,664,664,664,664,664,664,664,664, -664,664,664,664,664,664,116,116,665,665,665,665,665,665,665,665, -666,666,666,666,666,666,666,666,666,666,666,666,666,666,666,666, -666,666,666,116,116,116,116,116,667,667,667,667,667,667,667,667, +724,724,724,724,724,724,724,724,724,724,724,724,724,724,724,724, +724,724,724,724,724,724,724,724,724,724,724,724,724,725,725,725, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +726,726,726,726,726,726,726,726,727,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,726,726,728,728,119,119,119,119,729,729,729,729,729, +730,730,730,730,730,730,730,119,119,119,119,119,119,119,119,119, /* block 157 */ -668,668,668,668,668,668,668,668,668,668,668,668,668,668,668,668, -668,668,116,116,116,116,116,116,116,669,669,669,669,116,116,116, -116,116,116,116,116,116,116,116,116,670,670,670,670,670,670,670, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +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,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,119,119,119,732,732,732,732,732,732,732, +733,733,733,733,733,733,733,733,733,733,733,733,733,733,733,733, +733,733,733,733,733,733,119,119,734,734,734,734,734,734,734,734, +735,735,735,735,735,735,735,735,735,735,735,735,735,735,735,735, +735,735,735,119,119,119,119,119,736,736,736,736,736,736,736,736, /* block 158 */ -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,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,671,671,671,671,671,671,671,671,671,671, -671,671,671,671,671,671,671,671,671,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +737,737,737,737,737,737,737,737,737,737,737,737,737,737,737,737, +737,737,119,119,119,119,119,119,119,738,738,738,738,119,119,119, +119,119,119,119,119,119,119,119,119,739,739,739,739,739,739,739, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 159 */ -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,672,672,672,672,672,672,672,672,672,672,672,672,672, -672,672,672,116,116,116,116,116,116,116,116,116,116,116,116,116, -673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, -673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, -673,673,673,673,673,673,673,673,673,673,673,673,673,673,673,673, -673,673,673,116,116,116,116,116,116,116,674,674,674,674,674,674, +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,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,740,740,740,740,740,740,740,740, +740,740,740,740,740,740,740,740,740,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 160 */ -675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675, -675,675,675,675,675,675,675,675,675,675,675,675,675,675,675,675, -675,675,675,675,676,676,676,676,116,116,116,116,116,116,116,116, -677,677,677,677,677,677,677,677,677,677,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741, +741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741, +741,741,741,741,741,741,741,741,741,741,741,741,741,741,741,741, +741,741,741,119,119,119,119,119,119,119,119,119,119,119,119,119, +742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742, +742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742, +742,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742, +742,742,742,119,119,119,119,119,119,119,743,743,743,743,743,743, /* block 161 */ -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -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,116, +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,745,745,745,745,119,119,119,119,119,119,119,119, +746,746,746,746,746,746,746,746,746,746,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 162 */ -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,680,680,680, -680,680,680,680,680,680,680,679,116,116,116,116,116,116,116,116, -681,681,681,681,681,681,681,681,681,681,681,681,681,681,681,681, -681,681,681,681,681,681,682,682,682,682,682,682,682,682,682,682, -682,683,683,683,683,684,684,684,684,684,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,747, +747,747,747,747,747,747,747,747,747,747,747,747,747,747,747,119, /* block 163 */ -685,686,685,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,687,687,687,687,686,686,686,686,686,686,686,686, -686,686,686,686,686,686,686,688,688,688,688,688,688,688,116,116, -116,116,689,689,689,689,689,689,689,689,689,689,689,689,689,689, -689,689,689,689,689,689,690,690,690,690,690,690,690,690,690,690, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,686, +748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748, +748,748,748,748,748,748,748,748,748,748,748,748,748,749,749,749, +749,749,749,749,749,749,749,748,119,119,119,119,119,119,119,119, +750,750,750,750,750,750,750,750,750,750,750,750,750,750,750,750, +750,750,750,750,750,750,751,751,751,751,751,751,751,751,751,751, +751,752,752,752,752,753,753,753,753,753,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 164 */ -691,691,692,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,693,693,693,693,693,693,693, -692,692,692,691,691,691,691,692,692,691,691,694,694,695,694,694, -694,694,116,116,116,116,116,116,116,116,116,116,116,695,116,116, -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,116,116,116,116,116,116,116, -697,697,697,697,697,697,697,697,697,697,116,116,116,116,116,116, +754,755,754,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,756,756,755,755,755,755,755,755,755,755, +755,755,755,755,755,755,755,757,757,757,757,757,757,757,119,119, +119,119,758,758,758,758,758,758,758,758,758,758,758,758,758,758, +758,758,758,758,758,758,759,759,759,759,759,759,759,759,759,759, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,755, /* block 165 */ -698,698,698,699,699,699,699,699,699,699,699,699,699,699,699,699, -699,699,699,699,699,699,699,699,699,699,699,699,699,699,699,699, -699,699,699,699,699,699,699,698,698,698,698,698,700,698,698,698, -698,698,698,698,698,116,701,701,701,701,701,701,701,701,701,701, -702,702,702,702,699,700,700,116,116,116,116,116,116,116,116,116, -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,704,705,705,703,116,116,116,116,116,116,116,116,116, +760,760,761,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,762,762,762, +761,761,761,760,760,760,760,761,761,760,760,763,763,764,763,763, +763,763,119,119,119,119,119,119,119,119,119,119,119,764,119,119, +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,119,119,119,119,119,119,119, +766,766,766,766,766,766,766,766,766,766,119,119,119,119,119,119, /* block 166 */ -706,706,707,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,707,707,707,706,706,706,706,706,706,706,706,706,707, -707,708,709,709,708,710,710,710,710,706,706,706,706,710,116,116, -711,711,711,711,711,711,711,711,711,711,708,710,708,710,710,710, -116,712,712,712,712,712,712,712,712,712,712,712,712,712,712,712, -712,712,712,712,712,116,116,116,116,116,116,116,116,116,116,116, +767,767,767,768,768,768,768,768,768,768,768,768,768,768,768,768, +768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768, +768,768,768,768,768,768,768,767,767,767,767,767,769,767,767,767, +767,767,767,767,767,119,770,770,770,770,770,770,770,770,770,770, +771,771,771,771,768,769,769,119,119,119,119,119,119,119,119,119, +772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772, +772,772,772,772,772,772,772,772,772,772,772,772,772,772,772,772, +772,772,772,773,774,774,772,119,119,119,119,119,119,119,119,119, /* block 167 */ -713,713,713,713,713,713,713,713,713,713,713,713,713,713,713,713, -713,713,116,713,713,713,713,713,713,713,713,713,713,713,713,713, -713,713,713,713,713,713,713,713,713,713,713,713,714,714,714,715, -715,715,714,714,715,714,715,715,716,716,716,716,716,716,715,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +775,775,776,777,777,777,777,777,777,777,777,777,777,777,777,777, +777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777, +777,777,777,777,777,777,777,777,777,777,777,777,777,777,777,777, +777,777,777,776,776,776,775,775,775,775,775,775,775,775,775,776, +776,777,778,778,777,779,779,779,779,775,775,775,775,779,119,119, +780,780,780,780,780,780,780,780,780,780,777,779,777,779,779,779, +119,781,781,781,781,781,781,781,781,781,781,781,781,781,781,781, +781,781,781,781,781,119,119,119,119,119,119,119,119,119,119,119, /* block 168 */ -717,717,717,717,717,717,717,116,717,116,717,717,717,717,116,717, -717,717,717,717,717,717,717,717,717,717,717,717,717,717,116,717, -717,717,717,717,717,717,717,717,717,718,116,116,116,116,116,116, -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,719,719,719,719,719,719,719,720, -721,721,721,720,720,720,720,720,720,720,720,116,116,116,116,116, -722,722,722,722,722,722,722,722,722,722,116,116,116,116,116,116, +782,782,782,782,782,782,782,782,782,782,782,782,782,782,782,782, +782,782,119,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,783,783,783,784, +784,784,783,783,784,783,784,784,785,785,785,785,785,785,784,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 169 */ -723,723,724,724,116,725,725,725,725,725,725,725,725,116,116,725, -725,116,116,725,725,725,725,725,725,725,725,725,725,725,725,725, -725,725,725,725,725,725,725,725,725,116,725,725,725,725,725,725, -725,116,725,725,116,725,725,725,725,725,116,111,723,725,726,724, -723,724,724,724,724,116,116,724,724,116,116,724,724,724,116,116, -725,116,116,116,116,116,116,726,116,116,116,116,116,725,725,725, -725,725,724,724,116,116,723,723,723,723,723,723,723,116,116,116, -723,723,723,723,723,116,116,116,116,116,116,116,116,116,116,116, +786,786,786,786,786,786,786,119,786,119,786,786,786,786,119,786, +786,786,786,786,786,786,786,786,786,786,786,786,786,786,119,786, +786,786,786,786,786,786,786,786,786,787,119,119,119,119,119,119, +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,788,788,788,788,788,788,788,788,788,788,788,789, +790,790,790,789,789,789,789,789,789,789,789,119,119,119,119,119, +791,791,791,791,791,791,791,791,791,791,119,119,119,119,119,119, /* block 170 */ -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, -727,727,727,727,727,727,727,727,727,727,727,727,727,727,727,727, -727,727,727,727,727,728,728,728,729,729,729,729,729,729,729,729, -728,728,729,729,729,728,729,727,727,727,727,730,730,730,730,730, -731,731,731,731,731,731,731,731,731,731,116,730,116,730,729,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +792,793,794,795,119,796,796,796,796,796,796,796,796,119,119,796, +796,119,119,796,796,796,796,796,796,796,796,796,796,796,796,796, +796,796,796,796,796,796,796,796,796,119,796,796,796,796,796,796, +796,119,796,796,119,796,796,796,796,796,119,797,793,796,798,794, +792,794,794,794,794,119,119,794,794,119,119,794,794,794,119,119, +796,119,119,119,119,119,119,798,119,119,119,119,119,796,796,796, +796,796,794,794,119,119,792,792,792,792,792,792,792,119,119,119, +792,792,792,792,792,119,119,119,119,119,119,119,119,119,119,119, /* block 171 */ -732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732, -732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732, -732,732,732,732,732,732,732,732,732,732,732,732,732,732,732,732, -733,734,734,735,735,735,735,735,735,734,735,734,734,733,734,735, -735,734,735,735,732,732,736,732,116,116,116,116,116,116,116,116, -737,737,737,737,737,737,737,737,737,737,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799, +799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799, +799,799,799,799,799,799,799,799,799,799,799,799,799,799,799,799, +799,799,799,799,799,800,800,800,801,801,801,801,801,801,801,801, +800,800,801,801,801,800,801,799,799,799,799,802,802,802,802,802, +803,803,803,803,803,803,803,803,803,803,119,802,119,802,801,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 172 */ -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, -738,738,738,738,738,738,738,738,738,738,738,738,738,738,738,739, -740,740,741,741,741,741,116,116,740,740,740,740,741,741,740,741, -741,742,742,742,742,742,742,742,742,742,742,742,742,742,742,742, -742,742,742,742,742,742,742,742,738,738,738,738,741,741,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, +804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, +804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, +805,806,806,807,807,807,807,807,807,806,807,806,806,805,806,807, +807,806,807,807,804,804,808,804,119,119,119,119,119,119,119,119, +809,809,809,809,809,809,809,809,809,809,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 173 */ -743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743, -743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743, -743,743,743,743,743,743,743,743,743,743,743,743,743,743,743,743, -744,744,744,745,745,745,745,745,745,745,745,744,744,745,744,745, -745,746,746,746,743,116,116,116,116,116,116,116,116,116,116,116, -747,747,747,747,747,747,747,747,747,747,116,116,116,116,116,116, -373,373,373,373,373,373,373,373,373,373,373,373,373,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810, +810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,810, +810,810,810,810,810,810,810,810,810,810,810,810,810,810,810,811, +812,812,813,813,813,813,119,119,812,812,812,812,813,813,812,813, +813,814,814,814,814,814,814,814,814,814,814,814,814,814,814,814, +814,814,814,814,814,814,814,814,810,810,810,810,813,813,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 174 */ -748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748, -748,748,748,748,748,748,748,748,748,748,748,748,748,748,748,748, -748,748,748,748,748,748,748,748,748,748,748,749,750,749,750,750, -749,749,749,749,749,749,750,749,116,116,116,116,116,116,116,116, -751,751,751,751,751,751,751,751,751,751,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815, +815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815, +815,815,815,815,815,815,815,815,815,815,815,815,815,815,815,815, +816,816,816,817,817,817,817,817,817,817,817,816,816,817,816,817, +817,818,818,818,815,119,119,119,119,119,119,119,119,119,119,119, +819,819,819,819,819,819,819,819,819,819,119,119,119,119,119,119, +392,392,392,392,392,392,392,392,392,392,392,392,392,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 175 */ -752,752,752,752,752,752,752,752,752,752,752,752,752,752,752,752, -752,752,752,752,752,752,752,752,752,752,752,116,116,753,753,753, -754,754,753,753,753,753,754,753,753,753,753,753,116,116,116,116, -755,755,755,755,755,755,755,755,755,755,756,756,757,757,757,758, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +820,820,820,820,820,820,820,820,820,820,820,821,822,821,822,822, +821,821,821,821,821,821,822,821,119,119,119,119,119,119,119,119, +823,823,823,823,823,823,823,823,823,823,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 176 */ -759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759, -759,759,759,759,759,759,759,759,759,759,759,759,759,759,759,759, -759,759,759,759,759,759,759,759,759,759,759,759,760,760,760,761, -761,761,761,761,761,761,761,761,760,761,761,762,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +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,119,119,825,825,825, +826,826,825,825,825,825,826,825,825,825,825,825,119,119,119,119, +827,827,827,827,827,827,827,827,827,827,828,828,829,829,829,830, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 177 */ -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -763,763,763,763,763,763,763,763,763,763,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,764,764,764,764,764, -764,764,764,764,764,764,764,764,764,764,764,764,764,764,764,764, -765,765,765,765,765,765,765,765,765,765,766,766,766,766,766,766, -766,766,766,116,116,116,116,116,116,116,116,116,116,116,116,767, +831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, +831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, +831,831,831,831,831,831,831,831,831,831,831,831,832,832,832,833, +833,833,833,833,833,833,833,833,832,833,833,834,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 178 */ -768,769,769,769,769,769,769,769,769,769,769,768,768,768,768,768, -768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768, -768,768,768,768,768,768,768,768,768,768,768,768,768,768,768,768, -768,768,768,769,769,769,769,769,769,770,771,769,769,769,769,772, -772,772,772,772,772,772,772,769,116,116,116,116,116,116,116,116, -773,774,774,774,774,774,774,775,775,774,774,774,773,773,773,773, -773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773, -773,773,773,773,773,773,773,773,773,773,773,773,773,773,773,773, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +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,836,836,836,836,836,836,836,836,836,836,836,836,836, +836,836,836,836,836,836,836,836,836,836,836,836,836,836,836,836, +837,837,837,837,837,837,837,837,837,837,838,838,838,838,838,838, +838,838,838,119,119,119,119,119,119,119,119,119,119,119,119,839, /* block 179 */ -773,773,773,773,116,116,776,776,776,776,774,774,774,774,774,774, -774,774,774,774,774,774,774,775,774,774,777,777,777,773,777,777, -777,777,777,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778, -778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778, -778,778,778,778,778,778,778,778,778,778,778,778,778,778,778,778, -778,778,778,778,778,778,778,778,778,116,116,116,116,116,116,116, +840,841,841,841,841,841,841,841,841,841,841,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,841,841,841,841,841,842,843,841,841,841,841,844, +844,844,844,844,844,844,844,841,119,119,119,119,119,119,119,119, +845,846,846,846,846,846,846,847,847,846,846,846,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, /* block 180 */ -779,779,779,779,779,779,779,779,779,116,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,779,779,779,779,779,779,779,779,779,779,779,779,780, -781,781,781,781,781,781,781,116,781,781,781,781,781,781,780,781, -779,782,782,782,782,782,116,116,116,116,116,116,116,116,116,116, -783,783,783,783,783,783,783,783,783,783,784,784,784,784,784,784, -784,784,784,784,784,784,784,784,784,784,784,784,784,116,116,116, -785,785,786,786,786,786,786,786,786,786,786,786,786,786,786,786, +845,845,845,845,119,119,848,848,848,848,846,846,846,846,846,846, +846,846,846,846,846,846,846,847,846,846,849,849,849,845,849,849, +849,849,849,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +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, +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,119,119,119,119,119,119,119, /* block 181 */ -786,786,786,786,786,786,786,786,786,786,786,786,786,786,786,786, -116,116,787,787,787,787,787,787,787,787,787,787,787,787,787,787, -787,787,787,787,787,787,787,787,116,788,787,787,787,787,787,787, -787,788,787,787,788,787,787,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +851,851,851,851,851,851,851,851,851,119,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, +853,853,853,853,853,853,853,119,853,853,853,853,853,853,852,853, +851,854,854,854,854,854,119,119,119,119,119,119,119,119,119,119, +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,119,119,119, +857,857,858,858,858,858,858,858,858,858,858,858,858,858,858,858, /* block 182 */ -789,789,789,789,789,789,789,116,789,789,116,789,789,789,789,789, -789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789, -789,789,789,789,789,789,789,789,789,789,789,789,789,789,789,789, -789,790,790,790,790,790,790,116,116,116,790,116,790,790,116,790, -790,790,790,790,790,790,791,790,116,116,116,116,116,116,116,116, -792,792,792,792,792,792,792,792,792,792,116,116,116,116,116,116, -793,793,793,793,793,793,116,793,793,116,793,793,793,793,793,793, -793,793,793,793,793,793,793,793,793,793,793,793,793,793,793,793, +858,858,858,858,858,858,858,858,858,858,858,858,858,858,858,858, +119,119,859,859,859,859,859,859,859,859,859,859,859,859,859,859, +859,859,859,859,859,859,859,859,119,860,859,859,859,859,859,859, +859,860,859,859,860,859,859,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 183 */ -793,793,793,793,793,793,793,793,793,793,794,794,794,794,794,116, -795,795,116,794,794,795,794,795,793,116,116,116,116,116,116,116, -796,796,796,796,796,796,796,796,796,796,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +861,861,861,861,861,861,861,119,861,861,119,861,861,861,861,861, +861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861, +861,861,861,861,861,861,861,861,861,861,861,861,861,861,861,861, +861,862,862,862,862,862,862,119,119,119,862,119,862,862,119,862, +862,862,862,862,862,862,863,862,119,119,119,119,119,119,119,119, +864,864,864,864,864,864,864,864,864,864,119,119,119,119,119,119, +865,865,865,865,865,865,119,865,865,119,865,865,865,865,865,865, +865,865,865,865,865,865,865,865,865,865,865,865,865,865,865,865, /* block 184 */ -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -797,797,797,797,797,797,797,797,797,797,797,797,797,797,797,797, -797,797,797,798,798,799,799,800,800,116,116,116,116,116,116,116, +865,865,865,865,865,865,865,865,865,865,866,866,866,866,866,119, +867,867,119,866,866,867,866,867,865,119,119,119,119,119,119,119, +868,868,868,868,868,868,868,868,868,868,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 185 */ -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +869,869,869,869,869,869,869,869,869,869,869,869,869,869,869,869, +869,869,869,870,870,871,871,872,872,119,119,119,119,119,119,119, /* block 186 */ -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, /* block 187 */ -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,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,802,802, -802,802,802,802,802,802,802,802,802,802,802,802,802,802,802,116, -803,803,803,803,803,116,116,116,116,116,116,116,116,116,116,116, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 188 */ -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,801,801,801,801,801,801,801,801,801,801,801,801, -801,801,801,801,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, +874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, +874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, +874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, +874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, +874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,874, +874,874,874,874,874,874,874,874,874,874,874,874,874,874,874,119, +875,875,875,875,875,119,119,119,119,119,119,119,119,119,119,119, /* block 189 */ -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,873,873,873,873,873,873,873,873,873,873,873,873, +873,873,873,873,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 190 */ -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,804, -804,804,804,804,804,804,804,804,804,804,804,804,804,804,804,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +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,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,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,876,876,876,876, +876,876,876,876,876,876,876,876,876,876,876,876,876,876,876,876, /* block 191 */ -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, +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,876,876,876,876,876,876,876,876,876,876,876,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 192 */ -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,805,805,805,805,805,805,805,805,805, -805,805,805,805,805,805,805,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, /* block 193 */ -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,877,877,877,877,877,877,877,877,877, +877,877,877,877,877,877,877,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 194 */ -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,538,538,538,538,538,538,538, -538,538,538,538,538,538,538,538,538,116,116,116,116,116,116,116, -806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,806, -806,806,806,806,806,806,806,806,806,806,806,806,806,806,806,116, -807,807,807,807,807,807,807,807,807,807,116,116,116,116,808,808, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, /* block 195 */ -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -809,809,809,809,809,809,809,809,809,809,809,809,809,809,809,809, -809,809,809,809,809,809,809,809,809,809,809,809,809,809,116,116, -810,810,810,810,810,811,116,116,116,116,116,116,116,116,116,116, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,592,592,592,592,592,592,592, +592,592,592,592,592,592,592,592,592,119,119,119,119,119,119,119, +878,878,878,878,878,878,878,878,878,878,878,878,878,878,878,878, +878,878,878,878,878,878,878,878,878,878,878,878,878,878,878,119, +879,879,879,879,879,879,879,879,879,879,119,119,119,119,880,880, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 196 */ -812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812, -812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812, -812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812, -813,813,813,813,813,813,813,814,814,814,814,814,815,815,815,815, -816,816,816,816,814,815,116,116,116,116,116,116,116,116,116,116, -817,817,817,817,817,817,817,817,817,817,116,818,818,818,818,818, -818,818,116,812,812,812,812,812,812,812,812,812,812,812,812,812, -812,812,812,812,812,812,812,812,116,116,116,116,116,812,812,812, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +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,119,119, +882,882,882,882,882,883,119,119,119,119,119,119,119,119,119,119, /* block 197 */ -812,812,812,812,812,812,812,812,812,812,812,812,812,812,812,812, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884, +884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884, +884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884, +885,885,885,885,885,885,885,886,886,886,886,886,887,887,887,887, +888,888,888,888,886,887,119,119,119,119,119,119,119,119,119,119, +889,889,889,889,889,889,889,889,889,889,119,890,890,890,890,890, +890,890,119,884,884,884,884,884,884,884,884,884,884,884,884,884, +884,884,884,884,884,884,884,884,119,119,119,119,119,884,884,884, /* block 198 */ -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -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,820,820,820,820,820,820,820,820,820,820,820,820,820, -820,820,820,820,820,820,820,820,820,820,820,820,820,820,820,820, +884,884,884,884,884,884,884,884,884,884,884,884,884,884,884,884, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 199 */ -821,821,821,821,821,821,821,821,821,821,821,821,821,821,821,821, -821,821,821,821,821,821,821,822,822,822,822,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +891,891,891,891,891,891,891,891,891,891,891,891,891,891,891,891, +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, /* block 200 */ -823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823, -823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823, -823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823, -823,823,823,823,823,823,823,823,823,823,823,823,823,823,823,823, -823,823,823,823,823,116,116,116,116,116,116,116,116,116,116,116, -823,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,116, +893,893,893,893,893,893,893,893,893,893,893,893,893,893,893,893, +893,893,893,893,893,893,893,894,894,894,894,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 201 */ -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,825, -825,825,825,826,826,826,826,826,826,826,826,826,826,826,826,826, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -827,828,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, +895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, +895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, +895,895,895,895,895,895,895,895,895,895,895,895,895,895,895,895, +895,895,895,895,895,119,119,119,119,119,119,119,119,119,119,119, +895,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,119, /* block 202 */ -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, -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, -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, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,897, +897,897,897,898,898,898,898,898,898,898,898,898,898,898,898,898, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +899,900,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 203 */ -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, -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, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -829,829,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, /* block 204 */ -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, -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, -829,829,829,829,829,829,829,829,829,829,829,829,829,829,829,829, -829,829,829,116,116,116,116,116,116,116,116,116,116,116,116,116, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 205 */ -517,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,901,901,901,901,901,901,901,901,901,901,901,901,901, +901,901,901,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 206 */ -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, +569,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, /* block 207 */ -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,515, -515,515,515,515,515,515,515,515,515,515,515,515,515,515,515,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -830,830,830,830,830,830,830,830,830,830,830,830,830,830,830,830, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, /* block 208 */ -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,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,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, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,564, +564,564,564,564,564,564,564,564,564,564,564,564,564,564,564,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +902,902,902,902,902,902,902,902,902,902,902,902,902,902,902,902, /* block 209 */ -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,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,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,116,116,116,116, +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,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,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,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,902,902,902,902,902,902,902,902, /* block 210 */ -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,831,831,831,831,831, -831,831,831,831,831,831,831,831,831,831,831,116,116,116,116,116, -831,831,831,831,831,831,831,831,831,831,831,831,831,116,116,116, +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,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,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,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,902,902,902,902,119,119,119,119, /* block 211 */ -831,831,831,831,831,831,831,831,831,116,116,116,116,116,116,116, -831,831,831,831,831,831,831,831,831,831,116,116,832,833,833,834, - 23, 23, 23, 23,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,903,903,903,903,903, +903,903,903,903,903,903,903,903,903,903,903,119,119,119,119,119, +903,903,903,903,903,903,903,903,903,903,903,903,903,119,119,119, /* block 212 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19,116,116,116,116,116,116,116,116,116,116, +903,903,903,903,903,903,903,903,903,119,119,119,119,119,119,119, +903,903,903,903,903,903,903,903,903,903,119,119,904,905,905,906, +907,907,907,907,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 213 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19,116,116, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19,835,438,111,111,111, 19, 19, 19,438,835,835, -835,835,835, 23, 23, 23, 23, 23, 23, 23, 23,111,111,111,111,111, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119,119,119,119, /* block 214 */ -111,111,111, 19, 19,111,111,111,111,111,111,111, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,111,111,111,111, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20,119,119, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20,908,909,112,112,112, 20, 20, 20,909,908,908, +908,908,908, 24, 24, 24, 24, 24, 24, 24, 24,112,112,112,112,112, /* block 215 */ -604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604, -604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604, -604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604, -604,604,604,604,604,604,604,604,604,604,604,604,604,604,604,604, -604,604,836,836,836,604,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +112,112,112, 20, 20,112,112,112,112,112,112,112, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,112,112,112,112, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 216 */ -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24,116,116,116,116,116,116,116,116,116,116,116,116, +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,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,671,671,671,671,671,671,671,671,671,671, +671,671,910,910,910,671,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 217 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19,116,116,116,116,116,116,116,116,116, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24,116,116,116,116,116,116,116, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25,119,119,119,119,119,119,119,119,119,119,119,119, /* block 218 */ -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,472,472,472,472,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,473,473, -473,473,473,473,473,116,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20,119,119,119,119,119,119,119,119,119, +573,573,573,573,573,573,573,573,573,573,573,573,573,573,573,573, +573,573, 25, 25, 25, 25, 25, 25, 25,119,119,119,119,119,119,119, /* block 219 */ -472,472,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,472,116,472,472, -116,116,472,116,116,472,472,116,116,472,472,472,472,116,472,472, -472,472,472,472,472,472,473,473,473,473,116,473,116,473,473,473, -473,473,473,473,116,473,473,473,473,473,473,473,473,473,473,473, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,505,505, +505,505,505,505,505,119,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, /* block 220 */ -473,473,473,473,472,472,116,472,472,472,472,116,116,472,472,472, -472,472,472,472,472,116,472,472,472,472,472,472,472,116,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,472,472,116,472,472,472,472,116, -472,472,472,472,472,116,472,116,116,116,472,472,472,472,472,472, -472,116,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, +504,504,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,504,119,504,504, +119,119,504,119,119,504,504,119,119,504,504,504,504,119,504,504, +504,504,504,504,504,504,505,505,505,505,119,505,119,505,505,505, +505,505,505,505,119,505,505,505,505,505,505,505,505,505,505,505, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, /* block 221 */ -472,472,472,472,472,472,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,472,472,472,472,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, +505,505,505,505,504,504,119,504,504,504,504,119,119,504,504,504, +504,504,504,504,504,119,504,504,504,504,504,504,504,119,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,504,504,119,504,504,504,504,119, +504,504,504,504,504,119,504,119,119,119,504,504,504,504,504,504, +504,119,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, /* block 222 */ -473,473,473,473,473,473,473,473,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, -472,472,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, +504,504,504,504,504,504,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, /* block 223 */ -472,472,472,472,472,472,472,472,472,472,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,116,116,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, -472, 8,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473, 8,473,473,473,473, -473,473,472,472,472,472,472,472,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,472, 8,473,473,473,473, +505,505,505,505,505,505,505,505,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, /* block 224 */ -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473, 8,473,473,473,473,473,473,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, -472,472,472,472,472, 8,473,473,473,473,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, 8, -473,473,473,473,473,473,472,472,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, 8, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, +504,504,504,504,504,504,504,504,504,504,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,119,119,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504, 9,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505, 9,505,505,505,505, +505,505,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504, 9,505,505,505,505, /* block 225 */ -473,473,473,473,473,473,473,473,473, 8,473,473,473,473,473,473, -472,472,472,472,472,472,472,472,472,472,472,472,472,472,472,472, -472,472,472,472,472,472,472,472,472, 8,473,473,473,473,473,473, -473,473,473,473,473,473,473,473,473,473,473,473,473,473,473,473, -473,473,473, 8,473,473,473,473,473,473,472,473,116,116, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505, 9,505,505,505,505,505,505,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504, 9,505,505,505,505,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, 9, +505,505,505,505,505,505,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, 9, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, /* block 226 */ -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, -837,837,837,837,837,837,837,837,837,837,837,837,837,837,837,837, +505,505,505,505,505,505,505,505,505, 9,505,505,505,505,505,505, +504,504,504,504,504,504,504,504,504,504,504,504,504,504,504,504, +504,504,504,504,504,504,504,504,504, 9,505,505,505,505,505,505, +505,505,505,505,505,505,505,505,505,505,505,505,505,505,505,505, +505,505,505, 9,505,505,505,505,505,505,504,505,119,119, 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, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, /* block 227 */ -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,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,838,837,837,837,837,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,838,838,838,838,838,838,838,838,838,838, -838,838,838,838,838,838,838,838,838,838,838,838,838,837,837,837, -837,837,837,837,837,838,837,837,837,837,837,837,837,837,837,837, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,911,911,911,911,911,911,911,911, +911,911,911,911,911,911,911,911,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 228 */ -837,837,837,837,838,837,837,839,839,839,839,839,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,838,838,838,838,838, -116,838,838,838,838,838,838,838,838,838,838,838,838,838,838,838, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +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, +912,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, +912,912,912,912,912,912,912,911,911,911,911,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,912,912,912,912,912, +912,912,912,912,912,912,912,912,912,912,912,912,912,911,911,911, +911,911,911,911,911,912,911,911,911,911,911,911,911,911,911,911, /* block 229 */ -840,840,840,840,840,840,840,116,840,840,840,840,840,840,840,840, -840,840,840,840,840,840,840,840,840,116,116,840,840,840,840,840, -840,840,116,840,840,116,840,840,840,840,840,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +911,911,911,911,912,911,911,913,913,913,913,913,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,912,912,912,912,912, +119,912,912,912,912,912,912,912,912,912,912,912,912,912,912,912, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 230 */ -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, +914,914,914,914,914,914,914,119,914,914,914,914,914,914,914,914, +914,914,914,914,914,914,914,914,914,119,119,914,914,914,914,914, +914,914,119,914,914,119,914,914,914,914,914,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 231 */ -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,841,841,841,841,841,841,841,841,841,841,841, -841,841,841,841,841,116,116,842,842,842,842,842,842,842,842,842, -843,843,843,843,843,843,843,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +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,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,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,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,915,915,915,915,915,915,915,915, /* block 232 */ -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,844,844,844,844,844, -844,844,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,846,846,846,846,116,116,116,116,116, -847,847,847,847,847,847,847,847,847,847,116,116,116,116,848,848, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +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,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,915,915,915,915, +915,915,915,915,915,119,119,916,916,916,916,916,916,916,916,916, +917,917,917,917,917,917,917,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 233 */ -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, +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,919,919,919,919,919,919,919, +919,919,919,919,919,919,919,919,919,919,919,919,919,919,919,919, +919,919,919,919,920,920,920,920,920,920,920,119,119,119,119,119, +921,921,921,921,921,921,921,921,921,921,119,119,119,119,922,922, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 234 */ - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 19, 24, 24, 24, - 5, 24, 24, 24, 24,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, /* block 235 */ -217,217,217,217,116,217,217,217,217,217,217,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,217,217,217,217, -116,217,217,116,217,116,116,217,116,217,217,217,217,217,217,217, -217,217,217,116,217,217,217,217,116,217,116,217,116,116,116,116, -116,116,217,116,116,116,116,217,116,217,116,217,116,217,217,217, -116,217,217,116,217,116,116,217,116,217,116,217,116,217,116,217, -116,217,217,116,217,116,116,217,217,217,217,116,217,217,217,217, -217,217,217,116,217,217,217,217,116,217,217,217,217,116,217,116, + 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, + 6, 25, 25, 25, 25,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 236 */ -217,217,217,217,217,217,217,217,217,217,116,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,116,116,116,116, -116,217,217,217,116,217,217,217,217,217,116,217,217,217,217,217, -217,217,217,217,217,217,217,217,217,217,217,217,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -211,211,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +224,224,224,224,119,224,224,224,224,224,224,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,224,224,224,224, +119,224,224,119,224,119,119,224,119,224,224,224,224,224,224,224, +224,224,224,119,224,224,224,224,119,224,119,224,119,119,119,119, +119,119,224,119,119,119,119,224,119,224,119,224,119,224,224,224, +119,224,224,119,224,119,119,224,119,224,119,224,119,224,119,224, +119,224,224,119,224,119,119,224,224,224,224,119,224,224,224,224, +224,224,224,119,224,224,224,224,119,224,224,224,224,119,224,119, /* block 237 */ - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,849,849,849,849, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +224,224,224,224,224,224,224,224,224,224,119,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,119,119,119,119, +119,224,224,224,119,224,224,224,224,224,119,224,224,224,224,224, +224,224,224,224,224,224,224,224,224,224,224,224,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +217,217,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 238 */ - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20,849,849,849,849,849,849,849,849,849,849,849,849, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,849, -849, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -849, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -849, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20,849,849,849,849,849,849,849,849,849,849, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923,923, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 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 239 */ - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,849,849,849, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,849,849,849,849, - 20, 20, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923, +923, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +923, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, +923, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923, /* block 240 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 19, - 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,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,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, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,923,923,923, + 20, 20, 20, 20, 20, 20, 20, 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,923,923,923,923, + 21, 21, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, /* block 241 */ -851, 20, 20,849,849,849,849,849,849,849,849,849,849,849,849,849, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, - 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 19,849,849,849,849, - 19, 19, 19, 19, 19, 19, 19, 19, 19,849,849,849,849,849,849,849, - 20, 20,849,849,849,849,849,849,849,849,849,849,849,849,849,849, - 20, 20, 20, 20, 20, 20,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, + 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,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,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, /* block 242 */ -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, -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, -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, -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, +925, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923,923, + 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,923,923,923,923, + 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923,923, +575,575,923,923,923,923,923,923,923,923,923,923,923,923,923,923, + 21, 21, 21, 21, 21, 21,923,923,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 243 */ - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,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 244 */ + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 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 */ + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,926,926,926,926,926, + +/* block 246 */ + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 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, 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, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + +/* block 247 */ + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 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, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,852,852,852,852,852, -/* block 245 */ +/* 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, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923,923,923,923, + +/* block 249 */ + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 19, 19, - 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20,923,923,923,923,923,923,923,923,923,923,923,923, -/* block 246 */ +/* block 250 */ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, + 20, 20, 20, 20, 20, 21, 21, 21, 21,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,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 247 */ +/* block 251 */ + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923,923,923, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20,849,849,849,849,849,849,849,849,849,849,849, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,849,849,849, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,849,849,849,849,849,849, - -/* block 248 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19,849,849,849,849,849,849,849,849,849,849,849,849, - -/* block 249 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 20, 20, 20, 20,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,849,849,849,849,849,849,849, - -/* block 250 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,849,849,849,849, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19,849,849,849,849,849,849,849,849, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,849,849,849,849,849,849, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - -/* block 251 */ - 19, 19, 19, 19, 19, 19, 19, 19,849,849,849,849,849,849,849,849, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,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,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,849,849, -849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849, /* block 252 */ - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,849,849,849,849, + 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923,923,923,923,923, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 19, 20, 20, 20,849, - 20, 20, 20, 20, 20, 20, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20,849,849, 20, 20, 20, 20,849,849,849, 20,849, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,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 253 */ - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20,849,849,849,849,849,849,849,849,849,849,849,849,849, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,849,849,849,849,849,849, - 20, 20, 20,849,849,849,849,849,849,849,849,849,849,849,849,849, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,923,923,923,923, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 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,923, + 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,923,923, 21, 21, 21, 21,923,923,923, 21,923, 21, 21, 21, 21, /* block 254 */ -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, -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, -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, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,849,849, -849,849,849,849,849,849,849,849,849,849,849,849,849,849,849,849, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923,923, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923,923,923,923,923, + 21, 21, 21,923,923,923,923,923,923,923,923,923,923,923,923,923, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, + 21, 21, 21, 21, 21, 21, 21, 21, 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 255 */ -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, -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, -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, -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,116,116, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, /* block 256 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,923,923, +923,923,923,923,923,923,923,923,923,923,923,923,923,923,119,119, /* block 257 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,116,116,116,116,116,116,116,116,116,116,116, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 258 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,116,116, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,119,119,119,119,119,119,119,119,119,119,119, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, /* block 259 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,119,119, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, /* block 260 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, /* block 261 */ -523,523,523,523,523,523,523,523,523,523,523,523,523,523,523,523, -523,523,523,523,523,523,523,523,523,523,523,523,523,523,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, -116,116,116,116,116,116,116,116,116,116,116,116,116,116,116,116, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 262 */ -471, 23,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853, -853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853, -853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853, -853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853, -853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853, -853,853,853,853,853,853,853,853,853,853,853,853,853,853,853,853, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,577,577, +577,577,577,577,577,577,577,577,577,577,577,577,577,577,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, +119,119,119,119,119,119,119,119,119,119,119,119,119,119,119,119, /* block 263 */ -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, +502, 24,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, +927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, +927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, +927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, +927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, +927,927,927,927,927,927,927,927,927,927,927,927,927,927,927,927, /* block 264 */ -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, /* block 265 */ -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111, -471,471,471,471,471,471,471,471,471,471,471,471,471,471,471,471, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, /* block 266 */ -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,597,597, -597,597,597,597,597,597,597,597,597,597,597,597,597,597,116,116, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +112,112,112,112,112,112,112,112,112,112,112,112,112,112,112,112, +502,502,502,502,502,502,502,502,502,502,502,502,502,502,502,502, + +/* block 267 */ +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,659,659, +659,659,659,659,659,659,659,659,659,659,659,659,659,659,119,119, }; diff --git a/thirdparty/pcre2/src/pcre2_ucp.h b/thirdparty/pcre2/src/pcre2_ucp.h index 0c330edcb2..483abd18fc 100644 --- a/thirdparty/pcre2/src/pcre2_ucp.h +++ b/thirdparty/pcre2/src/pcre2_ucp.h @@ -124,6 +124,7 @@ enum { /* These are the script identifications. */ enum { + ucp_Unknown, ucp_Arabic, ucp_Armenian, ucp_Bengali, diff --git a/thirdparty/pcre2/src/pcre2_xclass.c b/thirdparty/pcre2/src/pcre2_xclass.c index 407d3f5b87..8b052be66a 100644 --- a/thirdparty/pcre2/src/pcre2_xclass.c +++ b/thirdparty/pcre2/src/pcre2_xclass.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 University of Cambridge + New API code Copyright (c) 2016-2019 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without @@ -85,10 +85,10 @@ if (c < 256) if ((*data & XCL_HASPROP) == 0) { if ((*data & XCL_MAP) == 0) return negated; - return (((uint8_t *)(data + 1))[c/8] & (1 << (c&7))) != 0; + return (((uint8_t *)(data + 1))[c/8] & (1u << (c&7))) != 0; } if ((*data & XCL_MAP) != 0 && - (((uint8_t *)(data + 1))[c/8] & (1 << (c&7))) != 0) + (((uint8_t *)(data + 1))[c/8] & (1u << (c&7))) != 0) return !negated; /* char found */ } diff --git a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h index f5703e8e7f..ba60311e45 100644 --- a/thirdparty/pcre2/src/sljit/sljitConfigInternal.h +++ b/thirdparty/pcre2/src/sljit/sljitConfigInternal.h @@ -530,7 +530,7 @@ typedef double sljit_f64; #endif /* !SLJIT_FUNC */ #ifndef SLJIT_INDIRECT_CALL -#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (defined SLJIT_BIG_ENDIAN && SLJIT_BIG_ENDIAN)) \ +#if ((defined SLJIT_CONFIG_PPC_64 && SLJIT_CONFIG_PPC_64) && (!defined _CALL_ELF || _CALL_ELF == 1)) \ || ((defined SLJIT_CONFIG_PPC_32 && SLJIT_CONFIG_PPC_32) && defined _AIX) /* It seems certain ppc compilers use an indirect addressing for functions which makes things complicated. */ diff --git a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c index 7c18578618..3b37a9751f 100644 --- a/thirdparty/pcre2/src/sljit/sljitExecAllocator.c +++ b/thirdparty/pcre2/src/sljit/sljitExecAllocator.c @@ -94,6 +94,46 @@ static SLJIT_INLINE void free_chunk(void *chunk, sljit_uw size) #else +#ifdef __APPLE__ +/* Configures TARGET_OS_OSX when appropriate */ +#include <TargetConditionals.h> + +#if TARGET_OS_OSX && defined(MAP_JIT) +#include <sys/utsname.h> +#endif /* TARGET_OS_OSX && MAP_JIT */ + +#ifdef MAP_JIT + +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. */ + 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. */ + if (map_jit_flag == -1) { + struct utsname name; + + uname(&name); + + /* Kernel version for 10.14.0 (Mojave) */ + map_jit_flag = (atoi(name.release) >= 18) ? MAP_JIT : 0; + } + + return map_jit_flag; +#else /* !TARGET_OS_OSX */ + return MAP_JIT; +#endif /* TARGET_OS_OSX */ +} + +#endif /* MAP_JIT */ + +#endif /* __APPLE__ */ + static SLJIT_INLINE void* alloc_chunk(sljit_uw size) { void *retval; @@ -103,17 +143,17 @@ static SLJIT_INLINE void* alloc_chunk(sljit_uw size) int flags = MAP_PRIVATE | MAP_ANON; #ifdef MAP_JIT - flags |= MAP_JIT; + flags |= get_map_jit_flag(); #endif retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, flags, -1, 0); -#else +#else /* !MAP_ANON */ if (dev_zero < 0) { if (open_dev_zero()) return NULL; } retval = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, dev_zero, 0); -#endif +#endif /* MAP_ANON */ return (retval != MAP_FAILED) ? retval : NULL; } diff --git a/thirdparty/pcre2/src/sljit/sljitLir.c b/thirdparty/pcre2/src/sljit/sljitLir.c index 5bdddc10cf..ded9541b31 100644 --- a/thirdparty/pcre2/src/sljit/sljitLir.c +++ b/thirdparty/pcre2/src/sljit/sljitLir.c @@ -201,15 +201,16 @@ # define IS_CALL 0x010 # define IS_BIT26_COND 0x020 # define IS_BIT16_COND 0x040 +# define IS_BIT23_COND 0x080 -# define IS_COND (IS_BIT26_COND | IS_BIT16_COND) +# define IS_COND (IS_BIT26_COND | IS_BIT16_COND | IS_BIT23_COND) -# define PATCH_B 0x080 -# define PATCH_J 0x100 +# define PATCH_B 0x100 +# define PATCH_J 0x200 #if (defined SLJIT_CONFIG_MIPS_64 && SLJIT_CONFIG_MIPS_64) -# define PATCH_ABS32 0x200 -# define PATCH_ABS48 0x400 +# define PATCH_ABS32 0x400 +# define PATCH_ABS48 0x800 #endif /* instruction types */ diff --git a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c index 27af741487..b015695c52 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeARM_64.c @@ -51,7 +51,7 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { 0, 0, 1, 2, 3, 4, 5, 6, 7 }; -#define W_OP (1 << 31) +#define W_OP (1u << 31) #define RD(rd) (reg_map[rd]) #define RT(rt) (reg_map[rt]) #define RN(rn) (reg_map[rn] << 5) @@ -560,7 +560,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s /* dst must be register, TMP_REG1 arg1 must be register, TMP_REG1, imm arg2 must be register, TMP_REG2, imm */ - sljit_ins inv_bits = (flags & INT_OP) ? (1 << 31) : 0; + sljit_ins inv_bits = (flags & INT_OP) ? W_OP : 0; sljit_ins inst_bits; sljit_s32 op = (flags & 0xffff); sljit_s32 reg; @@ -710,7 +710,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s return push_inst(compiler, ORR | RD(dst) | RN(TMP_ZERO) | RM(arg2)); case SLJIT_MOV_U8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (7 << 10)); + return push_inst(compiler, (UBFM ^ W_OP) | RD(dst) | RN(arg2) | (7 << 10)); case SLJIT_MOV_S8: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (!(flags & INT_OP)) @@ -718,7 +718,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s return push_inst(compiler, (SBFM ^ inv_bits) | RD(dst) | RN(arg2) | (7 << 10)); case SLJIT_MOV_U16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); - return push_inst(compiler, (UBFM ^ (1 << 31)) | RD(dst) | RN(arg2) | (15 << 10)); + return push_inst(compiler, (UBFM ^ W_OP) | RD(dst) | RN(arg2) | (15 << 10)); case SLJIT_MOV_S16: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if (!(flags & INT_OP)) @@ -728,7 +728,7 @@ static sljit_s32 emit_op_imm(struct sljit_compiler *compiler, sljit_s32 flags, s SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if ((flags & INT_OP) && dst == arg2) return SLJIT_SUCCESS; - return push_inst(compiler, (ORR ^ (1 << 31)) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); + return push_inst(compiler, (ORR ^ W_OP) | RD(dst) | RN(TMP_ZERO) | RM(arg2)); case SLJIT_MOV_S32: SLJIT_ASSERT(!(flags & SET_FLAGS) && arg1 == TMP_REG1); if ((flags & INT_OP) && dst == arg2) @@ -1080,7 +1080,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_return(struct sljit_compiler *comp SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_op0(struct sljit_compiler *compiler, sljit_s32 op) { - sljit_ins inv_bits = (op & SLJIT_I32_OP) ? (1 << 31) : 0; + sljit_ins inv_bits = (op & SLJIT_I32_OP) ? W_OP : 0; CHECK_ERROR(); CHECK(check_sljit_emit_op0(compiler, op)); @@ -1360,7 +1360,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_sw_from_f64(struct sljit_comp sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; if (GET_OPCODE(op) == SLJIT_CONV_S32_FROM_F64) - inv_bits |= (1 << 31); + inv_bits |= W_OP; if (src & SLJIT_MEM) { emit_fop_mem(compiler, (op & SLJIT_F32_OP) ? INT_SIZE : WORD_SIZE, TMP_FREG1, src, srcw); @@ -1382,7 +1382,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_conv_f64_from_sw(struct sljit_comp sljit_ins inv_bits = (op & SLJIT_F32_OP) ? (1 << 22) : 0; if (GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) - inv_bits |= (1 << 31); + inv_bits |= W_OP; if (src & SLJIT_MEM) { emit_op_mem(compiler, ((GET_OPCODE(op) == SLJIT_CONV_F64_FROM_S32) ? INT_SIZE : WORD_SIZE), TMP_REG1, src, srcw, TMP_REG1); @@ -1662,7 +1662,7 @@ static SLJIT_INLINE struct sljit_jump* emit_cmp_to0(struct sljit_compiler *compi sljit_s32 src, sljit_sw srcw) { struct sljit_jump *jump; - sljit_ins inv_bits = (type & SLJIT_I32_OP) ? (1 << 31) : 0; + sljit_ins inv_bits = (type & SLJIT_I32_OP) ? W_OP : 0; SLJIT_ASSERT((type & 0xff) == SLJIT_EQUAL || (type & 0xff) == SLJIT_NOT_EQUAL); ADJUST_LOCAL_OFFSET(src, srcw); @@ -1787,7 +1787,7 @@ SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_cmov(struct sljit_compiler *compil sljit_s32 dst_reg, sljit_s32 src, sljit_sw srcw) { - sljit_ins inv_bits = (dst_reg & SLJIT_I32_OP) ? (1 << 31) : 0; + sljit_ins inv_bits = (dst_reg & SLJIT_I32_OP) ? W_OP : 0; sljit_ins cc; CHECK_ERROR(); diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c index 094c9923bc..ad970bf25a 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_32.c @@ -368,16 +368,21 @@ 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) +#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) return push_inst(compiler, MUL | S(src1) | T(src2) | D(dst), DR(dst)); -#else +#else /* !SLJIT_MIPS_R1 && !SLJIT_MIPS_R6 */ FAIL_IF(push_inst(compiler, MULT | S(src1) | T(src2), MOVABLE_INS)); return push_inst(compiler, MFLO | D(dst), DR(dst)); -#endif +#endif /* SLJIT_MIPS_R1 || SLJIT_MIPS_R6 */ } +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) + 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 */ 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 */ 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); diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c index f841aef5dd..a6a2bcc0c9 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_64.c @@ -459,19 +459,26 @@ 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) +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) + return push_inst(compiler, SELECT_OP(DMUL, MUL) | S(src1) | T(src2) | D(dst), DR(dst)); +#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) 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 +#else /* !SLJIT_MIPS_R6 && !SLJIT_MIPS_R1 */ 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 +#endif /* SLJIT_MIPS_R6 */ } +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) + 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 */ 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 */ 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); diff --git a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c index 894e21304b..e0d6a3f085 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c +++ b/thirdparty/pcre2/src/sljit/sljitNativeMIPS_common.c @@ -27,17 +27,31 @@ /* Latest MIPS architecture. */ /* Automatically detect SLJIT_MIPS_R1 */ +#if (defined __mips_isa_rev) && (__mips_isa_rev >= 6) +#define SLJIT_MIPS_R6 1 +#endif + SLJIT_API_FUNC_ATTRIBUTE const char* sljit_get_platform_name(void) { -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) + +#if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) + return "MIPS32-R6" SLJIT_CPUINFO; +#else /* !SLJIT_CONFIG_MIPS_32 */ + return "MIPS64-R6" SLJIT_CPUINFO; +#endif /* SLJIT_CONFIG_MIPS_32 */ + +#elif (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) + #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) return "MIPS32-R1" SLJIT_CPUINFO; -#else +#else /* !SLJIT_CONFIG_MIPS_32 */ return "MIPS64-R1" SLJIT_CPUINFO; -#endif +#endif /* SLJIT_CONFIG_MIPS_32 */ + #else /* SLJIT_MIPS_R1 */ return "MIPS III" SLJIT_CPUINFO; -#endif +#endif /* SLJIT_MIPS_R6 */ } /* Length of an instruction word @@ -62,6 +76,7 @@ typedef sljit_u32 sljit_ins; #define TMP_FREG1 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 1) #define TMP_FREG2 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 2) +#define TMP_FREG3 (SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3) static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { 0, 2, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 24, 23, 22, 21, 20, 19, 18, 17, 16, 29, 4, 25, 31 @@ -69,14 +84,14 @@ static const sljit_u8 reg_map[SLJIT_NUMBER_OF_REGISTERS + 5] = { #if (defined SLJIT_CONFIG_MIPS_32 && SLJIT_CONFIG_MIPS_32) -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { - 0, 0, 14, 2, 4, 6, 8, 12, 10 +static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { + 0, 0, 14, 2, 4, 6, 8, 12, 10, 16 }; #else -static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { - 0, 0, 13, 14, 15, 16, 17, 12, 18 +static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 4] = { + 0, 0, 13, 14, 15, 16, 17, 12, 18, 10 }; #endif @@ -102,6 +117,11 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define FR(dr) (freg_map[dr]) #define HI(opcode) ((opcode) << 26) #define LO(opcode) (opcode) +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +/* CMP.cond.fmt */ +/* S = (20 << 21) D = (21 << 21) */ +#define CMP_FMT_S (20 << 21) +#endif /* SLJIT_MIPS_R6 */ /* S = (16 << 21) D = (17 << 21) */ #define FMT_S (16 << 21) #define FMT_D (17 << 21) @@ -114,8 +134,13 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define ANDI (HI(12)) #define B (HI(4)) #define BAL (HI(1) | (17 << 16)) +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#define BC1EQZ (HI(17) | (9 << 21) | FT(TMP_FREG3)) +#define BC1NEZ (HI(17) | (13 << 21) | FT(TMP_FREG3)) +#else /* !SLJIT_MIPS_R6 */ #define BC1F (HI(17) | (8 << 21)) #define BC1T (HI(17) | (8 << 21) | (1 << 16)) +#endif /* SLJIT_MIPS_R6 */ #define BEQ (HI(4)) #define BGEZ (HI(1) | (1 << 16)) #define BGTZ (HI(7)) @@ -124,20 +149,42 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define BNE (HI(5)) #define BREAK (HI(0) | LO(13)) #define CFC1 (HI(17) | (2 << 21)) -#define C_UN_S (HI(17) | FMT_S | LO(49)) +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#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 */ #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 */ #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) +#define DDIV (HI(0) | (2 << 6) | LO(30)) +#define DDIVU (HI(0) | (2 << 6) | LO(31)) +#define DMOD (HI(0) | (3 << 6) | LO(30)) +#define DMODU (HI(0) | (3 << 6) | LO(31)) +#define DIV (HI(0) | (2 << 6) | LO(26)) +#define DIVU (HI(0) | (2 << 6) | LO(27)) +#define DMUH (HI(0) | (3 << 6) | LO(28)) +#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 */ #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 DIV_S (HI(17) | FMT_S | LO(3)) #define DMULT (HI(0) | LO(28)) #define DMULTU (HI(0) | LO(29)) +#endif /* SLJIT_MIPS_R6 */ +#define DIV_S (HI(17) | FMT_S | LO(3)) #define DSLL (HI(0) | LO(56)) #define DSLL32 (HI(0) | LO(60)) #define DSLLV (HI(0) | LO(20)) @@ -151,18 +198,34 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define J (HI(2)) #define JAL (HI(3)) #define JALR (HI(0) | LO(9)) +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#define JR (HI(0) | LO(9)) +#else /* !SLJIT_MIPS_R6 */ #define JR (HI(0) | LO(8)) +#endif /* SLJIT_MIPS_R6 */ #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 */ +#define MOD (HI(0) | (3 << 6) | LO(26)) +#define MODU (HI(0) | (3 << 6) | LO(27)) +#endif /* !SLJIT_MIPS_R6 */ #define MOV_S (HI(17) | FMT_S | LO(6)) #define MTC1 (HI(17) | (4 << 21)) -#define MUL_S (HI(17) | FMT_S | LO(2)) +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#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 */ #define MULT (HI(0) | LO(24)) #define MULTU (HI(0) | LO(25)) +#endif /* SLJIT_MIPS_R6 */ +#define MUL_S (HI(17) | FMT_S | LO(2)) #define NEG_S (HI(17) | FMT_S | LO(7)) #define NOP (HI(0) | LO(0)) #define NOR (HI(0) | LO(39)) @@ -188,14 +251,18 @@ static const sljit_u8 freg_map[SLJIT_NUMBER_OF_FLOAT_REGISTERS + 3] = { #define XOR (HI(0) | LO(38)) #define XORI (HI(14)) -#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) +#if (defined SLJIT_MIPS_R1 && SLJIT_MIPS_R1) || (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) #define CLZ (HI(28) | LO(32)) +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) +#define DCLZ (LO(18)) +#else /* !SLJIT_MIPS_R6 */ #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 */ #define PREF (HI(51)) #define PREFX (HI(19) | LO(15)) #define SEB (HI(31) | (16 << 6) | LO(32)) @@ -234,7 +301,13 @@ static sljit_s32 push_inst(struct sljit_compiler *compiler, sljit_ins ins, sljit static SLJIT_INLINE sljit_ins invert_branch(sljit_s32 flags) { - return (flags & IS_BIT26_COND) ? (1 << 26) : (1 << 16); + if (flags & IS_BIT26_COND) + return (1 << 26); +#if (defined SLJIT_MIPS_R6 && SLJIT_MIPS_R6) + if (flags & IS_BIT23_COND) + return (1 << 23); +#endif /* SLJIT_MIPS_R6 */ + return (1 << 16); } static SLJIT_INLINE sljit_ins* detect_jump_type(struct sljit_jump *jump, sljit_ins *code_ptr, sljit_ins *code, sljit_sw executable_offset) @@ -1075,34 +1148,62 @@ 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_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))); +#else /* !SLJIT_CONFIG_MIPS_64 */ + FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULU : MUL) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3))); + FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MUHU : MUH) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1))); +#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 */ #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 +#else /* !SLJIT_CONFIG_MIPS_64 */ FAIL_IF(push_inst(compiler, (op == SLJIT_LMUL_UW ? MULTU : MULT) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); -#endif +#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 */ 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_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))); + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1))); + } + else { + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3))); + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DMODU : DMOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1))); + } +#else /* !SLJIT_CONFIG_MIPS_64 */ + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG3), DR(TMP_REG3))); + FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? MODU : MOD) | S(SLJIT_R0) | T(SLJIT_R1) | D(TMP_REG1), DR(TMP_REG1))); +#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) FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); FAIL_IF(push_inst(compiler, NOP, UNMOVABLE_INS)); -#endif - +#endif /* !SLJIT_MIPS_R1 */ #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)); else FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DDIVU : DDIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); -#else +#else /* !SLJIT_CONFIG_MIPS_64 */ FAIL_IF(push_inst(compiler, ((op | 0x2) == SLJIT_DIV_UW ? DIVU : DIV) | S(SLJIT_R0) | T(SLJIT_R1), MOVABLE_INS)); -#endif - +#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 */ } return SLJIT_SUCCESS; @@ -1408,8 +1509,7 @@ static SLJIT_INLINE sljit_s32 sljit_emit_fop1_cmp(struct sljit_compiler *compile inst = C_UN_S; break; } - - return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1), UNMOVABLE_INS); + return push_inst(compiler, inst | FMT(op) | FT(src2) | FS(src1) | C_FD, UNMOVABLE_INS); } SLJIT_API_FUNC_ATTRIBUTE sljit_s32 sljit_emit_fop1(struct sljit_compiler *compiler, sljit_s32 op, @@ -1608,16 +1708,30 @@ 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) + +#define BR_T() \ + inst = BC1NEZ; \ + flags = IS_BIT23_COND; \ + delay_check = FCSR_FCC; +#define BR_F() \ + inst = BC1EQZ; \ + flags = IS_BIT23_COND; \ + delay_check = FCSR_FCC; + +#else /* !SLJIT_MIPS_R6 */ + #define BR_T() \ inst = BC1T | JUMP_LENGTH; \ flags = IS_BIT16_COND; \ delay_check = FCSR_FCC; - #define BR_F() \ inst = BC1F | JUMP_LENGTH; \ flags = IS_BIT16_COND; \ delay_check = FCSR_FCC; +#endif /* SLJIT_MIPS_R6 */ + SLJIT_API_FUNC_ATTRIBUTE struct sljit_jump* sljit_emit_jump(struct sljit_compiler *compiler, sljit_s32 type) { struct sljit_jump *jump; @@ -1927,7 +2041,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) + FAIL_IF(push_inst(compiler, MFC1 | TA(dst_ar) | FS(TMP_FREG3), dst_ar)); +#else /* !SLJIT_MIPS_R6 */ FAIL_IF(push_inst(compiler, CFC1 | TA(dst_ar) | DA(FCSR_REG), dst_ar)); +#endif /* SLJIT_MIPS_R6 */ 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; diff --git a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c index 5ef4ac96c4..b34e3965ed 100644 --- a/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c +++ b/thirdparty/pcre2/src/sljit/sljitNativePPC_common.c @@ -42,7 +42,7 @@ typedef sljit_u32 sljit_ins; #include <sys/cache.h> #endif -#if (defined SLJIT_LITTLE_ENDIAN && SLJIT_LITTLE_ENDIAN) +#if (defined _CALL_ELF && _CALL_ELF == 2) #define SLJIT_PASS_ENTRY_ADDR_TO_CALL 1 #endif diff --git a/thirdparty/tinyexr/tinyexr.h b/thirdparty/tinyexr/tinyexr.h index 3c19391850..f22163738f 100644 --- a/thirdparty/tinyexr/tinyexr.h +++ b/thirdparty/tinyexr/tinyexr.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2014 - 2018, Syoyo Fujita and many contributors. +Copyright (c) 2014 - 2019, Syoyo Fujita and many contributors. All rights reserved. Redistribution and use in source and binary forms, with or without @@ -276,7 +276,8 @@ extern int LoadEXR(float **out_rgba, int *width, int *height, // @deprecated { to be removed. } // Simple wrapper API for ParseEXRHeaderFromFile. // checking given file is a EXR file(by just look up header) -// @return TINYEXR_SUCCEES for EXR image, TINYEXR_ERROR_INVALID_HEADER for others +// @return TINYEXR_SUCCEES for EXR image, TINYEXR_ERROR_INVALID_HEADER for +// others extern int IsEXR(const char *filename); // @deprecated { to be removed. } @@ -469,9 +470,10 @@ extern int LoadEXRFromMemory(float **out_rgba, int *width, int *height, #include <cstdio> #include <cstdlib> #include <cstring> -#include <iostream> #include <sstream> +//#include <iostream> // debug + #include <limits> #include <string> #include <vector> @@ -2537,10 +2539,10 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; - const mz_uint8 *pIn_buf_cur = pIn_buf_next, - *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; - mz_uint8 *pOut_buf_cur = pOut_buf_next, - *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; + const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = + pIn_buf_next + *pIn_buf_size; + mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = + pOut_buf_next + *pOut_buf_size; size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 @@ -2957,8 +2959,9 @@ void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, tinfl_status status = tinfl_decompress( &decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL, - &dst_buf_size, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + &dst_buf_size, + (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) { MZ_FREE(pBuf); *pOut_len = 0; @@ -3011,9 +3014,8 @@ int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, - (flags & - ~(TINFL_FLAG_HAS_MORE_INPUT | - TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); + (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); in_buf_ofs += in_buf_size; if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) @@ -3138,7 +3140,9 @@ static const mz_uint8 s_tdefl_large_dist_extra[128] = { // Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted // values. -typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq; +typedef struct { + mz_uint16 m_key, m_sym_index; +} tdefl_sym_freq; static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq *pSyms0, tdefl_sym_freq *pSyms1) { @@ -5282,9 +5286,10 @@ mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS); n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1); pStat->m_comment_size = n; - memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + - MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + - MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), + memcpy(pStat->m_comment, + p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + + MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) + + MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS), n); pStat->m_comment[n] = '\0'; @@ -7008,6 +7013,11 @@ static void swap2(unsigned short *val) { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-function" #endif + +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif static void cpy4(int *dst_val, const int *src_val) { unsigned char *dst = reinterpret_cast<unsigned char *>(dst_val); const unsigned char *src = reinterpret_cast<const unsigned char *>(src_val); @@ -7037,11 +7047,14 @@ static void cpy4(float *dst_val, const float *src_val) { dst[2] = src[2]; dst[3] = src[3]; } - #ifdef __clang__ #pragma clang diagnostic pop #endif +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif + static void swap4(unsigned int *val) { #ifdef MINIZ_LITTLE_ENDIAN (void)val; @@ -7696,7 +7709,8 @@ static int rleUncompress(int inLength, int maxLength, const signed char in[], int count = -(static_cast<int>(*in++)); inLength -= count + 1; - if (0 > (maxLength -= count)) return 0; + // Fixes #116: Add bounds check to in buffer. + if ((0 > (maxLength -= count)) || (inLength < 0)) return 0; memcpy(out, in, count); out += count; @@ -7790,13 +7804,19 @@ static void CompressRle(unsigned char *dst, } } -static void DecompressRle(unsigned char *dst, +static bool DecompressRle(unsigned char *dst, const unsigned long uncompressed_size, const unsigned char *src, unsigned long src_size) { if (uncompressed_size == src_size) { // Data is not compressed(Issue 40). memcpy(dst, src, src_size); - return; + return true; + } + + // Workaround for issue #112. + // TODO(syoyo): Add more robust out-of-bounds check in `rleUncompress`. + if (src_size <= 2) { + return false; } std::vector<unsigned char> tmpBuf(uncompressed_size); @@ -7805,8 +7825,9 @@ static void DecompressRle(unsigned char *dst, static_cast<int>(uncompressed_size), reinterpret_cast<const signed char *>(src), reinterpret_cast<char *>(&tmpBuf.at(0))); - assert(ret == static_cast<int>(uncompressed_size)); - (void)ret; + if (ret != static_cast<int>(uncompressed_size)) { + return false; + } // // Apply EXR-specific? postprocess. Grabbed from OpenEXR's @@ -7845,6 +7866,8 @@ static void DecompressRle(unsigned char *dst, break; } } + + return true; } #if TINYEXR_USE_PIZ @@ -8556,7 +8579,7 @@ static bool hufUnpackEncTable( int lc = 0; for (; im <= iM; im++) { - if (p - *pcode > ni) { + if (p - *pcode >= ni) { return false; } @@ -8854,7 +8877,7 @@ static bool getCode(int po, int rlc, long long &c, int &lc, const char *&in, if (out + cs > oe) return false; // Bounds check for safety - // Issue 100. + // Issue 100. if ((out - 1) < ob) return false; unsigned short s = out[-1]; @@ -9348,6 +9371,10 @@ static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr, tinyexr::cpy4(&length, reinterpret_cast<const int *>(ptr)); ptr += sizeof(int); + if (size_t((ptr - inPtr) + length) > inLen) { + return false; + } + std::vector<unsigned short> tmpBuffer(tmpBufSize); hufUncompress(reinterpret_cast<const char *>(ptr), length, &tmpBuffer); @@ -9642,8 +9669,9 @@ static bool DecodePixelData(/* out */ unsigned char **out_images, reinterpret_cast<unsigned char *>(&outBuf.at(0)), data_ptr, tmpBufLen, data_len, static_cast<int>(num_channels), channels, width, num_lines); - assert(ret); - (void)ret; + if (!ret) { + return false; + } // For PIZ_COMPRESSION: // pixel sample data for channel 0 for scanline 0 @@ -9688,16 +9716,18 @@ static bool DecodePixelData(/* out */ unsigned char **out_images, } else { // HALF -> FLOAT FP32 f32 = half_to_float(hf); float *image = reinterpret_cast<float **>(out_images)[c]; + size_t offset = 0; if (line_order == 0) { - image += (static_cast<size_t>(line_no) + v) * + offset = (static_cast<size_t>(line_no) + v) * static_cast<size_t>(x_stride) + u; } else { - image += static_cast<size_t>( + offset = static_cast<size_t>( (height - 1 - (line_no + static_cast<int>(v)))) * static_cast<size_t>(x_stride) + u; } + image += offset; *image = f32.f; } } @@ -9824,16 +9854,19 @@ static bool DecodePixelData(/* out */ unsigned char **out_images, } else { // HALF -> FLOAT tinyexr::FP32 f32 = half_to_float(hf); float *image = reinterpret_cast<float **>(out_images)[c]; + size_t offset = 0; if (line_order == 0) { - image += (static_cast<size_t>(line_no) + v) * + offset = (static_cast<size_t>(line_no) + v) * static_cast<size_t>(x_stride) + u; } else { - image += (static_cast<size_t>(height) - 1U - + offset = (static_cast<size_t>(height) - 1U - (static_cast<size_t>(line_no) + v)) * static_cast<size_t>(x_stride) + u; } + image += offset; + *image = f32.f; } } @@ -9906,10 +9939,15 @@ static bool DecodePixelData(/* out */ unsigned char **out_images, pixel_data_size); unsigned long dstLen = static_cast<unsigned long>(outBuf.size()); - assert(dstLen > 0); - tinyexr::DecompressRle(reinterpret_cast<unsigned char *>(&outBuf.at(0)), + if (dstLen == 0) { + return false; + } + + if (!tinyexr::DecompressRle(reinterpret_cast<unsigned char *>(&outBuf.at(0)), dstLen, data_ptr, - static_cast<unsigned long>(data_len)); + static_cast<unsigned long>(data_len))) { + return false; + } // For RLE_COMPRESSION: // pixel sample data for channel 0 for scanline 0 @@ -10739,12 +10777,28 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, if ((data_width < 0) || (data_height < 0)) { if (err) { std::stringstream ss; - ss << "Invalid data width or data height: " << data_width << ", " << data_height << std::endl; + ss << "Invalid data width or data height: " << data_width << ", " + << data_height << std::endl; (*err) += ss.str(); } return TINYEXR_ERROR_INVALID_DATA; } + // Do not allow too large data_width and data_height. header invalid? + { + const int threshold = 1024 * 8192; // heuristics + if ((data_width > threshold) || (data_height > threshold)) { + if (err) { + std::stringstream ss; + ss << "data_with or data_height too large. data_width: " << data_width + << ", " + << "data_height = " << data_height << std::endl; + (*err) += ss.str(); + } + return TINYEXR_ERROR_INVALID_DATA; + } + } + size_t num_blocks = offsets.size(); std::vector<size_t> channel_offset_list; @@ -10762,6 +10816,25 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, bool invalid_data = false; // TODO(LTE): Use atomic lock for MT safety. if (exr_header->tiled) { + // value check + if (exr_header->tile_size_x < 0) { + if (err) { + std::stringstream ss; + ss << "Invalid tile size x : " << exr_header->tile_size_x << "\n"; + (*err) += ss.str(); + } + return TINYEXR_ERROR_INVALID_HEADER; + } + + if (exr_header->tile_size_y < 0) { + if (err) { + std::stringstream ss; + ss << "Invalid tile size y : " << exr_header->tile_size_y << "\n"; + (*err) += ss.str(); + } + return TINYEXR_ERROR_INVALID_HEADER; + } + size_t num_tiles = offsets.size(); // = # of blocks exr_image->tiles = static_cast<EXRTile *>( @@ -10840,12 +10913,17 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, } } else { // scanline format - // Don't allow too large image(256GB * pixel_data_size or more). Workaround for #104. - size_t data_len = size_t(data_width) * size_t(data_height) * size_t(num_channels); - if ((data_len == 0) || (data_len >= 0x4000000000)) { + // Don't allow too large image(256GB * pixel_data_size or more). Workaround + // for #104. + size_t total_data_len = + size_t(data_width) * size_t(data_height) * size_t(num_channels); + const bool total_data_len_overflown = sizeof(void*) == 8 ? (total_data_len >= 0x4000000000) : false; + if ((total_data_len == 0) || total_data_len_overflown ) { if (err) { std::stringstream ss; - ss << "Image data size is zero or too large: width = " << data_width << ", height = " << data_height << ", channels = " << num_channels << std::endl; + ss << "Image data size is zero or too large: width = " << data_width + << ", height = " << data_height << ", channels = " << num_channels + << std::endl; (*err) += ss.str(); } return TINYEXR_ERROR_INVALID_DATA; @@ -10880,12 +10958,21 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, if (size_t(data_len) > data_size) { invalid_data = true; + + } else if ((line_no > (2 << 20)) || (line_no < -(2 << 20))) { + // Too large value. Assume this is invalid + // 2**20 = 1048576 = heuristic value. + invalid_data = true; + } else if (data_len == 0) { + // TODO(syoyo): May be ok to raise the threshold for example `data_len + // < 4` + invalid_data = true; } else { + // line_no may be negative. int end_line_no = (std::min)(line_no + num_scanline_blocks, (exr_header->data_window[3] + 1)); int num_lines = end_line_no - line_no; - // assert(num_lines > 0); if (num_lines <= 0) { invalid_data = true; @@ -10894,7 +10981,16 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, data_ptr += 8; // Adjust line_no with data_window.bmin.y - line_no -= exr_header->data_window[1]; + + // overflow check + tinyexr_int64 lno = static_cast<tinyexr_int64>(line_no) - static_cast<tinyexr_int64>(exr_header->data_window[1]); + if (lno > std::numeric_limits<int>::max()) { + line_no = -1; // invalid + } else if (lno < -std::numeric_limits<int>::max()) { + line_no = -1; // invalid + } else { + line_no -= exr_header->data_window[1]; + } if (line_no < 0) { invalid_data = true; @@ -10919,6 +11015,10 @@ static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header, } if (invalid_data) { + if (err) { + std::stringstream ss; + (*err) += "Invalid data found when decoding pixels.\n"; + } return TINYEXR_ERROR_INVALID_DATA; } @@ -10995,7 +11095,7 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header, int data_width = exr_header->data_window[2] - exr_header->data_window[0]; if (data_width >= std::numeric_limits<int>::max()) { // Issue 63 - tinyexr::SetErrorMessage("Invalid data window value", err); + tinyexr::SetErrorMessage("Invalid data width value", err); return TINYEXR_ERROR_INVALID_DATA; } data_width++; @@ -11008,10 +11108,23 @@ static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header, data_height++; if ((data_width < 0) || (data_height < 0)) { - tinyexr::SetErrorMessage("data window or data height is negative.", err); + tinyexr::SetErrorMessage("data width or data height is negative.", err); return TINYEXR_ERROR_INVALID_DATA; } + // Do not allow too large data_width and data_height. header invalid? + { + const int threshold = 1024 * 8192; // heuristics + if (data_width > threshold) { + tinyexr::SetErrorMessage("data width too large.", err); + return TINYEXR_ERROR_INVALID_DATA; + } + if (data_height > threshold) { + tinyexr::SetErrorMessage("data height too large.", err); + return TINYEXR_ERROR_INVALID_DATA; + } + } + // Read offset tables. size_t num_blocks = 0; @@ -11190,7 +11303,6 @@ int LoadEXR(float **out_rgba, int *width, int *height, const char *filename, static_cast<size_t>(exr_image.height))); if (exr_header.tiled) { - for (int it = 0; it < exr_image.num_tiles; it++) { for (int j = 0; j < exr_header.tile_size_y; j++) { for (int i = 0; i < exr_header.tile_size_x; i++) { @@ -11325,7 +11437,7 @@ int IsEXR(const char *filename) { if (ret != TINYEXR_SUCCESS) { return TINYEXR_ERROR_INVALID_HEADER; } - + return TINYEXR_SUCCESS; } @@ -11434,7 +11546,6 @@ int LoadEXRFromMemory(float **out_rgba, int *width, int *height, static_cast<size_t>(exr_image.height))); if (exr_header.tiled) { - for (int it = 0; it < exr_image.num_tiles; it++) { for (int j = 0; j < exr_header.tile_size_y; j++) { for (int i = 0; i < exr_header.tile_size_x; i++) { @@ -12115,7 +12226,7 @@ size_t SaveEXRImageToMemory(const EXRImage *exr_image, sizeof(tinyexr::tinyexr_uint64) * static_cast<size_t>(num_blocks)); } - if ( memory.size() == 0 ) { + if (memory.size() == 0) { tinyexr::SetErrorMessage("Output memory size is zero", err); return 0; } @@ -12286,6 +12397,9 @@ int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) { size_t marker_size; if (!tinyexr::ReadAttribute(&attr_name, &attr_type, &data, &marker_size, marker, size)) { + std::stringstream ss; + ss << "Failed to parse attribute\n"; + tinyexr::SetErrorMessage(ss.str(), err); return TINYEXR_ERROR_INVALID_DATA; } marker += marker_size; diff --git a/thirdparty/wslay/COPYING b/thirdparty/wslay/COPYING new file mode 100644 index 0000000000..6080330303 --- /dev/null +++ b/thirdparty/wslay/COPYING @@ -0,0 +1,22 @@ +The MIT License + +Copyright (c) 2011, 2012, 2015 Tatsuhiro Tsujikawa + +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. diff --git a/thirdparty/wslay/includes/config.h b/thirdparty/wslay/includes/config.h new file mode 100644 index 0000000000..771ad12528 --- /dev/null +++ b/thirdparty/wslay/includes/config.h @@ -0,0 +1,8 @@ +#ifndef CONFIG_H +#define CONFIG_H + +#ifdef BIG_ENDIAN_ENABLED +#define WORDS_BIGENDIAN +#endif + +#endif /* CONFIG_H */ diff --git a/thirdparty/wslay/includes/wslay/wslay.h b/thirdparty/wslay/includes/wslay/wslay.h new file mode 100644 index 0000000000..9c751b05b7 --- /dev/null +++ b/thirdparty/wslay/includes/wslay/wslay.h @@ -0,0 +1,778 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 WSLAY_H +#define WSLAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stdint.h> +#include <stdlib.h> +#include <sys/types.h> + +/* GODOT ADDITTION */ +#if defined(_MSC_VER) +#include <BaseTsd.h> +typedef SSIZE_T ssize_t; +#endif +/* GODOT END */ + +/* + * wslay/wslayver.h is generated from wslay/wslayver.h.in by + * configure. The projects which do not use autotools can set + * WSLAY_VERSION macro from outside to avoid to generating wslayver.h + */ +#ifndef WSLAY_VERSION +# include <wslay/wslayver.h> +#endif /* WSLAY_VERSION */ + +enum wslay_error { + WSLAY_ERR_WANT_READ = -100, + WSLAY_ERR_WANT_WRITE = -101, + WSLAY_ERR_PROTO = -200, + WSLAY_ERR_INVALID_ARGUMENT = -300, + WSLAY_ERR_INVALID_CALLBACK = -301, + WSLAY_ERR_NO_MORE_MSG = -302, + WSLAY_ERR_CALLBACK_FAILURE = -400, + WSLAY_ERR_WOULDBLOCK = -401, + WSLAY_ERR_NOMEM = -500 +}; + +/* + * Status codes defined in RFC6455 + */ +enum wslay_status_code { + WSLAY_CODE_NORMAL_CLOSURE = 1000, + WSLAY_CODE_GOING_AWAY = 1001, + WSLAY_CODE_PROTOCOL_ERROR = 1002, + WSLAY_CODE_UNSUPPORTED_DATA = 1003, + WSLAY_CODE_NO_STATUS_RCVD = 1005, + WSLAY_CODE_ABNORMAL_CLOSURE = 1006, + WSLAY_CODE_INVALID_FRAME_PAYLOAD_DATA = 1007, + WSLAY_CODE_POLICY_VIOLATION = 1008, + WSLAY_CODE_MESSAGE_TOO_BIG = 1009, + WSLAY_CODE_MANDATORY_EXT = 1010, + WSLAY_CODE_INTERNAL_SERVER_ERROR = 1011, + WSLAY_CODE_TLS_HANDSHAKE = 1015 +}; + +enum wslay_io_flags { + /* + * There is more data to send. + */ + WSLAY_MSG_MORE = 1 +}; + +/* + * Callback function used by wslay_frame_send() function when it needs + * to send data. The implementation of this function must send at most + * len bytes of data in data. flags is the bitwise OR of zero or more + * of the following flag: + * + * WSLAY_MSG_MORE + * There is more data to send + * + * It provides some hints to tune performance and behaviour. user_data + * is one given in wslay_frame_context_init() function. The + * implementation of this function must return the number of bytes + * sent. If there is an error, return -1. The return value 0 is also + * treated an error by the library. + */ +typedef ssize_t (*wslay_frame_send_callback)(const uint8_t *data, size_t len, + int flags, void *user_data); +/* + * Callback function used by wslay_frame_recv() function when it needs + * more data. The implementation of this function must fill at most + * len bytes of data into buf. The memory area of buf is allocated by + * library and not be freed by the application code. flags is always 0 + * in this version. user_data is one given in + * wslay_frame_context_init() function. The implementation of this + * function must return the number of bytes filled. If there is an + * error, return -1. The return value 0 is also treated an error by + * the library. + */ +typedef ssize_t (*wslay_frame_recv_callback)(uint8_t *buf, size_t len, + int flags, void *user_data); +/* + * Callback function used by wslay_frame_send() function when it needs + * new mask key. The implementation of this function must write + * exactly len bytes of mask key to buf. user_data is one given in + * wslay_frame_context_init() function. The implementation of this + * function return 0 on success. If there is an error, return -1. + */ +typedef int (*wslay_frame_genmask_callback)(uint8_t *buf, size_t len, + void *user_data); + +struct wslay_frame_callbacks { + wslay_frame_send_callback send_callback; + wslay_frame_recv_callback recv_callback; + wslay_frame_genmask_callback genmask_callback; +}; + +/* + * The opcode defined in RFC6455. + */ +enum wslay_opcode { + WSLAY_CONTINUATION_FRAME = 0x0u, + WSLAY_TEXT_FRAME = 0x1u, + WSLAY_BINARY_FRAME = 0x2u, + WSLAY_CONNECTION_CLOSE = 0x8u, + WSLAY_PING = 0x9u, + WSLAY_PONG = 0xau +}; + +/* + * Macro that returns 1 if opcode is control frame opcode, otherwise + * returns 0. + */ +#define wslay_is_ctrl_frame(opcode) ((opcode >> 3) & 1) + +/* + * Macros that represent and return reserved bits: RSV1, RSV2, RSV3. + * These macros assume that rsv is constructed by ((RSV1 << 2) | + * (RSV2 << 1) | RSV3) + */ +#define WSLAY_RSV_NONE ((uint8_t) 0) +#define WSLAY_RSV1_BIT (((uint8_t) 1) << 2) +#define WSLAY_RSV2_BIT (((uint8_t) 1) << 1) +#define WSLAY_RSV3_BIT (((uint8_t) 1) << 0) + +#define wslay_get_rsv1(rsv) ((rsv >> 2) & 1) +#define wslay_get_rsv2(rsv) ((rsv >> 1) & 1) +#define wslay_get_rsv3(rsv) (rsv & 1) + +struct wslay_frame_iocb { + /* 1 for fragmented final frame, 0 for otherwise */ + uint8_t fin; + /* + * reserved 3 bits. rsv = ((RSV1 << 2) | (RSV << 1) | RSV3). + * RFC6455 requires 0 unless extensions are negotiated. + */ + uint8_t rsv; + /* 4 bit opcode */ + uint8_t opcode; + /* payload length [0, 2**63-1] */ + uint64_t payload_length; + /* 1 for masked frame, 0 for unmasked */ + uint8_t mask; + /* part of payload data */ + const uint8_t *data; + /* bytes of data defined above */ + size_t data_length; +}; + +struct wslay_frame_context; +typedef struct wslay_frame_context *wslay_frame_context_ptr; + +/* + * Initializes ctx using given callbacks and user_data. This function + * allocates memory for struct wslay_frame_context and stores the + * result to *ctx. The callback functions specified in callbacks are + * copied to ctx. user_data is stored in ctx and it will be passed to + * callback functions. When the user code finished using ctx, it must + * call wslay_frame_context_free to deallocate memory. + */ +int wslay_frame_context_init(wslay_frame_context_ptr *ctx, + const struct wslay_frame_callbacks *callbacks, + void *user_data); + +/* + * Deallocates memory pointed by ctx. + */ +void wslay_frame_context_free(wslay_frame_context_ptr ctx); + +/* + * Send WebSocket frame specified in iocb. ctx must be initialized + * using wslay_frame_context_init() function. iocb->fin must be 1 if + * this is a fin frame, otherwise 0. iocb->rsv is reserved bits. + * iocb->opcode must be the opcode of this frame. iocb->mask must be + * 1 if this is masked frame, otherwise 0. iocb->payload_length is + * the payload_length of this frame. iocb->data must point to the + * payload data to be sent. iocb->data_length must be the length of + * the data. This function calls send_callback function if it needs + * to send bytes. This function calls gen_mask_callback function if + * it needs new mask key. This function returns the number of payload + * bytes sent. Please note that it does not include any number of + * header bytes. If it cannot send any single bytes of payload, it + * returns WSLAY_ERR_WANT_WRITE. If the library detects error in iocb, + * this function returns WSLAY_ERR_INVALID_ARGUMENT. If callback + * functions report a failure, this function returns + * WSLAY_ERR_INVALID_CALLBACK. This function does not always send all + * given data in iocb. If there are remaining data to be sent, adjust + * data and data_length in iocb accordingly and call this function + * again. + */ +ssize_t wslay_frame_send(wslay_frame_context_ptr ctx, + struct wslay_frame_iocb *iocb); + +/* + * Receives WebSocket frame and stores it in iocb. This function + * returns the number of payload bytes received. This does not + * include header bytes. In this case, iocb will be populated as + * follows: iocb->fin is 1 if received frame is fin frame, otherwise + * 0. iocb->rsv is reserved bits of received frame. iocb->opcode is + * opcode of received frame. iocb->mask is 1 if received frame is + * masked, otherwise 0. iocb->payload_length is the payload length of + * received frame. iocb->data is pointed to the buffer containing + * received payload data. This buffer is allocated by the library and + * must be read-only. iocb->data_length is the number of payload + * bytes recieved. This function calls recv_callback if it needs to + * receive additional bytes. If it cannot receive any single bytes of + * payload, it returns WSLAY_ERR_WANT_READ. If the library detects + * protocol violation in a received frame, this function returns + * WSLAY_ERR_PROTO. If callback functions report a failure, this + * function returns WSLAY_ERR_INVALID_CALLBACK. This function does + * not always receive whole frame in a single call. If there are + * remaining data to be received, call this function again. This + * function ensures frame alignment. + */ +ssize_t wslay_frame_recv(wslay_frame_context_ptr ctx, + struct wslay_frame_iocb *iocb); + +struct wslay_event_context; +/* Pointer to the event-based API context */ +typedef struct wslay_event_context *wslay_event_context_ptr; + +struct wslay_event_on_msg_recv_arg { + /* reserved bits: rsv = (RSV1 << 2) | (RSV2 << 1) | RSV3 */ + uint8_t rsv; + /* opcode */ + uint8_t opcode; + /* received message */ + const uint8_t *msg; + /* message length */ + size_t msg_length; + /* + * Status code iff opcode == WSLAY_CONNECTION_CLOSE. If no status + * code is included in the close control frame, it is set to 0. + */ + uint16_t status_code; +}; + +/* + * Callback function invoked by wslay_event_recv() when a message is + * completely received. + */ +typedef void (*wslay_event_on_msg_recv_callback) +(wslay_event_context_ptr ctx, + const struct wslay_event_on_msg_recv_arg *arg, void *user_data); + +struct wslay_event_on_frame_recv_start_arg { + /* fin bit; 1 for final frame, or 0. */ + uint8_t fin; + /* reserved bits: rsv = (RSV1 << 2) | (RSV2 << 1) | RSV3 */ + uint8_t rsv; + /* opcode of the frame */ + uint8_t opcode; + /* payload length of ths frame */ + uint64_t payload_length; +}; + +/* + * Callback function invoked by wslay_event_recv() when a new frame + * starts to be received. This callback function is only invoked once + * for each frame. + */ +typedef void (*wslay_event_on_frame_recv_start_callback) +(wslay_event_context_ptr ctx, + const struct wslay_event_on_frame_recv_start_arg *arg, void *user_data); + +struct wslay_event_on_frame_recv_chunk_arg { + /* chunk of payload data */ + const uint8_t *data; + /* length of data */ + size_t data_length; +}; + +/* + * Callback function invoked by wslay_event_recv() when a chunk of + * frame payload is received. + */ +typedef void (*wslay_event_on_frame_recv_chunk_callback) +(wslay_event_context_ptr ctx, + const struct wslay_event_on_frame_recv_chunk_arg *arg, void *user_data); + +/* + * Callback function invoked by wslay_event_recv() when a frame is + * completely received. + */ +typedef void (*wslay_event_on_frame_recv_end_callback) +(wslay_event_context_ptr ctx, void *user_data); + +/* + * Callback function invoked by wslay_event_recv() when it wants to + * receive more data from peer. The implementation of this callback + * function must read data at most len bytes from peer and store them + * in buf and return the number of bytes read. flags is always 0 in + * this version. + * + * If there is an error, return -1 and set error code + * WSLAY_ERR_CALLBACK_FAILURE using wslay_event_set_error(). Wslay + * event-based API on the whole assumes non-blocking I/O. If the cause + * of error is EAGAIN or EWOULDBLOCK, set WSLAY_ERR_WOULDBLOCK + * instead. This is important because it tells wslay_event_recv() to + * stop receiving further data and return. + */ +typedef ssize_t (*wslay_event_recv_callback)(wslay_event_context_ptr ctx, + uint8_t *buf, size_t len, + int flags, void *user_data); + +/* + * Callback function invoked by wslay_event_send() when it wants to + * send more data to peer. The implementation of this callback + * function must send data at most len bytes to peer and return the + * number of bytes sent. flags is the bitwise OR of zero or more of + * the following flag: + * + * WSLAY_MSG_MORE + * There is more data to send + * + * It provides some hints to tune performance and behaviour. + * + * If there is an error, return -1 and set error code + * WSLAY_ERR_CALLBACK_FAILURE using wslay_event_set_error(). Wslay + * event-based API on the whole assumes non-blocking I/O. If the cause + * of error is EAGAIN or EWOULDBLOCK, set WSLAY_ERR_WOULDBLOCK + * instead. This is important because it tells wslay_event_send() to + * stop sending data and return. + */ +typedef ssize_t (*wslay_event_send_callback)(wslay_event_context_ptr ctx, + const uint8_t *data, size_t len, + int flags, void *user_data); + +/* + * Callback function invoked by wslay_event_send() when it wants new + * mask key. As described in RFC6455, only the traffic from WebSocket + * client is masked, so this callback function is only needed if an + * event-based API is initialized for WebSocket client use. + */ +typedef int (*wslay_event_genmask_callback)(wslay_event_context_ptr ctx, + uint8_t *buf, size_t len, + void *user_data); + +struct wslay_event_callbacks { + wslay_event_recv_callback recv_callback; + wslay_event_send_callback send_callback; + wslay_event_genmask_callback genmask_callback; + wslay_event_on_frame_recv_start_callback on_frame_recv_start_callback; + wslay_event_on_frame_recv_chunk_callback on_frame_recv_chunk_callback; + wslay_event_on_frame_recv_end_callback on_frame_recv_end_callback; + wslay_event_on_msg_recv_callback on_msg_recv_callback; +}; + +/* + * Initializes ctx as WebSocket Server. user_data is an arbitrary + * pointer, which is directly passed to each callback functions as + * user_data argument. + * + * On success, returns 0. On error, returns one of following negative + * values: + * + * WSLAY_ERR_NOMEM + * Out of memory. + */ +int wslay_event_context_server_init +(wslay_event_context_ptr *ctx, + const struct wslay_event_callbacks *callbacks, void *user_data); + +/* + * Initializes ctx as WebSocket client. user_data is an arbitrary + * pointer, which is directly passed to each callback functions as + * user_data argument. + * + * On success, returns 0. On error, returns one of following negative + * values: + * + * WSLAY_ERR_NOMEM + * Out of memory. + */ +int wslay_event_context_client_init +(wslay_event_context_ptr *ctx, + const struct wslay_event_callbacks *callbacks, void *user_data); + +/* + * Releases allocated resources for ctx. + */ +void wslay_event_context_free(wslay_event_context_ptr ctx); + +/* + * Sets a bit mask of allowed reserved bits. + * Currently only permitted values are WSLAY_RSV1_BIT to allow PMCE + * extension (see RFC-7692) or WSLAY_RSV_NONE to disable. + * + * Default: WSLAY_RSV_NONE + */ +void wslay_event_config_set_allowed_rsv_bits(wslay_event_context_ptr ctx, + uint8_t rsv); + +/* + * Enables or disables buffering of an entire message for non-control + * frames. If val is 0, buffering is enabled. Otherwise, buffering is + * disabled. If wslay_event_on_msg_recv_callback is invoked when + * buffering is disabled, the msg_length member of struct + * wslay_event_on_msg_recv_arg is set to 0. + * + * The control frames are always buffered regardless of this function call. + * + * This function must not be used after the first invocation of + * wslay_event_recv() function. + */ +void wslay_event_config_set_no_buffering(wslay_event_context_ptr ctx, int val); + +/* + * Sets maximum length of a message that can be received. The length + * of message is checked by wslay_event_recv() function. If the length + * of a message is larger than this value, reading operation is + * disabled (same effect with wslay_event_shutdown_read() call) and + * close control frame with WSLAY_CODE_MESSAGE_TOO_BIG is queued. If + * buffering for non-control frames is disabled, the library checks + * each frame payload length and does not check length of entire + * message. + * + * The default value is (1u << 31)-1. + */ +void wslay_event_config_set_max_recv_msg_length(wslay_event_context_ptr ctx, + uint64_t val); + +/* + * Sets callbacks to ctx. The callbacks previouly set by this function + * or wslay_event_context_server_init() or + * wslay_event_context_client_init() are replaced with callbacks. + */ +void wslay_event_config_set_callbacks +(wslay_event_context_ptr ctx, const struct wslay_event_callbacks *callbacks); + +/* + * Receives messages from peer. When receiving + * messages, it uses wslay_event_recv_callback function. Single call + * of this function receives multiple messages until + * wslay_event_recv_callback function sets error code + * WSLAY_ERR_WOULDBLOCK. + * + * When close control frame is received, this function automatically + * queues close control frame. Also this function calls + * wslay_event_set_read_enabled() with second argument 0 to disable + * further read from peer. + * + * When ping control frame is received, this function automatically + * queues pong control frame. + * + * In case of a fatal errror which leads to negative return code, this + * function calls wslay_event_set_read_enabled() with second argument + * 0 to disable further read from peer. + * + * wslay_event_recv() returns 0 if it succeeds, or one of the + * following negative error codes: + * + * WSLAY_ERR_CALLBACK_FAILURE + * User defined callback function is failed. + * + * WSLAY_ERR_NOMEM + * Out of memory. + * + * When negative error code is returned, application must not make any + * further call of wslay_event_recv() and must close WebSocket + * connection. + */ +int wslay_event_recv(wslay_event_context_ptr ctx); + +/* + * Sends queued messages to peer. When sending a + * message, it uses wslay_event_send_callback function. Single call of + * wslay_event_send() sends multiple messages until + * wslay_event_send_callback sets error code WSLAY_ERR_WOULDBLOCK. + * + * If ctx is initialized for WebSocket client use, wslay_event_send() + * uses wslay_event_genmask_callback to get new mask key. + * + * When a message queued using wslay_event_queue_fragmented_msg() is + * sent, wslay_event_send() invokes + * wslay_event_fragmented_msg_callback for that message. + * + * After close control frame is sent, this function calls + * wslay_event_set_write_enabled() with second argument 0 to disable + * further transmission to peer. + * + * If there are any pending messages, wslay_event_want_write() returns + * 1, otherwise returns 0. + * + * In case of a fatal errror which leads to negative return code, this + * function calls wslay_event_set_write_enabled() with second argument + * 0 to disable further transmission to peer. + * + * wslay_event_send() returns 0 if it succeeds, or one of the + * following negative error codes: + * + * WSLAY_ERR_CALLBACK_FAILURE + * User defined callback function is failed. + * + * WSLAY_ERR_NOMEM + * Out of memory. + * + * When negative error code is returned, application must not make any + * further call of wslay_event_send() and must close WebSocket + * connection. + */ +int wslay_event_send(wslay_event_context_ptr ctx); + +struct wslay_event_msg { + uint8_t opcode; + const uint8_t *msg; + size_t msg_length; +}; + +/* + * Queues message specified in arg. + * + * This function supports both control and non-control messages and + * the given message is sent without fragmentation. If fragmentation + * is needed, use wslay_event_queue_fragmented_msg() function instead. + * + * This function just queues a message and does not send + * it. wslay_event_send() function call sends these queued messages. + * + * wslay_event_queue_msg() returns 0 if it succeeds, or returns the + * following negative error codes: + * + * WSLAY_ERR_NO_MORE_MSG + * Could not queue given message. The one of possible reason is that + * close control frame has been queued/sent and no further queueing + * message is not allowed. + * + * WSLAY_ERR_INVALID_ARGUMENT + * The given message is invalid. + * + * WSLAY_ERR_NOMEM + * Out of memory. + */ +int wslay_event_queue_msg(wslay_event_context_ptr ctx, + const struct wslay_event_msg *arg); + +/* + * Extended version of wslay_event_queue_msg which allows to set reserved bits. + */ +int wslay_event_queue_msg_ex(wslay_event_context_ptr ctx, + const struct wslay_event_msg *arg, uint8_t rsv); + +/* + * Specify "source" to generate message. + */ +union wslay_event_msg_source { + int fd; + void *data; +}; + +/* + * Callback function called by wslay_event_send() to read message data + * from source. The implementation of + * wslay_event_fragmented_msg_callback must store at most len bytes of + * data to buf and return the number of stored bytes. If all data is + * read (i.e., EOF), set *eof to 1. If no data can be generated at the + * moment, return 0. If there is an error, return -1 and set error + * code WSLAY_ERR_CALLBACK_FAILURE using wslay_event_set_error(). + */ +typedef ssize_t (*wslay_event_fragmented_msg_callback) +(wslay_event_context_ptr ctx, + uint8_t *buf, size_t len, const union wslay_event_msg_source *source, + int *eof, void *user_data); + +struct wslay_event_fragmented_msg { + /* opcode */ + uint8_t opcode; + /* "source" to generate message data */ + union wslay_event_msg_source source; + /* Callback function to read message data from source. */ + wslay_event_fragmented_msg_callback read_callback; +}; + +/* + * Queues a fragmented message specified in arg. + * + * This function supports non-control messages only. For control frames, + * use wslay_event_queue_msg() or wslay_event_queue_close(). + * + * This function just queues a message and does not send + * it. wslay_event_send() function call sends these queued messages. + * + * wslay_event_queue_fragmented_msg() returns 0 if it succeeds, or + * returns the following negative error codes: + * + * WSLAY_ERR_NO_MORE_MSG + * Could not queue given message. The one of possible reason is that + * close control frame has been queued/sent and no further queueing + * message is not allowed. + * + * WSLAY_ERR_INVALID_ARGUMENT + * The given message is invalid. + * + * WSLAY_ERR_NOMEM + * Out of memory. + */ +int wslay_event_queue_fragmented_msg +(wslay_event_context_ptr ctx, const struct wslay_event_fragmented_msg *arg); + +/* + * Extended version of wslay_event_queue_fragmented_msg which allows to set + * reserved bits. + */ +int wslay_event_queue_fragmented_msg_ex(wslay_event_context_ptr ctx, + const struct wslay_event_fragmented_msg *arg, uint8_t rsv); + +/* + * Queues close control frame. This function is provided just for + * convenience. wslay_event_queue_msg() can queue a close control + * frame as well. status_code is the status code of close control + * frame. reason is the close reason encoded in UTF-8. reason_length + * is the length of reason in bytes. reason_length must be less than + * 123 bytes. + * + * If status_code is 0, reason and reason_length is not used and close + * control frame with zero-length payload will be queued. + * + * This function just queues a message and does not send + * it. wslay_event_send() function call sends these queued messages. + * + * wslay_event_queue_close() returns 0 if it succeeds, or returns the + * following negative error codes: + * + * WSLAY_ERR_NO_MORE_MSG + * Could not queue given message. The one of possible reason is that + * close control frame has been queued/sent and no further queueing + * message is not allowed. + * + * WSLAY_ERR_INVALID_ARGUMENT + * The given message is invalid. + * + * WSLAY_ERR_NOMEM + * Out of memory. + */ +int wslay_event_queue_close(wslay_event_context_ptr ctx, + uint16_t status_code, + const uint8_t *reason, size_t reason_length); + +/* + * Sets error code to tell the library there is an error. This + * function is typically used in user defined callback functions. See + * the description of callback function to know which error code + * should be used. + */ +void wslay_event_set_error(wslay_event_context_ptr ctx, int val); + +/* + * Query whehter the library want to read more data from peer. + * + * wslay_event_want_read() returns 1 if the library want to read more + * data from peer, or returns 0. + */ +int wslay_event_want_read(wslay_event_context_ptr ctx); + +/* + * Query whehter the library want to send more data to peer. + * + * wslay_event_want_write() returns 1 if the library want to send more + * data to peer, or returns 0. + */ +int wslay_event_want_write(wslay_event_context_ptr ctx); + +/* + * Prevents the event-based API context from reading any further data + * from peer. + * + * This function may be used with wslay_event_queue_close() if the + * application detects error in the data received and wants to fail + * WebSocket connection. + */ +void wslay_event_shutdown_read(wslay_event_context_ptr ctx); + +/* + * Prevents the event-based API context from sending any further data + * to peer. + */ +void wslay_event_shutdown_write(wslay_event_context_ptr ctx); + +/* + * Returns 1 if the event-based API context allows read operation, or + * return 0. + * + * After wslay_event_shutdown_read() is called, + * wslay_event_get_read_enabled() returns 0. + */ +int wslay_event_get_read_enabled(wslay_event_context_ptr ctx); + +/* + * Returns 1 if the event-based API context allows write operation, or + * return 0. + * + * After wslay_event_shutdown_write() is called, + * wslay_event_get_write_enabled() returns 0. + */ +int wslay_event_get_write_enabled(wslay_event_context_ptr ctx); + +/* + * Returns 1 if a close control frame has been received from peer, or + * returns 0. + */ +int wslay_event_get_close_received(wslay_event_context_ptr ctx); + +/* + * Returns 1 if a close control frame has been sent to peer, or + * returns 0. + */ +int wslay_event_get_close_sent(wslay_event_context_ptr ctx); + +/* + * Returns status code received in close control frame. If no close + * control frame has not been received, returns + * WSLAY_CODE_ABNORMAL_CLOSURE. If received close control frame has no + * status code, returns WSLAY_CODE_NO_STATUS_RCVD. + */ +uint16_t wslay_event_get_status_code_received(wslay_event_context_ptr ctx); + +/* + * Returns status code sent in close control frame. If no close + * control frame has not been sent, returns + * WSLAY_CODE_ABNORMAL_CLOSURE. If sent close control frame has no + * status code, returns WSLAY_CODE_NO_STATUS_RCVD. + */ +uint16_t wslay_event_get_status_code_sent(wslay_event_context_ptr ctx); + +/* + * Returns the number of queued messages. + */ +size_t wslay_event_get_queued_msg_count(wslay_event_context_ptr ctx); + +/* + * Returns the sum of queued message length. It only counts the + * message length queued using wslay_event_queue_msg() or + * wslay_event_queue_close(). + */ +size_t wslay_event_get_queued_msg_length(wslay_event_context_ptr ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* WSLAY_H */ diff --git a/thirdparty/wslay/includes/wslay/wslayver.h b/thirdparty/wslay/includes/wslay/wslayver.h new file mode 100644 index 0000000000..2c3e282e9d --- /dev/null +++ b/thirdparty/wslay/includes/wslay/wslayver.h @@ -0,0 +1,31 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 WSLAYVER_H +#define WSLAYVER_H + +/* Version number of wslay release */ +#define WSLAY_VERSION "1.1.0" + +#endif /* WSLAYVER_H */ diff --git a/thirdparty/wslay/msvcfix.diff b/thirdparty/wslay/msvcfix.diff new file mode 100644 index 0000000000..28721844f4 --- /dev/null +++ b/thirdparty/wslay/msvcfix.diff @@ -0,0 +1,17 @@ +diff --git a/thirdparty/wslay/includes/wslay/wslay.h b/thirdparty/wslay/includes/wslay/wslay.h +index 2fde81a4e..9c751b05b 100644 +--- a/thirdparty/wslay/includes/wslay/wslay.h ++++ b/thirdparty/wslay/includes/wslay/wslay.h +@@ -33,6 +33,12 @@ extern "C" { + #include <stdlib.h> + #include <sys/types.h> + ++/* GODOT ADDITTION */ ++#if defined(_MSC_VER) ++#include <BaseTsd.h> ++typedef SSIZE_T ssize_t; ++#endif ++/* GODOT END */ + + /* + * wslay/wslayver.h is generated from wslay/wslayver.h.in by diff --git a/thirdparty/wslay/wslay_event.c b/thirdparty/wslay/wslay_event.c new file mode 100644 index 0000000000..57415c51e0 --- /dev/null +++ b/thirdparty/wslay/wslay_event.c @@ -0,0 +1,1027 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 "wslay_event.h" + +#include <string.h> +#include <assert.h> +#include <stdio.h> + +#include "wslay_queue.h" +#include "wslay_frame.h" +#include "wslay_net.h" +/* Start of utf8 dfa */ +/* Copyright (c) 2008-2010 Bjoern Hoehrmann <bjoern@hoehrmann.de> + * See http://bjoern.hoehrmann.de/utf-8/decoder/dfa/ for details. + * + * Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de> + * + * 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. + */ +#define UTF8_ACCEPT 0 +#define UTF8_REJECT 12 + +static const uint8_t utf8d[] = { + /* + * The first part of the table maps bytes to character classes that + * to reduce the size of the transition table and create bitmasks. + */ + 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, + 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, + 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, + 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,1,1,1,1,1,1,1,1,1,1,1,1, 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8, + + /* + * The second part is a transition table that maps a combination + * of a state of the automaton and a character class to a state. + */ + 0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12, + 12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12, + 12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12, + 12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12, + 12,36,12,12,12,12,12,12,12,12,12,12, +}; + +static uint32_t +decode(uint32_t* state, uint32_t* codep, uint32_t byte) { + uint32_t type = utf8d[byte]; + + *codep = (*state != UTF8_ACCEPT) ? + (byte & 0x3fu) | (*codep << 6) : + (0xff >> type) & (byte); + + *state = utf8d[256 + *state + type]; + return *state; +} + +/* End of utf8 dfa */ + +static ssize_t wslay_event_frame_recv_callback(uint8_t *buf, size_t len, + int flags, void *user_data) +{ + struct wslay_event_frame_user_data *e = + (struct wslay_event_frame_user_data*)user_data; + return e->ctx->callbacks.recv_callback(e->ctx, buf, len, flags, e->user_data); +} + +static ssize_t wslay_event_frame_send_callback(const uint8_t *data, size_t len, + int flags, void *user_data) +{ + struct wslay_event_frame_user_data *e = + (struct wslay_event_frame_user_data*)user_data; + return e->ctx->callbacks.send_callback(e->ctx, data, len, flags, + e->user_data); +} + +static int wslay_event_frame_genmask_callback(uint8_t *buf, size_t len, + void *user_data) +{ + struct wslay_event_frame_user_data *e = + (struct wslay_event_frame_user_data*)user_data; + return e->ctx->callbacks.genmask_callback(e->ctx, buf, len, e->user_data); +} + +static int wslay_event_byte_chunk_init +(struct wslay_event_byte_chunk **chunk, size_t len) +{ + *chunk = (struct wslay_event_byte_chunk*)malloc + (sizeof(struct wslay_event_byte_chunk)); + if(*chunk == NULL) { + return WSLAY_ERR_NOMEM; + } + memset(*chunk, 0, sizeof(struct wslay_event_byte_chunk)); + if(len) { + (*chunk)->data = (uint8_t*)malloc(len); + if((*chunk)->data == NULL) { + free(*chunk); + return WSLAY_ERR_NOMEM; + } + (*chunk)->data_length = len; + } + return 0; +} + +static void wslay_event_byte_chunk_free(struct wslay_event_byte_chunk *c) +{ + if(!c) { + return; + } + free(c->data); + free(c); +} + +static void wslay_event_byte_chunk_copy(struct wslay_event_byte_chunk *c, + size_t off, + const uint8_t *data, size_t data_length) +{ + memcpy(c->data+off, data, data_length); +} + +static void wslay_event_imsg_set(struct wslay_event_imsg *m, + uint8_t fin, uint8_t rsv, uint8_t opcode) +{ + m->fin = fin; + m->rsv = rsv; + m->opcode = opcode; + m->msg_length = 0; +} + +static void wslay_event_imsg_chunks_free(struct wslay_event_imsg *m) +{ + if(!m->chunks) { + return; + } + while(!wslay_queue_empty(m->chunks)) { + wslay_event_byte_chunk_free(wslay_queue_top(m->chunks)); + wslay_queue_pop(m->chunks); + } +} + +static void wslay_event_imsg_reset(struct wslay_event_imsg *m) +{ + m->opcode = 0xffu; + m->utf8state = UTF8_ACCEPT; + wslay_event_imsg_chunks_free(m); +} + +static int wslay_event_imsg_append_chunk(struct wslay_event_imsg *m, size_t len) +{ + if(len == 0) { + return 0; + } else { + int r; + struct wslay_event_byte_chunk *chunk; + if((r = wslay_event_byte_chunk_init(&chunk, len)) != 0) { + return r; + } + if((r = wslay_queue_push(m->chunks, chunk)) != 0) { + return r; + } + m->msg_length += len; + return 0; + } +} + +static int wslay_event_omsg_non_fragmented_init +(struct wslay_event_omsg **m, uint8_t opcode, uint8_t rsv, + const uint8_t *msg, size_t msg_length) +{ + *m = (struct wslay_event_omsg*)malloc(sizeof(struct wslay_event_omsg)); + if(!*m) { + return WSLAY_ERR_NOMEM; + } + memset(*m, 0, sizeof(struct wslay_event_omsg)); + (*m)->fin = 1; + (*m)->opcode = opcode; + (*m)->rsv = rsv; + (*m)->type = WSLAY_NON_FRAGMENTED; + if(msg_length) { + (*m)->data = (uint8_t*)malloc(msg_length); + if(!(*m)->data) { + free(*m); + return WSLAY_ERR_NOMEM; + } + memcpy((*m)->data, msg, msg_length); + (*m)->data_length = msg_length; + } + return 0; +} + +static int wslay_event_omsg_fragmented_init +(struct wslay_event_omsg **m, uint8_t opcode, uint8_t rsv, + const union wslay_event_msg_source source, + wslay_event_fragmented_msg_callback read_callback) +{ + *m = (struct wslay_event_omsg*)malloc(sizeof(struct wslay_event_omsg)); + if(!*m) { + return WSLAY_ERR_NOMEM; + } + memset(*m, 0, sizeof(struct wslay_event_omsg)); + (*m)->opcode = opcode; + (*m)->rsv = rsv; + (*m)->type = WSLAY_FRAGMENTED; + (*m)->source = source; + (*m)->read_callback = read_callback; + return 0; +} + +static void wslay_event_omsg_free(struct wslay_event_omsg *m) +{ + if(!m) { + return; + } + free(m->data); + free(m); +} + +static uint8_t* wslay_event_flatten_queue(struct wslay_queue *queue, size_t len) +{ + if(len == 0) { + return NULL; + } else { + size_t off = 0; + uint8_t *buf = (uint8_t*)malloc(len); + if(!buf) { + return NULL; + } + while(!wslay_queue_empty(queue)) { + struct wslay_event_byte_chunk *chunk = wslay_queue_top(queue); + memcpy(buf+off, chunk->data, chunk->data_length); + off += chunk->data_length; + wslay_event_byte_chunk_free(chunk); + wslay_queue_pop(queue); + assert(off <= len); + } + assert(len == off); + return buf; + } +} + +static int wslay_event_is_msg_queueable(wslay_event_context_ptr ctx) +{ + return ctx->write_enabled && (ctx->close_status & WSLAY_CLOSE_QUEUED) == 0; +} + +int wslay_event_queue_close(wslay_event_context_ptr ctx, uint16_t status_code, + const uint8_t *reason, size_t reason_length) +{ + if(!wslay_event_is_msg_queueable(ctx)) { + return WSLAY_ERR_NO_MORE_MSG; + } else if(reason_length > 123) { + return WSLAY_ERR_INVALID_ARGUMENT; + } else { + uint8_t msg[128]; + size_t msg_length; + struct wslay_event_msg arg; + uint16_t ncode; + int r; + if(status_code == 0) { + msg_length = 0; + } else { + ncode = htons(status_code); + memcpy(msg, &ncode, 2); + if(reason_length) { + memcpy(msg+2, reason, reason_length); + } + msg_length = reason_length+2; + } + arg.opcode = WSLAY_CONNECTION_CLOSE; + arg.msg = msg; + arg.msg_length = msg_length; + r = wslay_event_queue_msg(ctx, &arg); + if(r == 0) { + ctx->close_status |= WSLAY_CLOSE_QUEUED; + } + return r; + } +} + +static int wslay_event_queue_close_wrapper +(wslay_event_context_ptr ctx, uint16_t status_code, + const uint8_t *reason, size_t reason_length) +{ + int r; + ctx->read_enabled = 0; + if((r = wslay_event_queue_close(ctx, status_code, reason, reason_length)) && + r != WSLAY_ERR_NO_MORE_MSG) { + return r; + } + return 0; +} + +static int wslay_event_verify_rsv_bits(wslay_event_context_ptr ctx, uint8_t rsv) +{ + return ((rsv & ~ctx->allowed_rsv_bits) == 0); +} + +int wslay_event_queue_msg(wslay_event_context_ptr ctx, + const struct wslay_event_msg *arg) +{ + return wslay_event_queue_msg_ex(ctx, arg, WSLAY_RSV_NONE); +} + +int wslay_event_queue_msg_ex(wslay_event_context_ptr ctx, + const struct wslay_event_msg *arg, uint8_t rsv) +{ + int r; + struct wslay_event_omsg *omsg; + if(!wslay_event_is_msg_queueable(ctx)) { + return WSLAY_ERR_NO_MORE_MSG; + } + /* RSV1 is not allowed for control frames */ + if((wslay_is_ctrl_frame(arg->opcode) && + (arg->msg_length > 125 || wslay_get_rsv1(rsv))) + || !wslay_event_verify_rsv_bits(ctx, rsv)) { + return WSLAY_ERR_INVALID_ARGUMENT; + } + if((r = wslay_event_omsg_non_fragmented_init + (&omsg, arg->opcode, rsv, arg->msg, arg->msg_length)) != 0) { + return r; + } + if(wslay_is_ctrl_frame(arg->opcode)) { + if((r = wslay_queue_push(ctx->send_ctrl_queue, omsg)) != 0) { + return r; + } + } else { + if((r = wslay_queue_push(ctx->send_queue, omsg)) != 0) { + return r; + } + } + ++ctx->queued_msg_count; + ctx->queued_msg_length += arg->msg_length; + return 0; +} + +int wslay_event_queue_fragmented_msg +(wslay_event_context_ptr ctx, const struct wslay_event_fragmented_msg *arg) +{ + return wslay_event_queue_fragmented_msg_ex(ctx, arg, WSLAY_RSV_NONE); +} + +int wslay_event_queue_fragmented_msg_ex(wslay_event_context_ptr ctx, + const struct wslay_event_fragmented_msg *arg, uint8_t rsv) +{ + int r; + struct wslay_event_omsg *omsg; + if(!wslay_event_is_msg_queueable(ctx)) { + return WSLAY_ERR_NO_MORE_MSG; + } + if(wslay_is_ctrl_frame(arg->opcode) || + !wslay_event_verify_rsv_bits(ctx, rsv)) { + return WSLAY_ERR_INVALID_ARGUMENT; + } + if((r = wslay_event_omsg_fragmented_init + (&omsg, arg->opcode, rsv, arg->source, arg->read_callback)) != 0) { + return r; + } + if((r = wslay_queue_push(ctx->send_queue, omsg)) != 0) { + return r; + } + ++ctx->queued_msg_count; + return 0; +} + +void wslay_event_config_set_callbacks +(wslay_event_context_ptr ctx, const struct wslay_event_callbacks *callbacks) +{ + ctx->callbacks = *callbacks; +} + +static int wslay_event_context_init +(wslay_event_context_ptr *ctx, + const struct wslay_event_callbacks *callbacks, + void *user_data) +{ + int i, r; + struct wslay_frame_callbacks frame_callbacks = { + wslay_event_frame_send_callback, + wslay_event_frame_recv_callback, + wslay_event_frame_genmask_callback + }; + *ctx = (wslay_event_context_ptr)malloc(sizeof(struct wslay_event_context)); + if(!*ctx) { + return WSLAY_ERR_NOMEM; + } + memset(*ctx, 0, sizeof(struct wslay_event_context)); + wslay_event_config_set_callbacks(*ctx, callbacks); + (*ctx)->user_data = user_data; + (*ctx)->frame_user_data.ctx = *ctx; + (*ctx)->frame_user_data.user_data = user_data; + if((r = wslay_frame_context_init(&(*ctx)->frame_ctx, &frame_callbacks, + &(*ctx)->frame_user_data)) != 0) { + wslay_event_context_free(*ctx); + return r; + } + (*ctx)->read_enabled = (*ctx)->write_enabled = 1; + (*ctx)->send_queue = wslay_queue_new(); + if(!(*ctx)->send_queue) { + wslay_event_context_free(*ctx); + return WSLAY_ERR_NOMEM; + } + (*ctx)->send_ctrl_queue = wslay_queue_new(); + if(!(*ctx)->send_ctrl_queue) { + wslay_event_context_free(*ctx); + return WSLAY_ERR_NOMEM; + } + (*ctx)->queued_msg_count = 0; + (*ctx)->queued_msg_length = 0; + for(i = 0; i < 2; ++i) { + wslay_event_imsg_reset(&(*ctx)->imsgs[i]); + (*ctx)->imsgs[i].chunks = wslay_queue_new(); + if(!(*ctx)->imsgs[i].chunks) { + wslay_event_context_free(*ctx); + return WSLAY_ERR_NOMEM; + } + } + (*ctx)->imsg = &(*ctx)->imsgs[0]; + (*ctx)->obufmark = (*ctx)->obuflimit = (*ctx)->obuf; + (*ctx)->status_code_sent = WSLAY_CODE_ABNORMAL_CLOSURE; + (*ctx)->status_code_recv = WSLAY_CODE_ABNORMAL_CLOSURE; + (*ctx)->max_recv_msg_length = (1u << 31)-1; + return 0; +} + +int wslay_event_context_server_init +(wslay_event_context_ptr *ctx, + const struct wslay_event_callbacks *callbacks, + void *user_data) +{ + int r; + if((r = wslay_event_context_init(ctx, callbacks, user_data)) != 0) { + return r; + } + (*ctx)->server = 1; + return 0; +} + +int wslay_event_context_client_init +(wslay_event_context_ptr *ctx, + const struct wslay_event_callbacks *callbacks, + void *user_data) +{ + int r; + if((r = wslay_event_context_init(ctx, callbacks, user_data)) != 0) { + return r; + } + (*ctx)->server = 0; + return 0; +} + +void wslay_event_context_free(wslay_event_context_ptr ctx) +{ + int i; + if(!ctx) { + return; + } + for(i = 0; i < 2; ++i) { + wslay_event_imsg_chunks_free(&ctx->imsgs[i]); + wslay_queue_free(ctx->imsgs[i].chunks); + } + if(ctx->send_queue) { + while(!wslay_queue_empty(ctx->send_queue)) { + wslay_event_omsg_free(wslay_queue_top(ctx->send_queue)); + wslay_queue_pop(ctx->send_queue); + } + wslay_queue_free(ctx->send_queue); + } + if(ctx->send_ctrl_queue) { + while(!wslay_queue_empty(ctx->send_ctrl_queue)) { + wslay_event_omsg_free(wslay_queue_top(ctx->send_ctrl_queue)); + wslay_queue_pop(ctx->send_ctrl_queue); + } + wslay_queue_free(ctx->send_ctrl_queue); + } + wslay_frame_context_free(ctx->frame_ctx); + wslay_event_omsg_free(ctx->omsg); + free(ctx); +} + +static void wslay_event_call_on_frame_recv_start_callback +(wslay_event_context_ptr ctx, const struct wslay_frame_iocb *iocb) +{ + if(ctx->callbacks.on_frame_recv_start_callback) { + struct wslay_event_on_frame_recv_start_arg arg; + arg.fin = iocb->fin; + arg.rsv = iocb->rsv; + arg.opcode = iocb->opcode; + arg.payload_length = iocb->payload_length; + ctx->callbacks.on_frame_recv_start_callback(ctx, &arg, ctx->user_data); + } +} + +static void wslay_event_call_on_frame_recv_chunk_callback +(wslay_event_context_ptr ctx, const struct wslay_frame_iocb *iocb) +{ + if(ctx->callbacks.on_frame_recv_chunk_callback) { + struct wslay_event_on_frame_recv_chunk_arg arg; + arg.data = iocb->data; + arg.data_length = iocb->data_length; + ctx->callbacks.on_frame_recv_chunk_callback(ctx, &arg, ctx->user_data); + } +} + +static void wslay_event_call_on_frame_recv_end_callback +(wslay_event_context_ptr ctx) +{ + if(ctx->callbacks.on_frame_recv_end_callback) { + ctx->callbacks.on_frame_recv_end_callback(ctx, ctx->user_data); + } +} + +static int wslay_event_is_valid_status_code(uint16_t status_code) +{ + return (1000 <= status_code && status_code <= 1011 && + status_code != 1004 && status_code != 1005 && status_code != 1006) || + (3000 <= status_code && status_code <= 4999); +} + +static int wslay_event_config_get_no_buffering(wslay_event_context_ptr ctx) +{ + return (ctx->config & WSLAY_CONFIG_NO_BUFFERING) > 0; +} + +int wslay_event_recv(wslay_event_context_ptr ctx) +{ + struct wslay_frame_iocb iocb; + ssize_t r; + while(ctx->read_enabled) { + memset(&iocb, 0, sizeof(iocb)); + r = wslay_frame_recv(ctx->frame_ctx, &iocb); + if(r >= 0) { + int new_frame = 0; + /* RSV1 is not allowed on control and continuation frames */ + if((!wslay_event_verify_rsv_bits(ctx, iocb.rsv)) || + (wslay_get_rsv1(iocb.rsv) && (wslay_is_ctrl_frame(iocb.opcode) || + iocb.opcode == WSLAY_CONTINUATION_FRAME)) || + (ctx->server && !iocb.mask) || (!ctx->server && iocb.mask)) { + if((r = wslay_event_queue_close_wrapper + (ctx, WSLAY_CODE_PROTOCOL_ERROR, NULL, 0)) != 0) { + return r; + } + break; + } + if(ctx->imsg->opcode == 0xffu) { + if(iocb.opcode == WSLAY_TEXT_FRAME || + iocb.opcode == WSLAY_BINARY_FRAME || + iocb.opcode == WSLAY_CONNECTION_CLOSE || + iocb.opcode == WSLAY_PING || + iocb.opcode == WSLAY_PONG) { + wslay_event_imsg_set(ctx->imsg, iocb.fin, iocb.rsv, iocb.opcode); + new_frame = 1; + } else { + if((r = wslay_event_queue_close_wrapper + (ctx, WSLAY_CODE_PROTOCOL_ERROR, NULL, 0)) != 0) { + return r; + } + break; + } + } else if(ctx->ipayloadlen == 0 && ctx->ipayloadoff == 0) { + if(iocb.opcode == WSLAY_CONTINUATION_FRAME) { + ctx->imsg->fin = iocb.fin; + } else if(iocb.opcode == WSLAY_CONNECTION_CLOSE || + iocb.opcode == WSLAY_PING || + iocb.opcode == WSLAY_PONG) { + ctx->imsg = &ctx->imsgs[1]; + wslay_event_imsg_set(ctx->imsg, iocb.fin, iocb.rsv, iocb.opcode); + } else { + if((r = wslay_event_queue_close_wrapper + (ctx, WSLAY_CODE_PROTOCOL_ERROR, NULL, 0)) != 0) { + return r; + } + break; + } + new_frame = 1; + } + if(new_frame) { + if(ctx->imsg->msg_length+iocb.payload_length > + ctx->max_recv_msg_length) { + if((r = wslay_event_queue_close_wrapper + (ctx, WSLAY_CODE_MESSAGE_TOO_BIG, NULL, 0)) != 0) { + return r; + } + break; + } + ctx->ipayloadlen = iocb.payload_length; + wslay_event_call_on_frame_recv_start_callback(ctx, &iocb); + if(!wslay_event_config_get_no_buffering(ctx) || + wslay_is_ctrl_frame(iocb.opcode)) { + if((r = wslay_event_imsg_append_chunk(ctx->imsg, + iocb.payload_length)) != 0) { + ctx->read_enabled = 0; + return r; + } + } + } + /* If RSV1 bit is set then it is too early for utf-8 validation */ + if((!wslay_get_rsv1(ctx->imsg->rsv) && + ctx->imsg->opcode == WSLAY_TEXT_FRAME) || + ctx->imsg->opcode == WSLAY_CONNECTION_CLOSE) { + size_t i; + if(ctx->imsg->opcode == WSLAY_CONNECTION_CLOSE) { + i = 2; + } else { + i = 0; + } + for(; i < iocb.data_length; ++i) { + uint32_t codep; + if(decode(&ctx->imsg->utf8state, &codep, + iocb.data[i]) == UTF8_REJECT) { + if((r = wslay_event_queue_close_wrapper + (ctx, WSLAY_CODE_INVALID_FRAME_PAYLOAD_DATA, NULL, 0)) != 0) { + return r; + } + break; + } + } + } + if(ctx->imsg->utf8state == UTF8_REJECT) { + break; + } + wslay_event_call_on_frame_recv_chunk_callback(ctx, &iocb); + if(iocb.data_length > 0) { + if(!wslay_event_config_get_no_buffering(ctx) || + wslay_is_ctrl_frame(iocb.opcode)) { + struct wslay_event_byte_chunk *chunk; + chunk = wslay_queue_tail(ctx->imsg->chunks); + wslay_event_byte_chunk_copy(chunk, ctx->ipayloadoff, + iocb.data, iocb.data_length); + } + ctx->ipayloadoff += iocb.data_length; + } + if(ctx->ipayloadoff == ctx->ipayloadlen) { + if(ctx->imsg->fin && + (ctx->imsg->opcode == WSLAY_TEXT_FRAME || + ctx->imsg->opcode == WSLAY_CONNECTION_CLOSE) && + ctx->imsg->utf8state != UTF8_ACCEPT) { + if((r = wslay_event_queue_close_wrapper + (ctx, WSLAY_CODE_INVALID_FRAME_PAYLOAD_DATA, NULL, 0)) != 0) { + return r; + } + break; + } + wslay_event_call_on_frame_recv_end_callback(ctx); + if(ctx->imsg->fin) { + if(ctx->callbacks.on_msg_recv_callback || + ctx->imsg->opcode == WSLAY_CONNECTION_CLOSE || + ctx->imsg->opcode == WSLAY_PING) { + struct wslay_event_on_msg_recv_arg arg; + uint16_t status_code = 0; + uint8_t *msg = NULL; + size_t msg_length = 0; + if(!wslay_event_config_get_no_buffering(ctx) || + wslay_is_ctrl_frame(iocb.opcode)) { + msg = wslay_event_flatten_queue(ctx->imsg->chunks, + ctx->imsg->msg_length); + if(ctx->imsg->msg_length && !msg) { + ctx->read_enabled = 0; + return WSLAY_ERR_NOMEM; + } + msg_length = ctx->imsg->msg_length; + } + if(ctx->imsg->opcode == WSLAY_CONNECTION_CLOSE) { + const uint8_t *reason; + size_t reason_length; + if(ctx->imsg->msg_length >= 2) { + memcpy(&status_code, msg, 2); + status_code = ntohs(status_code); + if(!wslay_event_is_valid_status_code(status_code)) { + free(msg); + if((r = wslay_event_queue_close_wrapper + (ctx, WSLAY_CODE_PROTOCOL_ERROR, NULL, 0)) != 0) { + return r; + } + break; + } + reason = msg+2; + reason_length = ctx->imsg->msg_length-2; + } else { + reason = NULL; + reason_length = 0; + } + ctx->close_status |= WSLAY_CLOSE_RECEIVED; + ctx->status_code_recv = + status_code == 0 ? WSLAY_CODE_NO_STATUS_RCVD : status_code; + if((r = wslay_event_queue_close_wrapper + (ctx, status_code, reason, reason_length)) != 0) { + free(msg); + return r; + } + } else if(ctx->imsg->opcode == WSLAY_PING) { + struct wslay_event_msg arg; + arg.opcode = WSLAY_PONG; + arg.msg = msg; + arg.msg_length = ctx->imsg->msg_length; + if((r = wslay_event_queue_msg(ctx, &arg)) && + r != WSLAY_ERR_NO_MORE_MSG) { + ctx->read_enabled = 0; + free(msg); + return r; + } + } + if(ctx->callbacks.on_msg_recv_callback) { + arg.rsv = ctx->imsg->rsv; + arg.opcode = ctx->imsg->opcode; + arg.msg = msg; + arg.msg_length = msg_length; + arg.status_code = status_code; + ctx->error = 0; + ctx->callbacks.on_msg_recv_callback(ctx, &arg, ctx->user_data); + } + free(msg); + } + wslay_event_imsg_reset(ctx->imsg); + if(ctx->imsg == &ctx->imsgs[1]) { + ctx->imsg = &ctx->imsgs[0]; + } + } + ctx->ipayloadlen = ctx->ipayloadoff = 0; + } + } else { + if(r != WSLAY_ERR_WANT_READ || + (ctx->error != WSLAY_ERR_WOULDBLOCK && ctx->error != 0)) { + if((r = wslay_event_queue_close_wrapper(ctx, 0, NULL, 0)) != 0) { + return r; + } + return WSLAY_ERR_CALLBACK_FAILURE; + } + break; + } + } + return 0; +} + +static void wslay_event_on_non_fragmented_msg_popped +(wslay_event_context_ptr ctx) +{ + ctx->omsg->fin = 1; + ctx->opayloadlen = ctx->omsg->data_length; + ctx->opayloadoff = 0; +} + +static struct wslay_event_omsg* wslay_event_send_ctrl_queue_pop +(wslay_event_context_ptr ctx) +{ + /* + * If Close control frame is queued, we don't send any control frame + * other than Close. + */ + if(ctx->close_status & WSLAY_CLOSE_QUEUED) { + while(!wslay_queue_empty(ctx->send_ctrl_queue)) { + struct wslay_event_omsg *msg = wslay_queue_top(ctx->send_ctrl_queue); + wslay_queue_pop(ctx->send_ctrl_queue); + if(msg->opcode == WSLAY_CONNECTION_CLOSE) { + return msg; + } else { + wslay_event_omsg_free(msg); + } + } + return NULL; + } else { + struct wslay_event_omsg *msg = wslay_queue_top(ctx->send_ctrl_queue); + wslay_queue_pop(ctx->send_ctrl_queue); + return msg; + } +} + +int wslay_event_send(wslay_event_context_ptr ctx) +{ + struct wslay_frame_iocb iocb; + ssize_t r; + while(ctx->write_enabled && + (!wslay_queue_empty(ctx->send_queue) || + !wslay_queue_empty(ctx->send_ctrl_queue) || ctx->omsg)) { + if(!ctx->omsg) { + if(wslay_queue_empty(ctx->send_ctrl_queue)) { + ctx->omsg = wslay_queue_top(ctx->send_queue); + wslay_queue_pop(ctx->send_queue); + } else { + ctx->omsg = wslay_event_send_ctrl_queue_pop(ctx); + if(ctx->omsg == NULL) { + break; + } + } + if(ctx->omsg->type == WSLAY_NON_FRAGMENTED) { + wslay_event_on_non_fragmented_msg_popped(ctx); + } + } else if(!wslay_is_ctrl_frame(ctx->omsg->opcode) && + ctx->frame_ctx->ostate == PREP_HEADER && + !wslay_queue_empty(ctx->send_ctrl_queue)) { + if((r = wslay_queue_push_front(ctx->send_queue, ctx->omsg)) != 0) { + ctx->write_enabled = 0; + return r; + } + ctx->omsg = wslay_event_send_ctrl_queue_pop(ctx); + if(ctx->omsg == NULL) { + break; + } + /* ctrl message has WSLAY_NON_FRAGMENTED */ + wslay_event_on_non_fragmented_msg_popped(ctx); + } + if(ctx->omsg->type == WSLAY_NON_FRAGMENTED) { + memset(&iocb, 0, sizeof(iocb)); + iocb.fin = 1; + iocb.opcode = ctx->omsg->opcode; + iocb.rsv = ctx->omsg->rsv; + iocb.mask = ctx->server^1; + iocb.data = ctx->omsg->data+ctx->opayloadoff; + iocb.data_length = ctx->opayloadlen-ctx->opayloadoff; + iocb.payload_length = ctx->opayloadlen; + r = wslay_frame_send(ctx->frame_ctx, &iocb); + if(r >= 0) { + ctx->opayloadoff += r; + if(ctx->opayloadoff == ctx->opayloadlen) { + --ctx->queued_msg_count; + ctx->queued_msg_length -= ctx->omsg->data_length; + if(ctx->omsg->opcode == WSLAY_CONNECTION_CLOSE) { + uint16_t status_code = 0; + ctx->write_enabled = 0; + ctx->close_status |= WSLAY_CLOSE_SENT; + if(ctx->omsg->data_length >= 2) { + memcpy(&status_code, ctx->omsg->data, 2); + status_code = ntohs(status_code); + } + ctx->status_code_sent = + status_code == 0 ? WSLAY_CODE_NO_STATUS_RCVD : status_code; + } + wslay_event_omsg_free(ctx->omsg); + ctx->omsg = NULL; + } else { + break; + } + } else { + if(r != WSLAY_ERR_WANT_WRITE || + (ctx->error != WSLAY_ERR_WOULDBLOCK && ctx->error != 0)) { + ctx->write_enabled = 0; + return WSLAY_ERR_CALLBACK_FAILURE; + } + break; + } + } else { + if(ctx->omsg->fin == 0 && ctx->obuflimit == ctx->obufmark) { + int eof = 0; + r = ctx->omsg->read_callback(ctx, ctx->obuf, sizeof(ctx->obuf), + &ctx->omsg->source, + &eof, ctx->user_data); + if(r == 0) { + break; + } else if(r < 0) { + ctx->write_enabled = 0; + return WSLAY_ERR_CALLBACK_FAILURE; + } + ctx->obuflimit = ctx->obuf+r; + if(eof) { + ctx->omsg->fin = 1; + } + ctx->opayloadlen = r; + ctx->opayloadoff = 0; + } + memset(&iocb, 0, sizeof(iocb)); + iocb.fin = ctx->omsg->fin; + iocb.opcode = ctx->omsg->opcode; + iocb.rsv = ctx->omsg->rsv; + iocb.mask = ctx->server ? 0 : 1; + iocb.data = ctx->obufmark; + iocb.data_length = ctx->obuflimit-ctx->obufmark; + iocb.payload_length = ctx->opayloadlen; + r = wslay_frame_send(ctx->frame_ctx, &iocb); + if(r >= 0) { + ctx->obufmark += r; + if(ctx->obufmark == ctx->obuflimit) { + ctx->obufmark = ctx->obuflimit = ctx->obuf; + if(ctx->omsg->fin) { + --ctx->queued_msg_count; + wslay_event_omsg_free(ctx->omsg); + ctx->omsg = NULL; + } else { + ctx->omsg->opcode = WSLAY_CONTINUATION_FRAME; + /* RSV1 is not set on continuation frames */ + ctx->omsg->rsv = ctx->omsg->rsv & ~WSLAY_RSV1_BIT; + } + } else { + break; + } + } else { + if(r != WSLAY_ERR_WANT_WRITE || + (ctx->error != WSLAY_ERR_WOULDBLOCK && + ctx->error != 0)) { + ctx->write_enabled = 0; + return WSLAY_ERR_CALLBACK_FAILURE; + } + break; + } + } + } + return 0; +} + +void wslay_event_set_error(wslay_event_context_ptr ctx, int val) +{ + ctx->error = val; +} + +int wslay_event_want_read(wslay_event_context_ptr ctx) +{ + return ctx->read_enabled; +} + +int wslay_event_want_write(wslay_event_context_ptr ctx) +{ + return ctx->write_enabled && + (!wslay_queue_empty(ctx->send_queue) || + !wslay_queue_empty(ctx->send_ctrl_queue) || ctx->omsg); +} + +void wslay_event_shutdown_read(wslay_event_context_ptr ctx) +{ + ctx->read_enabled = 0; +} + +void wslay_event_shutdown_write(wslay_event_context_ptr ctx) +{ + ctx->write_enabled = 0; +} + +int wslay_event_get_read_enabled(wslay_event_context_ptr ctx) +{ + return ctx->read_enabled; +} + +int wslay_event_get_write_enabled(wslay_event_context_ptr ctx) +{ + return ctx->write_enabled; +} + +int wslay_event_get_close_received(wslay_event_context_ptr ctx) +{ + return (ctx->close_status & WSLAY_CLOSE_RECEIVED) > 0; +} + +int wslay_event_get_close_sent(wslay_event_context_ptr ctx) +{ + return (ctx->close_status & WSLAY_CLOSE_SENT) > 0; +} + +void wslay_event_config_set_allowed_rsv_bits(wslay_event_context_ptr ctx, + uint8_t rsv) +{ + /* We currently only allow WSLAY_RSV1_BIT or WSLAY_RSV_NONE */ + ctx->allowed_rsv_bits = rsv & WSLAY_RSV1_BIT; +} + +void wslay_event_config_set_no_buffering(wslay_event_context_ptr ctx, int val) +{ + if(val) { + ctx->config |= WSLAY_CONFIG_NO_BUFFERING; + } else { + ctx->config &= ~WSLAY_CONFIG_NO_BUFFERING; + } +} + +void wslay_event_config_set_max_recv_msg_length(wslay_event_context_ptr ctx, + uint64_t val) +{ + ctx->max_recv_msg_length = val; +} + +uint16_t wslay_event_get_status_code_received(wslay_event_context_ptr ctx) +{ + return ctx->status_code_recv; +} + +uint16_t wslay_event_get_status_code_sent(wslay_event_context_ptr ctx) +{ + return ctx->status_code_sent; +} + +size_t wslay_event_get_queued_msg_count(wslay_event_context_ptr ctx) +{ + return ctx->queued_msg_count; +} + +size_t wslay_event_get_queued_msg_length(wslay_event_context_ptr ctx) +{ + return ctx->queued_msg_length; +} diff --git a/thirdparty/wslay/wslay_event.h b/thirdparty/wslay/wslay_event.h new file mode 100644 index 0000000000..36feb9036d --- /dev/null +++ b/thirdparty/wslay/wslay_event.h @@ -0,0 +1,142 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 WSLAY_EVENT_H +#define WSLAY_EVENT_H + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <wslay/wslay.h> + +struct wslay_stack; +struct wslay_queue; + +struct wslay_event_byte_chunk { + uint8_t *data; + size_t data_length; +}; + +struct wslay_event_imsg { + uint8_t fin; + uint8_t rsv; + uint8_t opcode; + uint32_t utf8state; + struct wslay_queue *chunks; + size_t msg_length; +}; + +enum wslay_event_msg_type { + WSLAY_NON_FRAGMENTED, + WSLAY_FRAGMENTED +}; + +struct wslay_event_omsg { + uint8_t fin; + uint8_t opcode; + uint8_t rsv; + enum wslay_event_msg_type type; + + uint8_t *data; + size_t data_length; + + union wslay_event_msg_source source; + wslay_event_fragmented_msg_callback read_callback; +}; + +struct wslay_event_frame_user_data { + wslay_event_context_ptr ctx; + void *user_data; +}; + +enum wslay_event_close_status { + WSLAY_CLOSE_RECEIVED = 1 << 0, + WSLAY_CLOSE_QUEUED = 1 << 1, + WSLAY_CLOSE_SENT = 1 << 2 +}; + +enum wslay_event_config { + WSLAY_CONFIG_NO_BUFFERING = 1 << 0 +}; + +struct wslay_event_context { + /* config status, bitwise OR of enum wslay_event_config values*/ + uint32_t config; + /* maximum message length that can be received */ + uint64_t max_recv_msg_length; + /* 1 if initialized for server, otherwise 0 */ + uint8_t server; + /* bitwise OR of enum wslay_event_close_status values */ + uint8_t close_status; + /* status code in received close control frame */ + uint16_t status_code_recv; + /* status code in sent close control frame */ + uint16_t status_code_sent; + wslay_frame_context_ptr frame_ctx; + /* 1 if reading is enabled, otherwise 0. Upon receiving close + control frame this value set to 0. If any errors in read + operation will also set this value to 0. */ + uint8_t read_enabled; + /* 1 if writing is enabled, otherwise 0 Upon completing sending + close control frame, this value set to 0. If any errors in write + opration will also set this value to 0. */ + uint8_t write_enabled; + /* imsg buffer to allow interleaved control frame between + non-control frames. */ + struct wslay_event_imsg imsgs[2]; + /* Pointer to imsgs to indicate current used buffer. */ + struct wslay_event_imsg *imsg; + /* payload length of frame currently being received. */ + uint64_t ipayloadlen; + /* next byte offset of payload currently being received. */ + uint64_t ipayloadoff; + /* error value set by user callback */ + int error; + /* Pointer to the message currently being sent. NULL if no message + is currently sent. */ + struct wslay_event_omsg *omsg; + /* Queue for non-control frames */ + struct wslay_queue/*<wslay_omsg*>*/ *send_queue; + /* Queue for control frames */ + struct wslay_queue/*<wslay_omsg*>*/ *send_ctrl_queue; + /* Size of send_queue + size of send_ctrl_queue */ + size_t queued_msg_count; + /* The sum of message length in send_queue */ + size_t queued_msg_length; + /* Buffer used for fragmented messages */ + uint8_t obuf[4096]; + uint8_t *obuflimit; + uint8_t *obufmark; + /* payload length of frame currently being sent. */ + uint64_t opayloadlen; + /* next byte offset of payload currently being sent. */ + uint64_t opayloadoff; + struct wslay_event_callbacks callbacks; + struct wslay_event_frame_user_data frame_user_data; + void *user_data; + uint8_t allowed_rsv_bits; +}; + +#endif /* WSLAY_EVENT_H */ diff --git a/thirdparty/wslay/wslay_frame.c b/thirdparty/wslay/wslay_frame.c new file mode 100644 index 0000000000..445e750ca5 --- /dev/null +++ b/thirdparty/wslay/wslay_frame.c @@ -0,0 +1,340 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 "wslay_frame.h" + +#include <stddef.h> +#include <string.h> +#include <assert.h> + +#include "wslay_net.h" + +#define wslay_min(A, B) (((A) < (B)) ? (A) : (B)) + +int wslay_frame_context_init(wslay_frame_context_ptr *ctx, + const struct wslay_frame_callbacks *callbacks, + void *user_data) +{ + *ctx = (wslay_frame_context_ptr)malloc(sizeof(struct wslay_frame_context)); + if(*ctx == NULL) { + return -1; + } + memset(*ctx, 0, sizeof(struct wslay_frame_context)); + (*ctx)->istate = RECV_HEADER1; + (*ctx)->ireqread = 2; + (*ctx)->ostate = PREP_HEADER; + (*ctx)->user_data = user_data; + (*ctx)->ibufmark = (*ctx)->ibuflimit = (*ctx)->ibuf; + (*ctx)->callbacks = *callbacks; + return 0; +} + +void wslay_frame_context_free(wslay_frame_context_ptr ctx) +{ + free(ctx); +} + +ssize_t wslay_frame_send(wslay_frame_context_ptr ctx, + struct wslay_frame_iocb *iocb) +{ + if(iocb->data_length > iocb->payload_length) { + return WSLAY_ERR_INVALID_ARGUMENT; + } + if(ctx->ostate == PREP_HEADER) { + uint8_t *hdptr = ctx->oheader; + memset(ctx->oheader, 0, sizeof(ctx->oheader)); + *hdptr |= (iocb->fin << 7) & 0x80u; + *hdptr |= (iocb->rsv << 4) & 0x70u; + *hdptr |= iocb->opcode & 0xfu; + ++hdptr; + *hdptr |= (iocb->mask << 7) & 0x80u; + if(wslay_is_ctrl_frame(iocb->opcode) && iocb->payload_length > 125) { + return WSLAY_ERR_INVALID_ARGUMENT; + } + if(iocb->payload_length < 126) { + *hdptr |= iocb->payload_length; + ++hdptr; + } else if(iocb->payload_length < (1 << 16)) { + uint16_t len = htons(iocb->payload_length); + *hdptr |= 126; + ++hdptr; + memcpy(hdptr, &len, 2); + hdptr += 2; + } else if(iocb->payload_length < (1ull << 63)) { + uint64_t len = hton64(iocb->payload_length); + *hdptr |= 127; + ++hdptr; + memcpy(hdptr, &len, 8); + hdptr += 8; + } else { + /* Too large payload length */ + return WSLAY_ERR_INVALID_ARGUMENT; + } + if(iocb->mask) { + if(ctx->callbacks.genmask_callback(ctx->omaskkey, 4, + ctx->user_data) != 0) { + return WSLAY_ERR_INVALID_CALLBACK; + } else { + ctx->omask = 1; + memcpy(hdptr, ctx->omaskkey, 4); + hdptr += 4; + } + } + ctx->ostate = SEND_HEADER; + ctx->oheadermark = ctx->oheader; + ctx->oheaderlimit = hdptr; + ctx->opayloadlen = iocb->payload_length; + ctx->opayloadoff = 0; + } + if(ctx->ostate == SEND_HEADER) { + ptrdiff_t len = ctx->oheaderlimit-ctx->oheadermark; + ssize_t r; + int flags = 0; + if(iocb->data_length > 0) { + flags |= WSLAY_MSG_MORE; + }; + r = ctx->callbacks.send_callback(ctx->oheadermark, len, flags, + ctx->user_data); + if(r > 0) { + if(r > len) { + return WSLAY_ERR_INVALID_CALLBACK; + } else { + ctx->oheadermark += r; + if(ctx->oheadermark == ctx->oheaderlimit) { + ctx->ostate = SEND_PAYLOAD; + } else { + return WSLAY_ERR_WANT_WRITE; + } + } + } else { + return WSLAY_ERR_WANT_WRITE; + } + } + if(ctx->ostate == SEND_PAYLOAD) { + size_t totallen = 0; + if(iocb->data_length > 0) { + if(ctx->omask) { + uint8_t temp[4096]; + const uint8_t *datamark = iocb->data, + *datalimit = iocb->data+iocb->data_length; + while(datamark < datalimit) { + size_t datalen = datalimit - datamark; + const uint8_t *writelimit = datamark+ + wslay_min(sizeof(temp), datalen); + size_t writelen = writelimit-datamark; + ssize_t r; + size_t i; + for(i = 0; i < writelen; ++i) { + temp[i] = datamark[i]^ctx->omaskkey[(ctx->opayloadoff+i)%4]; + } + r = ctx->callbacks.send_callback(temp, writelen, 0, ctx->user_data); + if(r > 0) { + if((size_t)r > writelen) { + return WSLAY_ERR_INVALID_CALLBACK; + } else { + datamark += r; + ctx->opayloadoff += r; + totallen += r; + } + } else { + if(totallen > 0) { + break; + } else { + return WSLAY_ERR_WANT_WRITE; + } + } + } + } else { + ssize_t r; + r = ctx->callbacks.send_callback(iocb->data, iocb->data_length, 0, + ctx->user_data); + if(r > 0) { + if((size_t)r > iocb->data_length) { + return WSLAY_ERR_INVALID_CALLBACK; + } else { + ctx->opayloadoff += r; + totallen = r; + } + } else { + return WSLAY_ERR_WANT_WRITE; + } + } + } + if(ctx->opayloadoff == ctx->opayloadlen) { + ctx->ostate = PREP_HEADER; + } + return totallen; + } + return WSLAY_ERR_INVALID_ARGUMENT; +} + +static void wslay_shift_ibuf(wslay_frame_context_ptr ctx) +{ + ptrdiff_t len = ctx->ibuflimit-ctx->ibufmark; + memmove(ctx->ibuf, ctx->ibufmark, len); + ctx->ibuflimit = ctx->ibuf+len; + ctx->ibufmark = ctx->ibuf; +} + +static ssize_t wslay_recv(wslay_frame_context_ptr ctx) +{ + ssize_t r; + if(ctx->ibufmark != ctx->ibuf) { + wslay_shift_ibuf(ctx); + } + r = ctx->callbacks.recv_callback + (ctx->ibuflimit, ctx->ibuf+sizeof(ctx->ibuf)-ctx->ibuflimit, + 0, ctx->user_data); + if(r > 0) { + ctx->ibuflimit += r; + } else { + r = WSLAY_ERR_WANT_READ; + } + return r; +} + +#define WSLAY_AVAIL_IBUF(ctx) ((size_t)(ctx->ibuflimit - ctx->ibufmark)) + +ssize_t wslay_frame_recv(wslay_frame_context_ptr ctx, + struct wslay_frame_iocb *iocb) +{ + ssize_t r; + if(ctx->istate == RECV_HEADER1) { + uint8_t fin, opcode, rsv, payloadlen; + if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) { + if((r = wslay_recv(ctx)) <= 0) { + return r; + } + } + if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) { + return WSLAY_ERR_WANT_READ; + } + fin = (ctx->ibufmark[0] >> 7) & 1; + rsv = (ctx->ibufmark[0] >> 4) & 7; + opcode = ctx->ibufmark[0] & 0xfu; + ctx->iom.opcode = opcode; + ctx->iom.fin = fin; + ctx->iom.rsv = rsv; + ++ctx->ibufmark; + ctx->imask = (ctx->ibufmark[0] >> 7) & 1; + payloadlen = ctx->ibufmark[0] & 0x7fu; + ++ctx->ibufmark; + if(wslay_is_ctrl_frame(opcode) && (payloadlen > 125 || !fin)) { + return WSLAY_ERR_PROTO; + } + if(payloadlen == 126) { + ctx->istate = RECV_EXT_PAYLOADLEN; + ctx->ireqread = 2; + } else if(payloadlen == 127) { + ctx->istate = RECV_EXT_PAYLOADLEN; + ctx->ireqread = 8; + } else { + ctx->ipayloadlen = payloadlen; + ctx->ipayloadoff = 0; + if(ctx->imask) { + ctx->istate = RECV_MASKKEY; + ctx->ireqread = 4; + } else { + ctx->istate = RECV_PAYLOAD; + } + } + } + if(ctx->istate == RECV_EXT_PAYLOADLEN) { + if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) { + if((r = wslay_recv(ctx)) <= 0) { + return r; + } + if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) { + return WSLAY_ERR_WANT_READ; + } + } + ctx->ipayloadlen = 0; + ctx->ipayloadoff = 0; + memcpy((uint8_t*)&ctx->ipayloadlen+(8-ctx->ireqread), + ctx->ibufmark, ctx->ireqread); + ctx->ipayloadlen = ntoh64(ctx->ipayloadlen); + ctx->ibufmark += ctx->ireqread; + if(ctx->ireqread == 8) { + if(ctx->ipayloadlen < (1 << 16) || + ctx->ipayloadlen & (1ull << 63)) { + return WSLAY_ERR_PROTO; + } + } else if(ctx->ipayloadlen < 126) { + return WSLAY_ERR_PROTO; + } + if(ctx->imask) { + ctx->istate = RECV_MASKKEY; + ctx->ireqread = 4; + } else { + ctx->istate = RECV_PAYLOAD; + } + } + if(ctx->istate == RECV_MASKKEY) { + if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) { + if((r = wslay_recv(ctx)) <= 0) { + return r; + } + if(WSLAY_AVAIL_IBUF(ctx) < ctx->ireqread) { + return WSLAY_ERR_WANT_READ; + } + } + memcpy(ctx->imaskkey, ctx->ibufmark, 4); + ctx->ibufmark += 4; + ctx->istate = RECV_PAYLOAD; + } + if(ctx->istate == RECV_PAYLOAD) { + uint8_t *readlimit, *readmark; + uint64_t rempayloadlen = ctx->ipayloadlen-ctx->ipayloadoff; + if(WSLAY_AVAIL_IBUF(ctx) == 0 && rempayloadlen > 0) { + if((r = wslay_recv(ctx)) <= 0) { + return r; + } + } + readmark = ctx->ibufmark; + readlimit = WSLAY_AVAIL_IBUF(ctx) < rempayloadlen ? + ctx->ibuflimit : ctx->ibufmark+rempayloadlen; + if(ctx->imask) { + for(; ctx->ibufmark != readlimit; + ++ctx->ibufmark, ++ctx->ipayloadoff) { + ctx->ibufmark[0] ^= ctx->imaskkey[ctx->ipayloadoff % 4]; + } + } else { + ctx->ibufmark = readlimit; + ctx->ipayloadoff += readlimit-readmark; + } + iocb->fin = ctx->iom.fin; + iocb->rsv = ctx->iom.rsv; + iocb->opcode = ctx->iom.opcode; + iocb->payload_length = ctx->ipayloadlen; + iocb->mask = ctx->imask; + iocb->data = readmark; + iocb->data_length = ctx->ibufmark-readmark; + if(ctx->ipayloadlen == ctx->ipayloadoff) { + ctx->istate = RECV_HEADER1; + ctx->ireqread = 2; + } + return iocb->data_length; + } + return WSLAY_ERR_INVALID_ARGUMENT; +} diff --git a/thirdparty/wslay/wslay_frame.h b/thirdparty/wslay/wslay_frame.h new file mode 100644 index 0000000000..6a75858cc7 --- /dev/null +++ b/thirdparty/wslay/wslay_frame.h @@ -0,0 +1,76 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 WSLAY_FRAME_H +#define WSLAY_FRAME_H + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <wslay/wslay.h> + +enum wslay_frame_state { + PREP_HEADER, + SEND_HEADER, + SEND_PAYLOAD, + RECV_HEADER1, + RECV_PAYLOADLEN, + RECV_EXT_PAYLOADLEN, + RECV_MASKKEY, + RECV_PAYLOAD +}; + +struct wslay_frame_opcode_memo { + uint8_t fin; + uint8_t opcode; + uint8_t rsv; +}; + +struct wslay_frame_context { + uint8_t ibuf[4096]; + uint8_t *ibufmark; + uint8_t *ibuflimit; + struct wslay_frame_opcode_memo iom; + uint64_t ipayloadlen; + uint64_t ipayloadoff; + uint8_t imask; + uint8_t imaskkey[4]; + enum wslay_frame_state istate; + size_t ireqread; + + uint8_t oheader[14]; + uint8_t *oheadermark; + uint8_t *oheaderlimit; + uint64_t opayloadlen; + uint64_t opayloadoff; + uint8_t omask; + uint8_t omaskkey[4]; + enum wslay_frame_state ostate; + + struct wslay_frame_callbacks callbacks; + void *user_data; +}; + +#endif /* WSLAY_FRAME_H */ diff --git a/thirdparty/wslay/wslay_net.c b/thirdparty/wslay/wslay_net.c new file mode 100644 index 0000000000..d3867c21fb --- /dev/null +++ b/thirdparty/wslay/wslay_net.c @@ -0,0 +1,36 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 "wslay_net.h" + +#ifndef WORDS_BIGENDIAN + +uint64_t wslay_byteswap64(uint64_t x) +{ + uint64_t u = ntohl(x & 0xffffffffllu); + uint64_t l = ntohl(x >> 32); + return (u << 32) | l; +} + +#endif /* !WORDS_BIGENDIAN */ diff --git a/thirdparty/wslay/wslay_net.h b/thirdparty/wslay/wslay_net.h new file mode 100644 index 0000000000..2310870156 --- /dev/null +++ b/thirdparty/wslay/wslay_net.h @@ -0,0 +1,54 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 WSLAY_NET_H +#define WSLAY_NET_H + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <wslay/wslay.h> + +#ifdef HAVE_ARPA_INET_H +# include <arpa/inet.h> +#endif /* HAVE_ARPA_INET_H */ +#ifdef HAVE_NETINET_IN_H +# include <netinet/in.h> +#endif /* HAVE_NETINET_IN_H */ +/* For Mingw build */ +#ifdef HAVE_WINSOCK2_H +# include <winsock2.h> +#endif /* HAVE_WINSOCK2_H */ + +#ifdef WORDS_BIGENDIAN +# define ntoh64(x) (x) +# define hton64(x) (x) +#else /* !WORDS_BIGENDIAN */ +uint64_t wslay_byteswap64(uint64_t x); +# define ntoh64(x) wslay_byteswap64(x) +# define hton64(x) wslay_byteswap64(x) +#endif /* !WORDS_BIGENDIAN */ + +#endif /* WSLAY_NET_H */ diff --git a/thirdparty/wslay/wslay_queue.c b/thirdparty/wslay/wslay_queue.c new file mode 100644 index 0000000000..8d2669687d --- /dev/null +++ b/thirdparty/wslay/wslay_queue.c @@ -0,0 +1,117 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 "wslay_queue.h" + +#include <string.h> +#include <assert.h> + +struct wslay_queue* wslay_queue_new(void) +{ + struct wslay_queue *queue = (struct wslay_queue*)malloc + (sizeof(struct wslay_queue)); + if(!queue) { + return NULL; + } + queue->top = queue->tail = NULL; + return queue; +} + +void wslay_queue_free(struct wslay_queue *queue) +{ + if(!queue) { + return; + } else { + struct wslay_queue_cell *p = queue->top; + while(p) { + struct wslay_queue_cell *next = p->next; + free(p); + p = next; + } + free(queue); + } +} + +int wslay_queue_push(struct wslay_queue *queue, void *data) +{ + struct wslay_queue_cell *new_cell = (struct wslay_queue_cell*)malloc + (sizeof(struct wslay_queue_cell)); + if(!new_cell) { + return WSLAY_ERR_NOMEM; + } + new_cell->data = data; + new_cell->next = NULL; + if(queue->tail) { + queue->tail->next = new_cell; + queue->tail = new_cell; + + } else { + queue->top = queue->tail = new_cell; + } + return 0; +} + +int wslay_queue_push_front(struct wslay_queue *queue, void *data) +{ + struct wslay_queue_cell *new_cell = (struct wslay_queue_cell*)malloc + (sizeof(struct wslay_queue_cell)); + if(!new_cell) { + return WSLAY_ERR_NOMEM; + } + new_cell->data = data; + new_cell->next = queue->top; + queue->top = new_cell; + if(!queue->tail) { + queue->tail = queue->top; + } + return 0; +} + +void wslay_queue_pop(struct wslay_queue *queue) +{ + struct wslay_queue_cell *top = queue->top; + assert(top); + queue->top = top->next; + if(top == queue->tail) { + queue->tail = NULL; + } + free(top); +} + +void* wslay_queue_top(struct wslay_queue *queue) +{ + assert(queue->top); + return queue->top->data; +} + +void* wslay_queue_tail(struct wslay_queue *queue) +{ + assert(queue->tail); + return queue->tail->data; +} + +int wslay_queue_empty(struct wslay_queue *queue) +{ + return queue->top == NULL; +} diff --git a/thirdparty/wslay/wslay_queue.h b/thirdparty/wslay/wslay_queue.h new file mode 100644 index 0000000000..55e78a042e --- /dev/null +++ b/thirdparty/wslay/wslay_queue.h @@ -0,0 +1,53 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 WSLAY_QUEUE_H +#define WSLAY_QUEUE_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <wslay/wslay.h> + +struct wslay_queue_cell { + void *data; + struct wslay_queue_cell *next; +}; + +struct wslay_queue { + struct wslay_queue_cell *top; + struct wslay_queue_cell *tail; +}; + +struct wslay_queue* wslay_queue_new(void); +void wslay_queue_free(struct wslay_queue *queue); +int wslay_queue_push(struct wslay_queue *queue, void *data); +int wslay_queue_push_front(struct wslay_queue *queue, void *data); +void wslay_queue_pop(struct wslay_queue *queue); +void* wslay_queue_top(struct wslay_queue *queue); +void* wslay_queue_tail(struct wslay_queue *queue); +int wslay_queue_empty(struct wslay_queue *queue); + +#endif /* WSLAY_QUEUE_H */ diff --git a/thirdparty/wslay/wslay_stack.c b/thirdparty/wslay/wslay_stack.c new file mode 100644 index 0000000000..0e05d74031 --- /dev/null +++ b/thirdparty/wslay/wslay_stack.c @@ -0,0 +1,86 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 "wslay_stack.h" + +#include <string.h> +#include <assert.h> + +struct wslay_stack* wslay_stack_new() +{ + struct wslay_stack *stack = (struct wslay_stack*)malloc + (sizeof(struct wslay_stack)); + if(!stack) { + return NULL; + } + stack->top = NULL; + return stack; +} + +void wslay_stack_free(struct wslay_stack *stack) +{ + struct wslay_stack_cell *p; + if(!stack) { + return; + } + p = stack->top; + while(p) { + struct wslay_stack_cell *next = p->next; + free(p); + p = next; + } + free(stack); +} + +int wslay_stack_push(struct wslay_stack *stack, void *data) +{ + struct wslay_stack_cell *new_cell = (struct wslay_stack_cell*)malloc + (sizeof(struct wslay_stack_cell)); + if(!new_cell) { + return WSLAY_ERR_NOMEM; + } + new_cell->data = data; + new_cell->next = stack->top; + stack->top = new_cell; + return 0; +} + +void wslay_stack_pop(struct wslay_stack *stack) +{ + struct wslay_stack_cell *top = stack->top; + assert(top); + stack->top = top->next; + free(top); +} + +void* wslay_stack_top(struct wslay_stack *stack) +{ + assert(stack->top); + return stack->top->data; +} + +int wslay_stack_empty(struct wslay_stack *stack) +{ + return stack->top == NULL; +} diff --git a/thirdparty/wslay/wslay_stack.h b/thirdparty/wslay/wslay_stack.h new file mode 100644 index 0000000000..16e4e968eb --- /dev/null +++ b/thirdparty/wslay/wslay_stack.h @@ -0,0 +1,50 @@ +/* + * Wslay - The WebSocket Library + * + * Copyright (c) 2011, 2012 Tatsuhiro Tsujikawa + * + * 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 WSLAY_STACK_H +#define WSLAY_STACK_H + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include <wslay/wslay.h> + +struct wslay_stack_cell { + void *data; + struct wslay_stack_cell *next; +}; + +struct wslay_stack { + struct wslay_stack_cell *top; +}; + +struct wslay_stack* wslay_stack_new(); +void wslay_stack_free(struct wslay_stack *stack); +int wslay_stack_push(struct wslay_stack *stack, void *data); +void wslay_stack_pop(struct wslay_stack *stack); +void* wslay_stack_top(struct wslay_stack *stack); +int wslay_stack_empty(struct wslay_stack *stack); + +#endif /* WSLAY_STACK_H */ diff --git a/thirdparty/xatlas/xatlas.cpp b/thirdparty/xatlas/xatlas.cpp index 2cc2905eee..1b30305cd4 100644 --- a/thirdparty/xatlas/xatlas.cpp +++ b/thirdparty/xatlas/xatlas.cpp @@ -1,128 +1,443 @@ -// This code is in the public domain -- castanyo@yahoo.es +/* +MIT License + +Copyright (c) 2018-2019 Jonathan Young + +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. +*/ +/* +thekla_atlas +https://github.com/Thekla/thekla_atlas +MIT License +Copyright (c) 2013 Thekla, Inc +Copyright NVIDIA Corporation 2006 -- Ignacio Castano <icastano@nvidia.com> + +Fast-BVH +https://github.com/brandonpelfrey/Fast-BVH +MIT License +Copyright (c) 2012 Brandon Pelfrey +*/ #include <algorithm> -#include <cmath> -#include <memory> -#include <unordered_map> -#include <vector> +#include <atomic> +#include <condition_variable> +#include <mutex> +#include <thread> #include <assert.h> -#include <float.h> +#include <float.h> // FLT_MAX +#include <limits.h> #include <math.h> -#include <stdarg.h> +#define __STDC_LIMIT_MACROS #include <stdint.h> #include <stdio.h> #include <string.h> -#include <time.h> #include "xatlas.h" -#undef min -#undef max +#ifndef XA_DEBUG +#ifdef NDEBUG +#define XA_DEBUG 0 +#else +#define XA_DEBUG 1 +#endif +#endif -#ifndef xaAssert -#define xaAssert(exp) if (!(exp)) { xaPrint("%s %s %s\n", #exp, __FILE__, __LINE__); } +#ifndef XA_PROFILE +#define XA_PROFILE 0 #endif -#ifndef xaDebugAssert -#define xaDebugAssert(exp) assert(exp) +#if XA_PROFILE +#include <time.h> #endif -#ifndef xaPrint -#define xaPrint(...) if (xatlas::internal::s_print) { xatlas::internal::s_print(__VA_ARGS__); } + +#ifndef XA_MULTITHREADED +#define XA_MULTITHREADED 1 #endif -#ifdef _MSC_VER -// Ignore gcc attributes. -#define __attribute__(X) +#define XA_STR(x) #x +#define XA_XSTR(x) XA_STR(x) + +#ifndef XA_ASSERT +#define XA_ASSERT(exp) if (!(exp)) { XA_PRINT_WARNING("\rASSERT: %s %s %d\n", XA_XSTR(exp), __FILE__, __LINE__); } #endif -#ifdef _MSC_VER -#define restrict -#define NV_FORCEINLINE __forceinline -#else -#define restrict __restrict__ -#define NV_FORCEINLINE __attribute__((always_inline)) inline +#ifndef XA_DEBUG_ASSERT +#define XA_DEBUG_ASSERT(exp) assert(exp) #endif -#define NV_UINT32_MAX 0xffffffff -#define NV_FLOAT_MAX 3.402823466e+38F +#ifndef XA_PRINT +#define XA_PRINT(...) \ + if (xatlas::internal::s_print && xatlas::internal::s_printVerbose) \ + xatlas::internal::s_print(__VA_ARGS__); +#endif -#ifndef PI -#define PI float(3.1415926535897932384626433833) +#ifndef XA_PRINT_WARNING +#define XA_PRINT_WARNING(...) \ + if (xatlas::internal::s_print) \ + xatlas::internal::s_print(__VA_ARGS__); #endif -#define NV_EPSILON (0.0001f) -#define NV_NORMAL_EPSILON (0.001f) +#define XA_ALLOC(tag, type) (type *)internal::Realloc(nullptr, sizeof(type), tag, __FILE__, __LINE__) +#define XA_ALLOC_ARRAY(tag, type, num) (type *)internal::Realloc(nullptr, sizeof(type) * num, tag, __FILE__, __LINE__) +#define XA_REALLOC(tag, ptr, type, num) (type *)internal::Realloc(ptr, sizeof(type) * num, tag, __FILE__, __LINE__) +#define XA_FREE(ptr) internal::Realloc(ptr, 0, internal::MemTag::Default, __FILE__, __LINE__) +#define XA_NEW(tag, type, ...) new (XA_ALLOC(tag, type)) type(__VA_ARGS__) + +#define XA_UNUSED(a) ((void)(a)) + +#define XA_GROW_CHARTS_COPLANAR 1 +#define XA_MERGE_CHARTS 1 +#define XA_MERGE_CHARTS_MIN_NORMAL_DEVIATION 0.5f +#define XA_RECOMPUTE_CHARTS 1 +#define XA_CLOSE_HOLES_CHECK_EDGE_INTERSECTION 0 + +#define XA_DEBUG_HEAP 0 +#define XA_DEBUG_SINGLE_CHART 0 +#define XA_DEBUG_EXPORT_ATLAS_IMAGES 0 +#define XA_DEBUG_EXPORT_OBJ_SOURCE_MESHES 0 +#define XA_DEBUG_EXPORT_OBJ_CHART_GROUPS 0 +#define XA_DEBUG_EXPORT_OBJ_CHARTS 0 +#define XA_DEBUG_EXPORT_OBJ_BEFORE_FIX_TJUNCTION 0 +#define XA_DEBUG_EXPORT_OBJ_CLOSE_HOLES_ERROR 0 +#define XA_DEBUG_EXPORT_OBJ_NOT_DISK 0 +#define XA_DEBUG_EXPORT_OBJ_CHARTS_AFTER_PARAMETERIZATION 0 +#define XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION 0 +#define XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS 0 + +#define XA_DEBUG_EXPORT_OBJ (0 \ + || XA_DEBUG_EXPORT_OBJ_SOURCE_MESHES \ + || XA_DEBUG_EXPORT_OBJ_CHART_GROUPS \ + || XA_DEBUG_EXPORT_OBJ_CHARTS \ + || XA_DEBUG_EXPORT_OBJ_BEFORE_FIX_TJUNCTION \ + || XA_DEBUG_EXPORT_OBJ_CLOSE_HOLES_ERROR \ + || XA_DEBUG_EXPORT_OBJ_NOT_DISK \ + || XA_DEBUG_EXPORT_OBJ_CHARTS_AFTER_PARAMETERIZATION \ + || XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION \ + || XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS) + +#ifdef _MSC_VER +#define XA_FOPEN(_file, _filename, _mode) { if (fopen_s(&_file, _filename, _mode) != 0) _file = NULL; } +#define XA_SPRINTF(_buffer, _size, _format, ...) sprintf_s(_buffer, _size, _format, __VA_ARGS__) +#else +#define XA_FOPEN(_file, _filename, _mode) _file = fopen(_filename, _mode) +#define XA_SPRINTF(_buffer, _size, _format, ...) sprintf(_buffer, _format, __VA_ARGS__) +#endif namespace xatlas { namespace internal { -static PrintFunc s_print = NULL; +static ReallocFunc s_realloc = realloc; +static PrintFunc s_print = printf; +static bool s_printVerbose = false; + +struct MemTag +{ + enum + { + Default, + Mesh, + MeshBoundaries, + MeshColocals, + MeshEdgeMap, + MeshIndices, + MeshNormals, + MeshPositions, + MeshTexcoords, + Count + }; +}; + +#if XA_DEBUG_HEAP +struct AllocHeader +{ + size_t size; + const char *file; + int line; + int tag; + AllocHeader *prev, *next; + bool free; +}; + +static std::mutex s_allocMutex; +static AllocHeader *s_allocRoot = nullptr; +static size_t s_allocTotalSize = 0, s_allocPeakSize = 0, s_allocTotalTagSize[MemTag::Count] = { 0 }, s_allocPeakTagSize[MemTag::Count] = { 0 }; +static constexpr uint32_t kAllocRedzone = 0x12345678; + +static void *Realloc(void *ptr, size_t size, int tag, const char *file, int line) +{ + std::unique_lock<std::mutex> lock(s_allocMutex); + if (!size && !ptr) + return nullptr; + uint8_t *realPtr = nullptr; + AllocHeader *header = nullptr; + if (ptr) { + realPtr = ((uint8_t *)ptr) - sizeof(AllocHeader); + header = (AllocHeader *)realPtr; + } + if (realPtr && size) { + s_allocTotalSize -= header->size; + s_allocTotalTagSize[header->tag] -= header->size; + // realloc, remove. + if (header->prev) + header->prev->next = header->next; + else + s_allocRoot = header->next; + if (header->next) + header->next->prev = header->prev; + } + if (!size) { + s_allocTotalSize -= header->size; + s_allocTotalTagSize[header->tag] -= header->size; + XA_ASSERT(!header->free); // double free + header->free = true; + return nullptr; + } + size += sizeof(AllocHeader) + sizeof(kAllocRedzone); + uint8_t *newPtr = (uint8_t *)s_realloc(realPtr, size); + if (!newPtr) + return nullptr; + header = (AllocHeader *)newPtr; + header->size = size; + header->file = file; + header->line = line; + header->tag = tag; + header->free = false; + if (!s_allocRoot) { + s_allocRoot = header; + header->prev = header->next = 0; + } else { + header->prev = nullptr; + header->next = s_allocRoot; + s_allocRoot = header; + header->next->prev = header; + } + s_allocTotalSize += size; + if (s_allocTotalSize > s_allocPeakSize) + s_allocPeakSize = s_allocTotalSize; + s_allocTotalTagSize[tag] += size; + if (s_allocTotalTagSize[tag] > s_allocPeakTagSize[tag]) + s_allocPeakTagSize[tag] = s_allocTotalTagSize[tag]; + auto redzone = (uint32_t *)(newPtr + size - sizeof(kAllocRedzone)); + *redzone = kAllocRedzone; + return newPtr + sizeof(AllocHeader); +} + +static void ReportLeaks() +{ + printf("Checking for memory leaks...\n"); + bool anyLeaks = false; + AllocHeader *header = s_allocRoot; + while (header) { + if (!header->free) { + printf(" Leak: %zu bytes %s %d\n", header->size, header->file, header->line); + anyLeaks = true; + } + auto redzone = (const uint32_t *)((const uint8_t *)header + header->size - sizeof(kAllocRedzone)); + if (*redzone != kAllocRedzone) + printf(" Redzone corrupted: %zu bytes %s %d\n", header->size, header->file, header->line); + header = header->next; + } + if (!anyLeaks) + printf(" No memory leaks\n"); + header = s_allocRoot; + while (header) { + AllocHeader *destroy = header; + header = header->next; + s_realloc(destroy, 0); + } + s_allocRoot = nullptr; + s_allocTotalSize = s_allocPeakSize = 0; + for (int i = 0; i < MemTag::Count; i++) + s_allocTotalTagSize[i] = s_allocPeakTagSize[i] = 0; +} + +static void PrintMemoryUsage() +{ + XA_PRINT("Memory usage: %0.2fMB current, %0.2fMB peak\n", internal::s_allocTotalSize / 1024.0f / 1024.0f, internal::s_allocPeakSize / 1024.0f / 1024.0f); + static const char *labels[] = { // Sync with MemTag + "Default", + "Mesh", + "MeshBoundaries", + "MeshColocals", + "MeshEdgeMap", + "MeshIndices", + "MeshNormals", + "MeshPositions", + "MeshTexcoords" + }; + for (int i = 0; i < MemTag::Count; i++) { + XA_PRINT(" %s: %0.2fMB current, %0.2fMB peak\n", labels[i], internal::s_allocTotalTagSize[i] / 1024.0f / 1024.0f, internal::s_allocPeakTagSize[i] / 1024.0f / 1024.0f); + } +} + +#define XA_PRINT_MEM_USAGE internal::PrintMemoryUsage(); +#else +static void *Realloc(void *ptr, size_t size, int /*tag*/, const char * /*file*/, int /*line*/) +{ + void *mem = s_realloc(ptr, size); + if (size > 0) { + XA_DEBUG_ASSERT(mem); + } + return mem; +} +#define XA_PRINT_MEM_USAGE +#endif + +#if XA_PROFILE +#define XA_PROFILE_START(var) const clock_t var##Start = clock(); +#define XA_PROFILE_END(var) internal::s_profile.var += clock() - var##Start; +#define XA_PROFILE_PRINT_AND_RESET(label, var) XA_PRINT("%s%.2f seconds (%g ms)\n", label, internal::clockToSeconds(internal::s_profile.var), internal::clockToMs(internal::s_profile.var)); internal::s_profile.var = 0; + +struct ProfileData +{ + clock_t addMeshReal; + std::atomic<clock_t> addMeshThread; + std::atomic<clock_t> addMeshCreateColocals; + std::atomic<clock_t> addMeshCreateFaceGroups; + std::atomic<clock_t> addMeshCreateBoundaries; + std::atomic<clock_t> addMeshCreateChartGroupsReal; + std::atomic<clock_t> addMeshCreateChartGroupsThread; + clock_t computeChartsReal; + std::atomic<clock_t> computeChartsThread; + std::atomic<clock_t> atlasBuilder; + std::atomic<clock_t> atlasBuilderInit; + std::atomic<clock_t> atlasBuilderCreateInitialCharts; + std::atomic<clock_t> atlasBuilderGrowCharts; + std::atomic<clock_t> atlasBuilderMergeCharts; + std::atomic<clock_t> createChartMeshesReal; + std::atomic<clock_t> createChartMeshesThread; + std::atomic<clock_t> fixChartMeshTJunctions; + std::atomic<clock_t> closeChartMeshHoles; + clock_t parameterizeChartsReal; + std::atomic<clock_t> parameterizeChartsThread; + std::atomic<clock_t> parameterizeChartsOrthogonal; + std::atomic<clock_t> parameterizeChartsLSCM; + std::atomic<clock_t> parameterizeChartsEvaluateQuality; + clock_t packCharts; + clock_t packChartsRasterize; + clock_t packChartsDilate; + clock_t packChartsFindLocation; + std::atomic<clock_t> packChartsFindLocationThread; + clock_t packChartsBlit; +}; + +static ProfileData s_profile; + +static double clockToMs(clock_t c) +{ + return c * 1000.0 / CLOCKS_PER_SEC; +} + +static double clockToSeconds(clock_t c) +{ + return c / (double)CLOCKS_PER_SEC; +} +#else +#define XA_PROFILE_START(var) +#define XA_PROFILE_END(var) +#define XA_PROFILE_PRINT_AND_RESET(label, var) +#endif + +static constexpr float kPi = 3.14159265358979323846f; +static constexpr float kPi2 = 6.28318530717958647692f; +static constexpr float kEpsilon = 0.0001f; +static constexpr float kAreaEpsilon = FLT_EPSILON; +static constexpr float kNormalEpsilon = 0.001f; static int align(int x, int a) { return (x + a - 1) & ~(a - 1); } -static bool isAligned(int x, int a) +template <typename T> +static T max(const T &a, const T &b) { - return (x & (a - 1)) == 0; + return a > b ? a : b; +} + +template <typename T> +static T min(const T &a, const T &b) +{ + return a < b ? a : b; } -/// Return the maximum of the three arguments. template <typename T> static T max3(const T &a, const T &b, const T &c) { - return std::max(a, std::max(b, c)); + return max(a, max(b, c)); } /// Return the maximum of the three arguments. template <typename T> static T min3(const T &a, const T &b, const T &c) { - return std::min(a, std::min(b, c)); + return min(a, min(b, c)); } /// Clamp between two values. template <typename T> static T clamp(const T &x, const T &a, const T &b) { - return std::min(std::max(x, a), b); + return min(max(x, a), b); } -static float saturate(float f) +template <typename T> +static void swap(T &a, T &b) { - return clamp(f, 0.0f, 1.0f); + T temp; + temp = a; + a = b; + b = temp; + temp = T(); } -// Robust floating point comparisons: -// http://realtimecollisiondetection.net/blog/?p=89 -static bool equal(const float f0, const float f1, const float epsilon = NV_EPSILON) +union FloatUint32 { - //return fabs(f0-f1) <= epsilon; - return fabs(f0 - f1) <= epsilon * max3(1.0f, fabsf(f0), fabsf(f1)); -} + float f; + uint32_t u; +}; -NV_FORCEINLINE static int ftoi_floor(float val) +static bool isFinite(float f) { - return (int)val; + FloatUint32 fu; + fu.f = f; + return fu.u != 0x7F800000u && fu.u != 0x7F800001u; } -NV_FORCEINLINE static int ftoi_ceil(float val) +static bool isNan(float f) { - return (int)ceilf(val); + return f != f; } -NV_FORCEINLINE static int ftoi_round(float f) +// Robust floating point comparisons: +// http://realtimecollisiondetection.net/blog/?p=89 +static bool equal(const float f0, const float f1, const float epsilon) { - return int(floorf(f + 0.5f)); + //return fabs(f0-f1) <= epsilon; + return fabs(f0 - f1) <= epsilon * max3(1.0f, fabsf(f0), fabsf(f1)); } -static bool isZero(const float f, const float epsilon = NV_EPSILON) +static int ftoi_ceil(float val) { - return fabs(f) <= epsilon; + return (int)ceilf(val); } -static float lerp(float f0, float f1, float t) +static bool isZero(const float f, const float epsilon) { - const float s = 1.0f - t; - return f0 * s + f1 * t; + return fabs(f) <= epsilon; } static float square(float f) @@ -130,11 +445,6 @@ static float square(float f) return f * f; } -static int square(int i) -{ - return i * i; -} - /** Return the next power of two. * @see http://graphics.stanford.edu/~seander/bithacks.html * @warning Behaviour for 0 is undefined. @@ -143,7 +453,7 @@ static int square(int i) */ static uint32_t nextPowerOfTwo(uint32_t x) { - xaDebugAssert( x != 0 ); + XA_DEBUG_ASSERT( x != 0 ); // On modern CPUs this is supposed to be as fast as using the bsr instruction. x--; x |= x >> 1; @@ -154,16 +464,6 @@ static uint32_t nextPowerOfTwo(uint32_t x) return x + 1; } -static uint64_t nextPowerOfTwo(uint64_t x) -{ - xaDebugAssert(x != 0); - uint32_t p = 1; - while (x > p) { - p += p; - } - return p; -} - static uint32_t sdbmHash(const void *data_in, uint32_t size, uint32_t h = 5381) { const uint8_t *data = (const uint8_t *) data_in; @@ -174,31 +474,12 @@ static uint32_t sdbmHash(const void *data_in, uint32_t size, uint32_t h = 5381) return h; } -// Note that this hash does not handle NaN properly. -static uint32_t sdbmFloatHash(const float *f, uint32_t count, uint32_t h = 5381) -{ - for (uint32_t i = 0; i < count; i++) { - union { - float f; - uint32_t i; - } x = { f[i] }; - if (x.i == 0x80000000) x.i = 0; - h = sdbmHash(&x, 4, h); - } - return h; -} - template <typename T> static uint32_t hash(const T &t, uint32_t h = 5381) { return sdbmHash(&t, sizeof(T), h); } -static uint32_t hash(const float &f, uint32_t h) -{ - return sdbmFloatHash(&f, 1, h); -} - // Functors for hash table: template <typename Key> struct Hash { @@ -213,40 +494,22 @@ template <typename Key> struct Equal class Vector2 { public: - typedef Vector2 const &Arg; - Vector2() {} explicit Vector2(float f) : x(f), y(f) {} Vector2(float x, float y): x(x), y(y) {} - Vector2(Vector2::Arg v) : x(v.x), y(v.y) {} - - const Vector2 &operator=(Vector2::Arg v) - { - x = v.x; - y = v.y; - return - *this; - } - const float *ptr() const { return &x; } - - void set(float _x, float _y) - { - x = _x; - y = _y; - } Vector2 operator-() const { return Vector2(-x, -y); } - void operator+=(Vector2::Arg v) + void operator+=(const Vector2 &v) { x += v.x; y += v.y; } - void operator-=(Vector2::Arg v) + void operator-=(const Vector2 &v) { x -= v.x; y -= v.y; @@ -258,138 +521,99 @@ public: y *= s; } - void operator*=(Vector2::Arg v) + void operator*=(const Vector2 &v) { x *= v.x; y *= v.y; } - friend bool operator==(Vector2::Arg a, Vector2::Arg b) - { - return a.x == b.x && a.y == b.y; - } - - friend bool operator!=(Vector2::Arg a, Vector2::Arg b) - { - return a.x != b.x || a.y != b.y; - } - - union - { -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4201) -#endif - struct - { - float x, y; - }; -#ifdef _MSC_VER -#pragma warning(pop) -#endif - - float component[2]; - }; + float x, y; }; -Vector2 operator+(Vector2::Arg a, Vector2::Arg b) +static bool operator==(const Vector2 &a, const Vector2 &b) { - return Vector2(a.x + b.x, a.y + b.y); + return a.x == b.x && a.y == b.y; } -Vector2 operator-(Vector2::Arg a, Vector2::Arg b) +static bool operator!=(const Vector2 &a, const Vector2 &b) { - return Vector2(a.x - b.x, a.y - b.y); + return a.x != b.x || a.y != b.y; } -Vector2 operator*(Vector2::Arg v, float s) +static Vector2 operator+(const Vector2 &a, const Vector2 &b) { - return Vector2(v.x * s, v.y * s); -} - -Vector2 operator*(Vector2::Arg v1, Vector2::Arg v2) -{ - return Vector2(v1.x * v2.x, v1.y * v2.y); + return Vector2(a.x + b.x, a.y + b.y); } -Vector2 operator/(Vector2::Arg v, float s) +static Vector2 operator-(const Vector2 &a, const Vector2 &b) { - return Vector2(v.x / s, v.y / s); + return Vector2(a.x - b.x, a.y - b.y); } -Vector2 lerp(Vector2::Arg v1, Vector2::Arg v2, float t) +static Vector2 operator*(const Vector2 &v, float s) { - const float s = 1.0f - t; - return Vector2(v1.x * s + t * v2.x, v1.y * s + t * v2.y); + return Vector2(v.x * s, v.y * s); } -float dot(Vector2::Arg a, Vector2::Arg b) +static float dot(const Vector2 &a, const Vector2 &b) { return a.x * b.x + a.y * b.y; } -float lengthSquared(Vector2::Arg v) +static float lengthSquared(const Vector2 &v) { return v.x * v.x + v.y * v.y; } -float length(Vector2::Arg v) +static float length(const Vector2 &v) { return sqrtf(lengthSquared(v)); } -float distance(Vector2::Arg a, Vector2::Arg b) -{ - return length(a - b); -} - -bool isNormalized(Vector2::Arg v, float epsilon = NV_NORMAL_EPSILON) +#if XA_DEBUG +static bool isNormalized(const Vector2 &v, float epsilon = kNormalEpsilon) { return equal(length(v), 1, epsilon); } +#endif -Vector2 normalize(Vector2::Arg v, float epsilon = NV_EPSILON) +static Vector2 normalize(const Vector2 &v, float epsilon) { float l = length(v); - xaDebugAssert(!isZero(l, epsilon)); -#ifdef NDEBUG - epsilon = 0; // silence unused parameter warning -#endif + XA_DEBUG_ASSERT(!isZero(l, epsilon)); + XA_UNUSED(epsilon); Vector2 n = v * (1.0f / l); - xaDebugAssert(isNormalized(n)); + XA_DEBUG_ASSERT(isNormalized(n)); return n; } -Vector2 normalizeSafe(Vector2::Arg v, Vector2::Arg fallback, float epsilon = NV_EPSILON) +static bool equal(const Vector2 &v1, const Vector2 &v2, float epsilon) { - float l = length(v); - if (isZero(l, epsilon)) { - return fallback; - } - return v * (1.0f / l); + return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon); } -bool equal(Vector2::Arg v1, Vector2::Arg v2, float epsilon = NV_EPSILON) +static Vector2 min(const Vector2 &a, const Vector2 &b) { - return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon); + return Vector2(min(a.x, b.x), min(a.y, b.y)); } -Vector2 max(Vector2::Arg a, Vector2::Arg b) +static Vector2 max(const Vector2 &a, const Vector2 &b) { - return Vector2(std::max(a.x, b.x), std::max(a.y, b.y)); + return Vector2(max(a.x, b.x), max(a.y, b.y)); } -bool isFinite(Vector2::Arg v) +static bool isFinite(const Vector2 &v) { - return std::isfinite(v.x) && std::isfinite(v.y); + return isFinite(v.x) && isFinite(v.y); } // Note, this is the area scaled by 2! -float triangleArea(Vector2::Arg v0, Vector2::Arg v1) +static float triangleArea(const Vector2 &v0, const Vector2 &v1) { return (v0.x * v1.y - v0.y * v1.x); // * 0.5f; } -float triangleArea(Vector2::Arg a, Vector2::Arg b, Vector2::Arg c) + +static float triangleArea(const Vector2 &a, const Vector2 &b, const Vector2 &c) { // IC: While it may be appealing to use the following expression: //return (c.x * a.y + a.x * b.y + b.x * c.y - b.x * a.y - c.x * b.y - a.x * c.y); // * 0.5f; @@ -402,62 +626,55 @@ float triangleArea(Vector2::Arg a, Vector2::Arg b, Vector2::Arg c) return triangleArea(a - c, b - c); } -float triangleArea2(Vector2::Arg v1, Vector2::Arg v2, Vector2::Arg v3) +static bool linesIntersect(const Vector2 &a1, const Vector2 &a2, const Vector2 &b1, const Vector2 &b2, float epsilon) { - return 0.5f * (v3.x * v1.y + v1.x * v2.y + v2.x * v3.y - v2.x * v1.y - v3.x * v2.y - v1.x * v3.y); + const Vector2 v0 = a2 - a1; + const Vector2 v1 = b2 - b1; + const float denom = -v1.x * v0.y + v0.x * v1.y; + if (equal(denom, 0.0f, epsilon)) + return false; + const float s = (-v0.y * (a1.x - b1.x) + v0.x * (a1.y - b1.y)) / denom; + if (s > epsilon && s < 1.0f - epsilon) { + const float t = ( v1.x * (a1.y - b1.y) - v1.y * (a1.x - b1.x)) / denom; + return t > epsilon && t < 1.0f - epsilon; + } + return false; } -static uint32_t hash(const Vector2 &v, uint32_t h) +struct Vector2i { - return sdbmFloatHash(v.component, 2, h); -} + Vector2i() {} + Vector2i(int32_t x, int32_t y) : x(x), y(y) {} + + int32_t x, y; +}; class Vector3 { public: - typedef Vector3 const &Arg; - Vector3() {} explicit Vector3(float f) : x(f), y(f), z(f) {} Vector3(float x, float y, float z) : x(x), y(y), z(z) {} - Vector3(Vector2::Arg v, float z) : x(v.x), y(v.y), z(z) {} - Vector3(Vector3::Arg v) : x(v.x), y(v.y), z(v.z) {} - - const Vector3 &operator=(Vector3::Arg v) - { - x = v.x; - y = v.y; - z = v.z; - return *this; - } + Vector3(const Vector2 &v, float z) : x(v.x), y(v.y), z(z) {} Vector2 xy() const { return Vector2(x, y); } - const float *ptr() const { return &x; } - - void set(float _x, float _y, float _z) - { - x = _x; - y = _y; - z = _z; - } - Vector3 operator-() const { return Vector3(-x, -y, -z); } - void operator+=(Vector3::Arg v) + void operator+=(const Vector3 &v) { x += v.x; y += v.y; z += v.z; } - void operator-=(Vector3::Arg v) + void operator-=(const Vector3 &v) { x -= v.x; y -= v.y; @@ -479,159 +696,89 @@ public: z *= is; } - void operator*=(Vector3::Arg v) + void operator*=(const Vector3 &v) { x *= v.x; y *= v.y; z *= v.z; } - void operator/=(Vector3::Arg v) + void operator/=(const Vector3 &v) { x /= v.x; y /= v.y; z /= v.z; } - friend bool operator==(Vector3::Arg a, Vector3::Arg b) - { - return a.x == b.x && a.y == b.y && a.z == b.z; - } - - friend bool operator!=(Vector3::Arg a, Vector3::Arg b) - { - return a.x != b.x || a.y != b.y || a.z != b.z; - } - - union - { -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4201) -#endif - struct - { - float x, y, z; - }; -#ifdef _MSC_VER -#pragma warning(pop) -#endif - - float component[3]; - }; + float x, y, z; }; -Vector3 add(Vector3::Arg a, Vector3::Arg b) +static bool operator!=(const Vector3 &a, const Vector3 &b) { - return Vector3(a.x + b.x, a.y + b.y, a.z + b.z); -} -Vector3 add(Vector3::Arg a, float b) -{ - return Vector3(a.x + b, a.y + b, a.z + b); -} -Vector3 operator+(Vector3::Arg a, Vector3::Arg b) -{ - return add(a, b); -} -Vector3 operator+(Vector3::Arg a, float b) -{ - return add(a, b); -} - -Vector3 sub(Vector3::Arg a, Vector3::Arg b) -{ - return Vector3(a.x - b.x, a.y - b.y, a.z - b.z); + return a.x != b.x || a.y != b.y || a.z != b.z; } -Vector3 sub(Vector3::Arg a, float b) +static Vector3 operator+(const Vector3 &a, const Vector3 &b) { - return Vector3(a.x - b, a.y - b, a.z - b); -} - -Vector3 operator-(Vector3::Arg a, Vector3::Arg b) -{ - return sub(a, b); + return Vector3(a.x + b.x, a.y + b.y, a.z + b.z); } -Vector3 operator-(Vector3::Arg a, float b) +static Vector3 operator-(const Vector3 &a, const Vector3 &b) { - return sub(a, b); + return Vector3(a.x - b.x, a.y - b.y, a.z - b.z); } -Vector3 cross(Vector3::Arg a, Vector3::Arg b) +static Vector3 cross(const Vector3 &a, const Vector3 &b) { return Vector3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); } -Vector3 operator*(Vector3::Arg v, float s) +static Vector3 operator*(const Vector3 &v, float s) { return Vector3(v.x * s, v.y * s, v.z * s); } -Vector3 operator*(float s, Vector3::Arg v) +static Vector3 operator*(float s, const Vector3 &v) { return Vector3(v.x * s, v.y * s, v.z * s); } -Vector3 operator*(Vector3::Arg v, Vector3::Arg s) -{ - return Vector3(v.x * s.x, v.y * s.y, v.z * s.z); -} - -Vector3 operator/(Vector3::Arg v, float s) +static Vector3 operator/(const Vector3 &v, float s) { return v * (1.0f / s); } -Vector3 lerp(Vector3::Arg v1, Vector3::Arg v2, float t) -{ - const float s = 1.0f - t; - return Vector3(v1.x * s + t * v2.x, v1.y * s + t * v2.y, v1.z * s + t * v2.z); -} - -float dot(Vector3::Arg a, Vector3::Arg b) +static float dot(const Vector3 &a, const Vector3 &b) { return a.x * b.x + a.y * b.y + a.z * b.z; } -float lengthSquared(Vector3::Arg v) +static float lengthSquared(const Vector3 &v) { return v.x * v.x + v.y * v.y + v.z * v.z; } -float length(Vector3::Arg v) +static float length(const Vector3 &v) { return sqrtf(lengthSquared(v)); } -float distance(Vector3::Arg a, Vector3::Arg b) -{ - return length(a - b); -} - -float distanceSquared(Vector3::Arg a, Vector3::Arg b) -{ - return lengthSquared(a - b); -} - -bool isNormalized(Vector3::Arg v, float epsilon = NV_NORMAL_EPSILON) +static bool isNormalized(const Vector3 &v, float epsilon = kNormalEpsilon) { return equal(length(v), 1, epsilon); } -Vector3 normalize(Vector3::Arg v, float epsilon = NV_EPSILON) +static Vector3 normalize(const Vector3 &v, float epsilon) { float l = length(v); - xaDebugAssert(!isZero(l, epsilon)); -#ifdef NDEBUG - epsilon = 0; // silence unused parameter warning -#endif + XA_DEBUG_ASSERT(!isZero(l, epsilon)); + XA_UNUSED(epsilon); Vector3 n = v * (1.0f / l); - xaDebugAssert(isNormalized(n)); + XA_DEBUG_ASSERT(isNormalized(n)); return n; } -Vector3 normalizeSafe(Vector3::Arg v, Vector3::Arg fallback, float epsilon = NV_EPSILON) +static Vector3 normalizeSafe(const Vector3 &v, const Vector3 &fallback, float epsilon) { float l = length(v); if (isZero(l, epsilon)) { @@ -640,57 +787,423 @@ Vector3 normalizeSafe(Vector3::Arg v, Vector3::Arg fallback, float epsilon = NV_ return v * (1.0f / l); } -bool equal(Vector3::Arg v1, Vector3::Arg v2, float epsilon = NV_EPSILON) +static bool equal(const Vector3 &v0, const Vector3 &v1, float epsilon) { - return equal(v1.x, v2.x, epsilon) && equal(v1.y, v2.y, epsilon) && equal(v1.z, v2.z, epsilon); + return fabs(v0.x - v1.x) <= epsilon && fabs(v0.y - v1.y) <= epsilon && fabs(v0.z - v1.z) <= epsilon; } -Vector3 min(Vector3::Arg a, Vector3::Arg b) +static Vector3 min(const Vector3 &a, const Vector3 &b) { - return Vector3(std::min(a.x, b.x), std::min(a.y, b.y), std::min(a.z, b.z)); + return Vector3(min(a.x, b.x), min(a.y, b.y), min(a.z, b.z)); } -Vector3 max(Vector3::Arg a, Vector3::Arg b) +static Vector3 max(const Vector3 &a, const Vector3 &b) { - return Vector3(std::max(a.x, b.x), std::max(a.y, b.y), std::max(a.z, b.z)); + return Vector3(max(a.x, b.x), max(a.y, b.y), max(a.z, b.z)); } -Vector3 clamp(Vector3::Arg v, float min, float max) +#if XA_DEBUG +bool isFinite(const Vector3 &v) { - return Vector3(clamp(v.x, min, max), clamp(v.y, min, max), clamp(v.z, min, max)); + return isFinite(v.x) && isFinite(v.y) && isFinite(v.z); } +#endif -Vector3 saturate(Vector3::Arg v) +struct Plane { - return Vector3(saturate(v.x), saturate(v.y), saturate(v.z)); + Plane() = default; + + Plane(const Vector3 &p1, const Vector3 &p2, const Vector3 &p3) + { + normal = cross(p2 - p1, p3 - p1); + dist = dot(normal, p1); + } + + float distance(const Vector3 &p) const + { + return dot(normal, p) - dist; + } + + void normalize() + { + const float len = length(normal); + if (len > 0.0f) { + const float il = 1.0f / len; + normal *= il; + dist *= il; + } + } + + Vector3 normal; + float dist; +}; + +static bool lineIntersectsPoint(const Vector3 &point, const Vector3 &lineStart, const Vector3 &lineEnd, float *t, float epsilon) +{ + float tt; + if (!t) + t = &tt; + *t = 0.0f; + if (equal(lineStart, point, epsilon) || equal(lineEnd, point, epsilon)) + return false; // Vertex lies on either line vertices. + const Vector3 v01 = point - lineStart; + const Vector3 v21 = lineEnd - lineStart; + const float l = length(v21); + const float d = length(cross(v01, v21)) / l; + if (!isZero(d, epsilon)) + return false; + *t = dot(v01, v21) / (l * l); + return *t > kEpsilon && *t < 1.0f - kEpsilon; } -Vector3 floor(Vector3::Arg v) +static bool sameSide(const Vector3 &p1, const Vector3 &p2, const Vector3 &a, const Vector3 &b) { - return Vector3(floorf(v.x), floorf(v.y), floorf(v.z)); + const Vector3 &ab = b - a; + return dot(cross(ab, p1 - a), cross(ab, p2 - a)) >= 0.0f; } -bool isFinite(Vector3::Arg v) +// http://blackpawn.com/texts/pointinpoly/default.html +static bool pointInTriangle(const Vector3 &p, const Vector3 &a, const Vector3 &b, const Vector3 &c) { - return std::isfinite(v.x) && std::isfinite(v.y) && std::isfinite(v.z); + return sameSide(p, a, b, c) && sameSide(p, b, a, c) && sameSide(p, c, a, b); } -static uint32_t hash(const Vector3 &v, uint32_t h) +#if XA_CLOSE_HOLES_CHECK_EDGE_INTERSECTION +// https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm +static bool rayIntersectsTriangle(const Vector3 &rayOrigin, const Vector3 &rayDir, const Vector3 *tri, float *t) +{ + *t = 0.0f; + const Vector3 &edge1 = tri[1] - tri[0]; + const Vector3 &edge2 = tri[2] - tri[0]; + const Vector3 h = cross(rayDir, edge2); + const float a = dot(edge1, h); + if (a > -kEpsilon && a < kEpsilon) + return false; // This ray is parallel to this triangle. + const float f = 1.0f / a; + const Vector3 s = rayOrigin - tri[0]; + const float u = f * dot(s, h); + if (u < 0.0f || u > 1.0f) + return false; + const Vector3 q = cross(s, edge1); + const float v = f * dot(rayDir, q); + if (v < 0.0f || u + v > 1.0f) + return false; + // At this stage we can compute t to find out where the intersection point is on the line. + *t = f * dot(edge2, q); + if (*t > kEpsilon && *t < 1.0f - kEpsilon) + return true; + // This means that there is a line intersection but not a ray intersection. + return false; +} +#endif + +// From Fast-BVH +struct AABB { - return sdbmFloatHash(v.component, 3, h); + AABB() : min(FLT_MAX, FLT_MAX, FLT_MAX), max(-FLT_MAX, -FLT_MAX, -FLT_MAX) {} + AABB(const Vector3 &min, const Vector3 &max) : min(min), max(max) { } + AABB(const Vector3 &p, float radius = 0.0f) : min(p), max(p) { if (radius > 0.0f) expand(radius); } + + bool intersect(const AABB &other) const + { + return min.x <= other.max.x && max.x >= other.min.x && min.y <= other.max.y && max.y >= other.min.y && min.z <= other.max.z && max.z >= other.min.z; + } + + void expandToInclude(const Vector3 &p) + { + min = internal::min(min, p); + max = internal::max(max, p); + } + + void expandToInclude(const AABB &aabb) + { + min = internal::min(min, aabb.min); + max = internal::max(max, aabb.max); + } + + void expand(float amount) + { + min -= Vector3(amount); + max += Vector3(amount); + } + + Vector3 centroid() const + { + return min + (max - min) * 0.5f; + } + + uint32_t maxDimension() const + { + const Vector3 extent = max - min; + uint32_t result = 0; + if (extent.y > extent.x) { + result = 1; + if (extent.z > extent.y) + result = 2; + } + else if(extent.z > extent.x) + result = 2; + return result; + } + + Vector3 min, max; +}; + +template <typename T> +static void construct_range(T * ptr, uint32_t new_size, uint32_t old_size) { + for (uint32_t i = old_size; i < new_size; i++) { + new(ptr+i) T; // placement new + } +} + +template <typename T> +static void construct_range(T * ptr, uint32_t new_size, uint32_t old_size, const T & elem) { + for (uint32_t i = old_size; i < new_size; i++) { + new(ptr+i) T(elem); // placement new + } } +template <typename T> +static void construct_range(T * ptr, uint32_t new_size, uint32_t old_size, const T * src) { + for (uint32_t i = old_size; i < new_size; i++) { + new(ptr+i) T(src[i]); // placement new + } +} + +template <typename T> +static void destroy_range(T * ptr, uint32_t new_size, uint32_t old_size) { + for (uint32_t i = new_size; i < old_size; i++) { + (ptr+i)->~T(); // Explicit call to the destructor + } +} + +/** +* Replacement for std::vector that is easier to debug and provides +* some nice foreach enumerators. +*/ +template<typename T> +class Array { +public: + typedef uint32_t size_type; + + Array(int memTag = MemTag::Default) : m_memTag(memTag), m_buffer(nullptr), m_capacity(0), m_size(0) {} + + Array(const Array &a) : m_memTag(a.m_memTag), m_buffer(nullptr), m_capacity(0), m_size(0) + { + copy(a.m_buffer, a.m_size); + } + + ~Array() + { + destroy(); + } + + const Array<T> &operator=(const Array<T> &other) + { + m_memTag = other.m_memTag; + m_buffer = other.m_buffer; + m_capacity = other.m_capacity; + m_size = other.m_size; + return *this; + } + + const T & operator[]( uint32_t index ) const + { + XA_DEBUG_ASSERT(index < m_size); + return m_buffer[index]; + } + + T & operator[] ( uint32_t index ) + { + XA_DEBUG_ASSERT(index < m_size); + return m_buffer[index]; + } + + uint32_t size() const { return m_size; } + const T * data() const { return m_buffer; } + T * data() { return m_buffer; } + T * begin() { return m_buffer; } + T * end() { return m_buffer + m_size; } + const T * begin() const { return m_buffer; } + const T * end() const { return m_buffer + m_size; } + bool isEmpty() const { return m_size == 0; } + + void push_back( const T & val ) + { + XA_DEBUG_ASSERT(&val < m_buffer || &val >= m_buffer+m_size); + uint32_t old_size = m_size; + uint32_t new_size = m_size + 1; + setArraySize(new_size); + construct_range(m_buffer, new_size, old_size, val); + } + + void pop_back() + { + XA_DEBUG_ASSERT( m_size > 0 ); + resize( m_size - 1 ); + } + + const T & back() const + { + XA_DEBUG_ASSERT( m_size > 0 ); + return m_buffer[m_size-1]; + } + + T & back() + { + XA_DEBUG_ASSERT( m_size > 0 ); + return m_buffer[m_size-1]; + } + + const T & front() const + { + XA_DEBUG_ASSERT( m_size > 0 ); + return m_buffer[0]; + } + + T & front() + { + XA_DEBUG_ASSERT( m_size > 0 ); + return m_buffer[0]; + } + + // Remove the element at the given index. This is an expensive operation! + void removeAt(uint32_t index) + { + XA_DEBUG_ASSERT(index >= 0 && index < m_size); + if (m_size == 1) { + clear(); + } + else { + m_buffer[index].~T(); + memmove(m_buffer+index, m_buffer+index+1, sizeof(T) * (m_size - 1 - index)); + m_size--; + } + } + + // Insert the given element at the given index shifting all the elements up. + void insertAt(uint32_t index, const T & val = T()) + { + XA_DEBUG_ASSERT( index >= 0 && index <= m_size ); + setArraySize(m_size + 1); + if (index < m_size - 1) { + memmove(m_buffer+index+1, m_buffer+index, sizeof(T) * (m_size - 1 - index)); + } + // Copy-construct into the newly opened slot. + new(m_buffer+index) T(val); + } + + void append(const Array<T> & other) + { + append(other.m_buffer, other.m_size); + } + + void resize(uint32_t new_size) + { + uint32_t old_size = m_size; + // Destruct old elements (if we're shrinking). + destroy_range(m_buffer, new_size, old_size); + setArraySize(new_size); + // Call default constructors + construct_range(m_buffer, new_size, old_size); + } + + void resize(uint32_t new_size, const T & elem) + { + XA_DEBUG_ASSERT(&elem < m_buffer || &elem > m_buffer+m_size); + uint32_t old_size = m_size; + // Destruct old elements (if we're shrinking). + destroy_range(m_buffer, new_size, old_size); + setArraySize(new_size); + // Call copy constructors + construct_range(m_buffer, new_size, old_size, elem); + } + + void clear() + { + // Destruct old elements + destroy_range(m_buffer, 0, m_size); + m_size = 0; + } + + void destroy() + { + clear(); + XA_FREE(m_buffer); + m_buffer = nullptr; + m_capacity = 0; + m_size = 0; + } + + void reserve(uint32_t desired_size) + { + if (desired_size > m_capacity) { + setArrayCapacity(desired_size); + } + } + + void copy(const T * data, uint32_t count) + { + destroy_range(m_buffer, 0, m_size); + setArraySize(count); + construct_range(m_buffer, count, 0, data); + } + + void moveTo(Array<T> &other) + { + other.destroy(); + swap(m_buffer, other.m_buffer); + swap(m_capacity, other.m_capacity); + swap(m_size, other.m_size); + } + +protected: + void setArraySize(uint32_t new_size) + { + m_size = new_size; + if (new_size > m_capacity) { + uint32_t new_buffer_size; + if (m_capacity == 0) { + // first allocation is exact + new_buffer_size = new_size; + } + else { + // following allocations grow array by 25% + new_buffer_size = new_size + (new_size >> 2); + } + setArrayCapacity( new_buffer_size ); + } + } + void setArrayCapacity(uint32_t new_capacity) + { + XA_DEBUG_ASSERT(new_capacity >= m_size); + if (new_capacity == 0) { + // free the buffer. + if (m_buffer != nullptr) { + XA_FREE(m_buffer); + m_buffer = nullptr; + } + } + else { + // realloc the buffer + m_buffer = XA_REALLOC(m_memTag, m_buffer, T, new_capacity); + } + m_capacity = new_capacity; + } + + int m_memTag; + T * m_buffer; + uint32_t m_capacity; + uint32_t m_size; +}; + /// Basis class to compute tangent space basis, ortogonalizations and to /// transform vectors from one space to another. -class Basis +struct Basis { -public: - /// Create a null basis. - Basis() : tangent(0, 0, 0), bitangent(0, 0, 0), normal(0, 0, 0) {} - - void buildFrameForDirection(Vector3::Arg d, float angle = 0) + void buildFrameForDirection(const Vector3 &d, float angle = 0) { - xaAssert(isNormalized(d)); + XA_ASSERT(isNormalized(d)); normal = d; // Choose minimum axis. if (fabsf(normal.x) < fabsf(normal.y) && fabsf(normal.x) < fabsf(normal.z)) { @@ -702,7 +1215,7 @@ public: } // Ortogonalize tangent -= normal * dot(normal, tangent); - tangent = normalize(tangent); + tangent = normalize(tangent, kEpsilon); bitangent = cross(normal, tangent); // Rotate frame around normal according to angle. if (angle != 0.0f) { @@ -714,9 +1227,9 @@ public: } } - Vector3 tangent; - Vector3 bitangent; - Vector3 normal; + Vector3 tangent = Vector3(0.0f); + Vector3 bitangent = Vector3(0.0f); + Vector3 normal = Vector3(0.0f); }; // Simple bit array. @@ -724,21 +1237,12 @@ class BitArray { public: BitArray() : m_size(0) {} + BitArray(uint32_t sz) { resize(sz); } - uint32_t size() const - { - return m_size; - } - - void clear() - { - resize(0); - } - void resize(uint32_t new_size) { m_size = new_size; @@ -748,162 +1252,311 @@ public: /// Get bit. bool bitAt(uint32_t b) const { - xaDebugAssert( b < m_size ); + XA_DEBUG_ASSERT( b < m_size ); return (m_wordArray[b >> 5] & (1 << (b & 31))) != 0; } // Set a bit. void setBitAt(uint32_t idx) { - xaDebugAssert(idx < m_size); + XA_DEBUG_ASSERT(idx < m_size); m_wordArray[idx >> 5] |= (1 << (idx & 31)); } - // Toggle a bit. - void toggleBitAt(uint32_t idx) - { - xaDebugAssert(idx < m_size); - m_wordArray[idx >> 5] ^= (1 << (idx & 31)); - } - - // Set a bit to the given value. @@ Rename modifyBitAt? - void setBitAt(uint32_t idx, bool b) - { - xaDebugAssert(idx < m_size); - m_wordArray[idx >> 5] = setBits(m_wordArray[idx >> 5], 1 << (idx & 31), b); - xaDebugAssert(bitAt(idx) == b); - } - // Clear all the bits. void clearAll() { - memset(m_wordArray.data(), 0, m_wordArray.size() * sizeof(uint32_t )); - } - - // Set all the bits. - void setAll() - { - memset(m_wordArray.data(), 0xFF, m_wordArray.size() * sizeof(uint32_t )); + memset(m_wordArray.data(), 0, m_wordArray.size() * sizeof(uint32_t)); } private: - // See "Conditionally set or clear bits without branching" at http://graphics.stanford.edu/~seander/bithacks.html - uint32_t setBits(uint32_t w, uint32_t m, bool b) - { - return (w & ~m) | (-int(b) & m); - } - // Number of bits stored. uint32_t m_size; // Array of bits. - std::vector<uint32_t> m_wordArray; + Array<uint32_t> m_wordArray; }; -/// Bit map. This should probably be called BitImage. -class BitMap +class BitImage { public: - BitMap() : m_width(0), m_height(0) {} - BitMap(uint32_t w, uint32_t h) : m_width(w), m_height(h), m_bitArray(w * h) {} + BitImage() : m_width(0), m_height(0), m_rowStride(0) {} - uint32_t width() const + BitImage(uint32_t w, uint32_t h) : m_width(w), m_height(h) { - return m_width; + m_rowStride = (m_width + 63) >> 6; + m_data.resize(m_rowStride * m_height); } - uint32_t height() const + + BitImage(const BitImage &other) { - return m_height; + m_width = other.m_width; + m_height = other.m_height; + m_rowStride = other.m_rowStride; + m_data.resize(m_rowStride * m_height); + memcpy(m_data.data(), other.m_data.data(), m_rowStride * m_height * sizeof(uint64_t)); } - void resize(uint32_t w, uint32_t h, bool initValue) + const BitImage &operator=(const BitImage &other) { - BitArray tmp(w * h); - if (initValue) tmp.setAll(); - else tmp.clearAll(); - // @@ Copying one bit at a time. This could be much faster. - for (uint32_t y = 0; y < m_height; y++) { - for (uint32_t x = 0; x < m_width; x++) { - //tmp.setBitAt(y*w + x, bitAt(x, y)); - if (bitAt(x, y) != initValue) tmp.toggleBitAt(y * w + x); - } + m_width = other.m_width; + m_height = other.m_height; + m_rowStride = other.m_rowStride; + m_data = other.m_data; + return *this; + } + + uint32_t width() const { return m_width; } + uint32_t height() const { return m_height; } + + void resize(uint32_t w, uint32_t h, bool discard) + { + const uint32_t rowStride = (w + 63) >> 6; + if (discard) { + m_data.resize(rowStride * h); + memset(m_data.data(), 0, m_data.size() * sizeof(uint64_t)); + } else { + Array<uint64_t> tmp; + tmp.resize(rowStride * h); + memset(tmp.data(), 0, tmp.size() * sizeof(uint64_t)); + // If only height has changed, can copy all rows at once. + if (rowStride == m_rowStride) { + memcpy(tmp.data(), m_data.data(), m_rowStride * min(m_height, h) * sizeof(uint64_t)); + } else if (m_width > 0 && m_height > 0) { + const uint32_t height = min(m_height, h); + for (uint32_t i = 0; i < height; i++) + memcpy(&tmp[i * rowStride], &m_data[i * m_rowStride], min(rowStride, m_rowStride) * sizeof(uint64_t)); + } + tmp.moveTo(m_data); } - std::swap(m_bitArray, tmp); m_width = w; m_height = h; + m_rowStride = rowStride; } bool bitAt(uint32_t x, uint32_t y) const { - xaDebugAssert(x < m_width && y < m_height); - return m_bitArray.bitAt(y * m_width + x); + XA_DEBUG_ASSERT(x < m_width && y < m_height); + const uint32_t index = (x >> 6) + y * m_rowStride; + return (m_data[index] & (UINT64_C(1) << (uint64_t(x) & UINT64_C(63)))) != 0; } void setBitAt(uint32_t x, uint32_t y) { - xaDebugAssert(x < m_width && y < m_height); - m_bitArray.setBitAt(y * m_width + x); + XA_DEBUG_ASSERT(x < m_width && y < m_height); + const uint32_t index = (x >> 6) + y * m_rowStride; + m_data[index] |= UINT64_C(1) << (uint64_t(x) & UINT64_C(63)); + XA_DEBUG_ASSERT(bitAt(x, y)); } void clearAll() { - m_bitArray.clearAll(); + memset(m_data.data(), 0, m_data.size() * sizeof(uint64_t)); + } + + bool canBlit(const BitImage &image, uint32_t offsetX, uint32_t offsetY) const + { + for (uint32_t y = 0; y < image.m_height; y++) { + const uint32_t thisY = y + offsetY; + if (thisY >= m_height) + continue; + uint32_t x = 0; + for (;;) { + const uint32_t thisX = x + offsetX; + if (thisX >= m_width) + break; + const uint32_t thisBlockShift = thisX % 64; + const uint64_t thisBlock = m_data[(thisX >> 6) + thisY * m_rowStride] >> thisBlockShift; + const uint32_t blockShift = x % 64; + const uint64_t block = image.m_data[(x >> 6) + y * image.m_rowStride] >> blockShift; + if ((thisBlock & block) != 0) + return false; + x += 64 - max(thisBlockShift, blockShift); + if (x >= image.m_width) + break; + } + } + return true; + } + + void dilate(uint32_t padding) + { + BitImage tmp(m_width, m_height); + for (uint32_t p = 0; p < padding; p++) { + tmp.clearAll(); + for (uint32_t y = 0; y < m_height; y++) { + for (uint32_t x = 0; x < m_width; x++) { + bool b = bitAt(x, y); + if (!b) { + if (x > 0) { + b |= bitAt(x - 1, y); + if (y > 0) b |= bitAt(x - 1, y - 1); + if (y < m_height - 1) b |= bitAt(x - 1, y + 1); + } + if (y > 0) b |= bitAt(x, y - 1); + if (y < m_height - 1) b |= bitAt(x, y + 1); + if (x < m_width - 1) { + b |= bitAt(x + 1, y); + if (y > 0) b |= bitAt(x + 1, y - 1); + if (y < m_height - 1) b |= bitAt(x + 1, y + 1); + } + } + if (b) + tmp.setBitAt(x, y); + } + } + swap(m_data, tmp.m_data); + } } private: uint32_t m_width; uint32_t m_height; - BitArray m_bitArray; + uint32_t m_rowStride; // In uint64_t's + Array<uint64_t> m_data; }; -// Axis Aligned Bounding Box. -class Box +// From Fast-BVH +class BVH { public: - Box() {} - Box(const Box &b) : minCorner(b.minCorner), maxCorner(b.maxCorner) {} - Box(const Vector3 &mins, const Vector3 &maxs) : minCorner(mins), maxCorner(maxs) {} - - operator const float *() const + BVH(const Array<AABB> &objectAabbs, uint32_t leafSize = 4) { - return reinterpret_cast<const float *>(this); - } - - // Clear the bounds. - void clearBounds() - { - minCorner.set(FLT_MAX, FLT_MAX, FLT_MAX); - maxCorner.set(-FLT_MAX, -FLT_MAX, -FLT_MAX); - } - - // Return extents of the box. - Vector3 extents() const - { - return (maxCorner - minCorner) * 0.5f; + m_objectAabbs = &objectAabbs; + if (m_objectAabbs->isEmpty()) + return; + m_objectIds.resize(objectAabbs.size()); + for (uint32_t i = 0; i < m_objectIds.size(); i++) + m_objectIds[i] = i; + BuildEntry todo[128]; + uint32_t stackptr = 0; + const uint32_t kRoot = 0xfffffffc; + const uint32_t kUntouched = 0xffffffff; + const uint32_t kTouchedTwice = 0xfffffffd; + // Push the root + todo[stackptr].start = 0; + todo[stackptr].end = objectAabbs.size(); + todo[stackptr].parent = kRoot; + stackptr++; + Node node; + m_nodes.reserve(objectAabbs.size() * 2); + uint32_t nNodes = 0; + while(stackptr > 0) { + // Pop the next item off of the stack + const BuildEntry &bnode = todo[--stackptr]; + const uint32_t start = bnode.start; + const uint32_t end = bnode.end; + const uint32_t nPrims = end - start; + nNodes++; + node.start = start; + node.nPrims = nPrims; + node.rightOffset = kUntouched; + // Calculate the bounding box for this node + AABB bb(objectAabbs[m_objectIds[start]]); + AABB bc(objectAabbs[m_objectIds[start]].centroid()); + for(uint32_t p = start + 1; p < end; ++p) { + bb.expandToInclude(objectAabbs[m_objectIds[p]]); + bc.expandToInclude(objectAabbs[m_objectIds[p]].centroid()); + } + node.aabb = bb; + // If the number of primitives at this point is less than the leaf + // size, then this will become a leaf. (Signified by rightOffset == 0) + if (nPrims <= leafSize) + node.rightOffset = 0; + m_nodes.push_back(node); + // Child touches parent... + // Special case: Don't do this for the root. + if (bnode.parent != kRoot) { + m_nodes[bnode.parent].rightOffset--; + // When this is the second touch, this is the right child. + // The right child sets up the offset for the flat tree. + if (m_nodes[bnode.parent].rightOffset == kTouchedTwice ) + m_nodes[bnode.parent].rightOffset = nNodes - 1 - bnode.parent; + } + // If this is a leaf, no need to subdivide. + if (node.rightOffset == 0) + continue; + // Set the split dimensions + const uint32_t split_dim = bc.maxDimension(); + // Split on the center of the longest axis + const float split_coord = 0.5f * ((&bc.min.x)[split_dim] + (&bc.max.x)[split_dim]); + // Partition the list of objects on this split + uint32_t mid = start; + for (uint32_t i = start; i < end; ++i) { + const Vector3 centroid(objectAabbs[m_objectIds[i]].centroid()); + if ((¢roid.x)[split_dim] < split_coord) { + swap(m_objectIds[i], m_objectIds[mid]); + ++mid; + } + } + // If we get a bad split, just choose the center... + if (mid == start || mid == end) + mid = start + (end - start) / 2; + // Push right child + todo[stackptr].start = mid; + todo[stackptr].end = end; + todo[stackptr].parent = nNodes - 1; + stackptr++; + // Push left child + todo[stackptr].start = start; + todo[stackptr].end = mid; + todo[stackptr].parent = nNodes - 1; + stackptr++; + } + } + + void query(const AABB &queryAabb, Array<uint32_t> &result) const + { + result.clear(); + // Working set + uint32_t todo[64]; + int32_t stackptr = 0; + // "Push" on the root node to the working set + todo[stackptr] = 0; + while(stackptr >= 0) { + // Pop off the next node to work on. + const int ni = todo[stackptr--]; + const Node &node = m_nodes[ni]; + // Is leaf -> Intersect + if (node.rightOffset == 0) { + for(uint32_t o = 0; o < node.nPrims; ++o) { + const uint32_t obj = node.start + o; + if (queryAabb.intersect((*m_objectAabbs)[m_objectIds[obj]])) + result.push_back(m_objectIds[obj]); + } + } else { // Not a leaf + const uint32_t left = ni + 1; + const uint32_t right = ni + node.rightOffset; + if (queryAabb.intersect(m_nodes[left].aabb)) + todo[++stackptr] = left; + if (queryAabb.intersect(m_nodes[right].aabb)) + todo[++stackptr] = right; + } + } } - // Add a point to this box. - void addPointToBounds(const Vector3 &p) +private: + struct BuildEntry { - minCorner = min(minCorner, p); - maxCorner = max(maxCorner, p); - } + uint32_t parent; // If non-zero then this is the index of the parent. (used in offsets) + uint32_t start, end; // The range of objects in the object list covered by this node. + }; - // Get the volume of the box. - float volume() const + struct Node { - Vector3 d = extents(); - return 8.0f * (d.x * d.y * d.z); - } + AABB aabb; + uint32_t start, nPrims, rightOffset; + }; - Vector3 minCorner; - Vector3 maxCorner; + const Array<AABB> *m_objectAabbs; + Array<uint32_t> m_objectIds; + Array<Node> m_nodes; }; class Fit { public: - static Vector3 computeCentroid(int n, const Vector3 *__restrict points) + static Vector3 computeCentroid(int n, const Vector3 * points) { Vector3 centroid(0.0f); for (int i = 0; i < n; i++) { @@ -913,7 +1566,7 @@ public: return centroid; } - static Vector3 computeCovariance(int n, const Vector3 *__restrict points, float *__restrict covariance) + static Vector3 computeCovariance(int n, const Vector3 * points, float * covariance) { // compute the centroid Vector3 centroid = computeCentroid(n, points); @@ -933,25 +1586,12 @@ public: return centroid; } - static bool isPlanar(int n, const Vector3 *points, float epsilon = NV_EPSILON) - { - // compute the centroid and covariance - float matrix[6]; - computeCovariance(n, points, matrix); - float eigenValues[3]; - Vector3 eigenVectors[3]; - if (!eigenSolveSymmetric3(matrix, eigenValues, eigenVectors)) { - return false; - } - return eigenValues[2] < epsilon; - } - // Tridiagonal solver from Charles Bloom. // Householder transforms followed by QL decomposition. // Seems to be based on the code from Numerical Recipes in C. static bool eigenSolveSymmetric3(const float matrix[6], float eigenValues[3], Vector3 eigenVectors[3]) { - xaDebugAssert(matrix != NULL && eigenValues != NULL && eigenVectors != NULL); + XA_DEBUG_ASSERT(matrix != nullptr && eigenValues != nullptr && eigenVectors != nullptr); float subd[3]; float diag[3]; float work[3][3]; @@ -975,24 +1615,24 @@ public: // eigenvectors are the columns; make them the rows : for (int i = 0; i < 3; i++) { for (int j = 0; j < 3; j++) { - eigenVectors[j].component[i] = (float) work[i][j]; + (&eigenVectors[j].x)[i] = (float) work[i][j]; } } // shuffle to sort by singular value : if (eigenValues[2] > eigenValues[0] && eigenValues[2] > eigenValues[1]) { - std::swap(eigenValues[0], eigenValues[2]); - std::swap(eigenVectors[0], eigenVectors[2]); + swap(eigenValues[0], eigenValues[2]); + swap(eigenVectors[0], eigenVectors[2]); } if (eigenValues[1] > eigenValues[0]) { - std::swap(eigenValues[0], eigenValues[1]); - std::swap(eigenVectors[0], eigenVectors[1]); + swap(eigenValues[0], eigenValues[1]); + swap(eigenVectors[0], eigenVectors[1]); } if (eigenValues[2] > eigenValues[1]) { - std::swap(eigenValues[1], eigenValues[2]); - std::swap(eigenVectors[1], eigenVectors[2]); + swap(eigenValues[1], eigenValues[2]); + swap(eigenVectors[1], eigenVectors[2]); } - xaDebugAssert(eigenValues[0] >= eigenValues[1] && eigenValues[0] >= eigenValues[2]); - xaDebugAssert(eigenValues[1] >= eigenValues[2]); + XA_DEBUG_ASSERT(eigenValues[0] >= eigenValues[1] && eigenValues[0] >= eigenValues[2]); + XA_DEBUG_ASSERT(eigenValues[1] >= eigenValues[2]); return true; } @@ -1118,7 +1758,7 @@ public: const FullVector &operator=(const FullVector &v) { - xaAssert(dimension() == v.dimension()); + XA_ASSERT(dimension() == v.dimension()); m_array = v.m_array; return *this; } @@ -1135,1698 +1775,1695 @@ public: } } - void operator+=(const FullVector &v) - { - xaDebugAssert(dimension() == v.dimension()); - const uint32_t dim = dimension(); - for (uint32_t i = 0; i < dim; i++) { - m_array[i] += v.m_array[i]; - } - } - - void operator-=(const FullVector &v) - { - xaDebugAssert(dimension() == v.dimension()); - const uint32_t dim = dimension(); - for (uint32_t i = 0; i < dim; i++) { - m_array[i] -= v.m_array[i]; - } - } - - void operator*=(const FullVector &v) - { - xaDebugAssert(dimension() == v.dimension()); - const uint32_t dim = dimension(); - for (uint32_t i = 0; i < dim; i++) { - m_array[i] *= v.m_array[i]; - } - } - - void operator+=(float f) - { - const uint32_t dim = dimension(); - for (uint32_t i = 0; i < dim; i++) { - m_array[i] += f; - } - } - - void operator-=(float f) - { - const uint32_t dim = dimension(); - for (uint32_t i = 0; i < dim; i++) { - m_array[i] -= f; - } - } - - void operator*=(float f) - { - const uint32_t dim = dimension(); - for (uint32_t i = 0; i < dim; i++) { - m_array[i] *= f; - } - } - private: - std::vector<float> m_array; + Array<float> m_array; }; -namespace halfedge { -class Face; -class Vertex; - -class Edge +template<typename Key, typename Value, typename H = Hash<Key>, typename E = Equal<Key> > +class HashMap { public: - uint32_t id; - Edge *next; - Edge *prev; // This is not strictly half-edge, but makes algorithms easier and faster. - Edge *pair; - Vertex *vertex; - Face *face; - - // Default constructor. - Edge(uint32_t id) : id(id), next(NULL), prev(NULL), pair(NULL), vertex(NULL), face(NULL) {} - - // Vertex queries. - const Vertex *from() const + HashMap(int memTag, uint32_t size) : m_memTag(memTag), m_size(size), m_numSlots(0), m_slots(nullptr), m_keys(memTag), m_values(memTag), m_next(memTag) { - return vertex; } - Vertex *from() + ~HashMap() { - return vertex; + if (m_slots) + XA_FREE(m_slots); } - const Vertex *to() const - { - return pair->vertex; // This used to be 'next->vertex', but that changed often when the connectivity of the mesh changes. - } + const Value &value(uint32_t index) const { return m_values[index]; } - Vertex *to() + void add(const Key &key, const Value &value) { - return pair->vertex; + if (!m_slots) + alloc(); + const uint32_t hash = computeHash(key); + m_keys.push_back(key); + m_values.push_back(value); + m_next.push_back(m_slots[hash]); + m_slots[hash] = m_next.size() - 1; } - // Edge queries. - void setNext(Edge *e) + uint32_t get(const Key &key) const { - next = e; - if (e != NULL) e->prev = this; - } - void setPrev(Edge *e) - { - prev = e; - if (e != NULL) e->next = this; + if (!m_slots) + return UINT32_MAX; + const uint32_t hash = computeHash(key); + uint32_t i = m_slots[hash]; + E equal; + while (i != UINT32_MAX) { + if (equal(m_keys[i], key)) + return i; + i = m_next[i]; + } + return UINT32_MAX; } - // @@ It would be more simple to only check m_pair == NULL - // Face queries. - bool isBoundary() const + uint32_t getNext(uint32_t current) const { - return !(face && pair->face); + uint32_t i = m_next[current]; + E equal; + while (i != UINT32_MAX) { + if (equal(m_keys[i], m_keys[current])) + return i; + i = m_next[i]; + } + return UINT32_MAX; } - // @@ This is not exactly accurate, we should compare the texture coordinates... - bool isSeam() const +private: + void alloc() { - return vertex != pair->next->vertex || next->vertex != pair->vertex; + XA_DEBUG_ASSERT(m_size > 0); + m_numSlots = (uint32_t)(m_size * 1.3); + m_slots = XA_ALLOC_ARRAY(m_memTag, uint32_t, m_numSlots); + for (uint32_t i = 0; i < m_numSlots; i++) + m_slots[i] = UINT32_MAX; + m_keys.reserve(m_size); + m_values.reserve(m_size); + m_next.reserve(m_size); } - bool isNormalSeam() const; - bool isTextureSeam() const; - - bool isValid() const + uint32_t computeHash(const Key &key) const { - // null face is OK. - if (next == NULL || prev == NULL || pair == NULL || vertex == NULL) return false; - if (next->prev != this) return false; - if (prev->next != this) return false; - if (pair->pair != this) return false; - return true; + H hash; + return hash(key) % m_numSlots; } - float length() const; - - // Return angle between this edge and the previous one. - float angle() const; + int m_memTag; + uint32_t m_size; + uint32_t m_numSlots; + uint32_t *m_slots; + Array<Key> m_keys; + Array<Value> m_values; + Array<uint32_t> m_next; }; -class Vertex +template<typename T> +static void insertionSort(T *data, uint32_t length) { -public: - uint32_t id; - // -- GODOT start -- - uint32_t original_id; - // -- GODOT end -- - Edge *edge; - Vertex *next; - Vertex *prev; - Vector3 pos; - Vector3 nor; - Vector2 tex; - - // -- GODOT start -- - //Vertex(uint32_t id) : id(id), edge(NULL), pos(0.0f), nor(0.0f), tex(0.0f) - Vertex(uint32_t id) : id(id), original_id(id), edge(NULL), pos(0.0f), nor(0.0f), tex(0.0f) - // -- GODOT end -- - { - next = this; - prev = this; - } - - // Set first edge of all colocals. - void setEdge(Edge *e) - { - for (VertexIterator it(colocals()); !it.isDone(); it.advance()) { - it.current()->edge = e; + for (int32_t i = 1; i < (int32_t)length; i++) { + T x = data[i]; + int32_t j = i - 1; + while (j >= 0 && x < data[j]) { + data[j + 1] = data[j]; + j--; } + data[j + 1] = x; } +} - // Update position of all colocals. - void setPos(const Vector3 &p) +class KISSRng +{ +public: + uint32_t getRange(uint32_t range) { - for (VertexIterator it(colocals()); !it.isDone(); it.advance()) { - it.current()->pos = p; - } + if (range == 0) + return 0; + x = 69069 * x + 12345; + y ^= (y << 13); + y ^= (y >> 17); + y ^= (y << 5); + uint64_t t = 698769069ULL * z + c; + c = (t >> 32); + return (x + y + (z = (uint32_t)t)) % range; } - bool isFirstColocal() const - { - return firstColocal() == this; - } +private: + uint32_t x = 123456789, y = 362436000, z = 521288629, c = 7654321; +}; - const Vertex *firstColocal() const +// Based on Pierre Terdiman's and Michael Herf's source code. +// http://www.codercorner.com/RadixSortRevisited.htm +// http://www.stereopsis.com/radix.html +class RadixSort +{ +public: + RadixSort() : m_size(0), m_ranks(nullptr), m_ranks2(nullptr), m_validRanks(false) {} + + ~RadixSort() { - uint32_t firstId = id; - const Vertex *vertex = this; - for (ConstVertexIterator it(colocals()); !it.isDone(); it.advance()) { - if (it.current()->id < firstId) { - firstId = vertex->id; - vertex = it.current(); - } - } - return vertex; + // Release everything + XA_FREE(m_ranks2); + XA_FREE(m_ranks); } - Vertex *firstColocal() + RadixSort &sort(const float *input, uint32_t count) { - Vertex *vertex = this; - uint32_t firstId = id; - for (VertexIterator it(colocals()); !it.isDone(); it.advance()) { - if (it.current()->id < firstId) { - firstId = vertex->id; - vertex = it.current(); + if (input == nullptr || count == 0) return *this; + // Resize lists if needed + if (count != m_size) { + if (count > m_size) { + m_ranks2 = XA_REALLOC(MemTag::Default, m_ranks2, uint32_t, count); + m_ranks = XA_REALLOC(MemTag::Default, m_ranks, uint32_t, count); } + m_size = count; + m_validRanks = false; } - return vertex; - } - - bool isColocal(const Vertex *v) const - { - if (this == v) return true; - if (pos != v->pos) return false; - for (ConstVertexIterator it(colocals()); !it.isDone(); it.advance()) { - if (v == it.current()) { - return true; + if (count < 32) { + insertionSort(input, count); + } else { + // @@ Avoid touching the input multiple times. + for (uint32_t i = 0; i < count; i++) { + FloatFlip((uint32_t &)input[i]); + } + radixSort<uint32_t>((const uint32_t *)input, count); + for (uint32_t i = 0; i < count; i++) { + IFloatFlip((uint32_t &)input[i]); } } - return false; + return *this; } - void linkColocal(Vertex *v) + RadixSort &sort(const Array<float> &input) { - next->prev = v; - v->next = next; - next = v; - v->prev = this; - } - void unlinkColocal() - { - next->prev = prev; - prev->next = next; - next = this; - prev = this; + return sort(input.data(), input.size()); } - // @@ Note: This only works if linkBoundary has been called. - bool isBoundary() const + // Access to results. m_ranks is a list of indices in sorted order, i.e. in the order you may further process your data + const uint32_t *ranks() const { - return (edge && !edge->face); + XA_DEBUG_ASSERT(m_validRanks); + return m_ranks; } - // Iterator that visits the edges around this vertex in counterclockwise order. - class EdgeIterator //: public Iterator<Edge *> + uint32_t *ranks() { - public: - EdgeIterator(Edge *e) : m_end(NULL), m_current(e) { } - - virtual void advance() - { - if (m_end == NULL) m_end = m_current; - m_current = m_current->pair->next; - //m_current = m_current->prev->pair; - } - - virtual bool isDone() const - { - return m_end == m_current; - } - virtual Edge *current() const - { - return m_current; - } - Vertex *vertex() const - { - return m_current->vertex; - } + XA_DEBUG_ASSERT(m_validRanks); + return m_ranks; + } - private: - Edge *m_end; - Edge *m_current; - }; +private: + uint32_t m_size; + uint32_t *m_ranks; + uint32_t *m_ranks2; + bool m_validRanks; - EdgeIterator edges() + void FloatFlip(uint32_t &f) { - return EdgeIterator(edge); + int32_t mask = (int32_t(f) >> 31) | 0x80000000; // Warren Hunt, Manchor Ko. + f ^= mask; } - EdgeIterator edges(Edge *e) + + void IFloatFlip(uint32_t &f) { - return EdgeIterator(e); + uint32_t mask = ((f >> 31) - 1) | 0x80000000; // Michael Herf. + f ^= mask; } - // Iterator that visits the edges around this vertex in counterclockwise order. - class ConstEdgeIterator //: public Iterator<Edge *> + template<typename T> + void createHistograms(const T *buffer, uint32_t count, uint32_t *histogram) { - public: - ConstEdgeIterator(const Edge *e) : m_end(NULL), m_current(e) { } - ConstEdgeIterator(EdgeIterator it) : m_end(NULL), m_current(it.current()) { } - - virtual void advance() - { - if (m_end == NULL) m_end = m_current; - m_current = m_current->pair->next; - //m_current = m_current->prev->pair; - } - - virtual bool isDone() const - { - return m_end == m_current; - } - virtual const Edge *current() const - { - return m_current; + const uint32_t bucketCount = sizeof(T); // (8 * sizeof(T)) / log2(radix) + // Init bucket pointers. + uint32_t *h[bucketCount]; + for (uint32_t i = 0; i < bucketCount; i++) { + h[i] = histogram + 256 * i; } - const Vertex *vertex() const - { - return m_current->to(); + // Clear histograms. + memset(histogram, 0, 256 * bucketCount * sizeof(uint32_t )); + // @@ Add support for signed integers. + // Build histograms. + const uint8_t *p = (const uint8_t *)buffer; // @@ Does this break aliasing rules? + const uint8_t *pe = p + count * sizeof(T); + while (p != pe) { + h[0][*p++]++, h[1][*p++]++, h[2][*p++]++, h[3][*p++]++; +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4127) +#endif + if (bucketCount == 8) h[4][*p++]++, h[5][*p++]++, h[6][*p++]++, h[7][*p++]++; +#ifdef _MSC_VER +#pragma warning(pop) +#endif } - - private: - const Edge *m_end; - const Edge *m_current; - }; - - ConstEdgeIterator edges() const - { - return ConstEdgeIterator(edge); - } - ConstEdgeIterator edges(const Edge *e) const - { - return ConstEdgeIterator(e); } - // Iterator that visits all the colocal vertices. - class VertexIterator //: public Iterator<Edge *> + template <typename T> void insertionSort(const T *input, uint32_t count) { - public: - VertexIterator(Vertex *v) : m_end(NULL), m_current(v) { } - - virtual void advance() - { - if (m_end == NULL) m_end = m_current; - m_current = m_current->next; - } - - virtual bool isDone() const - { - return m_end == m_current; - } - virtual Vertex *current() const - { - return m_current; + if (!m_validRanks) { + m_ranks[0] = 0; + for (uint32_t i = 1; i != count; ++i) { + int rank = m_ranks[i] = i; + uint32_t j = i; + while (j != 0 && input[rank] < input[m_ranks[j - 1]]) { + m_ranks[j] = m_ranks[j - 1]; + --j; + } + if (i != j) { + m_ranks[j] = rank; + } + } + m_validRanks = true; + } else { + for (uint32_t i = 1; i != count; ++i) { + int rank = m_ranks[i]; + uint32_t j = i; + while (j != 0 && input[rank] < input[m_ranks[j - 1]]) { + m_ranks[j] = m_ranks[j - 1]; + --j; + } + if (i != j) { + m_ranks[j] = rank; + } + } } - - private: - Vertex *m_end; - Vertex *m_current; - }; - - VertexIterator colocals() - { - return VertexIterator(this); } - // Iterator that visits all the colocal vertices. - class ConstVertexIterator //: public Iterator<Edge *> + template <typename T> void radixSort(const T *input, uint32_t count) { - public: - ConstVertexIterator(const Vertex *v) : m_end(NULL), m_current(v) { } - - virtual void advance() - { - if (m_end == NULL) m_end = m_current; - m_current = m_current->next; - } - - virtual bool isDone() const - { - return m_end == m_current; + const uint32_t P = sizeof(T); // pass count + // Allocate histograms & offsets on the stack + uint32_t histogram[256 * P]; + uint32_t *link[256]; + createHistograms(input, count, histogram); + // Radix sort, j is the pass number (0=LSB, P=MSB) + for (uint32_t j = 0; j < P; j++) { + // Pointer to this bucket. + const uint32_t *h = &histogram[j * 256]; + const uint8_t *inputBytes = (const uint8_t *)input; // @@ Is this aliasing legal? + inputBytes += j; + if (h[inputBytes[0]] == count) { + // Skip this pass, all values are the same. + continue; + } + // Create offsets + link[0] = m_ranks2; + for (uint32_t i = 1; i < 256; i++) link[i] = link[i - 1] + h[i - 1]; + // Perform Radix Sort + if (!m_validRanks) { + for (uint32_t i = 0; i < count; i++) { + *link[inputBytes[i * P]]++ = i; + } + m_validRanks = true; + } else { + for (uint32_t i = 0; i < count; i++) { + const uint32_t idx = m_ranks[i]; + *link[inputBytes[idx * P]]++ = idx; + } + } + // Swap pointers for next pass. Valid indices - the most recent ones - are in m_ranks after the swap. + swap(m_ranks, m_ranks2); } - virtual const Vertex *current() const - { - return m_current; + // All values were equal, generate linear ranks. + if (!m_validRanks) { + for (uint32_t i = 0; i < count; i++) { + m_ranks[i] = i; + } + m_validRanks = true; } - - private: - const Vertex *m_end; - const Vertex *m_current; - }; - - ConstVertexIterator colocals() const - { - return ConstVertexIterator(this); } }; -bool Edge::isNormalSeam() const -{ - return (vertex->nor != pair->next->vertex->nor || next->vertex->nor != pair->vertex->nor); -} - -bool Edge::isTextureSeam() const -{ - return (vertex->tex != pair->next->vertex->tex || next->vertex->tex != pair->vertex->tex); -} - -float Edge::length() const -{ - return internal::length(to()->pos - from()->pos); -} - -float Edge::angle() const -{ - Vector3 p = vertex->pos; - Vector3 a = prev->vertex->pos; - Vector3 b = next->vertex->pos; - Vector3 v0 = a - p; - Vector3 v1 = b - p; - return acosf(dot(v0, v1) / (internal::length(v0) * internal::length(v1))); -} - -class Face +// Wrapping this in a class allows temporary arrays to be re-used. +class BoundingBox2D { public: - uint32_t id; - uint16_t group; - uint16_t material; - Edge *edge; - - Face(uint32_t id) : id(id), group(uint16_t(~0)), material(uint16_t(~0)), edge(NULL) {} + Vector2 majorAxis() const { return m_majorAxis; } + Vector2 minorAxis() const { return m_minorAxis; } + Vector2 minCorner() const { return m_minCorner; } + Vector2 maxCorner() const { return m_maxCorner; } - float area() const - { - float area = 0; - const Vector3 &v0 = edge->from()->pos; - for (ConstEdgeIterator it(edges(edge->next)); it.current() != edge->prev; it.advance()) { - const Edge *e = it.current(); - const Vector3 &v1 = e->vertex->pos; - const Vector3 &v2 = e->next->vertex->pos; - area += length(cross(v1 - v0, v2 - v0)); - } - return area * 0.5f; - } - - float parametricArea() const - { - float area = 0; - const Vector2 &v0 = edge->from()->tex; - for (ConstEdgeIterator it(edges(edge->next)); it.current() != edge->prev; it.advance()) { - const Edge *e = it.current(); - const Vector2 &v1 = e->vertex->tex; - const Vector2 &v2 = e->next->vertex->tex; - area += triangleArea(v0, v1, v2); - } - return area * 0.5f; - } - - Vector3 normal() const + // This should compute convex hull and use rotating calipers to find the best box. Currently it uses a brute force method. + void compute(const Vector2 *boundaryVertices, uint32_t boundaryVertexCount, const Vector2 *vertices, uint32_t vertexCount) { - Vector3 n(0); - const Vertex *vertex0 = NULL; - for (ConstEdgeIterator it(edges()); !it.isDone(); it.advance()) { - const Edge *e = it.current(); - xaAssert(e != NULL); - if (vertex0 == NULL) { - vertex0 = e->vertex; - } else if (e->next->vertex != vertex0) { - const halfedge::Vertex *vertex1 = e->from(); - const halfedge::Vertex *vertex2 = e->to(); - const Vector3 &p0 = vertex0->pos; - const Vector3 &p1 = vertex1->pos; - const Vector3 &p2 = vertex2->pos; - Vector3 v10 = p1 - p0; - Vector3 v20 = p2 - p0; - n += cross(v10, v20); + convexHull(boundaryVertices, boundaryVertexCount, m_hull, 0.00001f); + // @@ Ideally I should use rotating calipers to find the best box. Using brute force for now. + float best_area = FLT_MAX; + Vector2 best_min(0); + Vector2 best_max(0); + Vector2 best_axis(0); + const uint32_t hullCount = m_hull.size(); + for (uint32_t i = 0, j = hullCount - 1; i < hullCount; j = i, i++) { + if (equal(m_hull[i], m_hull[j], kEpsilon)) + continue; + Vector2 axis = normalize(m_hull[i] - m_hull[j], 0.0f); + XA_DEBUG_ASSERT(isFinite(axis)); + // Compute bounding box. + Vector2 box_min(FLT_MAX, FLT_MAX); + Vector2 box_max(-FLT_MAX, -FLT_MAX); + // Consider all points, not only boundary points, in case the input chart is malformed. + for (uint32_t v = 0; v < vertexCount; v++) { + const Vector2 &point = vertices[v]; + const float x = dot(axis, point); + const float y = dot(Vector2(-axis.y, axis.x), point); + box_min.x = min(box_min.x, x); + box_max.x = max(box_max.x, x); + box_min.y = min(box_min.y, y); + box_max.y = max(box_max.y, y); + } + // Compute box area. + const float area = (box_max.x - box_min.x) * (box_max.y - box_min.y); + if (area < best_area) { + best_area = area; + best_min = box_min; + best_max = box_max; + best_axis = axis; } } - return normalizeSafe(n, Vector3(0, 0, 1), 0.0f); - } - - Vector3 centroid() const - { - Vector3 sum(0.0f); - uint32_t count = 0; - for (ConstEdgeIterator it(edges()); !it.isDone(); it.advance()) { - const Edge *e = it.current(); - sum += e->from()->pos; - count++; - } - return sum / float(count); - } - - // Unnormalized face normal assuming it's a triangle. - Vector3 triangleNormal() const - { - Vector3 p0 = edge->vertex->pos; - Vector3 p1 = edge->next->vertex->pos; - Vector3 p2 = edge->next->next->vertex->pos; - Vector3 e0 = p2 - p0; - Vector3 e1 = p1 - p0; - return normalizeSafe(cross(e0, e1), Vector3(0), 0.0f); - } - - Vector3 triangleNormalAreaScaled() const - { - Vector3 p0 = edge->vertex->pos; - Vector3 p1 = edge->next->vertex->pos; - Vector3 p2 = edge->next->next->vertex->pos; - Vector3 e0 = p2 - p0; - Vector3 e1 = p1 - p0; - return cross(e0, e1); - } - - // Average of the edge midpoints weighted by the edge length. - // I want a point inside the triangle, but closer to the cirumcenter. - Vector3 triangleCenter() const - { - Vector3 p0 = edge->vertex->pos; - Vector3 p1 = edge->next->vertex->pos; - Vector3 p2 = edge->next->next->vertex->pos; - float l0 = length(p1 - p0); - float l1 = length(p2 - p1); - float l2 = length(p0 - p2); - Vector3 m0 = (p0 + p1) * l0 / (l0 + l1 + l2); - Vector3 m1 = (p1 + p2) * l1 / (l0 + l1 + l2); - Vector3 m2 = (p2 + p0) * l2 / (l0 + l1 + l2); - return m0 + m1 + m2; - } - - bool isValid() const - { - uint32_t count = 0; - for (ConstEdgeIterator it(edges()); !it.isDone(); it.advance()) { - const Edge *e = it.current(); - if (e->face != this) return false; - if (!e->isValid()) return false; - if (!e->pair->isValid()) return false; - count++; - } - if (count < 3) return false; - return true; - } - - bool contains(const Edge *e) const - { - for (ConstEdgeIterator it(edges()); !it.isDone(); it.advance()) { - if (it.current() == e) return true; - } - return false; - } - - uint32_t edgeCount() const - { - uint32_t count = 0; - for (ConstEdgeIterator it(edges()); !it.isDone(); it.advance()) { - ++count; - } - return count; + m_majorAxis = best_axis; + m_minorAxis = Vector2(-best_axis.y, best_axis.x); + m_minCorner = best_min; + m_maxCorner = best_max; + XA_ASSERT(isFinite(m_majorAxis) && isFinite(m_minorAxis) && isFinite(m_minCorner)); } - // The iterator that visits the edges of this face in clockwise order. - class EdgeIterator //: public Iterator<Edge *> +private: + // Compute the convex hull using Graham Scan. + void convexHull(const Vector2 *input, uint32_t inputCount, Array<Vector2> &output, float epsilon) { - public: - EdgeIterator(Edge *e) : m_end(NULL), m_current(e) { } - - virtual void advance() - { - if (m_end == NULL) m_end = m_current; - m_current = m_current->next; + m_coords.resize(inputCount); + for (uint32_t i = 0; i < inputCount; i++) + m_coords[i] = input[i].x; + RadixSort radix; + radix.sort(m_coords); + const uint32_t *ranks = radix.ranks(); + m_top.clear(); + m_bottom.clear(); + m_top.reserve(inputCount); + m_bottom.reserve(inputCount); + Vector2 P = input[ranks[0]]; + Vector2 Q = input[ranks[inputCount - 1]]; + float topy = max(P.y, Q.y); + float boty = min(P.y, Q.y); + for (uint32_t i = 0; i < inputCount; i++) { + Vector2 p = input[ranks[i]]; + if (p.y >= boty) + m_top.push_back(p); } - - virtual bool isDone() const - { - return m_end == m_current; + for (uint32_t i = 0; i < inputCount; i++) { + Vector2 p = input[ranks[inputCount - 1 - i]]; + if (p.y <= topy) + m_bottom.push_back(p); } - virtual Edge *current() const - { - return m_current; + // Filter top list. + output.clear(); + output.push_back(m_top[0]); + output.push_back(m_top[1]); + for (uint32_t i = 2; i < m_top.size(); ) { + Vector2 a = output[output.size() - 2]; + Vector2 b = output[output.size() - 1]; + Vector2 c = m_top[i]; + float area = triangleArea(a, b, c); + if (area >= -epsilon) + output.pop_back(); + if (area < -epsilon || output.size() == 1) { + output.push_back(c); + i++; + } } - Vertex *vertex() const - { - return m_current->vertex; + uint32_t top_count = output.size(); + output.push_back(m_bottom[1]); + // Filter bottom list. + for (uint32_t i = 2; i < m_bottom.size(); ) { + Vector2 a = output[output.size() - 2]; + Vector2 b = output[output.size() - 1]; + Vector2 c = m_bottom[i]; + float area = triangleArea(a, b, c); + if (area >= -epsilon) + output.pop_back(); + if (area < -epsilon || output.size() == top_count) { + output.push_back(c); + i++; + } } - - private: - Edge *m_end; - Edge *m_current; - }; - - EdgeIterator edges() - { - return EdgeIterator(edge); - } - EdgeIterator edges(Edge *e) - { - xaDebugAssert(contains(e)); - return EdgeIterator(e); + // Remove duplicate element. + XA_DEBUG_ASSERT(output.front() == output.back()); + output.pop_back(); } - // The iterator that visits the edges of this face in clockwise order. - class ConstEdgeIterator //: public Iterator<const Edge *> - { - public: - ConstEdgeIterator(const Edge *e) : m_end(NULL), m_current(e) { } - ConstEdgeIterator(const EdgeIterator &it) : m_end(NULL), m_current(it.current()) { } + Array<float> m_coords; + Array<Vector2> m_top, m_bottom, m_hull; + Vector2 m_majorAxis, m_minorAxis, m_minCorner, m_maxCorner; +}; - virtual void advance() - { - if (m_end == NULL) m_end = m_current; - m_current = m_current->next; - } +static uint32_t meshEdgeFace(uint32_t edge) { return edge / 3; } +static uint32_t meshEdgeIndex0(uint32_t edge) { return edge; } - virtual bool isDone() const - { - return m_end == m_current; - } - virtual const Edge *current() const - { - return m_current; - } - const Vertex *vertex() const - { - return m_current->vertex; - } - - private: - const Edge *m_end; - const Edge *m_current; - }; +static uint32_t meshEdgeIndex1(uint32_t edge) +{ + const uint32_t faceFirstEdge = edge / 3 * 3; + return faceFirstEdge + (edge - faceFirstEdge + 1) % 3; +} - ConstEdgeIterator edges() const - { - return ConstEdgeIterator(edge); - } - ConstEdgeIterator edges(const Edge *e) const +struct MeshFlags +{ + enum { - xaDebugAssert(contains(e)); - return ConstEdgeIterator(e); - } + HasFaceGroups = 1<<0, + HasIgnoredFaces = 1<<1, + HasNormals = 1<<2 + }; }; -/// Simple half edge mesh designed for dynamic mesh manipulation. +class Mesh; +static void meshGetBoundaryLoops(const Mesh &mesh, Array<uint32_t> &boundaryLoops); + class Mesh { public: - Mesh() : m_colocalVertexCount(0) {} - - Mesh(const Mesh *mesh) - { - // Copy mesh vertices. - const uint32_t vertexCount = mesh->vertexCount(); - m_vertexArray.resize(vertexCount); - for (uint32_t v = 0; v < vertexCount; v++) { - const Vertex *vertex = mesh->vertexAt(v); - xaDebugAssert(vertex->id == v); - m_vertexArray[v] = new Vertex(v); - m_vertexArray[v]->pos = vertex->pos; - m_vertexArray[v]->nor = vertex->nor; - m_vertexArray[v]->tex = vertex->tex; - } - m_colocalVertexCount = vertexCount; - // Copy mesh faces. - const uint32_t faceCount = mesh->faceCount(); - std::vector<uint32_t> indexArray; - indexArray.reserve(3); - for (uint32_t f = 0; f < faceCount; f++) { - const Face *face = mesh->faceAt(f); - for (Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const Vertex *vertex = it.current()->from(); - indexArray.push_back(vertex->id); - } - addFace(indexArray); - indexArray.clear(); - } - } - - ~Mesh() - { - clear(); - } - - void clear() - { - for (size_t i = 0; i < m_vertexArray.size(); i++) - delete m_vertexArray[i]; - m_vertexArray.clear(); - for (auto it = m_edgeMap.begin(); it != m_edgeMap.end(); it++) - delete it->second; - m_edgeArray.clear(); - m_edgeMap.clear(); - for (size_t i = 0; i < m_faceArray.size(); i++) - delete m_faceArray[i]; - m_faceArray.clear(); - } - - Vertex *addVertex(const Vector3 &pos) + Mesh(float epsilon, uint32_t approxVertexCount, uint32_t approxFaceCount, uint32_t flags = 0, uint32_t id = UINT32_MAX) : m_epsilon(epsilon), m_flags(flags), m_id(id), m_faceIgnore(MemTag::Mesh), m_faceGroups(MemTag::Mesh), m_indices(MemTag::MeshIndices), m_positions(MemTag::MeshPositions), m_normals(MemTag::MeshNormals), m_texcoords(MemTag::MeshTexcoords), m_colocalVertexCount(0), m_nextColocalVertex(MemTag::MeshColocals), m_boundaryVertices(MemTag::MeshBoundaries), m_oppositeEdges(MemTag::MeshBoundaries), m_nextBoundaryEdges(MemTag::MeshBoundaries), m_edgeMap(MemTag::MeshEdgeMap, approxFaceCount * 3) { - xaDebugAssert(isFinite(pos)); - Vertex *v = new Vertex(m_vertexArray.size()); - v->pos = pos; - m_vertexArray.push_back(v); - return v; + m_indices.reserve(approxFaceCount * 3); + m_positions.reserve(approxVertexCount); + m_texcoords.reserve(approxVertexCount); + if (m_flags & MeshFlags::HasFaceGroups) + m_faceGroups.reserve(approxFaceCount); + if (m_flags & MeshFlags::HasIgnoredFaces) + m_faceIgnore.reserve(approxFaceCount); + if (m_flags & MeshFlags::HasNormals) + m_normals.reserve(approxVertexCount); } - /// Link colocal vertices based on geometric location only. - void linkColocals() - { - xaPrint("--- Linking colocals:\n"); - const uint32_t vertexCount = this->vertexCount(); - std::unordered_map<Vector3, Vertex *, Hash<Vector3>, Equal<Vector3> > vertexMap; - vertexMap.reserve(vertexCount); - for (uint32_t v = 0; v < vertexCount; v++) { - Vertex *vertex = vertexAt(v); - Vertex *colocal = vertexMap[vertex->pos]; - if (colocal) { - colocal->linkColocal(vertex); - } else { - vertexMap[vertex->pos] = vertex; - } - } - m_colocalVertexCount = vertexMap.size(); - xaPrint("--- %d vertex positions.\n", m_colocalVertexCount); - // @@ Remove duplicated vertices? or just leave them as colocals? - } + uint32_t flags() const { return m_flags; } + uint32_t id() const { return m_id; } - void linkColocalsWithCanonicalMap(const std::vector<uint32_t> &canonicalMap) + void addVertex(const Vector3 &pos, const Vector3 &normal = Vector3(0.0f), const Vector2 &texcoord = Vector2(0.0f)) { - xaPrint("--- Linking colocals:\n"); - uint32_t vertexMapSize = 0; - for (uint32_t i = 0; i < canonicalMap.size(); i++) { - vertexMapSize = std::max(vertexMapSize, canonicalMap[i] + 1); - } - std::vector<Vertex *> vertexMap; - vertexMap.resize(vertexMapSize, NULL); - m_colocalVertexCount = 0; - const uint32_t vertexCount = this->vertexCount(); - for (uint32_t v = 0; v < vertexCount; v++) { - Vertex *vertex = vertexAt(v); - Vertex *colocal = vertexMap[canonicalMap[v]]; - if (colocal != NULL) { - xaDebugAssert(vertex->pos == colocal->pos); - colocal->linkColocal(vertex); - } else { - vertexMap[canonicalMap[v]] = vertex; - m_colocalVertexCount++; - } - } - xaPrint("--- %d vertex positions.\n", m_colocalVertexCount); + XA_DEBUG_ASSERT(isFinite(pos)); + m_positions.push_back(pos); + if (m_flags & MeshFlags::HasNormals) + m_normals.push_back(normal); + m_texcoords.push_back(texcoord); } - Face *addFace() + struct AddFaceResult { - Face *f = new Face(m_faceArray.size()); - m_faceArray.push_back(f); - return f; - } + enum Enum + { + OK, + DuplicateEdge = 1 + }; + }; - Face *addFace(uint32_t v0, uint32_t v1, uint32_t v2) + AddFaceResult::Enum addFace(uint32_t v0, uint32_t v1, uint32_t v2, bool ignore = false, bool hashEdge = true) { uint32_t indexArray[3]; indexArray[0] = v0; indexArray[1] = v1; indexArray[2] = v2; - return addFace(indexArray, 3, 0, 3); - } - - Face *addFace(uint32_t v0, uint32_t v1, uint32_t v2, uint32_t v3) - { - uint32_t indexArray[4]; - indexArray[0] = v0; - indexArray[1] = v1; - indexArray[2] = v2; - indexArray[3] = v3; - return addFace(indexArray, 4, 0, 4); + return addFace(indexArray, ignore, hashEdge); } - Face *addFace(const std::vector<uint32_t> &indexArray) + AddFaceResult::Enum addFace(const uint32_t *indices, bool ignore = false, bool hashEdge = true) { - return addFace(indexArray, 0, indexArray.size()); + AddFaceResult::Enum result = AddFaceResult::OK; + if (m_flags & MeshFlags::HasFaceGroups) + m_faceGroups.push_back(UINT32_MAX); + if (m_flags & MeshFlags::HasIgnoredFaces) + m_faceIgnore.push_back(ignore); + const uint32_t firstIndex = m_indices.size(); + for (uint32_t i = 0; i < 3; i++) + m_indices.push_back(indices[i]); + if (hashEdge) { + for (uint32_t i = 0; i < 3; i++) { + const uint32_t vertex0 = m_indices[firstIndex + i]; + const uint32_t vertex1 = m_indices[firstIndex + (i + 1) % 3]; + const EdgeKey key(vertex0, vertex1); + if (m_edgeMap.get(key) != UINT32_MAX) + result = AddFaceResult::DuplicateEdge; + m_edgeMap.add(key, firstIndex + i); + } + } + return result; } - Face *addFace(const std::vector<uint32_t> &indexArray, uint32_t first, uint32_t num) + void createColocals() { - return addFace(indexArray.data(), (uint32_t)indexArray.size(), first, num); + const uint32_t vertexCount = m_positions.size(); + Array<AABB> aabbs; + aabbs.resize(vertexCount); + for (uint32_t i = 0; i < m_positions.size(); i++) + aabbs[i] = AABB(m_positions[i], m_epsilon); + BVH bvh(aabbs); + Array<uint32_t> colocals; + Array<uint32_t> potential; + m_colocalVertexCount = 0; + m_nextColocalVertex.resize(vertexCount, UINT32_MAX); + for (uint32_t i = 0; i < vertexCount; i++) { + if (m_nextColocalVertex[i] != UINT32_MAX) + continue; // Already linked. + // Find other vertices colocal to this one. + colocals.clear(); + colocals.push_back(i); // Always add this vertex. + bvh.query(AABB(m_positions[i], m_epsilon), potential); + for (uint32_t j = 0; j < potential.size(); j++) { + const uint32_t otherVertex = potential[j]; + if (otherVertex != i && equal(m_positions[i], m_positions[otherVertex], m_epsilon) && m_nextColocalVertex[otherVertex] == UINT32_MAX) + colocals.push_back(otherVertex); + } + if (colocals.size() == 1) { + // No colocals for this vertex. + m_nextColocalVertex[i] = i; + continue; + } + m_colocalVertexCount += colocals.size(); + // Link in ascending order. + insertionSort(colocals.data(), colocals.size()); + for (uint32_t j = 0; j < colocals.size(); j++) + m_nextColocalVertex[colocals[j]] = colocals[(j + 1) % colocals.size()]; + XA_DEBUG_ASSERT(m_nextColocalVertex[i] != UINT32_MAX); + } } - Face *addFace(const uint32_t *indexArray, uint32_t indexCount, uint32_t first, uint32_t num) + // Check if the face duplicates any edges of any face already in the group. + bool faceDuplicatesGroupEdge(uint32_t group, uint32_t face) const { - xaDebugAssert(first < indexCount); - xaDebugAssert(num <= indexCount - first); - xaDebugAssert(num > 2); - if (!canAddFace(indexArray, first, num)) { - return NULL; - } - Face *f = new Face(m_faceArray.size()); - Edge *firstEdge = NULL; - Edge *last = NULL; - Edge *current = NULL; - for (uint32_t i = 0; i < num - 1; i++) { - current = addEdge(indexArray[first + i], indexArray[first + i + 1]); - xaAssert(current != NULL && current->face == NULL); - current->face = f; - if (last != NULL) last->setNext(current); - else firstEdge = current; - last = current; + for (FaceEdgeIterator edgeIt(this, face); !edgeIt.isDone(); edgeIt.advance()) { + for (ColocalEdgeIterator colocalEdgeIt(this, edgeIt.vertex0(), edgeIt.vertex1()); !colocalEdgeIt.isDone(); colocalEdgeIt.advance()) { + if (m_faceGroups[meshEdgeFace(colocalEdgeIt.edge())] == group) + return true; + } } - current = addEdge(indexArray[first + num - 1], indexArray[first]); - xaAssert(current != NULL && current->face == NULL); - current->face = f; - last->setNext(current); - current->setNext(firstEdge); - f->edge = firstEdge; - m_faceArray.push_back(f); - return f; + return false; } - // -- GODOT start -- - Face *addUniqueFace(uint32_t v0, uint32_t v1, uint32_t v2) { - - int base_vertex = m_vertexArray.size(); - - uint32_t ids[3] = { v0, v1, v2 }; - - Vector3 base[3] = { - m_vertexArray[v0]->pos, - m_vertexArray[v1]->pos, - m_vertexArray[v2]->pos, - }; - - //make sure its not a degenerate - bool degenerate = distanceSquared(base[0], base[1]) < NV_EPSILON || distanceSquared(base[0], base[2]) < NV_EPSILON || distanceSquared(base[1], base[2]) < NV_EPSILON; - xaDebugAssert(!degenerate); - - float min_x = 0; - - for (int i = 0; i < 3; i++) { - if (i == 0 || m_vertexArray[v0]->pos.x < min_x) { - min_x = m_vertexArray[v0]->pos.x; + // Check if the face mirrors any face already in the group. + // i.e. don't want two-sided faces in the same group. + // A face mirrors another face if all edges match with opposite winding. + bool faceMirrorsGroupFace(uint32_t group, uint32_t face) const + { + FaceEdgeIterator edgeIt(this, face); + for (ColocalEdgeIterator colocalEdgeIt(this, edgeIt.vertex1(), edgeIt.vertex0()); !colocalEdgeIt.isDone(); colocalEdgeIt.advance()) { + const uint32_t candidateFace = meshEdgeFace(colocalEdgeIt.edge()); + if (m_faceGroups[candidateFace] == group) { + // Found a match for mirrored first edge, try the other edges. + bool match = false; + for (; !edgeIt.isDone(); edgeIt.advance()) { + match = false; + for (ColocalEdgeIterator colocalEdgeIt2(this, edgeIt.vertex1(), edgeIt.vertex0()); !colocalEdgeIt2.isDone(); colocalEdgeIt2.advance()) { + if (meshEdgeFace(colocalEdgeIt2.edge()) == candidateFace) { + match = true; + break; + } + } + if (!match) + break; + } + if (match) + return true; // All edges are mirrored in this face. + // Try the next face. + edgeIt = FaceEdgeIterator(this, candidateFace); } } + return false; + } - float max_x = 0; - - for (int j = 0; j < m_vertexArray.size(); j++) { - if (j == 0 || m_vertexArray[j]->pos.x > max_x) { //vertex already exists - max_x = m_vertexArray[j]->pos.x; + void createFaceGroups() + { + uint32_t group = 0; + Array<uint32_t> growFaces; + for (;;) { + // Find an unassigned face. + uint32_t face = UINT32_MAX; + for (uint32_t f = 0; f < faceCount(); f++) { + if (m_faceGroups[f] == UINT32_MAX && !isFaceIgnored(f)) { + face = f; + break; + } } + if (face == UINT32_MAX) + break; // All faces assigned to a group (except ignored faces). + m_faceGroups[face] = group; + growFaces.clear(); + growFaces.push_back(face); + // Find faces connected to the face and assign them to the same group as the face, unless they are already assigned to another group. + for (;;) { + if (growFaces.isEmpty()) + break; + const uint32_t f = growFaces.back(); + growFaces.pop_back(); + for (FaceEdgeIterator edgeIt(this, f); !edgeIt.isDone(); edgeIt.advance()) { + // Iterate opposite edges. There may be more than one - non-manifold geometry can have duplicate edges. + // Prioritize the one with exact vertex match, not just colocal. + // If *any* of the opposite edges are already assigned to this group, don't do anything. + bool alreadyAssignedToThisGroup = false; + uint32_t bestConnectedFace = UINT32_MAX; + for (ColocalEdgeIterator oppositeEdgeIt(this, edgeIt.vertex1(), edgeIt.vertex0()); !oppositeEdgeIt.isDone(); oppositeEdgeIt.advance()) { + const uint32_t oppositeEdge = oppositeEdgeIt.edge(); + const uint32_t oppositeFace = meshEdgeFace(oppositeEdge); + if (isFaceIgnored(oppositeFace)) + continue; // Don't add ignored faces to group. + if (m_faceGroups[oppositeFace] == group) { + alreadyAssignedToThisGroup = true; + break; + } + if (m_faceGroups[oppositeFace] != UINT32_MAX) + continue; // Connected face is already assigned to another group. + if (faceDuplicatesGroupEdge(group, oppositeFace)) + continue; // Don't want duplicate edges in a group. + if (faceMirrorsGroupFace(group, oppositeFace)) + continue; // Don't want two-sided faces in a group. + const uint32_t oppositeVertex0 = m_indices[meshEdgeIndex0(oppositeEdge)]; + const uint32_t oppositeVertex1 = m_indices[meshEdgeIndex1(oppositeEdge)]; + if (bestConnectedFace == UINT32_MAX || (oppositeVertex0 == edgeIt.vertex1() && oppositeVertex1 == edgeIt.vertex0())) + bestConnectedFace = oppositeFace; + } + if (!alreadyAssignedToThisGroup && bestConnectedFace != UINT32_MAX) { + m_faceGroups[bestConnectedFace] = group; + growFaces.push_back(bestConnectedFace); + } + } + } + group++; } - - //separate from everything else, in x axis - for (int i = 0; i < 3; i++) { - - base[i].x -= min_x; - base[i].x += max_x + 10.0; - } - - for (int i = 0; i < 3; i++) { - Vertex *v = new Vertex(m_vertexArray.size()); - v->pos = base[i]; - v->nor = m_vertexArray[ids[i]]->nor, - v->tex = m_vertexArray[ids[i]]->tex, - - v->original_id = ids[i]; - m_vertexArray.push_back(v); - } - - uint32_t indexArray[3]; - indexArray[0] = base_vertex + 0; - indexArray[1] = base_vertex + 1; - indexArray[2] = base_vertex + 2; - return addFace(indexArray, 3, 0, 3); } - // -- GODOT end -- - // These functions disconnect the given element from the mesh and delete it. - - // @@ We must always disconnect edge pairs simultaneously. - void disconnect(Edge *edge) + void createBoundaries() { - xaDebugAssert(edge != NULL); - // Remove from edge list. - if ((edge->id & 1) == 0) { - xaDebugAssert(m_edgeArray[edge->id / 2] == edge); - m_edgeArray[edge->id / 2] = NULL; - } - // Remove edge from map. @@ Store map key inside edge? - xaDebugAssert(edge->from() != NULL && edge->to() != NULL); - size_t removed = m_edgeMap.erase(Key(edge->from()->id, edge->to()->id)); - xaDebugAssert(removed == 1); -#ifdef NDEBUG - removed = 0; // silence unused parameter warning + const uint32_t edgeCount = m_indices.size(); + const uint32_t vertexCount = m_positions.size(); + m_oppositeEdges.resize(edgeCount); + m_boundaryVertices.resize(vertexCount); + for (uint32_t i = 0; i < edgeCount; i++) + m_oppositeEdges[i] = UINT32_MAX; + for (uint32_t i = 0; i < vertexCount; i++) + m_boundaryVertices[i] = false; + const bool hasFaceGroups = m_flags & MeshFlags::HasFaceGroups; + for (uint32_t i = 0; i < faceCount(); i++) { + if (isFaceIgnored(i)) + continue; + for (uint32_t j = 0; j < 3; j++) { + const uint32_t vertex0 = m_indices[i * 3 + j]; + const uint32_t vertex1 = m_indices[i * 3 + (j + 1) % 3]; + // If there is an edge with opposite winding to this one, the edge isn't on a boundary. + const uint32_t oppositeEdge = findEdge(hasFaceGroups ? m_faceGroups[i] : UINT32_MAX, vertex1, vertex0); + if (oppositeEdge != UINT32_MAX) { +#if XA_DEBUG + if (hasFaceGroups) + XA_DEBUG_ASSERT(m_faceGroups[meshEdgeFace(oppositeEdge)] == m_faceGroups[i]); #endif - // Disconnect from vertex. - if (edge->vertex != NULL) { - if (edge->vertex->edge == edge) { - if (edge->prev && edge->prev->pair) { - edge->vertex->edge = edge->prev->pair; - } else if (edge->pair && edge->pair->next) { - edge->vertex->edge = edge->pair->next; + XA_DEBUG_ASSERT(!isFaceIgnored(meshEdgeFace(oppositeEdge))); + m_oppositeEdges[i * 3 + j] = oppositeEdge; } else { - edge->vertex->edge = NULL; - // @@ Remove disconnected vertex? + m_boundaryVertices[vertex0] = m_boundaryVertices[vertex1] = true; } } } - // Disconnect from face. - if (edge->face != NULL) { - if (edge->face->edge == edge) { - if (edge->next != NULL && edge->next != edge) { - edge->face->edge = edge->next; - } else if (edge->prev != NULL && edge->prev != edge) { - edge->face->edge = edge->prev; - } else { - edge->face->edge = NULL; - // @@ Remove disconnected face? + } + + void linkBoundaries() + { + const uint32_t edgeCount = m_indices.size(); + HashMap<uint32_t, uint32_t> vertexToEdgeMap(MemTag::Mesh, edgeCount); + for (uint32_t i = 0; i < edgeCount; i++) { + const uint32_t vertex0 = m_indices[meshEdgeIndex0(i)]; + const uint32_t vertex1 = m_indices[meshEdgeIndex1(i)]; + vertexToEdgeMap.add(vertex0, i); + vertexToEdgeMap.add(vertex1, i); + } + m_nextBoundaryEdges.resize(edgeCount); + for (uint32_t i = 0; i < edgeCount; i++) + m_nextBoundaryEdges[i] = UINT32_MAX; + uint32_t numBoundaryLoops = 0, numUnclosedBoundaries = 0; + BitArray linkedEdges(edgeCount); + linkedEdges.clearAll(); + for (;;) { + // Find the first boundary edge that hasn't been linked yet. + uint32_t firstEdge = UINT32_MAX; + for (uint32_t i = 0; i < edgeCount; i++) { + if (m_oppositeEdges[i] == UINT32_MAX && !linkedEdges.bitAt(i)) { + firstEdge = i; + break; } } - } - // Disconnect from previous. - if (edge->prev) { - if (edge->prev->next == edge) { - edge->prev->setNext(NULL); + if (firstEdge == UINT32_MAX) + break; + uint32_t currentEdge = firstEdge; + for (;;) { + // Find the next boundary edge. The first vertex will be the same as (or colocal to) the current edge second vertex. + const uint32_t startVertex = m_indices[meshEdgeIndex1(currentEdge)]; + uint32_t bestNextEdge = UINT32_MAX; + for (ColocalVertexIterator it(this, startVertex); !it.isDone(); it.advance()) { + uint32_t mapOtherEdgeIndex = vertexToEdgeMap.get(it.vertex()); + while (mapOtherEdgeIndex != UINT32_MAX) { + const uint32_t otherEdge = vertexToEdgeMap.value(mapOtherEdgeIndex); + if (m_oppositeEdges[otherEdge] != UINT32_MAX) + goto next; // Not a boundary edge. + if (linkedEdges.bitAt(otherEdge)) + goto next; // Already linked. + if (m_flags & MeshFlags::HasFaceGroups && m_faceGroups[meshEdgeFace(currentEdge)] != m_faceGroups[meshEdgeFace(otherEdge)]) + goto next; // Don't cross face groups. + if (isFaceIgnored(meshEdgeFace(otherEdge))) + goto next; // Face is ignored. + if (m_indices[meshEdgeIndex0(otherEdge)] != it.vertex()) + goto next; // Edge contains the vertex, but it's the wrong one. + // First edge (closing the boundary loop) has the highest priority. + // Non-colocal vertex has the next highest. + if (bestNextEdge != firstEdge && (bestNextEdge == UINT32_MAX || it.vertex() == startVertex)) + bestNextEdge = otherEdge; + next: + mapOtherEdgeIndex = vertexToEdgeMap.getNext(mapOtherEdgeIndex); + } + } + if (bestNextEdge == UINT32_MAX) { + numUnclosedBoundaries++; + if (currentEdge == firstEdge) + linkedEdges.setBitAt(firstEdge); // Only 1 edge in this boundary "loop". + break; // Can't find a next edge. + } + m_nextBoundaryEdges[currentEdge] = bestNextEdge; + linkedEdges.setBitAt(bestNextEdge); + currentEdge = bestNextEdge; + if (currentEdge == firstEdge) { + numBoundaryLoops++; + break; // Closed the boundary loop. + } } - //edge->setPrev(NULL); } - // Disconnect from next. - if (edge->next) { - if (edge->next->prev == edge) { - edge->next->setPrev(NULL); + // Find internal boundary loops and separate them. + // Detect by finding two edges in a boundary loop that have a colocal end vertex. + // Fix by swapping their next boundary edge. + // Need to start over after every fix since known boundary loops have changed. + Array<uint32_t> boundaryLoops; + fixInternalBoundary: + meshGetBoundaryLoops(*this, boundaryLoops); + for (uint32_t loop = 0; loop < boundaryLoops.size(); loop++) { + linkedEdges.clearAll(); + for (Mesh::BoundaryEdgeIterator it1(this, boundaryLoops[loop]); !it1.isDone(); it1.advance()) { + const uint32_t e1 = it1.edge(); + if (linkedEdges.bitAt(e1)) + continue; + for (Mesh::BoundaryEdgeIterator it2(this, boundaryLoops[loop]); !it2.isDone(); it2.advance()) { + const uint32_t e2 = it2.edge(); + if (e1 == e2 || !isBoundaryEdge(e2) || linkedEdges.bitAt(e2)) + continue; + if (!areColocal(m_indices[meshEdgeIndex1(e1)], m_indices[meshEdgeIndex1(e2)])) + continue; + swap(m_nextBoundaryEdges[e1], m_nextBoundaryEdges[e2]); + linkedEdges.setBitAt(e1); + linkedEdges.setBitAt(e2); + goto fixInternalBoundary; // start over + } } - //edge->setNext(NULL); } } - void remove(Edge *edge) - { - xaDebugAssert(edge != NULL); - disconnect(edge); - delete edge; + /// Find edge, test all colocals. + uint32_t findEdge(uint32_t faceGroup, uint32_t vertex0, uint32_t vertex1) const + { + uint32_t result = UINT32_MAX; + if (m_nextColocalVertex.isEmpty()) { + EdgeKey key(vertex0, vertex1); + uint32_t mapEdgeIndex = m_edgeMap.get(key); + while (mapEdgeIndex != UINT32_MAX) { + const uint32_t edge = m_edgeMap.value(mapEdgeIndex); + // Don't find edges of ignored faces. + if ((faceGroup == UINT32_MAX || m_faceGroups[meshEdgeFace(edge)] == faceGroup) && !isFaceIgnored(meshEdgeFace(edge))) { + //XA_DEBUG_ASSERT(m_id != UINT32_MAX || (m_id == UINT32_MAX && result == UINT32_MAX)); // duplicate edge - ignore on initial meshes + result = edge; +#if !XA_DEBUG + return result; +#endif + } + mapEdgeIndex = m_edgeMap.getNext(mapEdgeIndex); + } + } else { + for (ColocalVertexIterator it0(this, vertex0); !it0.isDone(); it0.advance()) { + for (ColocalVertexIterator it1(this, vertex1); !it1.isDone(); it1.advance()) { + EdgeKey key(it0.vertex(), it1.vertex()); + uint32_t mapEdgeIndex = m_edgeMap.get(key); + while (mapEdgeIndex != UINT32_MAX) { + const uint32_t edge = m_edgeMap.value(mapEdgeIndex); + // Don't find edges of ignored faces. + if ((faceGroup == UINT32_MAX || m_faceGroups[meshEdgeFace(edge)] == faceGroup) && !isFaceIgnored(meshEdgeFace(edge))) { + XA_DEBUG_ASSERT(m_id != UINT32_MAX || (m_id == UINT32_MAX && result == UINT32_MAX)); // duplicate edge - ignore on initial meshes + result = edge; +#if !XA_DEBUG + return result; +#endif + } + mapEdgeIndex = m_edgeMap.getNext(mapEdgeIndex); + } + } + } + } + return result; } - void remove(Vertex *vertex) +#if XA_DEBUG_EXPORT_OBJ + void writeObjVertices(FILE *file) const { - xaDebugAssert(vertex != NULL); - // Remove from vertex list. - m_vertexArray[vertex->id] = NULL; - // Disconnect from colocals. - vertex->unlinkColocal(); - // Disconnect from edges. - if (vertex->edge != NULL) { - // @@ Removing a connected vertex is asking for trouble... - if (vertex->edge->vertex == vertex) { - // @@ Connect edge to a colocal? - vertex->edge->vertex = NULL; - } - vertex->setEdge(NULL); + for (uint32_t i = 0; i < m_positions.size(); i++) + fprintf(file, "v %g %g %g\n", m_positions[i].x, m_positions[i].y, m_positions[i].z); + if (m_flags & MeshFlags::HasNormals) { + for (uint32_t i = 0; i < m_normals.size(); i++) + fprintf(file, "vn %g %g %g\n", m_normals[i].x, m_normals[i].y, m_normals[i].z); } - delete vertex; + for (uint32_t i = 0; i < m_texcoords.size(); i++) + fprintf(file, "vt %g %g\n", m_texcoords[i].x, m_texcoords[i].y); } - void remove(Face *face) + void writeObjFace(FILE *file, uint32_t face) const { - xaDebugAssert(face != NULL); - // Remove from face list. - m_faceArray[face->id] = NULL; - // Disconnect from edges. - if (face->edge != NULL) { - xaDebugAssert(face->edge->face == face); - face->edge->face = NULL; - face->edge = NULL; + fprintf(file, "f "); + for (uint32_t j = 0; j < 3; j++) { + const uint32_t index = m_indices[face * 3 + j] + 1; // 1-indexed + fprintf(file, "%d/%d/%d%c", index, index, index, j == 2 ? '\n' : ' '); } - delete face; } - // Triangulate in place. - void triangulate() + void writeObjBoundaryEges(FILE *file) const { - bool all_triangles = true; - const uint32_t faceCount = m_faceArray.size(); - for (uint32_t f = 0; f < faceCount; f++) { - Face *face = m_faceArray[f]; - if (face->edgeCount() != 3) { - all_triangles = false; - break; - } - } - if (all_triangles) { - return; - } - // Do not touch vertices, but rebuild edges and faces. - std::vector<Edge *> edgeArray; - std::vector<Face *> faceArray; - std::swap(edgeArray, m_edgeArray); - std::swap(faceArray, m_faceArray); - m_edgeMap.clear(); - for (uint32_t f = 0; f < faceCount; f++) { - Face *face = faceArray[f]; - // Trivial fan-like triangulation. - const uint32_t v0 = face->edge->vertex->id; - uint32_t v2, v1 = (uint32_t)-1; - for (Face::EdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - Edge *edge = it.current(); - v2 = edge->to()->id; - if (v2 == v0) break; - if (v1 != -1) addFace(v0, v1, v2); - v1 = v2; - } - } - xaDebugAssert(m_faceArray.size() > faceCount); // triangle count > face count - linkBoundary(); - for (size_t i = 0; i < edgeArray.size(); i++) - delete edgeArray[i]; - for (size_t i = 0; i < faceArray.size(); i++) - delete faceArray[i]; - } - - /// Link boundary edges once the mesh has been created. - void linkBoundary() - { - xaPrint("--- Linking boundaries:\n"); - int num = 0; - // Create boundary edges. - uint32_t edgeCount = this->edgeCount(); - for (uint32_t e = 0; e < edgeCount; e++) { - Edge *edge = edgeAt(e); - if (edge != NULL && edge->pair == NULL) { - Edge *pair = new Edge(edge->id + 1); - uint32_t i = edge->from()->id; - uint32_t j = edge->next->from()->id; - Key key(j, i); - xaAssert(m_edgeMap.find(key) == m_edgeMap.end()); - pair->vertex = m_vertexArray[j]; - m_edgeMap[key] = pair; - edge->pair = pair; - pair->pair = edge; - num++; - } - } - // Link boundary edges. - for (uint32_t e = 0; e < edgeCount; e++) { - Edge *edge = edgeAt(e); - if (edge != NULL && edge->pair->face == NULL) { - linkBoundaryEdge(edge->pair); + if (m_oppositeEdges.isEmpty()) + return; // Boundaries haven't been created. + fprintf(file, "o boundary_edges\n"); + for (uint32_t i = 0; i < edgeCount(); i++) { + if (m_oppositeEdges[i] != UINT32_MAX) + continue; + fprintf(file, "l %d %d\n", m_indices[meshEdgeIndex0(i)] + 1, m_indices[meshEdgeIndex1(i)] + 1); // 1-indexed + } + } + + void writeObjLinkedBoundaries(FILE *file) const + { + if (m_oppositeEdges.isEmpty() || m_nextBoundaryEdges.isEmpty()) + return; // Boundaries haven't been created and/or linked. + Array<uint32_t> boundaryLoops; + meshGetBoundaryLoops(*this, boundaryLoops); + for (uint32_t i = 0; i < boundaryLoops.size(); i++) { + uint32_t edge = boundaryLoops[i]; + fprintf(file, "o boundary_%04d\n", i); + fprintf(file, "l"); + for (;;) { + const uint32_t vertex0 = m_indices[meshEdgeIndex0(edge)]; + const uint32_t vertex1 = m_indices[meshEdgeIndex1(edge)]; + fprintf(file, " %d", vertex0 + 1); // 1-indexed + edge = m_nextBoundaryEdges[edge]; + if (edge == boundaryLoops[i] || edge == UINT32_MAX) { + fprintf(file, " %d\n", vertex1 + 1); // 1-indexed + break; + } } } - xaPrint("--- %d boundary edges.\n", num); } - /* - Fixing T-junctions. + void writeObjFile(const char *filename) const + { + FILE *file; + XA_FOPEN(file, filename, "w"); + if (!file) + return; + writeObjVertices(file); + fprintf(file, "s off\n"); + fprintf(file, "o object\n"); + for (uint32_t i = 0; i < faceCount(); i++) + writeObjFace(file, i); + writeObjBoundaryEges(file); + writeObjLinkedBoundaries(file); + fclose(file); + } +#endif - - Find T-junctions. Find vertices that are on an edge. - - This test is approximate. - - Insert edges on a spatial index to speedup queries. - - Consider only open edges, that is edges that have no pairs. - - Consider only vertices on boundaries. - - Close T-junction. - - Split edge. + float computeSurfaceArea() const + { + float area = 0; + for (uint32_t f = 0; f < faceCount(); f++) + area += faceArea(f); + XA_DEBUG_ASSERT(area >= 0); + return area; + } - */ - bool splitBoundaryEdges() // Returns true if any split was made. - { - std::vector<Vertex *> boundaryVertices; - for (uint32_t i = 0; i < m_vertexArray.size(); i++) { - Vertex *v = m_vertexArray[i]; - if (v->isBoundary()) { - boundaryVertices.push_back(v); - } - } - xaPrint("Fixing T-junctions:\n"); - int splitCount = 0; - for (uint32_t v = 0; v < boundaryVertices.size(); v++) { - Vertex *vertex = boundaryVertices[v]; - Vector3 x0 = vertex->pos; - // Find edges that this vertex overlaps with. - for (uint32_t e = 0; e < m_edgeArray.size(); e++) { - Edge *edge = m_edgeArray[e]; - if (edge != NULL && edge->isBoundary()) { - if (edge->from() == vertex || edge->to() == vertex) { - continue; - } - Vector3 x1 = edge->from()->pos; - Vector3 x2 = edge->to()->pos; - Vector3 v01 = x0 - x1; - Vector3 v21 = x2 - x1; - float l = length(v21); - float d = length(cross(v01, v21)) / l; - if (isZero(d)) { - float t = dot(v01, v21) / (l * l); - if (t > 0.0f + NV_EPSILON && t < 1.0f - NV_EPSILON) { - xaDebugAssert(equal(lerp(x1, x2, t), x0)); - Vertex *splitVertex = splitBoundaryEdge(edge, t, x0); - vertex->linkColocal(splitVertex); // @@ Should we do this here? - splitCount++; - } - } - } - } - } - xaPrint(" - %d edges split.\n", splitCount); - xaDebugAssert(isValid()); - return splitCount != 0; + float computeParametricArea() const + { + float area = 0; + for (uint32_t f = 0; f < faceCount(); f++) + area += faceParametricArea(f); + return fabsf(area); // May be negative, depends on texcoord winding. } - // Vertices - uint32_t vertexCount() const + float faceArea(uint32_t face) const { - return m_vertexArray.size(); + const Vector3 &p0 = m_positions[m_indices[face * 3 + 0]]; + const Vector3 &p1 = m_positions[m_indices[face * 3 + 1]]; + const Vector3 &p2 = m_positions[m_indices[face * 3 + 2]]; + return length(cross(p1 - p0, p2 - p0)) * 0.5f; } - const Vertex *vertexAt(int i) const + + Vector3 faceCentroid(uint32_t face) const { - return m_vertexArray[i]; + Vector3 sum(0.0f); + for (uint32_t i = 0; i < 3; i++) + sum += m_positions[m_indices[face * 3 + i]]; + return sum / 3.0f; } - Vertex *vertexAt(int i) + + Vector3 calculateFaceNormal(uint32_t face) const { - return m_vertexArray[i]; + return normalizeSafe(triangleNormalAreaScaled(face), Vector3(0, 0, 1), 0.0f); } - uint32_t colocalVertexCount() const + float faceParametricArea(uint32_t face) const { - return m_colocalVertexCount; + const Vector2 &t0 = m_texcoords[m_indices[face * 3 + 0]]; + const Vector2 &t1 = m_texcoords[m_indices[face * 3 + 1]]; + const Vector2 &t2 = m_texcoords[m_indices[face * 3 + 2]]; + return triangleArea(t0, t1, t2) * 0.5f; + } + + // Average of the edge midpoints weighted by the edge length. + // I want a point inside the triangle, but closer to the cirumcenter. + Vector3 triangleCenter(uint32_t face) const + { + const Vector3 &p0 = m_positions[m_indices[face * 3 + 0]]; + const Vector3 &p1 = m_positions[m_indices[face * 3 + 1]]; + const Vector3 &p2 = m_positions[m_indices[face * 3 + 2]]; + const float l0 = length(p1 - p0); + const float l1 = length(p2 - p1); + const float l2 = length(p0 - p2); + const Vector3 m0 = (p0 + p1) * l0 / (l0 + l1 + l2); + const Vector3 m1 = (p1 + p2) * l1 / (l0 + l1 + l2); + const Vector3 m2 = (p2 + p0) * l2 / (l0 + l1 + l2); + return m0 + m1 + m2; } - // Faces - uint32_t faceCount() const + // Unnormalized face normal assuming it's a triangle. + Vector3 triangleNormal(uint32_t face) const { - return m_faceArray.size(); + return normalizeSafe(triangleNormalAreaScaled(face), Vector3(0), 0.0f); } - const Face *faceAt(int i) const + + Vector3 triangleNormalAreaScaled(uint32_t face) const { - return m_faceArray[i]; + const Vector3 &p0 = m_positions[m_indices[face * 3 + 0]]; + const Vector3 &p1 = m_positions[m_indices[face * 3 + 1]]; + const Vector3 &p2 = m_positions[m_indices[face * 3 + 2]]; + const Vector3 e0 = p2 - p0; + const Vector3 e1 = p1 - p0; + return cross(e0, e1); } - Face *faceAt(int i) + + // @@ This is not exactly accurate, we should compare the texture coordinates... + bool isSeam(uint32_t edge) const { - return m_faceArray[i]; + const uint32_t oppositeEdge = m_oppositeEdges[edge]; + if (oppositeEdge == UINT32_MAX) + return false; // boundary edge + const uint32_t e0 = meshEdgeIndex0(edge); + const uint32_t e1 = meshEdgeIndex1(edge); + const uint32_t oe0 = meshEdgeIndex0(oppositeEdge); + const uint32_t oe1 = meshEdgeIndex1(oppositeEdge); + return m_indices[e0] != m_indices[oe1] || m_indices[e1] != m_indices[oe0]; } - // Edges - uint32_t edgeCount() const + bool isTextureSeam(uint32_t edge) const { - return m_edgeArray.size(); + const uint32_t oppositeEdge = m_oppositeEdges[edge]; + if (oppositeEdge == UINT32_MAX) + return false; // boundary edge + const uint32_t e0 = meshEdgeIndex0(edge); + const uint32_t e1 = meshEdgeIndex1(edge); + const uint32_t oe0 = meshEdgeIndex0(oppositeEdge); + const uint32_t oe1 = meshEdgeIndex1(oppositeEdge); + return m_texcoords[m_indices[e0]] != m_texcoords[m_indices[oe1]] || m_texcoords[m_indices[e1]] != m_texcoords[m_indices[oe0]]; } - const Edge *edgeAt(int i) const + + uint32_t firstColocal(uint32_t vertex) const { - return m_edgeArray[i]; + for (ColocalVertexIterator it(this, vertex); !it.isDone(); it.advance()) { + if (it.vertex() < vertex) + vertex = it.vertex(); + } + return vertex; } - Edge *edgeAt(int i) + + bool areColocal(uint32_t vertex0, uint32_t vertex1) const { - return m_edgeArray[i]; + if (vertex0 == vertex1) + return true; + if (m_nextColocalVertex.isEmpty()) + return false; + for (ColocalVertexIterator it(this, vertex0); !it.isDone(); it.advance()) { + if (it.vertex() == vertex1) + return true; + } + return false; } - class ConstVertexIterator; + float epsilon() const { return m_epsilon; } + uint32_t edgeCount() const { return m_indices.size(); } + uint32_t oppositeEdge(uint32_t edge) const { return m_oppositeEdges[edge]; } + bool isBoundaryEdge(uint32_t edge) const { return m_oppositeEdges[edge] == UINT32_MAX; } + bool isBoundaryVertex(uint32_t vertex) const { return m_boundaryVertices[vertex]; } + uint32_t colocalVertexCount() const { return m_colocalVertexCount; } + uint32_t vertexCount() const { return m_positions.size(); } + uint32_t vertexAt(uint32_t i) const { return m_indices[i]; } + const Vector3 &position(uint32_t vertex) const { return m_positions[vertex]; } + const Vector3 &normal(uint32_t vertex) const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasNormals); return m_normals[vertex]; } + const Vector2 &texcoord(uint32_t vertex) const { return m_texcoords[vertex]; } + Vector2 &texcoord(uint32_t vertex) { return m_texcoords[vertex]; } + Vector2 *texcoords() { return m_texcoords.data(); } + uint32_t faceCount() const { return m_indices.size() / 3; } + uint32_t faceGroupCount() const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasFaceGroups); return m_faceGroups.size(); } + uint32_t faceGroupAt(uint32_t face) const { XA_DEBUG_ASSERT(m_flags & MeshFlags::HasFaceGroups); return m_faceGroups[face]; } + const uint32_t *indices() const { return m_indices.data(); } + uint32_t indexCount() const { return m_indices.size(); } + +private: + bool isFaceIgnored(uint32_t face) const { return (m_flags & MeshFlags::HasIgnoredFaces) && m_faceIgnore[face]; } + + float m_epsilon; + uint32_t m_flags; + uint32_t m_id; + Array<bool> m_faceIgnore; + Array<uint32_t> m_faceGroups; + Array<uint32_t> m_indices; + Array<Vector3> m_positions; + Array<Vector3> m_normals; + Array<Vector2> m_texcoords; + + // Populated by createColocals + uint32_t m_colocalVertexCount; + Array<uint32_t> m_nextColocalVertex; // In: vertex index. Out: the vertex index of the next colocal position. + + // Populated by createBoundaries + Array<bool> m_boundaryVertices; + Array<uint32_t> m_oppositeEdges; // In: edge index. Out: the index of the opposite edge (i.e. wound the opposite direction). UINT32_MAX if the input edge is a boundary edge. + + // Populated by linkBoundaries + Array<uint32_t> m_nextBoundaryEdges; // The index of the next boundary edge. UINT32_MAX if the edge is not a boundary edge. - class VertexIterator + struct EdgeKey { - friend class ConstVertexIterator; - public: - VertexIterator(Mesh *mesh) : m_mesh(mesh), m_current(0) { } + EdgeKey() {} + EdgeKey(const EdgeKey &k) : v0(k.v0), v1(k.v1) {} + EdgeKey(uint32_t v0, uint32_t v1) : v0(v0), v1(v1) {} - virtual void advance() - { - m_current++; - } - virtual bool isDone() const + void operator=(const EdgeKey &k) { - return m_current == m_mesh->vertexCount(); + v0 = k.v0; + v1 = k.v1; } - virtual Vertex *current() const + bool operator==(const EdgeKey &k) const { - return m_mesh->vertexAt(m_current); + return v0 == k.v0 && v1 == k.v1; } - private: - halfedge::Mesh *m_mesh; - uint32_t m_current; + uint32_t v0; + uint32_t v1; }; - VertexIterator vertices() - { - return VertexIterator(this); - } - class ConstVertexIterator + HashMap<EdgeKey, uint32_t> m_edgeMap; + +public: + class BoundaryEdgeIterator { public: - ConstVertexIterator(const Mesh *mesh) : m_mesh(mesh), m_current(0) { } - ConstVertexIterator(class VertexIterator &it) : m_mesh(it.m_mesh), m_current(it.m_current) { } + BoundaryEdgeIterator(const Mesh *mesh, uint32_t edge) : m_mesh(mesh), m_first(UINT32_MAX), m_current(edge) {} - virtual void advance() + void advance() { - m_current++; + if (m_first == UINT32_MAX) + m_first = m_current; + m_current = m_mesh->m_nextBoundaryEdges[m_current]; } - virtual bool isDone() const + + bool isDone() const { - return m_current == m_mesh->vertexCount(); + return m_first == m_current || m_current == UINT32_MAX; } - virtual const Vertex *current() const + + uint32_t edge() const { - return m_mesh->vertexAt(m_current); + return m_current; + } + + uint32_t nextEdge() const + { + return m_mesh->m_nextBoundaryEdges[m_current]; } private: - const halfedge::Mesh *m_mesh; + const Mesh *m_mesh; + uint32_t m_first; uint32_t m_current; }; - ConstVertexIterator vertices() const - { - return ConstVertexIterator(this); - } - - class ConstFaceIterator; - class FaceIterator + class ColocalVertexIterator { - friend class ConstFaceIterator; public: - FaceIterator(Mesh *mesh) : m_mesh(mesh), m_current(0) { } + ColocalVertexIterator(const Mesh *mesh, uint32_t v) : m_mesh(mesh), m_first(UINT32_MAX), m_current(v) {} + + void advance() + { + if (m_first == UINT32_MAX) + m_first = m_current; + if (!m_mesh->m_nextColocalVertex.isEmpty()) + m_current = m_mesh->m_nextColocalVertex[m_current]; + } - virtual void advance() + bool isDone() const { - m_current++; + return m_first == m_current; } - virtual bool isDone() const + + uint32_t vertex() const { - return m_current == m_mesh->faceCount(); + return m_current; } - virtual Face *current() const + + const Vector3 *pos() const { - return m_mesh->faceAt(m_current); + return &m_mesh->m_positions[m_current]; } private: - halfedge::Mesh *m_mesh; + const Mesh *m_mesh; + uint32_t m_first; uint32_t m_current; }; - FaceIterator faces() - { - return FaceIterator(this); - } - class ConstFaceIterator + class ColocalEdgeIterator { public: - ConstFaceIterator(const Mesh *mesh) : m_mesh(mesh), m_current(0) { } - ConstFaceIterator(const FaceIterator &it) : m_mesh(it.m_mesh), m_current(it.m_current) { } + ColocalEdgeIterator(const Mesh *mesh, uint32_t vertex0, uint32_t vertex1) : m_mesh(mesh), m_vertex0It(mesh, vertex0), m_vertex1It(mesh, vertex1), m_vertex1(vertex1) + { + resetElement(); + } - virtual void advance() + void advance() { - m_current++; + advanceElement(); } - virtual bool isDone() const + + bool isDone() const { - return m_current == m_mesh->faceCount(); + return m_vertex0It.isDone() && m_vertex1It.isDone() && m_mapEdgeIndex == UINT32_MAX; } - virtual const Face *current() const + + uint32_t edge() const { - return m_mesh->faceAt(m_current); + return m_mesh->m_edgeMap.value(m_mapEdgeIndex); } private: - const halfedge::Mesh *m_mesh; - uint32_t m_current; - }; - ConstFaceIterator faces() const - { - return ConstFaceIterator(this); - } - - class ConstEdgeIterator; + void resetElement() + { + m_mapEdgeIndex = m_mesh->m_edgeMap.get(Mesh::EdgeKey(m_vertex0It.vertex(), m_vertex1It.vertex())); + while (m_mapEdgeIndex != UINT32_MAX) { + if (!isIgnoredFace()) + break; + m_mapEdgeIndex = m_mesh->m_edgeMap.getNext(m_mapEdgeIndex); + } + if (m_mapEdgeIndex == UINT32_MAX) + advanceVertex1(); + } - class EdgeIterator - { - friend class ConstEdgeIterator; - public: - EdgeIterator(Mesh *mesh) : m_mesh(mesh), m_current(0) { } + void advanceElement() + { + for (;;) { + m_mapEdgeIndex = m_mesh->m_edgeMap.getNext(m_mapEdgeIndex); + if (m_mapEdgeIndex == UINT32_MAX) + break; + if (!isIgnoredFace()) + break; + } + if (m_mapEdgeIndex == UINT32_MAX) + advanceVertex1(); + } - virtual void advance() + void advanceVertex0() { - m_current++; + m_vertex0It.advance(); + if (m_vertex0It.isDone()) + return; + m_vertex1It = ColocalVertexIterator(m_mesh, m_vertex1); + resetElement(); } - virtual bool isDone() const + + void advanceVertex1() { - return m_current == m_mesh->edgeCount(); + m_vertex1It.advance(); + if (m_vertex1It.isDone()) + advanceVertex0(); + else + resetElement(); } - virtual Edge *current() const + + bool isIgnoredFace() const { - return m_mesh->edgeAt(m_current); + const uint32_t edge = m_mesh->m_edgeMap.value(m_mapEdgeIndex); + return m_mesh->m_faceIgnore[meshEdgeFace(edge)]; } - private: - halfedge::Mesh *m_mesh; - uint32_t m_current; + const Mesh *m_mesh; + ColocalVertexIterator m_vertex0It, m_vertex1It; + const uint32_t m_vertex1; + uint32_t m_mapEdgeIndex; }; - EdgeIterator edges() - { - return EdgeIterator(this); - } - class ConstEdgeIterator + class FaceEdgeIterator { public: - ConstEdgeIterator(const Mesh *mesh) : m_mesh(mesh), m_current(0) { } - ConstEdgeIterator(const EdgeIterator &it) : m_mesh(it.m_mesh), m_current(it.m_current) { } + FaceEdgeIterator (const Mesh *mesh, uint32_t face) : m_mesh(mesh), m_face(face), m_relativeEdge(0) + { + m_edge = m_face * 3; + } + + void advance() + { + if (m_relativeEdge < 3) { + m_edge++; + m_relativeEdge++; + } + } - virtual void advance() + bool isDone() const + { + return m_relativeEdge == 3; + } + + bool isBoundary() const { return m_mesh->m_oppositeEdges[m_edge] == UINT32_MAX; } + bool isSeam() const { return m_mesh->isSeam(m_edge); } + bool isTextureSeam() const { return m_mesh->isTextureSeam(m_edge); } + uint32_t edge() const { return m_edge; } + uint32_t relativeEdge() const { return m_relativeEdge; } + uint32_t face() const { return m_face; } + uint32_t oppositeEdge() const { return m_mesh->m_oppositeEdges[m_edge]; } + + uint32_t oppositeFace() const { - m_current++; + const uint32_t oedge = m_mesh->m_oppositeEdges[m_edge]; + if (oedge == UINT32_MAX) + return UINT32_MAX; + return meshEdgeFace(oedge); } - virtual bool isDone() const + + uint32_t vertex0() const { - return m_current == m_mesh->edgeCount(); + return m_mesh->m_indices[m_face * 3 + m_relativeEdge]; } - virtual const Edge *current() const + + uint32_t vertex1() const { - return m_mesh->edgeAt(m_current); + return m_mesh->m_indices[m_face * 3 + (m_relativeEdge + 1) % 3]; } + const Vector3 &position0() const { return m_mesh->m_positions[vertex0()]; } + const Vector3 &position1() const { return m_mesh->m_positions[vertex1()]; } + const Vector3 &normal0() const { return m_mesh->m_normals[vertex0()]; } + const Vector3 &normal1() const { return m_mesh->m_normals[vertex1()]; } + const Vector2 &texcoord0() const { return m_mesh->m_texcoords[vertex0()]; } + const Vector2 &texcoord1() const { return m_mesh->m_texcoords[vertex1()]; } + private: - const halfedge::Mesh *m_mesh; - uint32_t m_current; + const Mesh *m_mesh; + uint32_t m_face; + uint32_t m_edge; + uint32_t m_relativeEdge; }; - ConstEdgeIterator edges() const - { - return ConstEdgeIterator(this); - } - - // @@ Add half-edge iterator. +}; - bool isValid() const - { - // Make sure all edges are valid. - const uint32_t edgeCount = m_edgeArray.size(); - for (uint32_t e = 0; e < edgeCount; e++) { - Edge *edge = m_edgeArray[e]; - if (edge != NULL) { - if (edge->id != 2 * e) { - return false; +static bool meshCloseHole(Mesh *mesh, const Array<uint32_t> &holeVertices, const Vector3 &normal) +{ +#if XA_CLOSE_HOLES_CHECK_EDGE_INTERSECTION + const uint32_t faceCount = mesh->faceCount(); +#endif + const bool compareNormal = equal(normal, Vector3(0.0f), FLT_EPSILON); + uint32_t frontCount = holeVertices.size(); + Array<uint32_t> frontVertices; + Array<Vector3> frontPoints; + Array<float> frontAngles; + frontVertices.resize(frontCount); + frontPoints.resize(frontCount); + for (uint32_t i = 0; i < frontCount; i++) { + frontVertices[i] = holeVertices[i]; + frontPoints[i] = mesh->position(frontVertices[i]); + } + while (frontCount >= 3) { + frontAngles.resize(frontCount); + float smallestAngle = kPi2, smallestAngleIgnoringNormal = kPi2; + uint32_t smallestAngleIndex = UINT32_MAX, smallestAngleIndexIgnoringNormal = UINT32_MAX; + for (uint32_t i = 0; i < frontCount; i++) { + const uint32_t i1 = i == 0 ? frontCount - 1 : i - 1; + const uint32_t i2 = i; + const uint32_t i3 = (i + 1) % frontCount; + const Vector3 edge1 = frontPoints[i1] - frontPoints[i2]; + const Vector3 edge2 = frontPoints[i3] - frontPoints[i2]; + frontAngles[i] = acosf(dot(edge1, edge2) / (length(edge1) * length(edge2))); + if (frontAngles[i] >= smallestAngle || isNan(frontAngles[i])) + continue; + // Don't duplicate edges. + if (mesh->findEdge(UINT32_MAX, frontVertices[i1], frontVertices[i2]) != UINT32_MAX) + continue; + if (mesh->findEdge(UINT32_MAX, frontVertices[i2], frontVertices[i3]) != UINT32_MAX) + continue; + if (mesh->findEdge(UINT32_MAX, frontVertices[i3], frontVertices[i1]) != UINT32_MAX) + continue; + /* + Make sure he new edge that would be formed by (i3, i1) doesn't intersect any vertices. This often happens when fixing t-junctions. + + i2 + * + / \ + / \ + i1 *--*--* i3 + \ | / + \|/ + * + */ + bool intersection = false; + for (uint32_t j = 0; j < frontCount; j++) { + if (j == i1 || j == i2 || j == i3) + continue; + if (lineIntersectsPoint(frontPoints[j], frontPoints[i3], frontPoints[i1], nullptr, mesh->epsilon())) { + intersection = true; + break; } - if (!edge->isValid()) { - return false; + } + if (intersection) + continue; + // Don't add the triangle if a boundary point lies on the same plane as the triangle, and is inside it. + intersection = false; + const Plane plane(frontPoints[i1], frontPoints[i2], frontPoints[i3]); + for (uint32_t j = 0; j < frontCount; j++) { + if (j == i1 || j == i2 || j == i3) + continue; + if (!isZero(plane.distance(frontPoints[j]), mesh->epsilon())) + continue; + if (pointInTriangle(frontPoints[j], frontPoints[i1], frontPoints[i2], frontPoints[i3])) { + intersection = true; + break; } - if (edge->pair->id != 2 * e + 1) { - return false; + } + if (intersection) + continue; +#if XA_CLOSE_HOLES_CHECK_EDGE_INTERSECTION + // Don't add the triangle if the new edge (i3, i1), intersects any other triangle that isn't part of the filled hole. + intersection = false; + const Vector3 newEdgeVector = frontPoints[i1] - frontPoints[i3]; + for (uint32_t f = 0; f < faceCount; f++) { + Vector3 tri[3]; + for (uint32_t j = 0; j < 3; j++) + tri[j] = mesh->position(mesh->vertexAt(f * 3 + j)); + float t; + if (rayIntersectsTriangle(frontPoints[i3], newEdgeVector, tri, &t)) { + intersection = true; + break; } - if (!edge->pair->isValid()) { - return false; + } + if (intersection) + continue; +#endif + // Skip backwards facing triangles. + if (compareNormal) { + if (frontAngles[i] < smallestAngleIgnoringNormal) { + smallestAngleIgnoringNormal = frontAngles[i]; + smallestAngleIndexIgnoringNormal = i; } + const Vector3 e0 = frontPoints[i3] - frontPoints[i1]; + const Vector3 e1 = frontPoints[i2] - frontPoints[i1]; + const Vector3 triNormal = normalizeSafe(cross(e0, e1), Vector3(0.0f), mesh->epsilon()); + if (dot(normal, triNormal) <= 0.0f) + continue; } + smallestAngle = smallestAngleIgnoringNormal = frontAngles[i]; + smallestAngleIndex = smallestAngleIndexIgnoringNormal = i; } - // @@ Make sure all faces are valid. - // @@ Make sure all vertices are valid. - return true; + // Closing holes failed if we don't have a smallest angle. + // Fallback to ignoring the backwards facing normal test if possible. + if (smallestAngleIndex == UINT32_MAX || smallestAngle <= 0.0f || smallestAngle >= kPi) { + if (smallestAngleIgnoringNormal == UINT32_MAX || smallestAngleIgnoringNormal <= 0.0f || smallestAngleIgnoringNormal >= kPi) + return false; + else + smallestAngleIndex = smallestAngleIndexIgnoringNormal; + } + const uint32_t i1 = smallestAngleIndex == 0 ? frontCount - 1 : smallestAngleIndex - 1; + const uint32_t i2 = smallestAngleIndex; + const uint32_t i3 = (smallestAngleIndex + 1) % frontCount; + const Mesh::AddFaceResult::Enum result = mesh->addFace(frontVertices[i1], frontVertices[i2], frontVertices[i3]); + XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK); // Shouldn't happen due to the findEdge calls above. + XA_UNUSED(result); + frontVertices.removeAt(i2); + frontPoints.removeAt(i2); + frontCount = frontVertices.size(); } + return true; +} - // Error status: - - struct ErrorCode - { - enum Enum - { - AlreadyAddedEdge, - DegenerateColocalEdge, - DegenerateEdge, - DuplicateEdge - }; - }; - - mutable ErrorCode::Enum errorCode; - mutable uint32_t errorIndex0; - mutable uint32_t errorIndex1; +static bool meshCloseHoles(Mesh *mesh, const Array<uint32_t> &boundaryLoops, const Vector3 &normal, Array<uint32_t> &holeFaceCounts) +{ + holeFaceCounts.clear(); + // Compute lengths. + const uint32_t boundaryCount = boundaryLoops.size(); + Array<float> boundaryLengths; + Array<uint32_t> boundaryEdgeCounts; + boundaryEdgeCounts.resize(boundaryCount); + for (uint32_t i = 0; i < boundaryCount; i++) { + float boundaryLength = 0.0f; + boundaryEdgeCounts[i] = 0; + for (Mesh::BoundaryEdgeIterator it(mesh, boundaryLoops[i]); !it.isDone(); it.advance()) { + const Vector3 &t0 = mesh->position(mesh->vertexAt(meshEdgeIndex0(it.edge()))); + const Vector3 &t1 = mesh->position(mesh->vertexAt(meshEdgeIndex1(it.edge()))); + boundaryLength += length(t1 - t0); + boundaryEdgeCounts[i]++; + } + boundaryLengths.push_back(boundaryLength); + } + // Find disk boundary. + uint32_t diskBoundary = 0; + float maxLength = boundaryLengths[0]; + for (uint32_t i = 1; i < boundaryCount; i++) { + if (boundaryLengths[i] > maxLength) { + maxLength = boundaryLengths[i]; + diskBoundary = i; + } + } + // Close holes. + Array<uint32_t> holeVertices; + Array<Vector3> holePoints; + bool result = true; + for (uint32_t i = 0; i < boundaryCount; i++) { + if (diskBoundary == i) + continue; // Skip disk boundary. + holeVertices.resize(boundaryEdgeCounts[i]); + holePoints.resize(boundaryEdgeCounts[i]); + // Winding is backwards for internal boundaries. + uint32_t e = 0; + for (Mesh::BoundaryEdgeIterator it(mesh, boundaryLoops[i]); !it.isDone(); it.advance()) { + const uint32_t vertex = mesh->vertexAt(meshEdgeIndex0(it.edge())); + holeVertices[boundaryEdgeCounts[i] - 1 - e] = vertex; + holePoints[boundaryEdgeCounts[i] - 1 - e] = mesh->position(vertex); + e++; + } + const uint32_t oldFaceCount = mesh->faceCount(); + if (!meshCloseHole(mesh, holeVertices, normal)) + result = false; // Return false if any hole failed to close, but keep trying to close other holes. + holeFaceCounts.push_back(mesh->faceCount() - oldFaceCount); + } + return result; +} -private: - // Return true if the face can be added to the manifold mesh. - bool canAddFace(const std::vector<uint32_t> &indexArray, uint32_t first, uint32_t num) const - { - return canAddFace(indexArray.data(), first, num); +static bool meshIsPlanar(const Mesh &mesh) +{ + const Vector3 p1 = mesh.position(mesh.vertexAt(0)); + const Vector3 p2 = mesh.position(mesh.vertexAt(1)); + const Vector3 p3 = mesh.position(mesh.vertexAt(2)); + const Plane plane(p1, p2, p3); + const uint32_t vertexCount = mesh.vertexCount(); + for (uint32_t v = 0; v < vertexCount; v++) { + const float d = plane.distance(mesh.position(v)); + if (!isZero(d, mesh.epsilon())) + return false; } + return true; +} - bool canAddFace(const uint32_t *indexArray, uint32_t first, uint32_t num) const - { - for (uint32_t j = num - 1, i = 0; i < num; j = i++) { - if (!canAddEdge(indexArray[first + j], indexArray[first + i])) { - errorIndex0 = indexArray[first + j]; - errorIndex1 = indexArray[first + i]; - return false; - } - } - // We also have to make sure the face does not have any duplicate edge! - for (uint32_t i = 0; i < num; i++) { - int i0 = indexArray[first + i + 0]; - int i1 = indexArray[first + (i + 1) % num]; - for (uint32_t j = i + 1; j < num; j++) { - int j0 = indexArray[first + j + 0]; - int j1 = indexArray[first + (j + 1) % num]; - if (i0 == j0 && i1 == j1) { - errorCode = ErrorCode::DuplicateEdge; - errorIndex0 = i0; - errorIndex1 = i1; - return false; - } - } - } - return true; - } +/* +Fixing T-junctions. - // Return true if the edge doesn't exist or doesn't have any adjacent face. - bool canAddEdge(uint32_t i, uint32_t j) const - { - if (i == j) { - // Skip degenerate edges. - errorCode = ErrorCode::DegenerateEdge; - return false; - } - // Same check, but taking into account colocal vertices. - const Vertex *v0 = vertexAt(i); - const Vertex *v1 = vertexAt(j); - for (Vertex::ConstVertexIterator it(v0->colocals()); !it.isDone(); it.advance()) { - if (it.current() == v1) { - // Skip degenerate edges. - errorCode = ErrorCode::DegenerateColocalEdge; - return false; - } - } - // Make sure edge has not been added yet. - Edge *edge = findEdge(i, j); - // We ignore edges that don't have an adjacent face yet, since this face could become the edge's face. - if (!(edge == NULL || edge->face == NULL)) { - errorCode = ErrorCode::AlreadyAddedEdge; - return false; - } - return true; - } +- Find T-junctions. Find vertices that are on an edge. +- This test is approximate. +- Insert edges on a spatial index to speedup queries. +- Consider only open edges, that is edges that have no pairs. +- Consider only vertices on boundaries. +- Close T-junction. +- Split edge. - Edge *addEdge(uint32_t i, uint32_t j) +*/ +struct SplitEdge +{ + uint32_t edge; + float t; + uint32_t vertex; + + bool operator<(const SplitEdge &other) const { - xaAssert(i != j); - Edge *edge = findEdge(i, j); - if (edge != NULL) { - // Edge may already exist, but its face must not be set. - xaDebugAssert(edge->face == NULL); - // Nothing else to do! - } else { - // Add new edge. - // Lookup pair. - Edge *pair = findEdge(j, i); - if (pair != NULL) { - // Create edge with same id. - edge = new Edge(pair->id + 1); - // Link edge pairs. - edge->pair = pair; - pair->pair = edge; - // @@ I'm not sure this is necessary! - pair->vertex->setEdge(pair); - } else { - // Create edge. - edge = new Edge(2 * m_edgeArray.size()); - // Add only unpaired edges. - m_edgeArray.push_back(edge); - } - edge->vertex = m_vertexArray[i]; - m_edgeMap[Key(i, j)] = edge; + if (edge < other.edge) + return true; + else if (edge == other.edge) { + if (t < other.t) + return true; } - // Face and Next are set by addFace. - return edge; + return false; } +}; - /// Find edge, test all colocals. - Edge *findEdge(uint32_t i, uint32_t j) const - { - Edge *edge = NULL; - const Vertex *v0 = vertexAt(i); - const Vertex *v1 = vertexAt(j); - // Test all colocal pairs. - for (Vertex::ConstVertexIterator it0(v0->colocals()); !it0.isDone(); it0.advance()) { - for (Vertex::ConstVertexIterator it1(v1->colocals()); !it1.isDone(); it1.advance()) { - Key key(it0.current()->id, it1.current()->id); - if (edge == NULL) { - auto edgeIt = m_edgeMap.find(key); - if (edgeIt != m_edgeMap.end()) - edge = (*edgeIt).second; - #if !defined(_DEBUG) - if (edge != NULL) return edge; - #endif - } else { - // Make sure that only one edge is found. - xaDebugAssert(m_edgeMap.find(key) == m_edgeMap.end()); +// Returns nullptr if there were no t-junctions to fix. +static Mesh *meshFixTJunctions(const Mesh &inputMesh, bool *duplicatedEdge, bool *failed, uint32_t *fixedTJunctionsCount) +{ + if (duplicatedEdge) + *duplicatedEdge = false; + if (failed) + *failed = false; + Array<SplitEdge> splitEdges; + const uint32_t vertexCount = inputMesh.vertexCount(); + const uint32_t edgeCount = inputMesh.edgeCount(); + for (uint32_t v = 0; v < vertexCount; v++) { + if (!inputMesh.isBoundaryVertex(v)) + continue; + // Find edges that this vertex overlaps with. + const Vector3 &pos = inputMesh.position(v); + for (uint32_t e = 0; e < edgeCount; e++) { + if (!inputMesh.isBoundaryEdge(e)) + continue; + const Vector3 &edgePos1 = inputMesh.position(inputMesh.vertexAt(meshEdgeIndex0(e))); + const Vector3 &edgePos2 = inputMesh.position(inputMesh.vertexAt(meshEdgeIndex1(e))); + float t; + if (!lineIntersectsPoint(pos, edgePos1, edgePos2, &t, inputMesh.epsilon())) + continue; + SplitEdge splitEdge; + splitEdge.edge = e; + splitEdge.t = t; + splitEdge.vertex = v; + splitEdges.push_back(splitEdge); + } + } + if (splitEdges.isEmpty()) + return nullptr; + const uint32_t faceCount = inputMesh.faceCount(); + Mesh *mesh = XA_NEW(MemTag::Mesh, Mesh, inputMesh.epsilon(), vertexCount + splitEdges.size(), faceCount); + for (uint32_t v = 0; v < vertexCount; v++) + mesh->addVertex(inputMesh.position(v)); + Array<uint32_t> indexArray; + indexArray.reserve(4); + Array<SplitEdge> faceSplitEdges; + faceSplitEdges.reserve(4); + for (uint32_t f = 0; f < faceCount; f++) { + // Find t-junctions in this face. + faceSplitEdges.clear(); + for (uint32_t i = 0; i < splitEdges.size(); i++) { + if (meshEdgeFace(splitEdges[i].edge) == f) + faceSplitEdges.push_back(splitEdges[i]); + } + if (!faceSplitEdges.isEmpty()) { + // Need to split edges in winding order when a single edge has multiple t-junctions. + insertionSort(faceSplitEdges.data(), faceSplitEdges.size()); + indexArray.clear(); + for (Mesh::FaceEdgeIterator it(&inputMesh, f); !it.isDone(); it.advance()) { + indexArray.push_back(it.vertex0()); + for (uint32_t se = 0; se < faceSplitEdges.size(); se++) { + const SplitEdge &splitEdge = faceSplitEdges[se]; + if (splitEdge.edge == it.edge()) + indexArray.push_back(splitEdge.vertex); } } + if (!meshCloseHole(mesh, indexArray, Vector3(0.0f))) { + if (failed) + *failed = true; + } + } else { + // No t-junctions in this face. Copy from input mesh. + if (mesh->addFace(&inputMesh.indices()[f * 3]) == Mesh::AddFaceResult::DuplicateEdge) { + if (duplicatedEdge) + *duplicatedEdge = true; + } } - return edge; - } - - /// Link this boundary edge. - void linkBoundaryEdge(Edge *edge) - { - xaAssert(edge->face == NULL); - // Make sure next pointer has not been set. @@ We want to be able to relink boundary edges after mesh changes. - Edge *next = edge; - while (next->pair->face != NULL) { - // Get pair prev - Edge *e = next->pair->next; - while (e->next != next->pair) { - e = e->next; - } - next = e; - } - edge->setNext(next->pair); - // Adjust vertex edge, so that it's the boundary edge. (required for isBoundary()) - if (edge->vertex->edge != edge) { - // Multiple boundaries in the same edge. - edge->vertex->edge = edge; - } - } - - Vertex *splitBoundaryEdge(Edge *edge, float t, const Vector3 &pos) - { - /* - We want to go from this configuration: - - + + - | ^ - edge |<->| pair - v | - + + - - To this one: - - + + - | ^ - e0 |<->| p0 - v | - vertex + + - | ^ - e1 |<->| p1 - v | - + + - - */ - Edge *pair = edge->pair; - // Make sure boundaries are linked. - xaDebugAssert(pair != NULL); - // Make sure edge is a boundary edge. - xaDebugAssert(pair->face == NULL); - // Add new vertex. - Vertex *vertex = addVertex(pos); - vertex->nor = lerp(edge->from()->nor, edge->to()->nor, t); - vertex->tex = lerp(edge->from()->tex, edge->to()->tex, t); - disconnect(edge); - disconnect(pair); - // Add edges. - Edge *e0 = addEdge(edge->from()->id, vertex->id); - Edge *p0 = addEdge(vertex->id, pair->to()->id); - Edge *e1 = addEdge(vertex->id, edge->to()->id); - Edge *p1 = addEdge(pair->from()->id, vertex->id); - // Link edges. - e0->setNext(e1); - p1->setNext(p0); - e0->setPrev(edge->prev); - e1->setNext(edge->next); - p1->setPrev(pair->prev); - p0->setNext(pair->next); - xaDebugAssert(e0->next == e1); - xaDebugAssert(e1->prev == e0); - xaDebugAssert(p1->next == p0); - xaDebugAssert(p0->prev == p1); - xaDebugAssert(p0->pair == e0); - xaDebugAssert(e0->pair == p0); - xaDebugAssert(p1->pair == e1); - xaDebugAssert(e1->pair == p1); - // Link faces. - e0->face = edge->face; - e1->face = edge->face; - // Link vertices. - edge->from()->setEdge(e0); - vertex->setEdge(e1); - delete edge; - delete pair; - return vertex; } + if (fixedTJunctionsCount) + *fixedTJunctionsCount = splitEdges.size(); + return mesh; +} -private: - std::vector<Vertex *> m_vertexArray; - std::vector<Edge *> m_edgeArray; - std::vector<Face *> m_faceArray; - - struct Key - { - Key() {} - Key(const Key &k) : p0(k.p0), p1(k.p1) {} - Key(uint32_t v0, uint32_t v1) : p0(v0), p1(v1) {} - void operator=(const Key &k) - { - p0 = k.p0; - p1 = k.p1; - } - bool operator==(const Key &k) const - { - return p0 == k.p0 && p1 == k.p1; - } - - uint32_t p0; - uint32_t p1; - }; - - friend struct Hash<Mesh::Key>; - std::unordered_map<Key, Edge *, Hash<Key>, Equal<Key> > m_edgeMap; - uint32_t m_colocalVertexCount; -}; +// boundaryLoops are the first edges for each boundary loop. +static void meshGetBoundaryLoops(const Mesh &mesh, Array<uint32_t> &boundaryLoops) +{ + const uint32_t edgeCount = mesh.edgeCount(); + BitArray bitFlags(edgeCount); + bitFlags.clearAll(); + boundaryLoops.clear(); + // Search for boundary edges. Mark all the edges that belong to the same boundary. + for (uint32_t e = 0; e < edgeCount; e++) { + if (bitFlags.bitAt(e) || !mesh.isBoundaryEdge(e)) + continue; + for (Mesh::BoundaryEdgeIterator it(&mesh, e); !it.isDone(); it.advance()) + bitFlags.setBitAt(it.edge()); + boundaryLoops.push_back(e); + } +} class MeshTopology { public: MeshTopology(const Mesh *mesh) { - buildTopologyInfo(mesh); - } - - /// Determine if the mesh is connected. - bool isConnected() const - { - return m_connectedCount == 1; - } - - /// Determine if the mesh is closed. (Each edge is shared by two faces) - bool isClosed() const - { - return m_boundaryCount == 0; - } - - /// Return true if the mesh has the topology of a disk. - bool isDisk() const - { - return isConnected() && m_boundaryCount == 1/* && m_eulerNumber == 1*/; - } - -private: - void buildTopologyInfo(const Mesh *mesh) - { const uint32_t vertexCount = mesh->colocalVertexCount(); const uint32_t faceCount = mesh->faceCount(); const uint32_t edgeCount = mesh->edgeCount(); - xaPrint( "--- Building mesh topology:\n" ); - std::vector<uint32_t> stack(faceCount); + Array<uint32_t> stack(MemTag::Default); + stack.reserve(faceCount); BitArray bitFlags(faceCount); bitFlags.clearAll(); // Compute connectivity. - xaPrint( "--- Computing connectivity.\n" ); m_connectedCount = 0; for (uint32_t f = 0; f < faceCount; f++ ) { - if ( bitFlags.bitAt(f) == false ) { + if (bitFlags.bitAt(f) == false) { m_connectedCount++; - stack.push_back( f ); - while ( !stack.empty() ) { + stack.push_back(f); + while (!stack.isEmpty()) { const uint32_t top = stack.back(); - xaAssert(top != uint32_t(~0)); + XA_ASSERT(top != uint32_t(~0)); stack.pop_back(); - if ( bitFlags.bitAt(top) == false ) { + if (bitFlags.bitAt(top) == false) { bitFlags.setBitAt(top); - const Face *face = mesh->faceAt(top); - const Edge *firstEdge = face->edge; - const Edge *edge = firstEdge; - do { - const Face *neighborFace = edge->pair->face; - if (neighborFace != NULL) { - stack.push_back(neighborFace->id); - } - edge = edge->next; - } while (edge != firstEdge); + for (Mesh::FaceEdgeIterator it(mesh, top); !it.isDone(); it.advance()) { + const uint32_t oppositeFace = it.oppositeFace(); + if (oppositeFace != UINT32_MAX) + stack.push_back(oppositeFace); + } } } } } - xaAssert(stack.empty()); - xaPrint( "--- %d connected components.\n", m_connectedCount ); + XA_ASSERT(stack.isEmpty()); // Count boundary loops. - xaPrint( "--- Counting boundary loops.\n" ); m_boundaryCount = 0; bitFlags.resize(edgeCount); bitFlags.clearAll(); // Don't forget to link the boundary otherwise this won't work. for (uint32_t e = 0; e < edgeCount; e++) { - const Edge *startEdge = mesh->edgeAt(e); - if (startEdge != NULL && startEdge->isBoundary() && bitFlags.bitAt(e) == false) { - xaDebugAssert(startEdge->face != NULL); - xaDebugAssert(startEdge->pair->face == NULL); - startEdge = startEdge->pair; - m_boundaryCount++; - const Edge *edge = startEdge; - do { - bitFlags.setBitAt(edge->id / 2); - edge = edge->next; - } while (startEdge != edge); - } - } - xaPrint("--- %d boundary loops found.\n", m_boundaryCount ); + if (bitFlags.bitAt(e) || !mesh->isBoundaryEdge(e)) + continue; + m_boundaryCount++; + for (Mesh::BoundaryEdgeIterator it(mesh, e); !it.isDone(); it.advance()) + bitFlags.setBitAt(it.edge()); + } // Compute euler number. m_eulerNumber = vertexCount - edgeCount + faceCount; - xaPrint("--- Euler number: %d.\n", m_eulerNumber); // Compute genus. (only valid on closed connected surfaces) m_genus = -1; - if ( isClosed() && isConnected() ) { + if (isClosed() && isConnected()) m_genus = (2 - m_eulerNumber) / 2; - xaPrint("--- Genus: %d.\n", m_genus); - } + } + + /// Determine if the mesh is connected. + bool isConnected() const + { + return m_connectedCount == 1; + } + + /// Determine if the mesh is closed. (Each edge is shared by two faces) + bool isClosed() const + { + return m_boundaryCount == 0; + } + + /// Return true if the mesh has the topology of a disk. + bool isDisk() const + { + return isConnected() && m_boundaryCount == 1/* && m_eulerNumber == 1*/; } private: @@ -2843,702 +3480,320 @@ private: int m_genus; }; -float computeSurfaceArea(const halfedge::Mesh *mesh) -{ - float area = 0; - for (halfedge::Mesh::ConstFaceIterator it(mesh->faces()); !it.isDone(); it.advance()) { - const halfedge::Face *face = it.current(); - area += face->area(); - } - xaDebugAssert(area >= 0); - return area; -} - -float computeParametricArea(const halfedge::Mesh *mesh) -{ - float area = 0; - for (halfedge::Mesh::ConstFaceIterator it(mesh->faces()); !it.isDone(); it.advance()) { - const halfedge::Face *face = it.current(); - area += face->parametricArea(); - } - return area; -} - -uint32_t countMeshTriangles(const Mesh *mesh) +struct Progress { - const uint32_t faceCount = mesh->faceCount(); - uint32_t triangleCount = 0; - for (uint32_t f = 0; f < faceCount; f++) { - const Face *face = mesh->faceAt(f); - uint32_t edgeCount = face->edgeCount(); - xaDebugAssert(edgeCount > 2); - triangleCount += edgeCount - 2; - } - return triangleCount; -} - -Mesh *unifyVertices(const Mesh *inputMesh) -{ - Mesh *mesh = new Mesh; - // Only add the first colocal. - const uint32_t vertexCount = inputMesh->vertexCount(); - for (uint32_t v = 0; v < vertexCount; v++) { - const Vertex *vertex = inputMesh->vertexAt(v); - if (vertex->isFirstColocal()) { - mesh->addVertex(vertex->pos); - } - } - std::vector<uint32_t> indexArray; - // Add new faces pointing to first colocals. - uint32_t faceCount = inputMesh->faceCount(); - for (uint32_t f = 0; f < faceCount; f++) { - const Face *face = inputMesh->faceAt(f); - indexArray.clear(); - for (Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const Edge *edge = it.current(); - const Vertex *vertex = edge->vertex->firstColocal(); - indexArray.push_back(vertex->id); - } - mesh->addFace(indexArray); - } - mesh->linkBoundary(); - return mesh; -} - -static bool pointInTriangle(const Vector2 &p, const Vector2 &a, const Vector2 &b, const Vector2 &c) -{ - return triangleArea(a, b, p) >= 0.00001f && - triangleArea(b, c, p) >= 0.00001f && - triangleArea(c, a, p) >= 0.00001f; -} - -// This is doing a simple ear-clipping algorithm that skips invalid triangles. Ideally, we should -// also sort the ears by angle, start with the ones that have the smallest angle and proceed in order. -Mesh *triangulate(const Mesh *inputMesh) -{ - Mesh *mesh = new Mesh; - // Add all vertices. - const uint32_t vertexCount = inputMesh->vertexCount(); - for (uint32_t v = 0; v < vertexCount; v++) { - const Vertex *vertex = inputMesh->vertexAt(v); - mesh->addVertex(vertex->pos); - } - std::vector<int> polygonVertices; - std::vector<float> polygonAngles; - std::vector<Vector2> polygonPoints; - const uint32_t faceCount = inputMesh->faceCount(); - for (uint32_t f = 0; f < faceCount; f++) { - const Face *face = inputMesh->faceAt(f); - xaDebugAssert(face != NULL); - const uint32_t edgeCount = face->edgeCount(); - xaDebugAssert(edgeCount >= 3); - polygonVertices.clear(); - polygonVertices.reserve(edgeCount); - if (edgeCount == 3) { - // Simple case for triangles. - for (Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const Edge *edge = it.current(); - const Vertex *vertex = edge->vertex; - polygonVertices.push_back(vertex->id); - } - int v0 = polygonVertices[0]; - int v1 = polygonVertices[1]; - int v2 = polygonVertices[2]; - mesh->addFace(v0, v1, v2); - } else { - // Build 2D polygon projecting vertices onto normal plane. - // Faces are not necesarily planar, this is for example the case, when the face comes from filling a hole. In such cases - // it's much better to use the best fit plane. - const Vector3 fn = face->normal(); - Basis basis; - basis.buildFrameForDirection(fn); - polygonPoints.clear(); - polygonPoints.reserve(edgeCount); - polygonAngles.clear(); - polygonAngles.reserve(edgeCount); - for (Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const Edge *edge = it.current(); - const Vertex *vertex = edge->vertex; - polygonVertices.push_back(vertex->id); - Vector2 p; - p.x = dot(basis.tangent, vertex->pos); - p.y = dot(basis.bitangent, vertex->pos); - polygonPoints.push_back(p); - } - polygonAngles.resize(edgeCount); - while (polygonVertices.size() > 2) { - uint32_t size = polygonVertices.size(); - // Update polygon angles. @@ Update only those that have changed. - float minAngle = 2 * PI; - uint32_t bestEar = 0; // Use first one if none of them is valid. - bool bestIsValid = false; - for (uint32_t i = 0; i < size; i++) { - uint32_t i0 = i; - uint32_t i1 = (i + 1) % size; // Use Sean's polygon interation trick. - uint32_t i2 = (i + 2) % size; - Vector2 p0 = polygonPoints[i0]; - Vector2 p1 = polygonPoints[i1]; - Vector2 p2 = polygonPoints[i2]; - - // -- GODOT start -- - bool degenerate = distance(p0, p1) < NV_EPSILON || distance(p0, p2) < NV_EPSILON || distance(p1, p2) < NV_EPSILON; - if (degenerate) { - continue; - } - // -- GODOT end -- - - float d = clamp(dot(p0 - p1, p2 - p1) / (length(p0 - p1) * length(p2 - p1)), -1.0f, 1.0f); - float angle = acosf(d); - float area = triangleArea(p0, p1, p2); - if (area < 0.0f) angle = 2.0f * PI - angle; - polygonAngles[i1] = angle; - if (angle < minAngle || !bestIsValid) { - // Make sure this is a valid ear, if not, skip this point. - bool valid = true; - for (uint32_t j = 0; j < size; j++) { - if (j == i0 || j == i1 || j == i2) continue; - Vector2 p = polygonPoints[j]; - if (pointInTriangle(p, p0, p1, p2)) { - valid = false; - break; - } - } - if (valid || !bestIsValid) { - minAngle = angle; - bestEar = i1; - bestIsValid = valid; - } - } - } - // -- GODOT start -- - if (!bestIsValid) - break; - // -- GODOT end -- - - xaDebugAssert(minAngle <= 2 * PI); - // Clip best ear: - uint32_t i0 = (bestEar + size - 1) % size; - uint32_t i1 = (bestEar + 0) % size; - uint32_t i2 = (bestEar + 1) % size; - int v0 = polygonVertices[i0]; - int v1 = polygonVertices[i1]; - int v2 = polygonVertices[i2]; - mesh->addFace(v0, v1, v2); - polygonVertices.erase(polygonVertices.begin() + i1); - polygonPoints.erase(polygonPoints.begin() + i1); - polygonAngles.erase(polygonAngles.begin() + i1); - } - } - } - mesh->linkBoundary(); - return mesh; -} - -} // namespace halfedge - -/// Mersenne twister random number generator. -class MTRand -{ -public: - enum time_e { Time }; - enum { N = 624 }; // length of state vector - enum { M = 397 }; - - /// Constructor that uses the current time as the seed. - MTRand( time_e ) + Progress(ProgressCategory::Enum category, ProgressFunc func, void *userData, uint32_t maxValue) : value(0), cancel(false), m_category(category), m_func(func), m_userData(userData), m_maxValue(maxValue), m_progress(0) { - seed((uint32_t )time(NULL)); - } - - /// Constructor that uses the given seed. - MTRand( uint32_t s = 0 ) - { - seed(s); - } - - /// Provide a new seed. - void seed( uint32_t s ) - { - initialize(s); - reload(); + if (m_func) { + if (!m_func(category, 0, userData)) + cancel = true; + } } - /// Get a random number between 0 - 65536. - uint32_t get() + ~Progress() { - // Pull a 32-bit integer from the generator state - // Every other access function simply transforms the numbers extracted here - if ( left == 0 ) { - reload(); + if (m_func) { + if (!m_func(m_category, 100, m_userData)) + cancel = true; } - left--; - uint32_t s1; - s1 = *next++; - s1 ^= (s1 >> 11); - s1 ^= (s1 << 7) & 0x9d2c5680U; - s1 ^= (s1 << 15) & 0xefc60000U; - return ( s1 ^ (s1 >> 18) ); - }; - - /// Get a random number on [0, max] interval. - uint32_t getRange( uint32_t max ) - { - if (max == 0) return 0; - if (max == NV_UINT32_MAX) return get(); - const uint32_t np2 = nextPowerOfTwo( max + 1 ); // @@ This fails if max == NV_UINT32_MAX - const uint32_t mask = np2 - 1; - uint32_t n; - do { - n = get() & mask; - } while ( n > max ); - return n; } -private: - void initialize( uint32_t seed ) + void update() { - // Initialize generator state with seed - // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier. - // In previous versions, most significant bits (MSBs) of the seed affect - // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto. - uint32_t *s = state; - uint32_t *r = state; - int i = 1; - *s++ = seed & 0xffffffffUL; - for ( ; i < N; ++i ) { - *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL; - r++; + if (!m_func) + return; + m_mutex.lock(); + const uint32_t newProgress = uint32_t(ceilf(value.load() / (float)m_maxValue * 100.0f)); + if (newProgress != m_progress && newProgress < 100) { + m_progress = newProgress; + if (!m_func(m_category, m_progress, m_userData)) + cancel = true; } + m_mutex.unlock(); } - void reload() + void setMaxValue(uint32_t maxValue) { - // Generate N new values in state - // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com) - uint32_t *p = state; - int i; - for ( i = N - M; i--; ++p ) - *p = twist( p[M], p[0], p[1] ); - for ( i = M; --i; ++p ) - *p = twist( p[M - N], p[0], p[1] ); - *p = twist( p[M - N], p[0], state[0] ); - left = N, next = state; + m_mutex.lock(); + m_maxValue = maxValue; + m_mutex.unlock(); } - uint32_t hiBit( uint32_t u ) const - { - return u & 0x80000000U; - } - uint32_t loBit( uint32_t u ) const - { - return u & 0x00000001U; - } - uint32_t loBits( uint32_t u ) const - { - return u & 0x7fffffffU; - } - uint32_t mixBits( uint32_t u, uint32_t v ) const - { - return hiBit(u) | loBits(v); - } - uint32_t twist( uint32_t m, uint32_t s0, uint32_t s1 ) const - { - return m ^ (mixBits(s0, s1) >> 1) ^ ((~loBit(s1) + 1) & 0x9908b0dfU); - } + std::atomic<uint32_t> value; + std::atomic<bool> cancel; - uint32_t state[N]; // internal state - uint32_t *next; // next value to get from state - int left; // number of values left before reload needed +private: + ProgressCategory::Enum m_category; + ProgressFunc m_func; + void *m_userData; + uint32_t m_maxValue; + uint32_t m_progress; + std::mutex m_mutex; }; -namespace morton { -// Code from ryg: -// http://fgiesen.wordpress.com/2009/12/13/decoding-morton-codes/ - -// Inverse of part1By1 - "delete" all odd-indexed bits -uint32_t compact1By1(uint32_t x) -{ - x &= 0x55555555; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0 - x = (x ^ (x >> 1)) & 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10 - x = (x ^ (x >> 2)) & 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210 - x = (x ^ (x >> 4)) & 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210 - x = (x ^ (x >> 8)) & 0x0000ffff; // x = ---- ---- ---- ---- fedc ba98 7654 3210 - return x; -} - -// Inverse of part1By2 - "delete" all bits not at positions divisible by 3 -uint32_t compact1By2(uint32_t x) +struct Spinlock { - x &= 0x09249249; // x = ---- 9--8 --7- -6-- 5--4 --3- -2-- 1--0 - x = (x ^ (x >> 2)) & 0x030c30c3; // x = ---- --98 ---- 76-- --54 ---- 32-- --10 - x = (x ^ (x >> 4)) & 0x0300f00f; // x = ---- --98 ---- ---- 7654 ---- ---- 3210 - x = (x ^ (x >> 8)) & 0xff0000ff; // x = ---- --98 ---- ---- ---- ---- 7654 3210 - x = (x ^ (x >> 16)) & 0x000003ff; // x = ---- ---- ---- ---- ---- --98 7654 3210 - return x; -} - -uint32_t decodeMorton2X(uint32_t code) -{ - return compact1By1(code >> 0); -} + void lock() { while(m_lock.test_and_set(std::memory_order_acquire)) {} } + void unlock() { m_lock.clear(std::memory_order_release); } -uint32_t decodeMorton2Y(uint32_t code) -{ - return compact1By1(code >> 1); -} +private: + std::atomic_flag m_lock = ATOMIC_FLAG_INIT; +}; -uint32_t decodeMorton3X(uint32_t code) +struct TaskGroupHandle { - return compact1By2(code >> 0); -} + uint32_t value = UINT32_MAX; +}; -uint32_t decodeMorton3Y(uint32_t code) +struct Task { - return compact1By2(code >> 1); -} + void (*func)(void *userData); + void *userData; +}; -uint32_t decodeMorton3Z(uint32_t code) +#if XA_MULTITHREADED +class TaskScheduler { - return compact1By2(code >> 2); -} -} // namespace morton - -// A simple, dynamic proximity grid based on Jon's code. -// Instead of storing pointers here I store indices. -struct ProximityGrid -{ - void init(const Box &box, uint32_t count) - { - cellArray.clear(); - // Determine grid size. - float cellWidth; - Vector3 diagonal = box.extents() * 2.f; - float volume = box.volume(); - if (equal(volume, 0)) { - // Degenerate box, treat like a quad. - Vector2 quad; - if (diagonal.x < diagonal.y && diagonal.x < diagonal.z) { - quad.x = diagonal.y; - quad.y = diagonal.z; - } else if (diagonal.y < diagonal.x && diagonal.y < diagonal.z) { - quad.x = diagonal.x; - quad.y = diagonal.z; - } else { - quad.x = diagonal.x; - quad.y = diagonal.y; - } - float cellArea = quad.x * quad.y / count; - cellWidth = sqrtf(cellArea); // pow(cellArea, 1.0f / 2.0f); - } else { - // Ideally we want one cell per point. - float cellVolume = volume / count; - cellWidth = powf(cellVolume, 1.0f / 3.0f); - } - xaDebugAssert(cellWidth != 0); - sx = std::max(1, ftoi_ceil(diagonal.x / cellWidth)); - sy = std::max(1, ftoi_ceil(diagonal.y / cellWidth)); - sz = std::max(1, ftoi_ceil(diagonal.z / cellWidth)); - invCellSize.x = float(sx) / diagonal.x; - invCellSize.y = float(sy) / diagonal.y; - invCellSize.z = float(sz) / diagonal.z; - cellArray.resize(sx * sy * sz); - corner = box.minCorner; // @@ Align grid better? - } - - int index_x(float x) const - { - return clamp(ftoi_floor((x - corner.x) * invCellSize.x), 0, sx - 1); - } - - int index_y(float y) const +public: + TaskScheduler() : m_shutdown(false) { - return clamp(ftoi_floor((y - corner.y) * invCellSize.y), 0, sy - 1); + // Max with current task scheduler usage is 1 per thread + 1 deep nesting, but allow for some slop. + m_maxGroups = std::thread::hardware_concurrency() * 4; + m_groups = XA_ALLOC_ARRAY(MemTag::Default, TaskGroup, m_maxGroups); + for (uint32_t i = 0; i < m_maxGroups; i++) { + new (&m_groups[i]) TaskGroup(); + m_groups[i].free = true; + m_groups[i].ref = 0; + } + m_workers.resize(std::thread::hardware_concurrency() <= 1 ? 1 : std::thread::hardware_concurrency() - 1); + for (uint32_t i = 0; i < m_workers.size(); i++) { + m_workers[i].wakeup = false; + m_workers[i].thread = XA_NEW(MemTag::Default, std::thread, workerThread, this, &m_workers[i]); + } } - int index_z(float z) const + ~TaskScheduler() { - return clamp(ftoi_floor((z - corner.z) * invCellSize.z), 0, sz - 1); + m_shutdown = true; + for (uint32_t i = 0; i < m_workers.size(); i++) { + Worker &worker = m_workers[i]; + XA_DEBUG_ASSERT(worker.thread); + worker.wakeup = true; + worker.cv.notify_one(); + if (worker.thread->joinable()) + worker.thread->join(); + worker.thread->~thread(); + XA_FREE(worker.thread); + } + for (uint32_t i = 0; i < m_maxGroups; i++) + m_groups[i].~TaskGroup(); + XA_FREE(m_groups); } - int index(int x, int y, int z) const + TaskGroupHandle createTaskGroup(uint32_t reserveSize = 0) { - xaDebugAssert(x >= 0 && x < sx); - xaDebugAssert(y >= 0 && y < sy); - xaDebugAssert(z >= 0 && z < sz); - int idx = (z * sy + y) * sx + x; - xaDebugAssert(idx >= 0 && uint32_t(idx) < cellArray.size()); - return idx; + // Claim the first free group. + for (uint32_t i = 0; i < m_maxGroups; i++) { + TaskGroup &group = m_groups[i]; + bool expected = true; + if (!group.free.compare_exchange_strong(expected, false)) + continue; + group.queueLock.lock(); + group.queueHead = 0; + group.queue.clear(); + group.queue.reserve(reserveSize); + group.queueLock.unlock(); + TaskGroupHandle handle; + handle.value = i; + return handle; + } + XA_DEBUG_ASSERT(false); + TaskGroupHandle handle; + handle.value = UINT32_MAX; + return handle; } - uint32_t mortonCount() const + void run(TaskGroupHandle handle, Task task) { - uint64_t s = uint64_t(max3(sx, sy, sz)); - s = nextPowerOfTwo(s); - if (s > 1024) { - return uint32_t(s * s * min3(sx, sy, sz)); + XA_DEBUG_ASSERT(handle.value != UINT32_MAX); + TaskGroup &group = m_groups[handle.value]; + group.queueLock.lock(); + group.queue.push_back(task); + group.queueLock.unlock(); + group.ref++; + // Wake up a worker to run this task. + for (uint32_t i = 0; i < m_workers.size(); i++) { + m_workers[i].wakeup = true; + m_workers[i].cv.notify_one(); } - return uint32_t(s * s * s); } - int mortonIndex(uint32_t code) const + void wait(TaskGroupHandle *handle) { - uint32_t x, y, z; - uint32_t s = uint32_t(max3(sx, sy, sz)); - if (s > 1024) { - // Use layered two-dimensional morton order. - s = nextPowerOfTwo(s); - uint32_t layer = code / (s * s); - code = code % (s * s); - uint32_t layer_count = uint32_t(min3(sx, sy, sz)); - if (sx == (int)layer_count) { - x = layer; - y = morton::decodeMorton2X(code); - z = morton::decodeMorton2Y(code); - } else if (sy == (int)layer_count) { - x = morton::decodeMorton2Y(code); - y = layer; - z = morton::decodeMorton2X(code); - } else { /*if (sz == layer_count)*/ - x = morton::decodeMorton2X(code); - y = morton::decodeMorton2Y(code); - z = layer; - } - } else { - x = morton::decodeMorton3X(code); - y = morton::decodeMorton3Y(code); - z = morton::decodeMorton3Z(code); + if (handle->value == UINT32_MAX) { + XA_DEBUG_ASSERT(false); + return; } - if (x >= uint32_t(sx) || y >= uint32_t(sy) || z >= uint32_t(sz)) { - return -1; + // Run tasks from the group queue until empty. + TaskGroup &group = m_groups[handle->value]; + for (;;) { + Task *task = nullptr; + group.queueLock.lock(); + if (group.queueHead < group.queue.size()) + task = &group.queue[group.queueHead++]; + group.queueLock.unlock(); + if (!task) + break; + task->func(task->userData); + group.ref--; } - return index(x, y, z); + // Even though the task queue is empty, workers can still be running tasks. + while (group.ref > 0) + std::this_thread::yield(); + group.free = true; + handle->value = UINT32_MAX; } - void add(const Vector3 &pos, uint32_t key) +private: + struct TaskGroup { - int x = index_x(pos.x); - int y = index_y(pos.y); - int z = index_z(pos.z); - uint32_t idx = index(x, y, z); - cellArray[idx].indexArray.push_back(key); - } + std::atomic<bool> free; + Array<Task> queue; // Items are never removed. queueHead is incremented to pop items. + uint32_t queueHead = 0; + Spinlock queueLock; + std::atomic<uint32_t> ref; // Increment when a task is enqueued, decrement when a task finishes. + }; - // Gather all points inside the given sphere. - // Radius is assumed to be small, so we don't bother culling the cells. - void gather(const Vector3 &position, float radius, std::vector<uint32_t> &indexArray) + struct Worker { - int x0 = index_x(position.x - radius); - int x1 = index_x(position.x + radius); - int y0 = index_y(position.y - radius); - int y1 = index_y(position.y + radius); - int z0 = index_z(position.z - radius); - int z1 = index_z(position.z + radius); - for (int z = z0; z <= z1; z++) { - for (int y = y0; y <= y1; y++) { - for (int x = x0; x <= x1; x++) { - int idx = index(x, y, z); - indexArray.insert(indexArray.begin(), cellArray[idx].indexArray.begin(), cellArray[idx].indexArray.end()); + std::thread *thread = nullptr; + std::mutex mutex; + std::condition_variable cv; + std::atomic<bool> wakeup; + }; + + TaskGroup *m_groups; + uint32_t m_maxGroups; + Array<Worker> m_workers; + std::atomic<bool> m_shutdown; + + static void workerThread(TaskScheduler *scheduler, Worker *worker) + { + std::unique_lock<std::mutex> lock(worker->mutex); + for (;;) { + worker->cv.wait(lock, [=]{ return worker->wakeup.load(); }); + worker->wakeup = false; + for (;;) { + if (scheduler->m_shutdown) + return; + // Look for a task in any of the groups and run it. + TaskGroup *group = nullptr; + Task *task = nullptr; + for (uint32_t i = 0; i < scheduler->m_maxGroups; i++) { + group = &scheduler->m_groups[i]; + if (group->free || group->ref == 0) + continue; + group->queueLock.lock(); + if (group->queueHead < group->queue.size()) { + task = &group->queue[group->queueHead++]; + group->queueLock.unlock(); + break; + } + group->queueLock.unlock(); } + if (!task) + break; + task->func(task->userData); + group->ref--; } } } - - struct Cell { - std::vector<uint32_t> indexArray; - }; - - std::vector<Cell> cellArray; - - Vector3 corner; - Vector3 invCellSize; - int sx, sy, sz; }; - -// Based on Pierre Terdiman's and Michael Herf's source code. -// http://www.codercorner.com/RadixSortRevisited.htm -// http://www.stereopsis.com/radix.html -class RadixSort +#else +class TaskScheduler { public: - RadixSort() : m_size(0), m_ranks(NULL), m_ranks2(NULL), m_validRanks(false) {} - ~RadixSort() + ~TaskScheduler() { - // Release everything - free(m_ranks2); - free(m_ranks); + for (uint32_t i = 0; i < m_groups.size(); i++) + destroyGroup({ i }); } - RadixSort &sort(const float *input, uint32_t count) + TaskGroupHandle createTaskGroup(uint32_t reserveSize = 0) { - if (input == NULL || count == 0) return *this; - // Resize lists if needed - if (count != m_size) { - if (count > m_size) { - m_ranks2 = (uint32_t *)realloc(m_ranks2, sizeof(uint32_t ) * count); - m_ranks = (uint32_t *)realloc(m_ranks, sizeof(uint32_t ) * count); - } - m_size = count; - m_validRanks = false; - } - if (count < 32) { - insertionSort(input, count); - } else { - // @@ Avoid touching the input multiple times. - for (uint32_t i = 0; i < count; i++) { - FloatFlip((uint32_t &)input[i]); - } - radixSort<uint32_t>((const uint32_t *)input, count); - for (uint32_t i = 0; i < count; i++) { - IFloatFlip((uint32_t &)input[i]); - } - } - return *this; + TaskGroup *group = XA_NEW(MemTag::Default, TaskGroup); + group->queue.reserve(reserveSize); + m_groups.push_back(group); + TaskGroupHandle handle; + handle.value = m_groups.size() - 1; + return handle; } - RadixSort &sort(const std::vector<float> &input) + void run(TaskGroupHandle handle, Task task) { - return sort(input.data(), input.size()); + m_groups[handle.value]->queue.push_back(task); } - // Access to results. m_ranks is a list of indices in sorted order, i.e. in the order you may further process your data - const uint32_t *ranks() const + void wait(TaskGroupHandle *handle) { - xaDebugAssert(m_validRanks); - return m_ranks; - } - uint32_t *ranks() - { - xaDebugAssert(m_validRanks); - return m_ranks; + if (handle->value == UINT32_MAX) { + XA_DEBUG_ASSERT(false); + return; + } + TaskGroup *group = m_groups[handle->value]; + for (uint32_t i = 0; i < group->queue.size(); i++) + group->queue[i].func(group->queue[i].userData); + group->queue.clear(); + destroyGroup(*handle); + handle->value = UINT32_MAX; } private: - uint32_t m_size; - uint32_t *m_ranks; - uint32_t *m_ranks2; - bool m_validRanks; - - void FloatFlip(uint32_t &f) + void destroyGroup(TaskGroupHandle handle) { - int32_t mask = (int32_t(f) >> 31) | 0x80000000; // Warren Hunt, Manchor Ko. - f ^= mask; + TaskGroup *group = m_groups[handle.value]; + if (group) { + group->~TaskGroup(); + XA_FREE(group); + m_groups[handle.value] = nullptr; + } } - void IFloatFlip(uint32_t &f) + struct TaskGroup { - uint32_t mask = ((f >> 31) - 1) | 0x80000000; // Michael Herf. - f ^= mask; - } + Array<Task> queue; + }; - template<typename T> - void createHistograms(const T *buffer, uint32_t count, uint32_t *histogram) - { - const uint32_t bucketCount = sizeof(T); // (8 * sizeof(T)) / log2(radix) - // Init bucket pointers. - uint32_t *h[bucketCount]; - for (uint32_t i = 0; i < bucketCount; i++) { - h[i] = histogram + 256 * i; - } - // Clear histograms. - memset(histogram, 0, 256 * bucketCount * sizeof(uint32_t )); - // @@ Add support for signed integers. - // Build histograms. - const uint8_t *p = (const uint8_t *)buffer; // @@ Does this break aliasing rules? - const uint8_t *pe = p + count * sizeof(T); - while (p != pe) { - h[0][*p++]++, h[1][*p++]++, h[2][*p++]++, h[3][*p++]++; -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4127) -#endif - if (bucketCount == 8) h[4][*p++]++, h[5][*p++]++, h[6][*p++]++, h[7][*p++]++; -#ifdef _MSC_VER -#pragma warning(pop) + Array<TaskGroup *> m_groups; +}; #endif - } - } - template <typename T> void insertionSort(const T *input, uint32_t count) - { - if (!m_validRanks) { - m_ranks[0] = 0; - for (uint32_t i = 1; i != count; ++i) { - int rank = m_ranks[i] = i; - uint32_t j = i; - while (j != 0 && input[rank] < input[m_ranks[j - 1]]) { - m_ranks[j] = m_ranks[j - 1]; - --j; - } - if (i != j) { - m_ranks[j] = rank; - } - } - m_validRanks = true; - } else { - for (uint32_t i = 1; i != count; ++i) { - int rank = m_ranks[i]; - uint32_t j = i; - while (j != 0 && input[rank] < input[m_ranks[j - 1]]) { - m_ranks[j] = m_ranks[j - 1]; - --j; - } - if (i != j) { - m_ranks[j] = rank; - } - } - } - } +struct UvMeshChart +{ + Array<uint32_t> indices; + uint32_t material; +}; - template <typename T> void radixSort(const T *input, uint32_t count) - { - const uint32_t P = sizeof(T); // pass count - // Allocate histograms & offsets on the stack - uint32_t histogram[256 * P]; - uint32_t *link[256]; - createHistograms(input, count, histogram); - // Radix sort, j is the pass number (0=LSB, P=MSB) - for (uint32_t j = 0; j < P; j++) { - // Pointer to this bucket. - const uint32_t *h = &histogram[j * 256]; - const uint8_t *inputBytes = (const uint8_t *)input; // @@ Is this aliasing legal? - inputBytes += j; - if (h[inputBytes[0]] == count) { - // Skip this pass, all values are the same. - continue; - } - // Create offsets - link[0] = m_ranks2; - for (uint32_t i = 1; i < 256; i++) link[i] = link[i - 1] + h[i - 1]; - // Perform Radix Sort - if (!m_validRanks) { - for (uint32_t i = 0; i < count; i++) { - *link[inputBytes[i * P]]++ = i; - } - m_validRanks = true; - } else { - for (uint32_t i = 0; i < count; i++) { - const uint32_t idx = m_ranks[i]; - *link[inputBytes[idx * P]]++ = idx; - } - } - // Swap pointers for next pass. Valid indices - the most recent ones - are in m_ranks after the swap. - std::swap(m_ranks, m_ranks2); - } - // All values were equal, generate linear ranks. - if (!m_validRanks) { - for (uint32_t i = 0; i < count; i++) { - m_ranks[i] = i; - } - m_validRanks = true; - } - } +struct UvMesh +{ + UvMeshDecl decl; + Array<uint32_t> indices; + Array<UvMeshChart *> charts; + Array<uint32_t> vertexToChartMap; +}; + +struct UvMeshInstance +{ + UvMesh *mesh; + Array<Vector2> texcoords; + bool rotateCharts; }; namespace raster { class ClippedTriangle { public: - ClippedTriangle(Vector2::Arg a, Vector2::Arg b, Vector2::Arg c) + ClippedTriangle(const Vector2 &a, const Vector2 &b, const Vector2 &c) { m_numVertices = 3; m_activeVertexBuffer = 0; @@ -3549,16 +3804,6 @@ public: m_vertexBuffers[1] = m_verticesB; } - uint32_t vertexCount() - { - return m_numVertices; - } - - const Vector2 *vertices() - { - return m_vertexBuffers[m_activeVertexBuffer]; - } - void clipHorizontalPlane(float offset, float clipdirection) { Vector2 *v = m_vertexBuffers[m_activeVertexBuffer]; @@ -3581,7 +3826,6 @@ public: dy1in = dy2in; } m_numVertices = p; - //for (uint32_t k=0; k<m_numVertices; k++) printf("(%f, %f)\n", v2[k].x, v2[k].y); printf("\n"); } void clipVerticalPlane(float offset, float clipdirection ) @@ -3608,7 +3852,7 @@ public: m_numVertices = p; } - void computeAreaCentroid() + void computeArea() { Vector2 *v = m_vertexBuffers[m_activeVertexBuffer]; v[m_numVertices] = v[0]; @@ -3622,25 +3866,15 @@ public: centroidy += f * (v[k].y + v[k + 1].y); } m_area = 0.5f * fabsf(m_area); - if (m_area == 0) { - m_centroid = Vector2(0.0f); - } else { - m_centroid = Vector2(centroidx / (6 * m_area), centroidy / (6 * m_area)); - } } void clipAABox(float x0, float y0, float x1, float y1) { - clipVerticalPlane ( x0, -1); - clipHorizontalPlane( y0, -1); - clipVerticalPlane ( x1, 1); - clipHorizontalPlane( y1, 1); - computeAreaCentroid(); - } - - Vector2 centroid() - { - return m_centroid; + clipVerticalPlane(x0, -1); + clipHorizontalPlane(y0, -1); + clipVerticalPlane(x1, 1); + clipHorizontalPlane(y1, 1); + computeArea(); } float area() @@ -3652,212 +3886,50 @@ private: Vector2 m_verticesA[7 + 1]; Vector2 m_verticesB[7 + 1]; Vector2 *m_vertexBuffers[2]; - uint32_t m_numVertices; - uint32_t m_activeVertexBuffer; - float m_area; - Vector2 m_centroid; + uint32_t m_numVertices; + uint32_t m_activeVertexBuffer; + float m_area; }; /// A callback to sample the environment. Return false to terminate rasterization. -typedef bool (* SamplingCallback)(void *param, int x, int y, Vector3::Arg bar, Vector3::Arg dx, Vector3::Arg dy, float coverage); +typedef bool (*SamplingCallback)(void *param, int x, int y); /// A triangle for rasterization. struct Triangle { - Triangle(Vector2::Arg v0, Vector2::Arg v1, Vector2::Arg v2, Vector3::Arg t0, Vector3::Arg t1, Vector3::Arg t2) + Triangle(const Vector2 &v0, const Vector2 &v1, const Vector2 &v2) { // Init vertices. this->v1 = v0; this->v2 = v2; this->v3 = v1; - // Set barycentric coordinates. - this->t1 = t0; - this->t2 = t2; - this->t3 = t1; // make sure every triangle is front facing. flipBackface(); // Compute deltas. - valid = computeDeltas(); computeUnitInwardNormals(); } - /// Compute texture space deltas. - /// This method takes two edge vectors that form a basis, determines the - /// coordinates of the canonic vectors in that basis, and computes the - /// texture gradient that corresponds to those vectors. - bool computeDeltas() + bool isValid() { - Vector2 e0 = v3 - v1; - Vector2 e1 = v2 - v1; - Vector3 de0 = t3 - t1; - Vector3 de1 = t2 - t1; - float denom = 1.0f / (e0.y * e1.x - e1.y * e0.x); - if (!std::isfinite(denom)) { - return false; - } - float lambda1 = - e1.y * denom; - float lambda2 = e0.y * denom; - float lambda3 = e1.x * denom; - float lambda4 = - e0.x * denom; - dx = de0 * lambda1 + de1 * lambda2; - dy = de0 * lambda3 + de1 * lambda4; - return true; - } - - bool draw(const Vector2 &extents, bool enableScissors, SamplingCallback cb, void *param) - { - // 28.4 fixed-point coordinates - const int Y1 = ftoi_round(16.0f * v1.y); - const int Y2 = ftoi_round(16.0f * v2.y); - const int Y3 = ftoi_round(16.0f * v3.y); - const int X1 = ftoi_round(16.0f * v1.x); - const int X2 = ftoi_round(16.0f * v2.x); - const int X3 = ftoi_round(16.0f * v3.x); - // Deltas - const int DX12 = X1 - X2; - const int DX23 = X2 - X3; - const int DX31 = X3 - X1; - const int DY12 = Y1 - Y2; - const int DY23 = Y2 - Y3; - const int DY31 = Y3 - Y1; - // Fixed-point deltas - const int FDX12 = DX12 << 4; - const int FDX23 = DX23 << 4; - const int FDX31 = DX31 << 4; - const int FDY12 = DY12 << 4; - const int FDY23 = DY23 << 4; - const int FDY31 = DY31 << 4; - int minx, miny, maxx, maxy; - if (enableScissors) { - int frustumX0 = 0 << 4; - int frustumY0 = 0 << 4; - int frustumX1 = (int)extents.x << 4; - int frustumY1 = (int)extents.y << 4; - // Bounding rectangle - minx = (std::max(min3(X1, X2, X3), frustumX0) + 0xF) >> 4; - miny = (std::max(min3(Y1, Y2, Y3), frustumY0) + 0xF) >> 4; - maxx = (std::min(max3(X1, X2, X3), frustumX1) + 0xF) >> 4; - maxy = (std::min(max3(Y1, Y2, Y3), frustumY1) + 0xF) >> 4; - } else { - // Bounding rectangle - minx = (min3(X1, X2, X3) + 0xF) >> 4; - miny = (min3(Y1, Y2, Y3) + 0xF) >> 4; - maxx = (max3(X1, X2, X3) + 0xF) >> 4; - maxy = (max3(Y1, Y2, Y3) + 0xF) >> 4; - } - // Block size, standard 8x8 (must be power of two) - const int q = 8; - // @@ This won't work when minx,miny are negative. This code path is not used. Leaving as is for now. - xaAssert(minx >= 0); - xaAssert(miny >= 0); - // Start in corner of 8x8 block - minx &= ~(q - 1); - miny &= ~(q - 1); - // Half-edge constants - int C1 = DY12 * X1 - DX12 * Y1; - int C2 = DY23 * X2 - DX23 * Y2; - int C3 = DY31 * X3 - DX31 * Y3; - // Correct for fill convention - if (DY12 < 0 || (DY12 == 0 && DX12 > 0)) C1++; - if (DY23 < 0 || (DY23 == 0 && DX23 > 0)) C2++; - if (DY31 < 0 || (DY31 == 0 && DX31 > 0)) C3++; - // Loop through blocks - for (int y = miny; y < maxy; y += q) { - for (int x = minx; x < maxx; x += q) { - // Corners of block - int x0 = x << 4; - int x1 = (x + q - 1) << 4; - int y0 = y << 4; - int y1 = (y + q - 1) << 4; - // Evaluate half-space functions - bool a00 = C1 + DX12 * y0 - DY12 * x0 > 0; - bool a10 = C1 + DX12 * y0 - DY12 * x1 > 0; - bool a01 = C1 + DX12 * y1 - DY12 * x0 > 0; - bool a11 = C1 + DX12 * y1 - DY12 * x1 > 0; - int a = (a00 << 0) | (a10 << 1) | (a01 << 2) | (a11 << 3); - bool b00 = C2 + DX23 * y0 - DY23 * x0 > 0; - bool b10 = C2 + DX23 * y0 - DY23 * x1 > 0; - bool b01 = C2 + DX23 * y1 - DY23 * x0 > 0; - bool b11 = C2 + DX23 * y1 - DY23 * x1 > 0; - int b = (b00 << 0) | (b10 << 1) | (b01 << 2) | (b11 << 3); - bool c00 = C3 + DX31 * y0 - DY31 * x0 > 0; - bool c10 = C3 + DX31 * y0 - DY31 * x1 > 0; - bool c01 = C3 + DX31 * y1 - DY31 * x0 > 0; - bool c11 = C3 + DX31 * y1 - DY31 * x1 > 0; - int c = (c00 << 0) | (c10 << 1) | (c01 << 2) | (c11 << 3); - // Skip block when outside an edge - if (a == 0x0 || b == 0x0 || c == 0x0) continue; - // Accept whole block when totally covered - if (a == 0xF && b == 0xF && c == 0xF) { - Vector3 texRow = t1 + dy * (y0 - v1.y) + dx * (x0 - v1.x); - for (int iy = y; iy < y + q; iy++) { - Vector3 tex = texRow; - for (int ix = x; ix < x + q; ix++) { - //Vector3 tex = t1 + dx * (ix - v1.x) + dy * (iy - v1.y); - if (!cb(param, ix, iy, tex, dx, dy, 1.0)) { - // early out. - return false; - } - tex += dx; - } - texRow += dy; - } - } else { // Partially covered block - int CY1 = C1 + DX12 * y0 - DY12 * x0; - int CY2 = C2 + DX23 * y0 - DY23 * x0; - int CY3 = C3 + DX31 * y0 - DY31 * x0; - Vector3 texRow = t1 + dy * (y0 - v1.y) + dx * (x0 - v1.x); - for (int iy = y; iy < y + q; iy++) { - int CX1 = CY1; - int CX2 = CY2; - int CX3 = CY3; - Vector3 tex = texRow; - for (int ix = x; ix < x + q; ix++) { - if (CX1 > 0 && CX2 > 0 && CX3 > 0) { - if (!cb(param, ix, iy, tex, dx, dy, 1.0)) { - // early out. - return false; - } - } - CX1 -= FDY12; - CX2 -= FDY23; - CX3 -= FDY31; - tex += dx; - } - CY1 += FDX12; - CY2 += FDX23; - CY3 += FDX31; - texRow += dy; - } - } - } - } - return true; + const Vector2 e0 = v3 - v1; + const Vector2 e1 = v2 - v1; + const float denom = 1.0f / (e0.y * e1.x - e1.y * e0.x); + return isFinite(denom); } // extents has to be multiple of BK_SIZE!! - bool drawAA(const Vector2 &extents, bool enableScissors, SamplingCallback cb, void *param) + bool drawAA(const Vector2 &extents, SamplingCallback cb, void *param) { - const float PX_INSIDE = 1.0f/sqrt(2.0f); - const float PX_OUTSIDE = -1.0f/sqrt(2.0f); + const float PX_INSIDE = 1.0f/sqrtf(2.0f); + const float PX_OUTSIDE = -1.0f/sqrtf(2.0f); const float BK_SIZE = 8; - const float BK_INSIDE = sqrt(BK_SIZE*BK_SIZE/2.0f); - const float BK_OUTSIDE = -sqrt(BK_SIZE*BK_SIZE/2.0f); - - float minx, miny, maxx, maxy; - if (enableScissors) { - // Bounding rectangle - minx = floorf(std::max(min3(v1.x, v2.x, v3.x), 0.0f)); - miny = floorf(std::max(min3(v1.y, v2.y, v3.y), 0.0f)); - maxx = ceilf( std::min(max3(v1.x, v2.x, v3.x), extents.x - 1.0f)); - maxy = ceilf( std::min(max3(v1.y, v2.y, v3.y), extents.y - 1.0f)); - } else { - // Bounding rectangle - minx = floorf(min3(v1.x, v2.x, v3.x)); - miny = floorf(min3(v1.y, v2.y, v3.y)); - maxx = ceilf( max3(v1.x, v2.x, v3.x)); - maxy = ceilf( max3(v1.y, v2.y, v3.y)); - } + const float BK_INSIDE = sqrtf(BK_SIZE*BK_SIZE/2.0f); + const float BK_OUTSIDE = -sqrtf(BK_SIZE*BK_SIZE/2.0f); + // Bounding rectangle + float minx = floorf(max(min3(v1.x, v2.x, v3.x), 0.0f)); + float miny = floorf(max(min3(v1.y, v2.y, v3.y), 0.0f)); + float maxx = ceilf( min(max3(v1.x, v2.x, v3.x), extents.x - 1.0f)); + float maxy = ceilf( min(max3(v1.y, v2.y, v3.y), extents.y - 1.0f)); // There's no reason to align the blocks to the viewport, instead we align them to the origin of the triangle bounds. minx = floorf(minx); miny = floorf(miny); @@ -3885,47 +3957,32 @@ struct Triangle if ( (aC <= BK_OUTSIDE) || (bC <= BK_OUTSIDE) || (cC <= BK_OUTSIDE) ) continue; // Accept whole block when totally covered if ( (aC >= BK_INSIDE) && (bC >= BK_INSIDE) && (cC >= BK_INSIDE) ) { - Vector3 texRow = t1 + dy * (y0 - v1.y) + dx * (x0 - v1.x); for (float y = y0; y < y0 + BK_SIZE; y++) { - Vector3 tex = texRow; for (float x = x0; x < x0 + BK_SIZE; x++) { - if (!cb(param, (int)x, (int)y, tex, dx, dy, 1.0f)) { + if (!cb(param, (int)x, (int)y)) { return false; } - tex += dx; } - texRow += dy; } } else { // Partially covered block float CY1 = C1 + n1.x * x0 + n1.y * y0; float CY2 = C2 + n2.x * x0 + n2.y * y0; float CY3 = C3 + n3.x * x0 + n3.y * y0; - Vector3 texRow = t1 + dy * (y0 - v1.y) + dx * (x0 - v1.x); for (float y = y0; y < y0 + BK_SIZE; y++) { // @@ This is not clipping to scissor rectangle correctly. float CX1 = CY1; float CX2 = CY2; float CX3 = CY3; - Vector3 tex = texRow; for (float x = x0; x < x0 + BK_SIZE; x++) { // @@ This is not clipping to scissor rectangle correctly. if (CX1 >= PX_INSIDE && CX2 >= PX_INSIDE && CX3 >= PX_INSIDE) { - // pixel completely covered - Vector3 tex2 = t1 + dx * (x - v1.x) + dy * (y - v1.y); - if (!cb(param, (int)x, (int)y, tex2, dx, dy, 1.0f)) { + if (!cb(param, (int)x, (int)y)) { return false; } } else if ((CX1 >= PX_OUTSIDE) && (CX2 >= PX_OUTSIDE) && (CX3 >= PX_OUTSIDE)) { // triangle partially covers pixel. do clipping. ClippedTriangle ct(v1 - Vector2(x, y), v2 - Vector2(x, y), v3 - Vector2(x, y)); ct.clipAABox(-0.5, -0.5, 0.5, 0.5); - Vector2 centroid = ct.centroid(); - float area = ct.area(); - if (area > 0.0f) { - Vector3 texCent = tex - dx * centroid.x - dy * centroid.y; - //xaAssert(texCent.x >= -0.1f && texCent.x <= 1.1f); // @@ Centroid is not very exact... - //xaAssert(texCent.y >= -0.1f && texCent.y <= 1.1f); - //xaAssert(texCent.z >= -0.1f && texCent.z <= 1.1f); - //Vector3 texCent2 = t1 + dx * (x - v1.x) + dy * (y - v1.y); - if (!cb(param, (int)x, (int)y, texCent, dx, dy, area)) { + if (ct.area() > 0.0f) { + if (!cb(param, (int)x, (int)y)) { return false; } } @@ -3933,12 +3990,10 @@ struct Triangle CX1 += n1.x; CX2 += n2.x; CX3 += n3.x; - tex += dx; } CY1 += n1.y; CY2 += n2.y; CY3 += n3.y; - texRow += dy; } } } @@ -3953,9 +4008,6 @@ struct Triangle Vector2 hv = v1; v1 = v2; v2 = hv; // swap pos - Vector3 ht = t1; - t1 = t2; - t2 = ht; // swap tex } } @@ -3976,77 +4028,24 @@ struct Triangle // Vertices. Vector2 v1, v2, v3; Vector2 n1, n2, n3; // unit inward normals - Vector3 t1, t2, t3; - - // Deltas. - Vector3 dx, dy; - - float sign; - bool valid; -}; - -enum Mode -{ - Mode_Nearest, - Mode_Antialiased }; // Process the given triangle. Returns false if rasterization was interrupted by the callback. -static bool drawTriangle(Mode mode, Vector2::Arg extents, bool enableScissors, const Vector2 v[3], SamplingCallback cb, void *param) +static bool drawTriangle(const Vector2 &extents, const Vector2 v[3], SamplingCallback cb, void *param) { - Triangle tri(v[0], v[1], v[2], Vector3(1, 0, 0), Vector3(0, 1, 0), Vector3(0, 0, 1)); + Triangle tri(v[0], v[1], v[2]); // @@ It would be nice to have a conservative drawing mode that enlarges the triangle extents by one texel and is able to handle degenerate triangles. // @@ Maybe the simplest thing to do would be raster triangle edges. - if (tri.valid) { - if (mode == Mode_Antialiased) { - return tri.drawAA(extents, enableScissors, cb, param); - } - if (mode == Mode_Nearest) { - return tri.draw(extents, enableScissors, cb, param); - } - } + if (tri.isValid()) + return tri.drawAA(extents, cb, param); return true; } -// Process the given quad. Returns false if rasterization was interrupted by the callback. -static bool drawQuad(Mode mode, Vector2::Arg extents, bool enableScissors, const Vector2 v[4], SamplingCallback cb, void *param) -{ - bool sign0 = triangleArea2(v[0], v[1], v[2]) > 0.0f; - bool sign1 = triangleArea2(v[0], v[2], v[3]) > 0.0f; - // Divide the quad into two non overlapping triangles. - if (sign0 == sign1) { - Triangle tri0(v[0], v[1], v[2], Vector3(0, 0, 0), Vector3(1, 0, 0), Vector3(1, 1, 0)); - Triangle tri1(v[0], v[2], v[3], Vector3(0, 0, 0), Vector3(1, 1, 0), Vector3(0, 1, 0)); - if (tri0.valid && tri1.valid) { - if (mode == Mode_Antialiased) { - return tri0.drawAA(extents, enableScissors, cb, param) && tri1.drawAA(extents, enableScissors, cb, param); - } else { - return tri0.draw(extents, enableScissors, cb, param) && tri1.draw(extents, enableScissors, cb, param); - } - } - } else { - Triangle tri0(v[0], v[1], v[3], Vector3(0, 0, 0), Vector3(1, 0, 0), Vector3(0, 1, 0)); - Triangle tri1(v[1], v[2], v[3], Vector3(1, 0, 0), Vector3(1, 1, 0), Vector3(0, 1, 0)); - if (tri0.valid && tri1.valid) { - if (mode == Mode_Antialiased) { - return tri0.drawAA(extents, enableScissors, cb, param) && tri1.drawAA(extents, enableScissors, cb, param); - } else { - return tri0.draw(extents, enableScissors, cb, param) && tri1.draw(extents, enableScissors, cb, param); - } - } - } - return true; -} } // namespace raster // Full and sparse vector and matrix classes. BLAS subset. // Pseudo-BLAS interface. namespace sparse { -enum Transpose -{ - NoTransposed = 0, - Transposed = 1 -}; /** * Sparse matrix class. The matrix is assumed to be sparse and to have @@ -4072,8 +4071,8 @@ public: const Matrix &operator=(const Matrix &m) { - xaAssert(width() == m.width()); - xaAssert(height() == m.height()); + XA_ASSERT(width() == m.width()); + XA_ASSERT(height() == m.height()); m_array = m.m_array; return *this; } @@ -4085,8 +4084,8 @@ public: // x is column, y is row float getCoefficient(uint32_t x, uint32_t y) const { - xaDebugAssert( x < width() ); - xaDebugAssert( y < height() ); + XA_DEBUG_ASSERT( x < width() ); + XA_DEBUG_ASSERT( y < height() ); const uint32_t count = m_array[y].size(); for (uint32_t i = 0; i < count; i++) { if (m_array[y][i].x == x) return m_array[y][i].v; @@ -4096,8 +4095,8 @@ public: void setCoefficient(uint32_t x, uint32_t y, float f) { - xaDebugAssert( x < width() ); - xaDebugAssert( y < height() ); + XA_DEBUG_ASSERT( x < width() ); + XA_DEBUG_ASSERT( y < height() ); const uint32_t count = m_array[y].size(); for (uint32_t i = 0; i < count; i++) { if (m_array[y][i].x == x) { @@ -4113,7 +4112,7 @@ public: float dotRow(uint32_t y, const FullVector &v) const { - xaDebugAssert( y < height() ); + XA_DEBUG_ASSERT( y < height() ); const uint32_t count = m_array[y].size(); float sum = 0; for (uint32_t i = 0; i < count; i++) { @@ -4124,7 +4123,7 @@ public: void madRow(uint32_t y, float alpha, FullVector &v) const { - xaDebugAssert(y < height()); + XA_DEBUG_ASSERT(y < height()); const uint32_t count = m_array[y].size(); for (uint32_t i = 0; i < count; i++) { v[m_array[y][i].x] += alpha * m_array[y][i].v; @@ -4133,33 +4132,24 @@ public: void clearRow(uint32_t y) { - xaDebugAssert( y < height() ); + XA_DEBUG_ASSERT( y < height() ); m_array[y].clear(); } - void scaleRow(uint32_t y, float f) - { - xaDebugAssert( y < height() ); - const uint32_t count = m_array[y].size(); - for (uint32_t i = 0; i < count; i++) { - m_array[y][i].v *= f; - } - } - - const std::vector<Coefficient> &getRow(uint32_t y) const { return m_array[y]; } + const Array<Coefficient> &getRow(uint32_t y) const { return m_array[y]; } private: /// Number of columns. const uint32_t m_width; /// Array of matrix elements. - std::vector< std::vector<Coefficient> > m_array; + Array< Array<Coefficient> > m_array; }; // y = a * x + y static void saxpy(float a, const FullVector &x, FullVector &y) { - xaDebugAssert(x.dimension() == y.dimension()); + XA_DEBUG_ASSERT(x.dimension() == y.dimension()); const uint32_t dim = x.dimension(); for (uint32_t i = 0; i < dim; i++) { y[i] += a * x[i]; @@ -4168,7 +4158,7 @@ static void saxpy(float a, const FullVector &x, FullVector &y) static void copy(const FullVector &x, FullVector &y) { - xaDebugAssert(x.dimension() == y.dimension()); + XA_DEBUG_ASSERT(x.dimension() == y.dimension()); const uint32_t dim = x.dimension(); for (uint32_t i = 0; i < dim; i++) { y[i] = x[i]; @@ -4185,7 +4175,7 @@ static void scal(float a, FullVector &x) static float dot(const FullVector &x, const FullVector &y) { - xaDebugAssert(x.dimension() == y.dimension()); + XA_DEBUG_ASSERT(x.dimension() == y.dimension()); const uint32_t dim = x.dimension(); float sum = 0; for (uint32_t i = 0; i < dim; i++) { @@ -4194,61 +4184,35 @@ static float dot(const FullVector &x, const FullVector &y) return sum; } -static void mult(Transpose TM, const Matrix &M, const FullVector &x, FullVector &y) -{ - const uint32_t w = M.width(); - const uint32_t h = M.height(); - if (TM == Transposed) { - xaDebugAssert( h == x.dimension() ); - xaDebugAssert( w == y.dimension() ); - y.fill(0.0f); - for (uint32_t i = 0; i < h; i++) { - M.madRow(i, x[i], y); - } - } else { - xaDebugAssert( w == x.dimension() ); - xaDebugAssert( h == y.dimension() ); - for (uint32_t i = 0; i < h; i++) { - y[i] = M.dotRow(i, x); - } - } -} - // y = M * x static void mult(const Matrix &M, const FullVector &x, FullVector &y) { - mult(NoTransposed, M, x, y); -} - -static void sgemv(float alpha, Transpose TA, const Matrix &A, const FullVector &x, float beta, FullVector &y) -{ - const uint32_t w = A.width(); - const uint32_t h = A.height(); - if (TA == Transposed) { - xaDebugAssert( h == x.dimension() ); - xaDebugAssert( w == y.dimension() ); - for (uint32_t i = 0; i < h; i++) { - A.madRow(i, alpha * x[i], y); - } - } else { - xaDebugAssert( w == x.dimension() ); - xaDebugAssert( h == y.dimension() ); - for (uint32_t i = 0; i < h; i++) { - y[i] = alpha * A.dotRow(i, x) + beta * y[i]; - } - } + uint32_t w = M.width(); + uint32_t h = M.height(); + XA_DEBUG_ASSERT( w == x.dimension() ); + XA_UNUSED(w); + XA_DEBUG_ASSERT( h == y.dimension() ); + for (uint32_t i = 0; i < h; i++) + y[i] = M.dotRow(i, x); } // y = alpha*A*x + beta*y static void sgemv(float alpha, const Matrix &A, const FullVector &x, float beta, FullVector &y) { - sgemv(alpha, NoTransposed, A, x, beta, y); + const uint32_t w = A.width(); + const uint32_t h = A.height(); + XA_DEBUG_ASSERT( w == x.dimension() ); + XA_DEBUG_ASSERT( h == y.dimension() ); + XA_UNUSED(w); + XA_UNUSED(h); + for (uint32_t i = 0; i < h; i++) + y[i] = alpha * A.dotRow(i, x) + beta * y[i]; } // dot y-row of A by x-column of B static float dotRowColumn(int y, const Matrix &A, int x, const Matrix &B) { - const std::vector<Matrix::Coefficient> &row = A.getRow(y); + const Array<Matrix::Coefficient> &row = A.getRow(y); const uint32_t count = row.size(); float sum = 0.0f; for (uint32_t i = 0; i < count; i++) { @@ -4258,96 +4222,54 @@ static float dotRowColumn(int y, const Matrix &A, int x, const Matrix &B) return sum; } -// dot y-row of A by x-row of B -static float dotRowRow(int y, const Matrix &A, int x, const Matrix &B) -{ - const std::vector<Matrix::Coefficient> &row = A.getRow(y); - const uint32_t count = row.size(); - float sum = 0.0f; - for (uint32_t i = 0; i < count; i++) { - const Matrix::Coefficient &c = row[i]; - sum += c.v * B.getCoefficient(c.x, x); - } - return sum; -} - -// dot y-column of A by x-column of B -static float dotColumnColumn(int y, const Matrix &A, int x, const Matrix &B) -{ - xaDebugAssert(A.height() == B.height()); - const uint32_t h = A.height(); - float sum = 0.0f; - for (uint32_t i = 0; i < h; i++) { - sum += A.getCoefficient(y, i) * B.getCoefficient(x, i); - } - return sum; -} - static void transpose(const Matrix &A, Matrix &B) { - xaDebugAssert(A.width() == B.height()); - xaDebugAssert(B.width() == A.height()); + XA_DEBUG_ASSERT(A.width() == B.height()); + XA_DEBUG_ASSERT(B.width() == A.height()); const uint32_t w = A.width(); for (uint32_t x = 0; x < w; x++) { B.clearRow(x); } const uint32_t h = A.height(); for (uint32_t y = 0; y < h; y++) { - const std::vector<Matrix::Coefficient> &row = A.getRow(y); + const Array<Matrix::Coefficient> &row = A.getRow(y); const uint32_t count = row.size(); for (uint32_t i = 0; i < count; i++) { const Matrix::Coefficient &c = row[i]; - xaDebugAssert(c.x < w); + XA_DEBUG_ASSERT(c.x < w); B.setCoefficient(y, c.x, c.v); } } } -static void sgemm(float alpha, Transpose TA, const Matrix &A, Transpose TB, const Matrix &B, float beta, Matrix &C) +static void sgemm(float alpha, const Matrix &A, const Matrix &B, float beta, Matrix &C) { const uint32_t w = C.width(); const uint32_t h = C.height(); - uint32_t aw = (TA == NoTransposed) ? A.width() : A.height(); - uint32_t ah = (TA == NoTransposed) ? A.height() : A.width(); - uint32_t bw = (TB == NoTransposed) ? B.width() : B.height(); - uint32_t bh = (TB == NoTransposed) ? B.height() : B.width(); - xaDebugAssert(aw == bh); - xaDebugAssert(bw == ah); - xaDebugAssert(w == bw); - xaDebugAssert(h == ah); -#ifdef NDEBUG - aw = ah = bw = bh = 0; // silence unused parameter warning +#if XA_DEBUG + const uint32_t aw = A.width(); + const uint32_t ah = A.height(); + const uint32_t bw = B.width(); + const uint32_t bh = B.height(); + XA_DEBUG_ASSERT(aw == bh); + XA_DEBUG_ASSERT(bw == ah); + XA_DEBUG_ASSERT(w == bw); + XA_DEBUG_ASSERT(h == ah); #endif for (uint32_t y = 0; y < h; y++) { for (uint32_t x = 0; x < w; x++) { float c = beta * C.getCoefficient(x, y); - if (TA == NoTransposed && TB == NoTransposed) { - // dot y-row of A by x-column of B. - c += alpha * dotRowColumn(y, A, x, B); - } else if (TA == Transposed && TB == Transposed) { - // dot y-column of A by x-row of B. - c += alpha * dotRowColumn(x, B, y, A); - } else if (TA == Transposed && TB == NoTransposed) { - // dot y-column of A by x-column of B. - c += alpha * dotColumnColumn(y, A, x, B); - } else if (TA == NoTransposed && TB == Transposed) { - // dot y-row of A by x-row of B. - c += alpha * dotRowRow(y, A, x, B); - } + // dot y-row of A by x-column of B. + c += alpha * dotRowColumn(y, A, x, B); C.setCoefficient(x, y, c); } } } -static void mult(Transpose TA, const Matrix &A, Transpose TB, const Matrix &B, Matrix &C) -{ - sgemm(1.0f, TA, A, TB, B, 0.0f, C); -} - // C = A * B static void mult(const Matrix &A, const Matrix &B, Matrix &C) { - mult(NoTransposed, A, NoTransposed, B, C); + sgemm(1.0f, A, B, 0.0f, C); } } // namespace sparse @@ -4357,10 +4279,10 @@ class JacobiPreconditioner public: JacobiPreconditioner(const sparse::Matrix &M, bool symmetric) : m_inverseDiagonal(M.width()) { - xaAssert(M.isSquare()); + XA_ASSERT(M.isSquare()); for (uint32_t x = 0; x < M.width(); x++) { float elem = M.getCoefficient(x, x); - //xaDebugAssert( elem != 0.0f ); // This can be zero in the presence of zero area triangles. + //XA_DEBUG_ASSERT( elem != 0.0f ); // This can be zero in the presence of zero area triangles. if (symmetric) { m_inverseDiagonal[x] = (elem != 0) ? 1.0f / sqrtf(fabsf(elem)) : 1.0f; } else { @@ -4371,8 +4293,8 @@ public: void apply(const FullVector &x, FullVector &y) const { - xaDebugAssert(x.dimension() == m_inverseDiagonal.dimension()); - xaDebugAssert(y.dimension() == m_inverseDiagonal.dimension()); + XA_DEBUG_ASSERT(x.dimension() == m_inverseDiagonal.dimension()); + XA_DEBUG_ASSERT(y.dimension() == m_inverseDiagonal.dimension()); // @@ Wrap vector component-wise product into a separate function. const uint32_t D = x.dimension(); for (uint32_t i = 0; i < D; i++) { @@ -4391,9 +4313,9 @@ public: // Solve the symmetric system: At·A·x = At·b static bool LeastSquaresSolver(const sparse::Matrix &A, const FullVector &b, FullVector &x, float epsilon = 1e-5f) { - xaDebugAssert(A.width() == x.dimension()); - xaDebugAssert(A.height() == b.dimension()); - xaDebugAssert(A.height() >= A.width()); // @@ If height == width we could solve it directly... + XA_DEBUG_ASSERT(A.width() == x.dimension()); + XA_DEBUG_ASSERT(A.height() == b.dimension()); + XA_DEBUG_ASSERT(A.height() >= A.width()); // @@ If height == width we could solve it directly... const uint32_t D = A.width(); sparse::Matrix At(A.height(), A.width()); sparse::transpose(A, At); @@ -4407,12 +4329,12 @@ public: // See section 10.4.3 in: Mesh Parameterization: Theory and Practice, Siggraph Course Notes, August 2007 static bool LeastSquaresSolver(const sparse::Matrix &A, const FullVector &b, FullVector &x, const uint32_t *lockedParameters, uint32_t lockedCount, float epsilon = 1e-5f) { - xaDebugAssert(A.width() == x.dimension()); - xaDebugAssert(A.height() == b.dimension()); - xaDebugAssert(A.height() >= A.width() - lockedCount); + XA_DEBUG_ASSERT(A.width() == x.dimension()); + XA_DEBUG_ASSERT(A.height() == b.dimension()); + XA_DEBUG_ASSERT(A.height() >= A.width() - lockedCount); // @@ This is not the most efficient way of building a system with reduced degrees of freedom. It would be faster to do it on the fly. const uint32_t D = A.width() - lockedCount; - xaDebugAssert(D > 0); + XA_DEBUG_ASSERT(D > 0); // Compute: b - Al * xl FullVector b_Alxl(b); for (uint32_t y = 0; y < A.height(); y++) { @@ -4504,62 +4426,12 @@ private: * Jonhathan Richard Shewchuk. * **/ - static bool ConjugateGradientSolver(const sparse::Matrix &A, const FullVector &b, FullVector &x, float epsilon) - { - xaDebugAssert( A.isSquare() ); - xaDebugAssert( A.width() == b.dimension() ); - xaDebugAssert( A.width() == x.dimension() ); - int i = 0; - const int D = A.width(); - const int i_max = 4 * D; // Convergence should be linear, but in some cases, it's not. - FullVector r(D); // residual - FullVector p(D); // search direction - FullVector q(D); // - float delta_0; - float delta_old; - float delta_new; - float alpha; - float beta; - // r = b - A·x; - sparse::copy(b, r); - sparse::sgemv(-1, A, x, 1, r); - // p = r; - sparse::copy(r, p); - delta_new = sparse::dot( r, r ); - delta_0 = delta_new; - while (i < i_max && delta_new > epsilon * epsilon * delta_0) { - i++; - // q = A·p - mult(A, p, q); - // alpha = delta_new / p·q - alpha = delta_new / sparse::dot( p, q ); - // x = alfa·p + x - sparse::saxpy(alpha, p, x); - if ((i & 31) == 0) { // recompute r after 32 steps - // r = b - A·x - sparse::copy(b, r); - sparse::sgemv(-1, A, x, 1, r); - } else { - // r = r - alpha·q - sparse::saxpy(-alpha, q, r); - } - delta_old = delta_new; - delta_new = sparse::dot( r, r ); - beta = delta_new / delta_old; - // p = beta·p + r - sparse::scal(beta, p); - sparse::saxpy(1, r, p); - } - return delta_new <= epsilon * epsilon * delta_0; - } - - // Conjugate gradient with preconditioner. static bool ConjugateGradientSolver(const JacobiPreconditioner &preconditioner, const sparse::Matrix &A, const FullVector &b, FullVector &x, float epsilon) { - xaDebugAssert( A.isSquare() ); - xaDebugAssert( A.width() == b.dimension() ); - xaDebugAssert( A.width() == x.dimension() ); + XA_DEBUG_ASSERT( A.isSquare() ); + XA_DEBUG_ASSERT( A.width() == b.dimension() ); + XA_DEBUG_ASSERT( A.width() == x.dimension() ); int i = 0; const int D = A.width(); const int i_max = 4 * D; // Convergence should be linear, but in some cases, it's not. @@ -4582,7 +4454,7 @@ private: while (i < i_max && delta_new > epsilon * epsilon * delta_0) { i++; // q = A·p - mult(A, p, q); + sparse::mult(A, p, q); // alpha = delta_new / p·q alpha = delta_new / sparse::dot(p, q); // x = alfa·p + x @@ -4609,59 +4481,59 @@ private: static bool SymmetricSolver(const sparse::Matrix &A, const FullVector &b, FullVector &x, float epsilon = 1e-5f) { - xaDebugAssert(A.height() == A.width()); - xaDebugAssert(A.height() == b.dimension()); - xaDebugAssert(b.dimension() == x.dimension()); + XA_DEBUG_ASSERT(A.height() == A.width()); + XA_DEBUG_ASSERT(A.height() == b.dimension()); + XA_DEBUG_ASSERT(b.dimension() == x.dimension()); JacobiPreconditioner jacobi(A, true); return ConjugateGradientSolver(jacobi, A, b, x, epsilon); } }; namespace param { -class Atlas; -class Chart; // Fast sweep in 3 directions -static bool findApproximateDiameterVertices(halfedge::Mesh *mesh, halfedge::Vertex **a, halfedge::Vertex **b) +static bool findApproximateDiameterVertices(Mesh *mesh, uint32_t *a, uint32_t *b) { - xaDebugAssert(mesh != NULL); - xaDebugAssert(a != NULL); - xaDebugAssert(b != NULL); + XA_DEBUG_ASSERT(a != nullptr); + XA_DEBUG_ASSERT(b != nullptr); const uint32_t vertexCount = mesh->vertexCount(); - halfedge::Vertex *minVertex[3]; - halfedge::Vertex *maxVertex[3]; - minVertex[0] = minVertex[1] = minVertex[2] = NULL; - maxVertex[0] = maxVertex[1] = maxVertex[2] = NULL; + uint32_t minVertex[3]; + uint32_t maxVertex[3]; + minVertex[0] = minVertex[1] = minVertex[2] = UINT32_MAX; + maxVertex[0] = maxVertex[1] = maxVertex[2] = UINT32_MAX; for (uint32_t v = 1; v < vertexCount; v++) { - halfedge::Vertex *vertex = mesh->vertexAt(v); - xaDebugAssert(vertex != NULL); - if (vertex->isBoundary()) { - minVertex[0] = minVertex[1] = minVertex[2] = vertex; - maxVertex[0] = maxVertex[1] = maxVertex[2] = vertex; + if (mesh->isBoundaryVertex(v)) { + minVertex[0] = minVertex[1] = minVertex[2] = v; + maxVertex[0] = maxVertex[1] = maxVertex[2] = v; break; } } - if (minVertex[0] == NULL) { + if (minVertex[0] == UINT32_MAX) { // Input mesh has not boundaries. return false; } for (uint32_t v = 1; v < vertexCount; v++) { - halfedge::Vertex *vertex = mesh->vertexAt(v); - xaDebugAssert(vertex != NULL); - if (!vertex->isBoundary()) { + if (!mesh->isBoundaryVertex(v)) { // Skip interior vertices. continue; } - if (vertex->pos.x < minVertex[0]->pos.x) minVertex[0] = vertex; - else if (vertex->pos.x > maxVertex[0]->pos.x) maxVertex[0] = vertex; - if (vertex->pos.y < minVertex[1]->pos.y) minVertex[1] = vertex; - else if (vertex->pos.y > maxVertex[1]->pos.y) maxVertex[1] = vertex; - if (vertex->pos.z < minVertex[2]->pos.z) minVertex[2] = vertex; - else if (vertex->pos.z > maxVertex[2]->pos.z) maxVertex[2] = vertex; + const Vector3 &pos = mesh->position(v); + if (pos.x < mesh->position(minVertex[0]).x) + minVertex[0] = v; + else if (pos.x > mesh->position(maxVertex[0]).x) + maxVertex[0] = v; + if (pos.y < mesh->position(minVertex[1]).y) + minVertex[1] = v; + else if (pos.y > mesh->position(maxVertex[1]).y) + maxVertex[1] = v; + if (pos.z < mesh->position(minVertex[2]).z) + minVertex[2] = v; + else if (pos.z > mesh->position(maxVertex[2]).z) + maxVertex[2] = v; } float lengths[3]; for (int i = 0; i < 3; i++) { - lengths[i] = length(minVertex[i]->pos - maxVertex[i]->pos); + lengths[i] = length(mesh->position(minVertex[i]) - mesh->position(maxVertex[i])); } if (lengths[0] > lengths[1] && lengths[0] > lengths[2]) { *a = minVertex[0]; @@ -4678,34 +4550,28 @@ static bool findApproximateDiameterVertices(halfedge::Mesh *mesh, halfedge::Vert // Conformal relations from Brecht Van Lommel (based on ABF): -static float vec_angle_cos(Vector3::Arg v1, Vector3::Arg v2, Vector3::Arg v3) +static float vec_angle_cos(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3) { Vector3 d1 = v1 - v2; Vector3 d2 = v3 - v2; return clamp(dot(d1, d2) / (length(d1) * length(d2)), -1.0f, 1.0f); } -static float vec_angle(Vector3::Arg v1, Vector3::Arg v2, Vector3::Arg v3) +static float vec_angle(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3) { float dot = vec_angle_cos(v1, v2, v3); return acosf(dot); } -static void triangle_angles(Vector3::Arg v1, Vector3::Arg v2, Vector3::Arg v3, float *a1, float *a2, float *a3) +static void triangle_angles(const Vector3 &v1, const Vector3 &v2, const Vector3 &v3, float *a1, float *a2, float *a3) { *a1 = vec_angle(v3, v1, v2); *a2 = vec_angle(v1, v2, v3); - *a3 = PI - *a2 - *a1; + *a3 = kPi - *a2 - *a1; } -static void setup_abf_relations(sparse::Matrix &A, int row, const halfedge::Vertex *v0, const halfedge::Vertex *v1, const halfedge::Vertex *v2) +static void setup_abf_relations(sparse::Matrix &A, int row, int id0, int id1, int id2, const Vector3 &p0, const Vector3 &p1, const Vector3 &p2) { - int id0 = v0->id; - int id1 = v1->id; - int id2 = v2->id; - Vector3 p0 = v0->pos; - Vector3 p1 = v1->pos; - Vector3 p2 = v2->pos; // @@ IC: Wouldn't it be more accurate to return cos and compute 1-cos^2? // It does indeed seem to be a little bit more robust. // @@ Need to revisit this more carefully! @@ -4715,19 +4581,19 @@ static void setup_abf_relations(sparse::Matrix &A, int row, const halfedge::Vert float s1 = sinf(a1); float s2 = sinf(a2); if (s1 > s0 && s1 > s2) { - std::swap(s1, s2); - std::swap(s0, s1); - std::swap(a1, a2); - std::swap(a0, a1); - std::swap(id1, id2); - std::swap(id0, id1); + swap(s1, s2); + swap(s0, s1); + swap(a1, a2); + swap(a0, a1); + swap(id1, id2); + swap(id0, id1); } else if (s0 > s1 && s0 > s2) { - std::swap(s0, s2); - std::swap(s0, s1); - std::swap(a0, a2); - std::swap(a0, a1); - std::swap(id0, id2); - std::swap(id0, id1); + swap(s0, s2); + swap(s0, s1); + swap(a0, a2); + swap(a0, a1); + swap(id0, id2); + swap(id0, id1); } float c0 = cosf(a0); float ratio = (s2 == 0.0f) ? 1.0f : s1 / s2; @@ -4755,14 +4621,13 @@ static void setup_abf_relations(sparse::Matrix &A, int row, const halfedge::Vert A.setCoefficient(v2_id, 2 * row + 1, 1); } -bool computeLeastSquaresConformalMap(halfedge::Mesh *mesh) +static bool computeLeastSquaresConformalMap(Mesh *mesh) { - xaDebugAssert(mesh != NULL); // For this to work properly, mesh should not have colocals that have the same // attributes, unless you want the vertices to actually have different texcoords. const uint32_t vertexCount = mesh->vertexCount(); const uint32_t D = 2 * vertexCount; - const uint32_t N = 2 * halfedge::countMeshTriangles(mesh); + const uint32_t N = 2 * mesh->faceCount(); // N is the number of equations (one per triangle) // D is the number of variables (one per vertex; there are 2 pinned vertices). if (N < D - 4) { @@ -4774,118 +4639,64 @@ bool computeLeastSquaresConformalMap(halfedge::Mesh *mesh) // Fill b: b.fill(0.0f); // Fill x: - halfedge::Vertex *v0; - halfedge::Vertex *v1; + uint32_t v0, v1; if (!findApproximateDiameterVertices(mesh, &v0, &v1)) { // Mesh has no boundaries. return false; } - if (v0->tex == v1->tex) { + if (mesh->texcoord(v0) == mesh->texcoord(v1)) { // LSCM expects an existing parameterization. return false; } for (uint32_t v = 0; v < vertexCount; v++) { - halfedge::Vertex *vertex = mesh->vertexAt(v); - xaDebugAssert(vertex != NULL); // Initial solution. - x[2 * v + 0] = vertex->tex.x; - x[2 * v + 1] = vertex->tex.y; + x[2 * v + 0] = mesh->texcoord(v).x; + x[2 * v + 1] = mesh->texcoord(v).y; } // Fill A: const uint32_t faceCount = mesh->faceCount(); for (uint32_t f = 0, t = 0; f < faceCount; f++) { - const halfedge::Face *face = mesh->faceAt(f); - xaDebugAssert(face != NULL); - xaDebugAssert(face->edgeCount() == 3); - const halfedge::Vertex *vertex0 = NULL; - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Edge *edge = it.current(); - xaAssert(edge != NULL); - if (vertex0 == NULL) { - vertex0 = edge->vertex; - } else if (edge->next->vertex != vertex0) { - const halfedge::Vertex *vertex1 = edge->from(); - const halfedge::Vertex *vertex2 = edge->to(); - setup_abf_relations(A, t, vertex0, vertex1, vertex2); - //setup_conformal_map_relations(A, t, vertex0, vertex1, vertex2); - t++; - } - } + const uint32_t vertex0 = mesh->vertexAt(f * 3 + 0); + const uint32_t vertex1 = mesh->vertexAt(f * 3 + 1); + const uint32_t vertex2 = mesh->vertexAt(f * 3 + 2); + setup_abf_relations(A, t, vertex0, vertex1, vertex2, mesh->position(vertex0), mesh->position(vertex1), mesh->position(vertex2)); + t++; } const uint32_t lockedParameters[] = { - 2 * v0->id + 0, - 2 * v0->id + 1, - 2 * v1->id + 0, - 2 * v1->id + 1 + 2 * v0 + 0, + 2 * v0 + 1, + 2 * v1 + 0, + 2 * v1 + 1 }; // Solve Solver::LeastSquaresSolver(A, b, x, lockedParameters, 4, 0.000001f); // Map x back to texcoords: - for (uint32_t v = 0; v < vertexCount; v++) { - halfedge::Vertex *vertex = mesh->vertexAt(v); - xaDebugAssert(vertex != NULL); - vertex->tex = Vector2(x[2 * v + 0], x[2 * v + 1]); - } + for (uint32_t v = 0; v < vertexCount; v++) + mesh->texcoord(v) = Vector2(x[2 * v + 0], x[2 * v + 1]); return true; } -bool computeOrthogonalProjectionMap(halfedge::Mesh *mesh) +static bool computeOrthogonalProjectionMap(Mesh *mesh) { - Vector3 axis[2]; uint32_t vertexCount = mesh->vertexCount(); - std::vector<Vector3> points(vertexCount); - points.resize(vertexCount); - for (uint32_t i = 0; i < vertexCount; i++) { - points[i] = mesh->vertexAt(i)->pos; - } // Avoid redundant computations. float matrix[6]; - Fit::computeCovariance(vertexCount, points.data(), matrix); - if (matrix[0] == 0 && matrix[3] == 0 && matrix[5] == 0) { + Fit::computeCovariance(vertexCount, &mesh->position(0), matrix); + if (matrix[0] == 0 && matrix[3] == 0 && matrix[5] == 0) return false; - } float eigenValues[3]; Vector3 eigenVectors[3]; - if (!Fit::eigenSolveSymmetric3(matrix, eigenValues, eigenVectors)) { + if (!Fit::eigenSolveSymmetric3(matrix, eigenValues, eigenVectors)) return false; - } - axis[0] = normalize(eigenVectors[0]); - axis[1] = normalize(eigenVectors[1]); + Vector3 axis[2]; + axis[0] = normalize(eigenVectors[0], kEpsilon); + axis[1] = normalize(eigenVectors[1], kEpsilon); // Project vertices to plane. - for (halfedge::Mesh::VertexIterator it(mesh->vertices()); !it.isDone(); it.advance()) { - halfedge::Vertex *vertex = it.current(); - vertex->tex.x = dot(axis[0], vertex->pos); - vertex->tex.y = dot(axis[1], vertex->pos); - } + for (uint32_t i = 0; i < vertexCount; i++) + mesh->texcoord(i) = Vector2(dot(axis[0], mesh->position(i)), dot(axis[1], mesh->position(i))); return true; } -void computeSingleFaceMap(halfedge::Mesh *mesh) -{ - xaDebugAssert(mesh != NULL); - xaDebugAssert(mesh->faceCount() == 1); - halfedge::Face *face = mesh->faceAt(0); - xaAssert(face != NULL); - Vector3 p0 = face->edge->from()->pos; - Vector3 p1 = face->edge->to()->pos; - Vector3 X = normalizeSafe(p1 - p0, Vector3(0.0f), 0.0f); - Vector3 Z = face->normal(); - Vector3 Y = normalizeSafe(cross(Z, X), Vector3(0.0f), 0.0f); - uint32_t i = 0; - for (halfedge::Face::EdgeIterator it(face->edges()); !it.isDone(); it.advance(), i++) { - halfedge::Vertex *vertex = it.vertex(); - xaAssert(vertex != NULL); - if (i == 0) { - vertex->tex = Vector2(0); - } else { - Vector3 pn = vertex->pos; - float xn = dot((pn - p0), X); - float yn = dot((pn - p0), Y); - vertex->tex = Vector2(xn, yn); - } - } -} - // Dummy implementation of a priority queue using sort at insertion. // - Insertion is o(n) // - Smallest element goes at the end, so that popping it is o(1). @@ -4894,7 +4705,7 @@ void computeSingleFaceMap(halfedge::Mesh *mesh) // @@ Searcing at removal would remove the need for sorting when priorities change. struct PriorityQueue { - PriorityQueue(uint32_t size = UINT_MAX) : maxSize(size) {} + PriorityQueue(uint32_t size = UINT32_MAX) : maxSize(size) {} void push(float priority, uint32_t face) { @@ -4904,10 +4715,9 @@ struct PriorityQueue if (pairs[i].priority > priority) break; } Pair p = { priority, face }; - pairs.insert(pairs.begin() + i, p); - if (pairs.size() > maxSize) { - pairs.erase(pairs.begin()); - } + pairs.insertAt(i, p); + if (pairs.size() > maxSize) + pairs.removeAt(0); } // push face out of order, to be sorted later. @@ -4949,7 +4759,7 @@ struct PriorityQueue struct Pair { - bool operator <(const Pair &p) const + bool operator<(const Pair &p) const { return priority > p.priority; // !! Sort in inverse priority order! } @@ -4958,164 +4768,411 @@ struct PriorityQueue uint32_t face; }; - std::vector<Pair> pairs; + Array<Pair> pairs; }; struct ChartBuildData { - ChartBuildData(int id) : id(id) - { - planeNormal = Vector3(0); - centroid = Vector3(0); - coneAxis = Vector3(0); - coneAngle = 0; - area = 0; - boundaryLength = 0; - normalSum = Vector3(0); - centroidSum = Vector3(0); - } - - int id; - - // Proxy info: - Vector3 planeNormal; - Vector3 centroid; - Vector3 coneAxis; - float coneAngle; - - float area; - float boundaryLength; - Vector3 normalSum; - Vector3 centroidSum; - - std::vector<uint32_t> seeds; // @@ These could be a pointers to the halfedge faces directly. - std::vector<uint32_t> faces; + int id = -1; + Vector3 averageNormal = Vector3(0.0f); + float area = 0.0f; + float boundaryLength = 0.0f; + Vector3 normalSum = Vector3(0.0f); + Vector3 centroidSum = Vector3(0.0f); // Sum of chart face centroids. + Vector3 centroid = Vector3(0.0f); // Average centroid of chart faces. + Array<uint32_t> seeds; + Array<uint32_t> faces; PriorityQueue candidates; + Basis basis; // Of first face. }; struct AtlasBuilder { - AtlasBuilder(const halfedge::Mesh *m) : mesh(m), facesLeft(m->faceCount()) + // @@ Hardcoded to 10? + AtlasBuilder(const Mesh *mesh, Array<uint32_t> *meshFaces, const ChartOptions &options) : m_mesh(mesh), m_meshFaces(meshFaces), m_facesLeft(mesh->faceCount()), m_bestTriangles(10), m_options(options) { - const uint32_t faceCount = m->faceCount(); - faceChartArray.resize(faceCount, -1); - faceCandidateArray.resize(faceCount, (uint32_t)-1); + XA_PROFILE_START(atlasBuilderInit) + const uint32_t faceCount = m_mesh->faceCount(); + if (meshFaces) { + m_ignoreFaces.resize(faceCount, true); + for (uint32_t f = 0; f < meshFaces->size(); f++) + m_ignoreFaces[(*meshFaces)[f]] = false; + m_facesLeft = meshFaces->size(); + } else { + m_ignoreFaces.resize(faceCount, false); + } + m_faceChartArray.resize(faceCount, -1); + m_faceCandidateArray.resize(faceCount, (uint32_t)-1); + m_texcoords.resize(faceCount * 3); // @@ Floyd for the whole mesh is too slow. We could compute floyd progressively per patch as the patch grows. We need a better solution to compute most central faces. //computeShortestPaths(); // Precompute edge lengths and face areas. - uint32_t edgeCount = m->edgeCount(); - edgeLengths.resize(edgeCount); - for (uint32_t i = 0; i < edgeCount; i++) { - uint32_t id = m->edgeAt(i)->id; - xaDebugAssert(id / 2 == i); -#ifdef NDEBUG - id = 0; // silence unused parameter warning -#endif - edgeLengths[i] = m->edgeAt(i)->length(); - } - faceAreas.resize(faceCount); - for (uint32_t i = 0; i < faceCount; i++) { - faceAreas[i] = m->faceAt(i)->area(); + const uint32_t edgeCount = m_mesh->edgeCount(); + m_edgeLengths.resize(edgeCount, 0.0f); + m_faceAreas.resize(m_mesh->faceCount(), 0.0f); + m_faceNormals.resize(m_mesh->faceCount()); + for (uint32_t f = 0; f < faceCount; f++) { + if (m_ignoreFaces[f]) + continue; + for (Mesh::FaceEdgeIterator it(m_mesh, f); !it.isDone(); it.advance()) { + m_edgeLengths[it.edge()] = internal::length(it.position1() - it.position0()); + XA_DEBUG_ASSERT(m_edgeLengths[it.edge()] > 0.0f); + } + m_faceAreas[f] = mesh->faceArea(f); + XA_DEBUG_ASSERT(m_faceAreas[f] > 0.0f); + m_faceNormals[f] = m_mesh->triangleNormal(f); } + XA_PROFILE_END(atlasBuilderInit) } ~AtlasBuilder() { - const uint32_t chartCount = chartArray.size(); + const uint32_t chartCount = m_chartArray.size(); for (uint32_t i = 0; i < chartCount; i++) { - delete chartArray[i]; + m_chartArray[i]->~ChartBuildData(); + XA_FREE(m_chartArray[i]); } } - void markUnchartedFaces(const std::vector<uint32_t> &unchartedFaces) + uint32_t facesLeft() const { return m_facesLeft; } + uint32_t chartCount() const { return m_chartArray.size(); } + const Array<uint32_t> &chartFaces(uint32_t i) const { return m_chartArray[i]->faces; } + const Basis &chartBasis(uint32_t chartIndex) const { return m_chartArray[chartIndex]->basis; } + + void placeSeeds(float threshold) { - const uint32_t unchartedFaceCount = unchartedFaces.size(); - for (uint32_t i = 0; i < unchartedFaceCount; i++) { - uint32_t f = unchartedFaces[i]; - faceChartArray[f] = -2; - //faceCandidateArray[f] = -2; // @@ ? - removeCandidate(f); - } - xaDebugAssert(facesLeft >= unchartedFaceCount); - facesLeft -= unchartedFaceCount; + // Instead of using a predefiened number of seeds: + // - Add seeds one by one, growing chart until a certain treshold. + // - Undo charts and restart growing process. + // @@ How can we give preference to faces far from sharp features as in the LSCM paper? + // - those points can be found using a simple flood filling algorithm. + // - how do we weight the probabilities? + while (m_facesLeft > 0) + createRandomChart(threshold); } - void computeShortestPaths() + // Returns true if any of the charts can grow more. + bool growCharts(float threshold, uint32_t faceCount) { - const uint32_t faceCount = mesh->faceCount(); - shortestPaths.resize(faceCount * faceCount, FLT_MAX); - // Fill edges: + XA_PROFILE_START(atlasBuilderGrowCharts) + // Using one global list. + faceCount = min(faceCount, m_facesLeft); + bool canAddAny = false; for (uint32_t i = 0; i < faceCount; i++) { - shortestPaths[i * faceCount + i] = 0.0f; - const halfedge::Face *face_i = mesh->faceAt(i); - Vector3 centroid_i = face_i->centroid(); - for (halfedge::Face::ConstEdgeIterator it(face_i->edges()); !it.isDone(); it.advance()) { - const halfedge::Edge *edge = it.current(); - if (!edge->isBoundary()) { - const halfedge::Face *face_j = edge->pair->face; - uint32_t j = face_j->id; - Vector3 centroid_j = face_j->centroid(); - shortestPaths[i * faceCount + j] = shortestPaths[j * faceCount + i] = length(centroid_i - centroid_j); - } + const Candidate &candidate = getBestCandidate(); + if (candidate.metric > threshold) { + XA_PROFILE_END(atlasBuilderGrowCharts) + return false; // Can't grow more. } + createFaceTexcoords(candidate.chart, candidate.face); + if (!canAddFaceToChart(candidate.chart, candidate.face)) + continue; + addFaceToChart(candidate.chart, candidate.face); + canAddAny = true; } - // Use Floyd-Warshall algorithm to compute all paths: - for (uint32_t k = 0; k < faceCount; k++) { - for (uint32_t i = 0; i < faceCount; i++) { - for (uint32_t j = 0; j < faceCount; j++) { - shortestPaths[i * faceCount + j] = std::min(shortestPaths[i * faceCount + j], shortestPaths[i * faceCount + k] + shortestPaths[k * faceCount + j]); - } + XA_PROFILE_END(atlasBuilderGrowCharts) + return canAddAny && m_facesLeft != 0; // Can continue growing. + } + + void resetCharts() + { + const uint32_t faceCount = m_mesh->faceCount(); + for (uint32_t i = 0; i < faceCount; i++) { + m_faceChartArray[i] = -1; + m_faceCandidateArray[i] = (uint32_t)-1; + } + m_facesLeft = m_meshFaces ? m_meshFaces->size() : faceCount; + m_candidateArray.clear(); + const uint32_t chartCount = m_chartArray.size(); + for (uint32_t i = 0; i < chartCount; i++) { + ChartBuildData *chart = m_chartArray[i]; + const uint32_t seed = chart->seeds.back(); + chart->area = 0.0f; + chart->boundaryLength = 0.0f; + chart->normalSum = Vector3(0.0f); + chart->centroidSum = Vector3(0.0f); + chart->centroid = Vector3(0.0f); + chart->faces.clear(); + chart->candidates.clear(); + addFaceToChart(chart, seed); + } +#if XA_GROW_CHARTS_COPLANAR + for (uint32_t i = 0; i < chartCount; i++) { + ChartBuildData *chart = m_chartArray[i]; + growChartCoplanar(chart); + } +#endif + } + + void updateCandidates(ChartBuildData *chart, uint32_t f) + { + // Traverse neighboring faces, add the ones that do not belong to any chart yet. + for (Mesh::FaceEdgeIterator it(m_mesh, f); !it.isDone(); it.advance()) { + if (!it.isBoundary() && !m_ignoreFaces[it.oppositeFace()] && m_faceChartArray[it.oppositeFace()] == -1) + chart->candidates.push(it.oppositeFace()); + } + } + + void updateProxies() + { + const uint32_t chartCount = m_chartArray.size(); + for (uint32_t i = 0; i < chartCount; i++) + updateProxy(m_chartArray[i]); + } + + bool relocateSeeds() + { + bool anySeedChanged = false; + const uint32_t chartCount = m_chartArray.size(); + for (uint32_t i = 0; i < chartCount; i++) { + if (relocateSeed(m_chartArray[i])) { + anySeedChanged = true; } } + return anySeedChanged; } - void placeSeeds(float threshold, uint32_t maxSeedCount) + void fillHoles(float threshold) { - // Instead of using a predefiened number of seeds: - // - Add seeds one by one, growing chart until a certain treshold. - // - Undo charts and restart growing process. - // @@ How can we give preference to faces far from sharp features as in the LSCM paper? - // - those points can be found using a simple flood filling algorithm. - // - how do we weight the probabilities? - for (uint32_t i = 0; i < maxSeedCount; i++) { - if (facesLeft == 0) { - // No faces left, stop creating seeds. + while (m_facesLeft > 0) + createRandomChart(threshold); + } + +#if XA_MERGE_CHARTS + void mergeCharts() + { + XA_PROFILE_START(atlasBuilderMergeCharts) + Array<float> sharedBoundaryLengths; + Array<float> sharedBoundaryLengthsNoSeams; + Array<uint32_t> sharedBoundaryEdgeCountNoSeams; + Array<Vector2> tempTexcoords; + const uint32_t chartCount = m_chartArray.size(); + // Merge charts progressively until there's none left to merge. + for (;;) { + bool merged = false; + for (int c = chartCount - 1; c >= 0; c--) { + ChartBuildData *chart = m_chartArray[c]; + if (chart == nullptr) + continue; + float externalBoundaryLength = 0.0f; + sharedBoundaryLengths.clear(); + sharedBoundaryLengths.resize(chartCount, 0.0f); + sharedBoundaryLengthsNoSeams.clear(); + sharedBoundaryLengthsNoSeams.resize(chartCount, 0.0f); + sharedBoundaryEdgeCountNoSeams.clear(); + sharedBoundaryEdgeCountNoSeams.resize(chartCount, 0u); + const uint32_t faceCount = chart->faces.size(); + for (uint32_t i = 0; i < faceCount; i++) { + const uint32_t f = chart->faces[i]; + for (Mesh::FaceEdgeIterator it(m_mesh, f); !it.isDone(); it.advance()) { + const float l = m_edgeLengths[it.edge()]; + if (it.isBoundary() || m_ignoreFaces[it.oppositeFace()]) { + externalBoundaryLength += l; + } else { + const int neighborChart = m_faceChartArray[it.oppositeFace()]; + if (m_chartArray[neighborChart] != chart) { + if ((it.isSeam() && (isNormalSeam(it.edge()) || it.isTextureSeam()))) { + externalBoundaryLength += l; + } else { + sharedBoundaryLengths[neighborChart] += l; + } + sharedBoundaryLengthsNoSeams[neighborChart] += l; + sharedBoundaryEdgeCountNoSeams[neighborChart]++; + } + } + } + } + for (int cc = chartCount - 1; cc >= 0; cc--) { + if (cc == c) + continue; + ChartBuildData *chart2 = m_chartArray[cc]; + if (chart2 == nullptr) + continue; + // Compare proxies. + if (dot(chart2->averageNormal, chart->averageNormal) < XA_MERGE_CHARTS_MIN_NORMAL_DEVIATION) + continue; + // Obey max chart area and boundary length. + if (m_options.maxChartArea > 0.0f && chart->area + chart2->area > m_options.maxChartArea) + continue; + if (m_options.maxBoundaryLength > 0.0f && chart->boundaryLength + chart2->boundaryLength - sharedBoundaryLengthsNoSeams[cc] > m_options.maxBoundaryLength) + continue; + // Merge if chart2 has a single face. + // chart1 must have more than 1 face. + // chart2 area must be <= 10% of chart1 area. + if (sharedBoundaryLengthsNoSeams[cc] > 0.0f && chart->faces.size() > 1 && chart2->faces.size() == 1 && chart2->area <= chart->area * 0.1f) + goto merge; + // Merge if chart2 has two faces (probably a quad), and chart1 bounds at least 2 of its edges. + if (chart2->faces.size() == 2 && sharedBoundaryEdgeCountNoSeams[cc] >= 2) + goto merge; + // Merge if chart2 is wholely inside chart1, ignoring seams. + if (sharedBoundaryLengthsNoSeams[cc] > 0.0f && equal(sharedBoundaryLengthsNoSeams[cc], chart2->boundaryLength, kEpsilon)) + goto merge; + if (sharedBoundaryLengths[cc] > 0.2f * max(0.0f, chart->boundaryLength - externalBoundaryLength) || + sharedBoundaryLengths[cc] > 0.75f * chart2->boundaryLength) + goto merge; + continue; + merge: + // Create texcoords for chart 2 using chart 1 basis. Backup chart 2 texcoords for restoration if charts cannot be merged. + tempTexcoords.resize(chart2->faces.size()); + for (uint32_t i = 0; i < chart2->faces.size(); i++) { + const uint32_t face = chart2->faces[i]; + tempTexcoords[i] = m_texcoords[face]; + createFaceTexcoords(chart, face); + } + if (!canMergeCharts(chart, chart2)) { + // Restore chart 2 texcoords. + for (uint32_t i = 0; i < chart2->faces.size(); i++) + m_texcoords[chart2->faces[i]] = tempTexcoords[i]; + continue; + } + mergeChart(chart, chart2, sharedBoundaryLengthsNoSeams[cc]); + merged = true; + break; + } + if (merged) + break; + } + if (!merged) break; + } + // Remove deleted charts. + for (int c = 0; c < int32_t(m_chartArray.size()); /*do not increment if removed*/) { + if (m_chartArray[c] == nullptr) { + m_chartArray.removeAt(c); + // Update m_faceChartArray. + const uint32_t faceCount = m_faceChartArray.size(); + for (uint32_t i = 0; i < faceCount; i++) { + XA_DEBUG_ASSERT(m_faceChartArray[i] != c); + XA_DEBUG_ASSERT(m_faceChartArray[i] <= int32_t(m_chartArray.size())); + if (m_faceChartArray[i] > c) { + m_faceChartArray[i]--; + } + } + } else { + m_chartArray[c]->id = c; + c++; } - createRandomChart(threshold); } + XA_PROFILE_END(atlasBuilderMergeCharts) } +#endif +private: void createRandomChart(float threshold) { - ChartBuildData *chart = new ChartBuildData(chartArray.size()); - chartArray.push_back(chart); + ChartBuildData *chart = XA_NEW(MemTag::Default, ChartBuildData); + chart->id = (int)m_chartArray.size(); + m_chartArray.push_back(chart); // Pick random face that is not used by any chart yet. - uint32_t randomFaceIdx = rand.getRange(facesLeft - 1); - uint32_t i = 0; - for (uint32_t f = 0; f != randomFaceIdx; f++, i++) { - while (faceChartArray[i] != -1) i++; - } - while (faceChartArray[i] != -1) i++; - chart->seeds.push_back(i); - addFaceToChart(chart, i, true); + uint32_t face = m_rand.getRange(m_mesh->faceCount() - 1); + while (m_ignoreFaces[face] || m_faceChartArray[face] != -1) { + if (++face >= m_mesh->faceCount()) + face = 0; + } + chart->seeds.push_back(face); + addFaceToChart(chart, face, true); +#if XA_GROW_CHARTS_COPLANAR + growChartCoplanar(chart); +#endif // Grow the chart as much as possible within the given threshold. - growChart(chart, threshold * 0.5f, facesLeft); - //growCharts(threshold - threshold * 0.75f / chartCount(), facesLeft); + growChart(chart, threshold, m_facesLeft); + } + + void createFaceTexcoords(ChartBuildData *chart, uint32_t face) + { + for (uint32_t i = 0; i < 3; i++) { + const Vector3 &pos = m_mesh->position(m_mesh->vertexAt(face * 3 + i)); + m_texcoords[face * 3 + i] = Vector2(dot(chart->basis.tangent, pos), dot(chart->basis.bitangent, pos)); + } + } + + bool isChartBoundaryEdge(ChartBuildData *chart, uint32_t edge) const + { + const uint32_t oppositeEdge = m_mesh->oppositeEdge(edge); + const uint32_t oppositeFace = meshEdgeFace(oppositeEdge); + return oppositeEdge == UINT32_MAX || m_ignoreFaces[oppositeFace] || m_faceChartArray[oppositeFace] != chart->id; + } + + bool canAddFaceToChart(ChartBuildData *chart, uint32_t face) + { + // Find face edges that are on a mesh boundary or form a boundary with another chart. + uint32_t edgesToCompare[3]; + for (uint32_t i = 0; i < 3; i++) { + const uint32_t edge = face * 3 + i; + const uint32_t oppositeEdge = m_mesh->oppositeEdge(edge); + const uint32_t oppositeFace = meshEdgeFace(oppositeEdge); + if (oppositeEdge == UINT32_MAX || m_ignoreFaces[oppositeFace] || m_faceChartArray[oppositeFace] != chart->id) + edgesToCompare[i] = edge; + else + edgesToCompare[i] = UINT32_MAX; + } + // All edges on boundary? This can happen if the face is surrounded by the chart. + if (edgesToCompare[0] == UINT32_MAX && edgesToCompare[1] == UINT32_MAX && edgesToCompare[2] == UINT32_MAX) + return true; + // Check if any valid face edge intersects the chart boundary. + for (uint32_t i = 0; i < chart->faces.size(); i++) { + const uint32_t chartFace = chart->faces[i]; + for (uint32_t j = 0; j < 3; j++) { + const uint32_t chartEdge = chartFace * 3 + j; + if (!isChartBoundaryEdge(chart, chartEdge)) + continue; + // Don't check chart boundary edges that border the face. + const uint32_t oppositeChartEdge = m_mesh->oppositeEdge(chartEdge); + if (meshEdgeFace(oppositeChartEdge) == face) + continue; + for (uint32_t k = 0; k < 3; k++) { + if (edgesToCompare[k] == UINT32_MAX) + continue; + const uint32_t e1 = chartEdge; + const uint32_t e2 = edgesToCompare[k]; + if (linesIntersect(m_texcoords[meshEdgeIndex0(e1)], m_texcoords[meshEdgeIndex1(e1)], m_texcoords[meshEdgeIndex0(e2)], m_texcoords[meshEdgeIndex1(e2)], m_mesh->epsilon())) + return false; + } + } + } + return true; + } + + bool canMergeCharts(ChartBuildData *chart1, ChartBuildData *chart2) + { + for (uint32_t f1 = 0; f1 < chart1->faces.size(); f1++) { + const uint32_t face1 = chart1->faces[f1]; + for (uint32_t i = 0; i < 3; i++) { + const uint32_t edge1 = face1 * 3 + i; + if (!isChartBoundaryEdge(chart1, edge1)) + continue; + for (uint32_t f2 = 0; f2 < chart2->faces.size(); f2++) { + const uint32_t face2 = chart2->faces[f2]; + for (uint32_t j = 0; j < 3; j++) { + const uint32_t edge2 = face2 * 3 + j; + if (!isChartBoundaryEdge(chart2, edge2)) + continue; + if (linesIntersect(m_texcoords[meshEdgeIndex0(edge1)], m_texcoords[meshEdgeIndex1(edge1)], m_texcoords[meshEdgeIndex0(edge2)], m_texcoords[meshEdgeIndex1(edge2)], m_mesh->epsilon())) + return false; + } + } + } + } + return true; } void addFaceToChart(ChartBuildData *chart, uint32_t f, bool recomputeProxy = false) { + // Use the first face normal as the chart basis. + if (chart->faces.isEmpty()) { + chart->basis.buildFrameForDirection(m_faceNormals[f]); + createFaceTexcoords(chart, f); + } // Add face to chart. chart->faces.push_back(f); - xaDebugAssert(faceChartArray[f] == -1); - faceChartArray[f] = chart->id; - facesLeft--; + XA_DEBUG_ASSERT(m_faceChartArray[f] == -1); + m_faceChartArray[f] = chart->id; + m_facesLeft--; // Update area and boundary length. chart->area = evaluateChartArea(chart, f); chart->boundaryLength = evaluateBoundaryLength(chart, f); chart->normalSum = evaluateChartNormalSum(chart, f); - chart->centroidSum = evaluateChartCentroidSum(chart, f); + chart->centroidSum += m_mesh->triangleCenter(f); if (recomputeProxy) { // Update proxy and candidate's priorities. updateProxy(chart); @@ -5126,142 +5183,93 @@ struct AtlasBuilder updatePriorities(chart); } - // Returns true if any of the charts can grow more. - bool growCharts(float threshold, uint32_t faceCount) - { - // Using one global list. - faceCount = std::min(faceCount, facesLeft); - for (uint32_t i = 0; i < faceCount; i++) { - const Candidate &candidate = getBestCandidate(); - if (candidate.metric > threshold) { - return false; // Can't grow more. - } - addFaceToChart(candidate.chart, candidate.face); - } - return facesLeft != 0; // Can continue growing. - } - bool growChart(ChartBuildData *chart, float threshold, uint32_t faceCount) { // Try to add faceCount faces within threshold to chart. for (uint32_t i = 0; i < faceCount; ) { - if (chart->candidates.count() == 0 || chart->candidates.firstPriority() > threshold) { + if (chart->candidates.count() == 0 || chart->candidates.firstPriority() > threshold) return false; - } - uint32_t f = chart->candidates.pop(); - if (faceChartArray[f] == -1) { - addFaceToChart(chart, f); - i++; - } + const uint32_t f = chart->candidates.pop(); + if (m_faceChartArray[f] != -1) + continue; + createFaceTexcoords(chart, f); + if (!canAddFaceToChart(chart, f)) + continue; + addFaceToChart(chart, f); + i++; } - if (chart->candidates.count() == 0 || chart->candidates.firstPriority() > threshold) { + if (chart->candidates.count() == 0 || chart->candidates.firstPriority() > threshold) return false; - } return true; } - void resetCharts() - { - const uint32_t faceCount = mesh->faceCount(); - for (uint32_t i = 0; i < faceCount; i++) { - faceChartArray[i] = -1; - faceCandidateArray[i] = (uint32_t)-1; - } - facesLeft = faceCount; - candidateArray.clear(); - const uint32_t chartCount = chartArray.size(); - for (uint32_t i = 0; i < chartCount; i++) { - ChartBuildData *chart = chartArray[i]; - const uint32_t seed = chart->seeds.back(); - chart->area = 0.0f; - chart->boundaryLength = 0.0f; - chart->normalSum = Vector3(0); - chart->centroidSum = Vector3(0); - chart->faces.clear(); - chart->candidates.clear(); - addFaceToChart(chart, seed); - } - } - - void updateCandidates(ChartBuildData *chart, uint32_t f) +#if XA_GROW_CHARTS_COPLANAR + void growChartCoplanar(ChartBuildData *chart) { - const halfedge::Face *face = mesh->faceAt(f); - // Traverse neighboring faces, add the ones that do not belong to any chart yet. - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Edge *edge = it.current()->pair; - if (!edge->isBoundary()) { - uint32_t faceId = edge->face->id; - if (faceChartArray[faceId] == -1) { - chart->candidates.push(faceId); + XA_DEBUG_ASSERT(!chart->faces.isEmpty()); + const Vector3 chartNormal = m_faceNormals[chart->faces[0]]; + m_growFaces.clear(); + for (uint32_t f = 0; f < chart->faces.size(); f++) + m_growFaces.push_back(chart->faces[f]); + for (;;) { + if (m_growFaces.isEmpty()) + break; + const uint32_t face = m_growFaces.back(); + m_growFaces.pop_back(); + for (Mesh::FaceEdgeIterator it(m_mesh, face); !it.isDone(); it.advance()) { + if (it.isBoundary() || m_ignoreFaces[it.oppositeFace()] || m_faceChartArray[it.oppositeFace()] != -1) + continue; + if (equal(dot(chartNormal, m_faceNormals[it.oppositeFace()]), 1.0f, kEpsilon)) { + createFaceTexcoords(chart, it.oppositeFace()); + addFaceToChart(chart, it.oppositeFace()); + m_growFaces.push_back(it.oppositeFace()); } } } } +#endif - void updateProxies() - { - const uint32_t chartCount = chartArray.size(); - for (uint32_t i = 0; i < chartCount; i++) { - updateProxy(chartArray[i]); - } - } - - void updateProxy(ChartBuildData *chart) + void updateProxy(ChartBuildData *chart) const { //#pragma message(NV_FILE_LINE "TODO: Use best fit plane instead of average normal.") - chart->planeNormal = normalizeSafe(chart->normalSum, Vector3(0), 0.0f); + chart->averageNormal = normalizeSafe(chart->normalSum, Vector3(0), 0.0f); chart->centroid = chart->centroidSum / float(chart->faces.size()); } - bool relocateSeeds() - { - bool anySeedChanged = false; - const uint32_t chartCount = chartArray.size(); - for (uint32_t i = 0; i < chartCount; i++) { - if (relocateSeed(chartArray[i])) { - anySeedChanged = true; - } - } - return anySeedChanged; - } - bool relocateSeed(ChartBuildData *chart) { - Vector3 centroid = computeChartCentroid(chart); - const uint32_t N = 10; // @@ Hardcoded to 10? - PriorityQueue bestTriangles(N); // Find the first N triangles that fit the proxy best. const uint32_t faceCount = chart->faces.size(); + m_bestTriangles.clear(); for (uint32_t i = 0; i < faceCount; i++) { float priority = evaluateProxyFitMetric(chart, chart->faces[i]); - bestTriangles.push(priority, chart->faces[i]); + m_bestTriangles.push(priority, chart->faces[i]); } - // Of those, choose the most central triangle. - uint32_t mostCentral; + // Of those, choose the least central triangle. + uint32_t leastCentral = 0; float maxDistance = -1; - const uint32_t bestCount = bestTriangles.count(); + const uint32_t bestCount = m_bestTriangles.count(); for (uint32_t i = 0; i < bestCount; i++) { - const halfedge::Face *face = mesh->faceAt(bestTriangles.pairs[i].face); - Vector3 faceCentroid = face->triangleCenter(); - float distance = length(centroid - faceCentroid); + Vector3 faceCentroid = m_mesh->triangleCenter(m_bestTriangles.pairs[i].face); + float distance = length(chart->centroid - faceCentroid); if (distance > maxDistance) { maxDistance = distance; - mostCentral = bestTriangles.pairs[i].face; + leastCentral = m_bestTriangles.pairs[i].face; } } - xaDebugAssert(maxDistance >= 0); + XA_DEBUG_ASSERT(maxDistance >= 0); // In order to prevent k-means cyles we record all the previously chosen seeds. - uint32_t index = std::find(chart->seeds.begin(), chart->seeds.end(), mostCentral) - chart->seeds.begin(); - if (index < chart->seeds.size()) { - // Move new seed to the end of the seed array. - uint32_t last = chart->seeds.size() - 1; - std::swap(chart->seeds[index], chart->seeds[last]); - return false; - } else { - // Append new seed. - chart->seeds.push_back(mostCentral); - return true; + for (uint32_t i = 0; i < chart->seeds.size(); i++) { + if (chart->seeds[i] == leastCentral) { + // Move new seed to the end of the seed array. + uint32_t last = chart->seeds.size() - 1; + swap(chart->seeds[i], chart->seeds[last]); + return false; + } } + // Append new seed. + chart->seeds.push_back(leastCentral); + return true; } void updatePriorities(ChartBuildData *chart) @@ -5269,299 +5277,197 @@ struct AtlasBuilder // Re-evaluate candidate priorities. uint32_t candidateCount = chart->candidates.count(); for (uint32_t i = 0; i < candidateCount; i++) { - chart->candidates.pairs[i].priority = evaluatePriority(chart, chart->candidates.pairs[i].face); - if (faceChartArray[chart->candidates.pairs[i].face] == -1) { - updateCandidate(chart, chart->candidates.pairs[i].face, chart->candidates.pairs[i].priority); - } + PriorityQueue::Pair &pair = chart->candidates.pairs[i]; + pair.priority = evaluatePriority(chart, pair.face); + if (m_faceChartArray[pair.face] == -1) + updateCandidate(chart, pair.face, pair.priority); } // Sort candidates. chart->candidates.sort(); } // Evaluate combined metric. - float evaluatePriority(ChartBuildData *chart, uint32_t face) + float evaluatePriority(ChartBuildData *chart, uint32_t face) const { // Estimate boundary length and area: - float newBoundaryLength = evaluateBoundaryLength(chart, face); - float newChartArea = evaluateChartArea(chart, face); - float F = evaluateProxyFitMetric(chart, face); - float C = evaluateRoundnessMetric(chart, face, newBoundaryLength, newChartArea); - float P = evaluateStraightnessMetric(chart, face); + const float newChartArea = evaluateChartArea(chart, face); + const float newBoundaryLength = evaluateBoundaryLength(chart, face); + // Enforce limits strictly: + if (m_options.maxChartArea > 0.0f && newChartArea > m_options.maxChartArea) + return FLT_MAX; + if (m_options.maxBoundaryLength > 0.0f && newBoundaryLength > m_options.maxBoundaryLength) + return FLT_MAX; + if (dot(m_faceNormals[face], chart->averageNormal) < 0.5f) + return FLT_MAX; // Penalize faces that cross seams, reward faces that close seams or reach boundaries. - float N = evaluateNormalSeamMetric(chart, face); - float T = evaluateTextureSeamMetric(chart, face); + // Make sure normal seams are fully respected: + const float N = evaluateNormalSeamMetric(chart, face); + if (m_options.normalSeamMetricWeight >= 1000.0f && N > 0.0f) + return FLT_MAX; + float cost = m_options.normalSeamMetricWeight * N; + if (m_options.proxyFitMetricWeight > 0.0f) + cost += m_options.proxyFitMetricWeight * evaluateProxyFitMetric(chart, face); + if (m_options.roundnessMetricWeight > 0.0f) + cost += m_options.roundnessMetricWeight * evaluateRoundnessMetric(chart, face, newBoundaryLength, newChartArea); + if (m_options.straightnessMetricWeight > 0.0f) + cost += m_options.straightnessMetricWeight * evaluateStraightnessMetric(chart, face); + if (m_options.textureSeamMetricWeight > 0.0f) + cost += m_options.textureSeamMetricWeight * evaluateTextureSeamMetric(chart, face); //float R = evaluateCompletenessMetric(chart, face); //float D = evaluateDihedralAngleMetric(chart, face); // @@ Add a metric based on local dihedral angle. // @@ Tweaking the normal and texture seam metrics. // - Cause more impedance. Never cross 90 degree edges. - // - - float cost = float( - options.proxyFitMetricWeight * F + - options.roundnessMetricWeight * C + - options.straightnessMetricWeight * P + - options.normalSeamMetricWeight * N + - options.textureSeamMetricWeight * T); - // Enforce limits strictly: - if (newChartArea > options.maxChartArea) cost = FLT_MAX; - if (newBoundaryLength > options.maxBoundaryLength) cost = FLT_MAX; - // Make sure normal seams are fully respected: - if (options.normalSeamMetricWeight >= 1000 && N != 0) cost = FLT_MAX; - xaAssert(std::isfinite(cost)); + XA_DEBUG_ASSERT(isFinite(cost)); return cost; } // Returns a value in [0-1]. - float evaluateProxyFitMetric(ChartBuildData *chart, uint32_t f) + float evaluateProxyFitMetric(ChartBuildData *chart, uint32_t f) const { - const halfedge::Face *face = mesh->faceAt(f); - Vector3 faceNormal = face->triangleNormal(); + const Vector3 faceNormal = m_faceNormals[f]; // Use plane fitting metric for now: - return 1 - dot(faceNormal, chart->planeNormal); // @@ normal deviations should be weighted by face area + return 1 - dot(faceNormal, chart->averageNormal); // @@ normal deviations should be weighted by face area } - float evaluateRoundnessMetric(ChartBuildData *chart, uint32_t /*face*/, float newBoundaryLength, float newChartArea) + float evaluateRoundnessMetric(ChartBuildData *chart, uint32_t /*face*/, float newBoundaryLength, float newChartArea) const { float roundness = square(chart->boundaryLength) / chart->area; float newRoundness = square(newBoundaryLength) / newChartArea; if (newRoundness > roundness) { - return square(newBoundaryLength) / (newChartArea * 4 * PI); + return square(newBoundaryLength) / (newChartArea * 4.0f * kPi); } else { // Offer no impedance to faces that improve roundness. return 0; } } - float evaluateStraightnessMetric(ChartBuildData *chart, uint32_t f) + float evaluateStraightnessMetric(ChartBuildData *chart, uint32_t f) const { float l_out = 0.0f; float l_in = 0.0f; - const halfedge::Face *face = mesh->faceAt(f); - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Edge *edge = it.current(); - float l = edgeLengths[edge->id / 2]; - if (edge->isBoundary()) { + for (Mesh::FaceEdgeIterator it(m_mesh, f); !it.isDone(); it.advance()) { + float l = m_edgeLengths[it.edge()]; + if (it.isBoundary() || m_ignoreFaces[it.oppositeFace()]) { l_out += l; } else { - uint32_t neighborFaceId = edge->pair->face->id; - if (faceChartArray[neighborFaceId] != chart->id) { + if (m_faceChartArray[it.oppositeFace()] != chart->id) { l_out += l; } else { l_in += l; } } } - xaDebugAssert(l_in != 0.0f); // Candidate face must be adjacent to chart. @@ This is not true if the input mesh has zero-length edges. + XA_DEBUG_ASSERT(l_in != 0.0f); // Candidate face must be adjacent to chart. @@ This is not true if the input mesh has zero-length edges. float ratio = (l_out - l_in) / (l_out + l_in); - return std::min(ratio, 0.0f); // Only use the straightness metric to close gaps. + return min(ratio, 0.0f); // Only use the straightness metric to close gaps. + } + + bool isNormalSeam(uint32_t edge) const + { + const uint32_t oppositeEdge = m_mesh->oppositeEdge(edge); + if (oppositeEdge == UINT32_MAX) + return false; // boundary edge + if (m_mesh->flags() & MeshFlags::HasNormals) { + const uint32_t v0 = m_mesh->vertexAt(meshEdgeIndex0(edge)); + const uint32_t v1 = m_mesh->vertexAt(meshEdgeIndex1(edge)); + const uint32_t ov0 = m_mesh->vertexAt(meshEdgeIndex0(oppositeEdge)); + const uint32_t ov1 = m_mesh->vertexAt(meshEdgeIndex1(oppositeEdge)); + return m_mesh->normal(v0) != m_mesh->normal(ov1) || m_mesh->normal(v1) != m_mesh->normal(ov0); + } + return m_faceNormals[meshEdgeFace(edge)] != m_faceNormals[meshEdgeFace(oppositeEdge)]; } - float evaluateNormalSeamMetric(ChartBuildData *chart, uint32_t f) + float evaluateNormalSeamMetric(ChartBuildData *chart, uint32_t f) const { float seamFactor = 0.0f; float totalLength = 0.0f; - const halfedge::Face *face = mesh->faceAt(f); - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Edge *edge = it.current(); - if (edge->isBoundary()) { + for (Mesh::FaceEdgeIterator it(m_mesh, f); !it.isDone(); it.advance()) { + if (it.isBoundary() || m_ignoreFaces[it.oppositeFace()]) continue; - } - const uint32_t neighborFaceId = edge->pair->face->id; - if (faceChartArray[neighborFaceId] != chart->id) { + if (m_faceChartArray[it.oppositeFace()] != chart->id) continue; - } - //float l = edge->length(); - float l = edgeLengths[edge->id / 2]; + float l = m_edgeLengths[it.edge()]; totalLength += l; - if (!edge->isSeam()) { + if (!it.isSeam()) continue; - } // Make sure it's a normal seam. - if (edge->isNormalSeam()) { - float d0 = clamp(dot(edge->vertex->nor, edge->pair->next->vertex->nor), 0.0f, 1.0f); - float d1 = clamp(dot(edge->next->vertex->nor, edge->pair->vertex->nor), 0.0f, 1.0f); - l *= 1 - (d0 + d1) * 0.5f; + if (isNormalSeam(it.edge())) { + float d; + if (m_mesh->flags() & MeshFlags::HasNormals) { + const Vector3 &n0 = m_mesh->normal(it.vertex0()); + const Vector3 &n1 = m_mesh->normal(it.vertex1()); + const Vector3 &on0 = m_mesh->normal(m_mesh->vertexAt(meshEdgeIndex0(it.oppositeEdge()))); + const Vector3 &on1 = m_mesh->normal(m_mesh->vertexAt(meshEdgeIndex1(it.oppositeEdge()))); + const float d0 = clamp(dot(n0, on1), 0.0f, 1.0f); + const float d1 = clamp(dot(n1, on0), 0.0f, 1.0f); + d = (d0 + d1) * 0.5f; + } else { + d = clamp(dot(m_faceNormals[f], m_faceNormals[meshEdgeFace(it.oppositeEdge())]), 0.0f, 1.0f); + } + l *= 1 - d; seamFactor += l; } } - if (seamFactor == 0) return 0.0f; + if (seamFactor <= 0.0f) + return 0.0f; return seamFactor / totalLength; } - float evaluateTextureSeamMetric(ChartBuildData *chart, uint32_t f) + float evaluateTextureSeamMetric(ChartBuildData *chart, uint32_t f) const { float seamLength = 0.0f; float totalLength = 0.0f; - const halfedge::Face *face = mesh->faceAt(f); - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Edge *edge = it.current(); - if (edge->isBoundary()) { + for (Mesh::FaceEdgeIterator it(m_mesh, f); !it.isDone(); it.advance()) { + if (it.isBoundary() || m_ignoreFaces[it.oppositeFace()]) continue; - } - const uint32_t neighborFaceId = edge->pair->face->id; - if (faceChartArray[neighborFaceId] != chart->id) { + if (m_faceChartArray[it.oppositeFace()] != chart->id) continue; - } - //float l = edge->length(); - float l = edgeLengths[edge->id / 2]; + float l = m_edgeLengths[it.edge()]; totalLength += l; - if (!edge->isSeam()) { + if (!it.isSeam()) continue; - } // Make sure it's a texture seam. - if (edge->isTextureSeam()) { + if (it.isTextureSeam()) seamLength += l; - } } - if (seamLength == 0.0f) { + if (seamLength == 0.0f) return 0.0f; // Avoid division by zero. - } return seamLength / totalLength; } - float evaluateChartArea(ChartBuildData *chart, uint32_t f) + float evaluateChartArea(ChartBuildData *chart, uint32_t f) const { - const halfedge::Face *face = mesh->faceAt(f); - return chart->area + faceAreas[face->id]; + return chart->area + m_faceAreas[f]; } - float evaluateBoundaryLength(ChartBuildData *chart, uint32_t f) + float evaluateBoundaryLength(ChartBuildData *chart, uint32_t f) const { float boundaryLength = chart->boundaryLength; // Add new edges, subtract edges shared with the chart. - const halfedge::Face *face = mesh->faceAt(f); - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Edge *edge = it.current(); - //float edgeLength = edge->length(); - float edgeLength = edgeLengths[edge->id / 2]; - if (edge->isBoundary()) { + for (Mesh::FaceEdgeIterator it(m_mesh, f); !it.isDone(); it.advance()) { + const float edgeLength = m_edgeLengths[it.edge()]; + if (it.isBoundary() || m_ignoreFaces[it.oppositeFace()]) { boundaryLength += edgeLength; } else { - uint32_t neighborFaceId = edge->pair->face->id; - if (faceChartArray[neighborFaceId] != chart->id) { + if (m_faceChartArray[it.oppositeFace()] != chart->id) boundaryLength += edgeLength; - } else { + else boundaryLength -= edgeLength; - } } } - return std::max(0.0f, boundaryLength); // @@ Hack! - } - - Vector3 evaluateChartNormalSum(ChartBuildData *chart, uint32_t f) - { - const halfedge::Face *face = mesh->faceAt(f); - return chart->normalSum + face->triangleNormalAreaScaled(); + return max(0.0f, boundaryLength); // @@ Hack! } - Vector3 evaluateChartCentroidSum(ChartBuildData *chart, uint32_t f) + Vector3 evaluateChartNormalSum(ChartBuildData *chart, uint32_t f) const { - const halfedge::Face *face = mesh->faceAt(f); - return chart->centroidSum + face->centroid(); - } - - Vector3 computeChartCentroid(const ChartBuildData *chart) - { - Vector3 centroid(0); - const uint32_t faceCount = chart->faces.size(); - for (uint32_t i = 0; i < faceCount; i++) { - const halfedge::Face *face = mesh->faceAt(chart->faces[i]); - centroid += face->triangleCenter(); - } - return centroid / float(faceCount); - } - - void fillHoles(float threshold) - { - while (facesLeft > 0) - createRandomChart(threshold); - } - - void mergeCharts() - { - std::vector<float> sharedBoundaryLengths; - const uint32_t chartCount = chartArray.size(); - for (int c = chartCount - 1; c >= 0; c--) { - sharedBoundaryLengths.clear(); - sharedBoundaryLengths.resize(chartCount, 0.0f); - ChartBuildData *chart = chartArray[c]; - float externalBoundary = 0.0f; - const uint32_t faceCount = chart->faces.size(); - for (uint32_t i = 0; i < faceCount; i++) { - uint32_t f = chart->faces[i]; - const halfedge::Face *face = mesh->faceAt(f); - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Edge *edge = it.current(); - //float l = edge->length(); - float l = edgeLengths[edge->id / 2]; - if (edge->isBoundary()) { - externalBoundary += l; - } else { - uint32_t neighborFace = edge->pair->face->id; - uint32_t neighborChart = faceChartArray[neighborFace]; - if (neighborChart != (uint32_t)c) { - if ((edge->isSeam() && (edge->isNormalSeam() || edge->isTextureSeam())) || neighborChart == -2) { - externalBoundary += l; - } else { - sharedBoundaryLengths[neighborChart] += l; - } - } - } - } - } - for (int cc = chartCount - 1; cc >= 0; cc--) { - if (cc == c) - continue; - ChartBuildData *chart2 = chartArray[cc]; - if (chart2 == NULL) - continue; - if (sharedBoundaryLengths[cc] > 0.8 * std::max(0.0f, chart->boundaryLength - externalBoundary)) { - // Try to avoid degenerate configurations. - if (chart2->boundaryLength > sharedBoundaryLengths[cc]) { - if (dot(chart2->planeNormal, chart->planeNormal) > -0.25) { - mergeChart(chart2, chart, sharedBoundaryLengths[cc]); - delete chart; - chartArray[c] = NULL; - break; - } - } - } - if (sharedBoundaryLengths[cc] > 0.20 * std::max(0.0f, chart->boundaryLength - externalBoundary)) { - // Compare proxies. - if (dot(chart2->planeNormal, chart->planeNormal) > 0) { - mergeChart(chart2, chart, sharedBoundaryLengths[cc]); - delete chart; - chartArray[c] = NULL; - break; - } - } - } - } - // Remove deleted charts. - for (int c = 0; c < int32_t(chartArray.size()); /*do not increment if removed*/) { - if (chartArray[c] == NULL) { - chartArray.erase(chartArray.begin() + c); - // Update faceChartArray. - const uint32_t faceCount = faceChartArray.size(); - for (uint32_t i = 0; i < faceCount; i++) { - xaDebugAssert (faceChartArray[i] != -1); - xaDebugAssert (faceChartArray[i] != c); - xaDebugAssert (faceChartArray[i] <= int32_t(chartArray.size())); - if (faceChartArray[i] > c) { - faceChartArray[i]--; - } - } - } else { - chartArray[c]->id = c; - c++; - } - } + return chart->normalSum + m_mesh->triangleNormalAreaScaled(f); } // @@ Cleanup. struct Candidate { - uint32_t face; ChartBuildData *chart; + uint32_t face; float metric; }; @@ -5570,48 +5476,48 @@ struct AtlasBuilder { uint32_t best = 0; float bestCandidateMetric = FLT_MAX; - const uint32_t candidateCount = candidateArray.size(); - xaAssert(candidateCount > 0); + const uint32_t candidateCount = m_candidateArray.size(); + XA_ASSERT(candidateCount > 0); for (uint32_t i = 0; i < candidateCount; i++) { - const Candidate &candidate = candidateArray[i]; + const Candidate &candidate = m_candidateArray[i]; if (candidate.metric < bestCandidateMetric) { bestCandidateMetric = candidate.metric; best = i; } } - return candidateArray[best]; + return m_candidateArray[best]; } void removeCandidate(uint32_t f) { - int c = faceCandidateArray[f]; + int c = m_faceCandidateArray[f]; if (c != -1) { - faceCandidateArray[f] = (uint32_t)-1; - if (c == int(candidateArray.size() - 1)) { - candidateArray.pop_back(); + m_faceCandidateArray[f] = (uint32_t)-1; + if (c == int(m_candidateArray.size() - 1)) { + m_candidateArray.pop_back(); } else { // Replace with last. - candidateArray[c] = candidateArray[candidateArray.size() - 1]; - candidateArray.pop_back(); - faceCandidateArray[candidateArray[c].face] = c; + m_candidateArray[c] = m_candidateArray[m_candidateArray.size() - 1]; + m_candidateArray.pop_back(); + m_faceCandidateArray[m_candidateArray[c].face] = c; } } } void updateCandidate(ChartBuildData *chart, uint32_t f, float metric) { - if (faceCandidateArray[f] == -1) { - const uint32_t index = candidateArray.size(); - faceCandidateArray[f] = index; - candidateArray.resize(index + 1); - candidateArray[index].face = f; - candidateArray[index].chart = chart; - candidateArray[index].metric = metric; + if (m_faceCandidateArray[f] == (uint32_t)-1) { + const uint32_t index = m_candidateArray.size(); + m_faceCandidateArray[f] = index; + m_candidateArray.resize(index + 1); + m_candidateArray[index].face = f; + m_candidateArray[index].chart = chart; + m_candidateArray[index].metric = metric; } else { - int c = faceCandidateArray[f]; - xaDebugAssert(c != -1); - Candidate &candidate = candidateArray[c]; - xaDebugAssert(candidate.face == f); + const uint32_t c = m_faceCandidateArray[f]; + XA_DEBUG_ASSERT(c != (uint32_t)-1); + Candidate &candidate = m_candidateArray[c]; + XA_DEBUG_ASSERT(candidate.face == f); if (metric < candidate.metric || chart == candidate.chart) { candidate.metric = metric; candidate.chart = chart; @@ -5624,803 +5530,585 @@ struct AtlasBuilder const uint32_t faceCount = chart->faces.size(); for (uint32_t i = 0; i < faceCount; i++) { uint32_t f = chart->faces[i]; - xaDebugAssert(faceChartArray[f] == chart->id); - faceChartArray[f] = owner->id; + XA_DEBUG_ASSERT(m_faceChartArray[f] == chart->id); + m_faceChartArray[f] = owner->id; owner->faces.push_back(f); } // Update adjacencies? owner->area += chart->area; owner->boundaryLength += chart->boundaryLength - sharedBoundaryLength; owner->normalSum += chart->normalSum; - owner->centroidSum += chart->centroidSum; updateProxy(owner); - } + // Delete chart. + m_chartArray[chart->id] = nullptr; + chart->~ChartBuildData(); + XA_FREE(chart); + } + + const Mesh *m_mesh; + const Array<uint32_t> *m_meshFaces; + Array<bool> m_ignoreFaces; + Array<float> m_edgeLengths; + Array<float> m_faceAreas; + Array<Vector3> m_faceNormals; + Array<Vector2> m_texcoords; + Array<uint32_t> m_growFaces; + uint32_t m_facesLeft; + Array<int> m_faceChartArray; + Array<ChartBuildData *> m_chartArray; + Array<Candidate> m_candidateArray; + Array<uint32_t> m_faceCandidateArray; // Map face index to candidate index. + PriorityQueue m_bestTriangles; + KISSRng m_rand; + ChartOptions m_options; +}; +// Estimate quality of existing parameterization. +struct ParameterizationQuality +{ + uint32_t totalTriangleCount = 0; + uint32_t flippedTriangleCount = 0; + uint32_t zeroAreaTriangleCount = 0; + float parametricArea = 0.0f; + float geometricArea = 0.0f; + float stretchMetric = 0.0f; + float maxStretchMetric = 0.0f; + float conformalMetric = 0.0f; + float authalicMetric = 0.0f; + bool boundaryIntersection = false; +}; - uint32_t chartCount() const { return chartArray.size(); } - const std::vector<uint32_t> &chartFaces(uint32_t i) const { return chartArray[i]->faces; } +static ParameterizationQuality calculateParameterizationQuality(const Mesh *mesh, Array<uint32_t> *flippedFaces) +{ + XA_DEBUG_ASSERT(mesh != nullptr); + ParameterizationQuality quality; + const uint32_t faceCount = mesh->faceCount(); + uint32_t firstBoundaryEdge = UINT32_MAX; + for (uint32_t e = 0; e < mesh->edgeCount(); e++) { + if (mesh->isBoundaryEdge(e)) { + firstBoundaryEdge = e; + } + } + XA_DEBUG_ASSERT(firstBoundaryEdge != UINT32_MAX); + for (Mesh::BoundaryEdgeIterator it1(mesh, firstBoundaryEdge); !it1.isDone(); it1.advance()) { + const uint32_t edge1 = it1.edge(); + for (Mesh::BoundaryEdgeIterator it2(mesh, firstBoundaryEdge); !it2.isDone(); it2.advance()) { + const uint32_t edge2 = it2.edge(); + // Skip self and edges directly connected to edge1. + if (edge1 == edge2 || it1.nextEdge() == edge2 || it2.nextEdge() == edge1) + continue; + const Vector2 &a1 = mesh->texcoord(mesh->vertexAt(meshEdgeIndex0(edge1))); + const Vector2 &a2 = mesh->texcoord(mesh->vertexAt(meshEdgeIndex1(edge1))); + const Vector2 &b1 = mesh->texcoord(mesh->vertexAt(meshEdgeIndex0(edge2))); + const Vector2 &b2 = mesh->texcoord(mesh->vertexAt(meshEdgeIndex1(edge2))); + if (linesIntersect(a1, a2, b1, b2, mesh->epsilon())) { + quality.boundaryIntersection = true; + break; + } + } + if (quality.boundaryIntersection) + break; + } + if (flippedFaces) + flippedFaces->clear(); + for (uint32_t f = 0; f < faceCount; f++) { + Vector3 pos[3]; + Vector2 texcoord[3]; + for (int i = 0; i < 3; i++) { + const uint32_t v = mesh->vertexAt(f * 3 + i); + pos[i] = mesh->position(v); + texcoord[i] = mesh->texcoord(v); + } + quality.totalTriangleCount++; + // Evaluate texture stretch metric. See: + // - "Texture Mapping Progressive Meshes", Sander, Snyder, Gortler & Hoppe + // - "Mesh Parameterization: Theory and Practice", Siggraph'07 Course Notes, Hormann, Levy & Sheffer. + const float t1 = texcoord[0].x; + const float s1 = texcoord[0].y; + const float t2 = texcoord[1].x; + const float s2 = texcoord[1].y; + const float t3 = texcoord[2].x; + const float s3 = texcoord[2].y; + float parametricArea = ((s2 - s1) * (t3 - t1) - (s3 - s1) * (t2 - t1)) / 2; + if (isZero(parametricArea, kAreaEpsilon)) { + quality.zeroAreaTriangleCount++; + continue; + } + if (parametricArea < 0.0f) { + // Count flipped triangles. + quality.flippedTriangleCount++; + if (flippedFaces) + flippedFaces->push_back(f); + parametricArea = fabsf(parametricArea); + } + const float geometricArea = length(cross(pos[1] - pos[0], pos[2] - pos[0])) / 2; + const Vector3 Ss = (pos[0] * (t2 - t3) + pos[1] * (t3 - t1) + pos[2] * (t1 - t2)) / (2 * parametricArea); + const Vector3 St = (pos[0] * (s3 - s2) + pos[1] * (s1 - s3) + pos[2] * (s2 - s1)) / (2 * parametricArea); + const float a = dot(Ss, Ss); // E + const float b = dot(Ss, St); // F + const float c = dot(St, St); // G + // Compute eigen-values of the first fundamental form: + const float sigma1 = sqrtf(0.5f * max(0.0f, a + c - sqrtf(square(a - c) + 4 * square(b)))); // gamma uppercase, min eigenvalue. + const float sigma2 = sqrtf(0.5f * max(0.0f, a + c + sqrtf(square(a - c) + 4 * square(b)))); // gamma lowercase, max eigenvalue. + XA_ASSERT(sigma2 > sigma1 || equal(sigma1, sigma2, kEpsilon)); + // isometric: sigma1 = sigma2 = 1 + // conformal: sigma1 / sigma2 = 1 + // authalic: sigma1 * sigma2 = 1 + const float rmsStretch = sqrtf((a + c) * 0.5f); + const float rmsStretch2 = sqrtf((square(sigma1) + square(sigma2)) * 0.5f); + XA_DEBUG_ASSERT(equal(rmsStretch, rmsStretch2, 0.01f)); + XA_UNUSED(rmsStretch2); + quality.stretchMetric += square(rmsStretch) * geometricArea; + quality.maxStretchMetric = max(quality.maxStretchMetric, sigma2); + if (!isZero(sigma1, 0.000001f)) { + // sigma1 is zero when geometricArea is zero. + quality.conformalMetric += (sigma2 / sigma1) * geometricArea; + } + quality.authalicMetric += (sigma1 * sigma2) * geometricArea; + // Accumulate total areas. + quality.geometricArea += geometricArea; + quality.parametricArea += parametricArea; + //triangleConformalEnergy(q, p); + } + if (quality.flippedTriangleCount + quality.zeroAreaTriangleCount == quality.totalTriangleCount) { + // If all triangles are flipped, then none are. + if (flippedFaces) + flippedFaces->clear(); + quality.flippedTriangleCount = 0; + } + if (quality.flippedTriangleCount > quality.totalTriangleCount / 2) + { + // If more than half the triangles are flipped, reverse the flipped / not flipped classification. + quality.flippedTriangleCount = quality.totalTriangleCount - quality.flippedTriangleCount; + if (flippedFaces) { + Array<uint32_t> temp(*flippedFaces); + flippedFaces->clear(); + for (uint32_t f = 0; f < faceCount; f++) { + bool match = false; + for (uint32_t ff = 0; ff < temp.size(); ff++) { + if (temp[ff] == f) { + match = true; + break; + } + } + if (!match) + flippedFaces->push_back(f); + } + } + } + XA_DEBUG_ASSERT(isFinite(quality.parametricArea) && quality.parametricArea >= 0); + XA_DEBUG_ASSERT(isFinite(quality.geometricArea) && quality.geometricArea >= 0); + XA_DEBUG_ASSERT(isFinite(quality.stretchMetric)); + XA_DEBUG_ASSERT(isFinite(quality.maxStretchMetric)); + XA_DEBUG_ASSERT(isFinite(quality.conformalMetric)); + XA_DEBUG_ASSERT(isFinite(quality.authalicMetric)); + if (quality.geometricArea <= 0.0f) { + quality.stretchMetric = 0.0f; + quality.maxStretchMetric = 0.0f; + quality.conformalMetric = 0.0f; + quality.authalicMetric = 0.0f; + } else { + const float normFactor = sqrtf(quality.parametricArea / quality.geometricArea); + quality.stretchMetric = sqrtf(quality.stretchMetric / quality.geometricArea) * normFactor; + quality.maxStretchMetric *= normFactor; + quality.conformalMetric = sqrtf(quality.conformalMetric / quality.geometricArea); + quality.authalicMetric = sqrtf(quality.authalicMetric / quality.geometricArea); + } + return quality; +} - const halfedge::Mesh *mesh; - uint32_t facesLeft; - std::vector<int> faceChartArray; - std::vector<ChartBuildData *> chartArray; - std::vector<float> shortestPaths; - std::vector<float> edgeLengths; - std::vector<float> faceAreas; - std::vector<Candidate> candidateArray; // - std::vector<uint32_t> faceCandidateArray; // Map face index to candidate index. - MTRand rand; - CharterOptions options; +struct ChartWarningFlags +{ + enum Enum + { + CloseHolesFailed = 1<<1, + FixTJunctionsDuplicatedEdge = 1<<2, + FixTJunctionsFailed = 1<<3, + TriangulateDuplicatedEdge = 1<<4, + }; }; /// A chart is a connected set of faces with a certain topology (usually a disk). class Chart { public: - Chart() : m_isDisk(false), m_isVertexMapped(false) {} - - void build(const halfedge::Mesh *originalMesh, const std::vector<uint32_t> &faceArray) + Chart(const Mesh *originalMesh, const Array<uint32_t> &faceArray, const Basis &basis, uint32_t meshId, uint32_t chartGroupId, uint32_t chartId) : m_basis(basis), m_mesh(nullptr), m_unifiedMesh(nullptr), m_isDisk(false), m_isOrtho(false), m_isPlanar(false), m_warningFlags(0), m_closedHolesCount(0), m_fixedTJunctionsCount(0), m_faceArray(faceArray) { + XA_UNUSED(meshId); + XA_UNUSED(chartGroupId); + XA_UNUSED(chartId); // Copy face indices. - m_faceArray = faceArray; - const uint32_t meshVertexCount = originalMesh->vertexCount(); - m_chartMesh.reset(new halfedge::Mesh()); - m_unifiedMesh.reset(new halfedge::Mesh()); - std::vector<uint32_t> chartMeshIndices(meshVertexCount, (uint32_t)~0); - std::vector<uint32_t> unifiedMeshIndices(meshVertexCount, (uint32_t)~0); + m_mesh = XA_NEW(MemTag::Mesh, Mesh, originalMesh->epsilon(), faceArray.size() * 3, faceArray.size()); + m_unifiedMesh = XA_NEW(MemTag::Mesh, Mesh, originalMesh->epsilon(), faceArray.size() * 3, faceArray.size()); + Array<uint32_t> chartMeshIndices; + chartMeshIndices.resize(originalMesh->vertexCount(), (uint32_t)~0); + Array<uint32_t> unifiedMeshIndices; + unifiedMeshIndices.resize(originalMesh->vertexCount(), (uint32_t)~0); // Add vertices. const uint32_t faceCount = faceArray.size(); for (uint32_t f = 0; f < faceCount; f++) { - const halfedge::Face *face = originalMesh->faceAt(faceArray[f]); - xaDebugAssert(face != NULL); - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Vertex *vertex = it.current()->vertex; - const halfedge::Vertex *unifiedVertex = vertex->firstColocal(); - if (unifiedMeshIndices[unifiedVertex->id] == ~0) { - unifiedMeshIndices[unifiedVertex->id] = m_unifiedMesh->vertexCount(); - xaDebugAssert(vertex->pos == unifiedVertex->pos); - m_unifiedMesh->addVertex(vertex->pos); + for (uint32_t i = 0; i < 3; i++) { + const uint32_t vertex = originalMesh->vertexAt(faceArray[f] * 3 + i); + const uint32_t unifiedVertex = originalMesh->firstColocal(vertex); + if (unifiedMeshIndices[unifiedVertex] == (uint32_t)~0) { + unifiedMeshIndices[unifiedVertex] = m_unifiedMesh->vertexCount(); + XA_DEBUG_ASSERT(equal(originalMesh->position(vertex), originalMesh->position(unifiedVertex), originalMesh->epsilon())); + m_unifiedMesh->addVertex(originalMesh->position(vertex)); } - if (chartMeshIndices[vertex->id] == ~0) { - chartMeshIndices[vertex->id] = m_chartMesh->vertexCount(); - // -- GODOT start -- - //m_chartToOriginalMap.push_back(vertex->id); - m_chartToOriginalMap.push_back(vertex->original_id); - // -- GODOT end -- - m_chartToUnifiedMap.push_back(unifiedMeshIndices[unifiedVertex->id]); - halfedge::Vertex *v = m_chartMesh->addVertex(vertex->pos); - v->nor = vertex->nor; - v->tex = vertex->tex; + if (chartMeshIndices[vertex] == (uint32_t)~0) { + chartMeshIndices[vertex] = m_mesh->vertexCount(); + m_chartToOriginalMap.push_back(vertex); + m_chartToUnifiedMap.push_back(unifiedMeshIndices[unifiedVertex]); + m_mesh->addVertex(originalMesh->position(vertex), Vector3(0.0f), originalMesh->texcoord(vertex)); } } } - // This is ignoring the canonical map: - // - Is it really necessary to link colocals? - m_chartMesh->linkColocals(); - //m_unifiedMesh->linkColocals(); // Not strictly necessary, no colocals in the unified mesh. # Wrong. - // This check is not valid anymore, if the original mesh vertices were linked with a canonical map, then it might have - // some colocal vertices that were unlinked. So, the unified mesh might have some duplicate vertices, because firstColocal() - // is not guaranteed to return the same vertex for two colocal vertices. - //xaAssert(m_chartMesh->colocalVertexCount() == m_unifiedMesh->vertexCount()); - // Is that OK? What happens in meshes were that happens? Does anything break? Apparently not... - std::vector<uint32_t> faceIndices; - faceIndices.reserve(7); // Add faces. for (uint32_t f = 0; f < faceCount; f++) { - const halfedge::Face *face = originalMesh->faceAt(faceArray[f]); - xaDebugAssert(face != NULL); - faceIndices.clear(); - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Vertex *vertex = it.current()->vertex; - xaDebugAssert(vertex != NULL); - faceIndices.push_back(chartMeshIndices[vertex->id]); - } - m_chartMesh->addFace(faceIndices); - faceIndices.clear(); - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Vertex *vertex = it.current()->vertex; - xaDebugAssert(vertex != NULL); - vertex = vertex->firstColocal(); - faceIndices.push_back(unifiedMeshIndices[vertex->id]); - } - m_unifiedMesh->addFace(faceIndices); - } - m_chartMesh->linkBoundary(); - m_unifiedMesh->linkBoundary(); - //exportMesh(m_unifiedMesh.ptr(), "debug_input.obj"); - if (m_unifiedMesh->splitBoundaryEdges()) { - m_unifiedMesh.reset(halfedge::unifyVertices(m_unifiedMesh.get())); - } - //exportMesh(m_unifiedMesh.ptr(), "debug_split.obj"); - // Closing the holes is not always the best solution and does not fix all the problems. - // We need to do some analysis of the holes and the genus to: - // - Find cuts that reduce genus. - // - Find cuts to connect holes. - // - Use minimal spanning trees or seamster. - if (!closeHoles()) { - /*static int pieceCount = 0; - StringBuilder fileName; - fileName.format("debug_hole_%d.obj", pieceCount++); - exportMesh(m_unifiedMesh.ptr(), fileName.str());*/ - } - m_unifiedMesh.reset(halfedge::triangulate(m_unifiedMesh.get())); - //exportMesh(m_unifiedMesh.ptr(), "debug_triangulated.obj"); - // Analyze chart topology. - halfedge::MeshTopology topology(m_unifiedMesh.get()); - m_isDisk = topology.isDisk(); - } - - void buildVertexMap(const halfedge::Mesh *originalMesh, const std::vector<uint32_t> &unchartedMaterialArray) - { - xaAssert(m_chartMesh.get() == NULL && m_unifiedMesh.get() == NULL); - m_isVertexMapped = true; - // Build face indices. - m_faceArray.clear(); - const uint32_t meshFaceCount = originalMesh->faceCount(); - for (uint32_t f = 0; f < meshFaceCount; f++) { - const halfedge::Face *face = originalMesh->faceAt(f); - if (std::find(unchartedMaterialArray.begin(), unchartedMaterialArray.end(), face->material) != unchartedMaterialArray.end()) { - m_faceArray.push_back(f); - } - } - const uint32_t faceCount = m_faceArray.size(); - if (faceCount == 0) { - return; - } - // @@ The chartMesh construction is basically the same as with regular charts, don't duplicate! - const uint32_t meshVertexCount = originalMesh->vertexCount(); - m_chartMesh.reset(new halfedge::Mesh()); - std::vector<uint32_t> chartMeshIndices(meshVertexCount, (uint32_t)~0); - // Vertex map mesh only has disconnected vertices. - for (uint32_t f = 0; f < faceCount; f++) { - const halfedge::Face *face = originalMesh->faceAt(m_faceArray[f]); - xaDebugAssert(face != NULL); - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Vertex *vertex = it.current()->vertex; - if (chartMeshIndices[vertex->id] == ~0) { - chartMeshIndices[vertex->id] = m_chartMesh->vertexCount(); - // -- GODOT start -- - //m_chartToOriginalMap.push_back(vertex->id); - m_chartToOriginalMap.push_back(vertex->original_id); - // -- GODOT end -- - halfedge::Vertex *v = m_chartMesh->addVertex(vertex->pos); - v->nor = vertex->nor; - v->tex = vertex->tex; // @@ Not necessary. - } + uint32_t indices[3], unifiedIndices[3]; + for (uint32_t i = 0; i < 3; i++) { + const uint32_t vertex = originalMesh->vertexAt(faceArray[f] * 3 + i); + indices[i] = chartMeshIndices[vertex]; + unifiedIndices[i] = unifiedMeshIndices[originalMesh->firstColocal(vertex)]; + } + Mesh::AddFaceResult::Enum result = m_mesh->addFace(indices); + XA_UNUSED(result); + XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK); +#if XA_DEBUG + // Unifying colocals may create degenerate edges. e.g. if two triangle vertices are colocal. + for (int i = 0; i < 3; i++) { + const uint32_t index1 = unifiedIndices[i]; + const uint32_t index2 = unifiedIndices[(i + 1) % 3]; + XA_DEBUG_ASSERT(index1 != index2); } - } - // @@ Link colocals using the original mesh canonical map? Build canonical map on the fly? Do we need to link colocals at all for this? - //m_chartMesh->linkColocals(); - std::vector<uint32_t> faceIndices; - faceIndices.reserve(7); - // Add faces. - for (uint32_t f = 0; f < faceCount; f++) { - const halfedge::Face *face = originalMesh->faceAt(m_faceArray[f]); - xaDebugAssert(face != NULL); - faceIndices.clear(); - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Vertex *vertex = it.current()->vertex; - xaDebugAssert(vertex != NULL); - xaDebugAssert(chartMeshIndices[vertex->id] != ~0); - faceIndices.push_back(chartMeshIndices[vertex->id]); - } - halfedge::Face *new_face = m_chartMesh->addFace(faceIndices); - xaDebugAssert(new_face != NULL); -#ifdef NDEBUG - new_face = NULL; // silence unused parameter warning #endif - } - m_chartMesh->linkBoundary(); - const uint32_t chartVertexCount = m_chartMesh->vertexCount(); - Box bounds; - bounds.clearBounds(); - for (uint32_t i = 0; i < chartVertexCount; i++) { - halfedge::Vertex *vertex = m_chartMesh->vertexAt(i); - bounds.addPointToBounds(vertex->pos); - } - ProximityGrid grid; - grid.init(bounds, chartVertexCount); - for (uint32_t i = 0; i < chartVertexCount; i++) { - halfedge::Vertex *vertex = m_chartMesh->vertexAt(i); - grid.add(vertex->pos, i); - } - uint32_t texelCount = 0; - const float positionThreshold = 0.01f; - const float normalThreshold = 0.01f; - uint32_t verticesVisited = 0; - uint32_t cellsVisited = 0; - std::vector<int> vertexIndexArray(chartVertexCount, -1); // Init all indices to -1. - // Traverse vertices in morton order. @@ It may be more interesting to sort them based on orientation. - const uint32_t cellCodeCount = grid.mortonCount(); - for (uint32_t cellCode = 0; cellCode < cellCodeCount; cellCode++) { - int cell = grid.mortonIndex(cellCode); - if (cell < 0) continue; - cellsVisited++; - const std::vector<uint32_t> &indexArray = grid.cellArray[cell].indexArray; - for (uint32_t i = 0; i < indexArray.size(); i++) { - uint32_t idx = indexArray[i]; - halfedge::Vertex *vertex = m_chartMesh->vertexAt(idx); - xaDebugAssert(vertexIndexArray[idx] == -1); - std::vector<uint32_t> neighbors; - grid.gather(vertex->pos, positionThreshold, /*ref*/neighbors); - // Compare against all nearby vertices, cluster greedily. - for (uint32_t j = 0; j < neighbors.size(); j++) { - uint32_t otherIdx = neighbors[j]; - if (vertexIndexArray[otherIdx] != -1) { - halfedge::Vertex *otherVertex = m_chartMesh->vertexAt(otherIdx); - if (distance(vertex->pos, otherVertex->pos) < positionThreshold && - distance(vertex->nor, otherVertex->nor) < normalThreshold) { - vertexIndexArray[idx] = vertexIndexArray[otherIdx]; - break; + result = m_unifiedMesh->addFace(unifiedIndices); + XA_UNUSED(result); + XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK); + } + m_mesh->createBoundaries(); // For AtlasPacker::computeBoundingBox + m_unifiedMesh->createBoundaries(); + m_unifiedMesh->linkBoundaries(); + m_isPlanar = meshIsPlanar(*m_unifiedMesh); + if (m_isPlanar) { + m_isDisk = true; + } else { +#if XA_DEBUG_EXPORT_OBJ_BEFORE_FIX_TJUNCTION + m_unifiedMesh->writeObjFile("debug_before_fix_tjunction.obj"); +#endif + bool duplicatedEdge = false, failed = false; + XA_PROFILE_START(fixChartMeshTJunctions) + Mesh *fixedUnifiedMesh = meshFixTJunctions(*m_unifiedMesh, &duplicatedEdge, &failed, &m_fixedTJunctionsCount); + XA_PROFILE_END(fixChartMeshTJunctions) + if (fixedUnifiedMesh) { + if (duplicatedEdge) + m_warningFlags |= ChartWarningFlags::FixTJunctionsDuplicatedEdge; + if (failed) + m_warningFlags |= ChartWarningFlags::FixTJunctionsFailed; + m_unifiedMesh->~Mesh(); + XA_FREE(m_unifiedMesh); + m_unifiedMesh = fixedUnifiedMesh; + m_unifiedMesh->createBoundaries(); + m_unifiedMesh->linkBoundaries(); + } + // See if there are any holes that need closing. + Array<uint32_t> boundaryLoops; + meshGetBoundaryLoops(*m_unifiedMesh, boundaryLoops); + if (boundaryLoops.size() > 1) { +#if XA_DEBUG_EXPORT_OBJ_CLOSE_HOLES_ERROR + const uint32_t faceCountBeforeHolesClosed = m_unifiedMesh->faceCount(); +#endif + // Closing the holes is not always the best solution and does not fix all the problems. + // We need to do some analysis of the holes and the genus to: + // - Find cuts that reduce genus. + // - Find cuts to connect holes. + // - Use minimal spanning trees or seamster. + Array<uint32_t> holeFaceCounts; + XA_PROFILE_START(closeChartMeshHoles) + failed = !meshCloseHoles(m_unifiedMesh, boundaryLoops, basis.normal, holeFaceCounts); + XA_PROFILE_END(closeChartMeshHoles) + m_unifiedMesh->createBoundaries(); + m_unifiedMesh->linkBoundaries(); + meshGetBoundaryLoops(*m_unifiedMesh, boundaryLoops); + if (failed || boundaryLoops.size() > 1) + m_warningFlags |= ChartWarningFlags::CloseHolesFailed; + m_closedHolesCount = holeFaceCounts.size(); +#if XA_DEBUG_EXPORT_OBJ_CLOSE_HOLES_ERROR + if (m_warningFlags & ChartWarningFlags::CloseHolesFailed) { + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_chart_%03u_close_holes_error.obj", meshId, chartGroupId, chartId); + FILE *file; + XA_FOPEN(file, filename, "w"); + if (file) { + m_unifiedMesh->writeObjVertices(file); + fprintf(file, "s off\n"); + fprintf(file, "o object\n"); + for (uint32_t i = 0; i < faceCountBeforeHolesClosed; i++) + m_unifiedMesh->writeObjFace(file, i); + uint32_t face = faceCountBeforeHolesClosed; + for (uint32_t i = 0; i < holeFaceCounts.size(); i++) { + fprintf(file, "s off\n"); + fprintf(file, "o hole%u\n", i); + for (uint32_t j = 0; j < holeFaceCounts[i]; j++) { + m_unifiedMesh->writeObjFace(file, face); + face++; + } } + m_unifiedMesh->writeObjBoundaryEges(file); + m_unifiedMesh->writeObjLinkedBoundaries(file); + fclose(file); } } - // If index not assigned, assign new one. - if (vertexIndexArray[idx] == -1) { - vertexIndexArray[idx] = texelCount++; - } - verticesVisited++; - } - } - xaDebugAssert(cellsVisited == grid.cellArray.size()); - xaDebugAssert(verticesVisited == chartVertexCount); - vertexMapWidth = ftoi_ceil(sqrtf(float(texelCount))); - vertexMapWidth = (vertexMapWidth + 3) & ~3; // Width aligned to 4. - vertexMapHeight = vertexMapWidth == 0 ? 0 : (texelCount + vertexMapWidth - 1) / vertexMapWidth; - //vertexMapHeight = (vertexMapHeight + 3) & ~3; // Height aligned to 4. - xaDebugAssert(vertexMapWidth >= vertexMapHeight); - xaPrint("Reduced vertex count from %d to %d.\n", chartVertexCount, texelCount); - // Lay down the clustered vertices in morton order. - std::vector<uint32_t> texelCodes(texelCount); - // For each texel, assign one morton code. - uint32_t texelCode = 0; - for (uint32_t i = 0; i < texelCount; i++) { - uint32_t x, y; - do { - x = morton::decodeMorton2X(texelCode); - y = morton::decodeMorton2Y(texelCode); - texelCode++; - } while (x >= uint32_t(vertexMapWidth) || y >= uint32_t(vertexMapHeight)); - texelCodes[i] = texelCode - 1; - } - for (uint32_t i = 0; i < chartVertexCount; i++) { - halfedge::Vertex *vertex = m_chartMesh->vertexAt(i); - int idx = vertexIndexArray[i]; - if (idx != -1) { - uint32_t tc = texelCodes[idx]; - uint32_t x = morton::decodeMorton2X(tc); - uint32_t y = morton::decodeMorton2Y(tc); - vertex->tex.x = float(x); - vertex->tex.y = float(y); - } - } - } - - bool closeHoles() - { - xaDebugAssert(!m_isVertexMapped); - std::vector<halfedge::Edge *> boundaryEdges; - getBoundaryEdges(m_unifiedMesh.get(), boundaryEdges); - uint32_t boundaryCount = boundaryEdges.size(); - if (boundaryCount <= 1) { - // Nothing to close. - return true; - } - // Compute lengths and areas. - std::vector<float> boundaryLengths; - for (uint32_t i = 0; i < boundaryCount; i++) { - const halfedge::Edge *startEdge = boundaryEdges[i]; - xaAssert(startEdge->face == NULL); - //float boundaryEdgeCount = 0; - float boundaryLength = 0.0f; - //Vector3 boundaryCentroid(zero); - const halfedge::Edge *edge = startEdge; - do { - Vector3 t0 = edge->from()->pos; - Vector3 t1 = edge->to()->pos; - //boundaryEdgeCount++; - boundaryLength += length(t1 - t0); - //boundaryCentroid += edge->vertex()->pos; - edge = edge->next; - } while (edge != startEdge); - boundaryLengths.push_back(boundaryLength); - //boundaryCentroids.append(boundaryCentroid / boundaryEdgeCount); - } - // Find disk boundary. - uint32_t diskBoundary = 0; - float maxLength = boundaryLengths[0]; - for (uint32_t i = 1; i < boundaryCount; i++) { - if (boundaryLengths[i] > maxLength) { - maxLength = boundaryLengths[i]; - diskBoundary = i; - } - } - // Close holes. - for (uint32_t i = 0; i < boundaryCount; i++) { - if (diskBoundary == i) { - // Skip disk boundary. - continue; +#endif } - halfedge::Edge *startEdge = boundaryEdges[i]; - xaDebugAssert(startEdge != NULL); - xaDebugAssert(startEdge->face == NULL); - std::vector<halfedge::Vertex *> vertexLoop; - std::vector<halfedge::Edge *> edgeLoop; - halfedge::Edge *edge = startEdge; - do { - halfedge::Vertex *vertex = edge->next->vertex; // edge->to() - uint32_t j; - for (j = 0; j < vertexLoop.size(); j++) { - if (vertex->isColocal(vertexLoop[j])) { - break; - } - } - bool isCrossing = (j != vertexLoop.size()); - if (isCrossing) { - halfedge::Edge *prev = edgeLoop[j]; // Previous edge before the loop. - halfedge::Edge *next = edge->next; // Next edge after the loop. - xaDebugAssert(prev->to()->isColocal(next->from())); - // Close loop. - edgeLoop.push_back(edge); - closeLoop(j + 1, edgeLoop); - // Link boundary loop. - prev->setNext(next); - vertex->setEdge(next); - // Start over again. - vertexLoop.clear(); - edgeLoop.clear(); - edge = startEdge; - vertex = edge->to(); - } - vertexLoop.push_back(vertex); - edgeLoop.push_back(edge); - edge = edge->next; - } while (edge != startEdge); - closeLoop(0, edgeLoop); + // Note: MeshTopology needs linked boundaries. + MeshTopology topology(m_unifiedMesh); + m_isDisk = topology.isDisk(); +#if XA_DEBUG_EXPORT_OBJ_NOT_DISK + if (!m_isDisk) { + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_chart_%03u_not_disk.obj", meshId, chartGroupId, chartId); + m_unifiedMesh->writeObjFile(filename); + } +#endif } - getBoundaryEdges(m_unifiedMesh.get(), boundaryEdges); - boundaryCount = boundaryEdges.size(); - xaDebugAssert(boundaryCount == 1); - return boundaryCount == 1; - } - - bool isDisk() const - { - return m_isDisk; - } - bool isVertexMapped() const - { - return m_isVertexMapped; - } - - uint32_t vertexCount() const - { - return m_chartMesh->vertexCount(); - } - uint32_t colocalVertexCount() const - { - return m_unifiedMesh->vertexCount(); } - uint32_t faceCount() const + ~Chart() { - return m_faceArray.size(); - } - uint32_t faceAt(uint32_t i) const - { - return m_faceArray[i]; - } - - const halfedge::Mesh *chartMesh() const - { - return m_chartMesh.get(); - } - halfedge::Mesh *chartMesh() - { - return m_chartMesh.get(); - } - const halfedge::Mesh *unifiedMesh() const - { - return m_unifiedMesh.get(); - } - halfedge::Mesh *unifiedMesh() - { - return m_unifiedMesh.get(); + if (m_mesh) { + m_mesh->~Mesh(); + XA_FREE(m_mesh); + } + if (m_unifiedMesh) { + m_unifiedMesh->~Mesh(); + XA_FREE(m_unifiedMesh); + } } - //uint32_t vertexIndex(uint32_t i) const { return m_vertexIndexArray[i]; } + const Basis &basis() const { return m_basis; } + bool isDisk() const { return m_isDisk; } + bool isOrtho() const { return m_isOrtho; } + bool isPlanar() const { return m_isPlanar; } + uint32_t warningFlags() const { return m_warningFlags; } + uint32_t closedHolesCount() const { return m_closedHolesCount; } + uint32_t fixedTJunctionsCount() const { return m_fixedTJunctionsCount; } + const ParameterizationQuality ¶mQuality() const { return m_paramQuality; } +#if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION + const Array<uint32_t> ¶mFlippedFaces() const { return m_paramFlippedFaces; } +#endif + uint32_t mapFaceToSourceFace(uint32_t i) const { return m_faceArray[i]; } + const Mesh *mesh() const { return m_mesh; } + Mesh *mesh() { return m_mesh; } + const Mesh *unifiedMesh() const { return m_unifiedMesh; } + Mesh *unifiedMesh() { return m_unifiedMesh; } + uint32_t mapChartVertexToOriginalVertex(uint32_t i) const { return m_chartToOriginalMap[i]; } - uint32_t mapChartVertexToOriginalVertex(uint32_t i) const - { - return m_chartToOriginalMap[i]; - } - uint32_t mapChartVertexToUnifiedVertex(uint32_t i) const + void evaluateOrthoParameterizationQuality() { - return m_chartToUnifiedMap[i]; + XA_PROFILE_START(parameterizeChartsEvaluateQuality) + m_paramQuality = calculateParameterizationQuality(m_unifiedMesh, nullptr); + XA_PROFILE_END(parameterizeChartsEvaluateQuality) + // Use orthogonal parameterization if quality is acceptable. + if (!m_paramQuality.boundaryIntersection && m_paramQuality.geometricArea > 0.0f && m_paramQuality.stretchMetric <= 1.1f && m_paramQuality.maxStretchMetric <= 1.25f) + m_isOrtho = true; } - const std::vector<uint32_t> &faceArray() const + void evaluateParameterizationQuality() { - return m_faceArray; + XA_PROFILE_START(parameterizeChartsEvaluateQuality) +#if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION + m_paramQuality = calculateParameterizationQuality(m_unifiedMesh, &m_paramFlippedFaces); +#else + m_paramQuality = calculateParameterizationQuality(m_unifiedMesh, nullptr); +#endif + XA_PROFILE_END(parameterizeChartsEvaluateQuality) } // Transfer parameterization from unified mesh to chart mesh. void transferParameterization() { - xaDebugAssert(!m_isVertexMapped); - uint32_t vertexCount = m_chartMesh->vertexCount(); - for (uint32_t v = 0; v < vertexCount; v++) { - halfedge::Vertex *vertex = m_chartMesh->vertexAt(v); - halfedge::Vertex *unifiedVertex = m_unifiedMesh->vertexAt(mapChartVertexToUnifiedVertex(v)); - vertex->tex = unifiedVertex->tex; - } + const uint32_t vertexCount = m_mesh->vertexCount(); + for (uint32_t v = 0; v < vertexCount; v++) + m_mesh->texcoord(v) = m_unifiedMesh->texcoord(m_chartToUnifiedMap[v]); } float computeSurfaceArea() const { - return halfedge::computeSurfaceArea(m_chartMesh.get()) * scale; + return m_mesh->computeSurfaceArea(); } float computeParametricArea() const { - // This only makes sense in parameterized meshes. - xaDebugAssert(m_isDisk); - xaDebugAssert(!m_isVertexMapped); - return halfedge::computeParametricArea(m_chartMesh.get()); + return m_mesh->computeParametricArea(); } Vector2 computeParametricBounds() const { - // This only makes sense in parameterized meshes. - xaDebugAssert(m_isDisk); - xaDebugAssert(!m_isVertexMapped); - Box bounds; - bounds.clearBounds(); - uint32_t vertexCount = m_chartMesh->vertexCount(); + Vector2 minCorner(FLT_MAX, FLT_MAX); + Vector2 maxCorner(-FLT_MAX, -FLT_MAX); + const uint32_t vertexCount = m_mesh->vertexCount(); for (uint32_t v = 0; v < vertexCount; v++) { - halfedge::Vertex *vertex = m_chartMesh->vertexAt(v); - bounds.addPointToBounds(Vector3(vertex->tex, 0)); + minCorner = min(minCorner, m_mesh->texcoord(v)); + maxCorner = max(maxCorner, m_mesh->texcoord(v)); } - return bounds.extents().xy(); + return (maxCorner - minCorner) * 0.5f; } - float scale = 1.0f; - uint32_t vertexMapWidth; - uint32_t vertexMapHeight; - bool blockAligned = true; - private: - bool closeLoop(uint32_t start, const std::vector<halfedge::Edge *> &loop) - { - const uint32_t vertexCount = loop.size() - start; - xaDebugAssert(vertexCount >= 3); - if (vertexCount < 3) return false; - xaDebugAssert(loop[start]->vertex->isColocal(loop[start + vertexCount - 1]->to())); - // If the hole is planar, then we add a single face that will be properly triangulated later. - // If the hole is not planar, we add a triangle fan with a vertex at the hole centroid. - // This is still a bit of a hack. There surely are better hole filling algorithms out there. - std::vector<Vector3> points(vertexCount); - for (uint32_t i = 0; i < vertexCount; i++) { - points[i] = loop[start + i]->vertex->pos; - } - bool isPlanar = Fit::isPlanar(vertexCount, points.data()); - if (isPlanar) { - // Add face and connect edges. - halfedge::Face *face = m_unifiedMesh->addFace(); - for (uint32_t i = 0; i < vertexCount; i++) { - halfedge::Edge *edge = loop[start + i]; - edge->face = face; - edge->setNext(loop[start + (i + 1) % vertexCount]); - } - face->edge = loop[start]; - xaDebugAssert(face->isValid()); - } else { - // If the polygon is not planar, we just cross our fingers, and hope this will work: - // Compute boundary centroid: - Vector3 centroidPos(0); - for (uint32_t i = 0; i < vertexCount; i++) { - centroidPos += points[i]; - } - centroidPos *= (1.0f / vertexCount); - halfedge::Vertex *centroid = m_unifiedMesh->addVertex(centroidPos); - // Add one pair of edges for each boundary vertex. - for (uint32_t j = vertexCount - 1, i = 0; i < vertexCount; j = i++) { - halfedge::Face *face = m_unifiedMesh->addFace(centroid->id, loop[start + j]->vertex->id, loop[start + i]->vertex->id); - xaDebugAssert(face != NULL); -#ifdef NDEBUG - face = NULL; // silence unused parameter warning -#endif - } - } - return true; - } - - static void getBoundaryEdges(halfedge::Mesh *mesh, std::vector<halfedge::Edge *> &boundaryEdges) - { - xaDebugAssert(mesh != NULL); - const uint32_t edgeCount = mesh->edgeCount(); - BitArray bitFlags(edgeCount); - bitFlags.clearAll(); - boundaryEdges.clear(); - // Search for boundary edges. Mark all the edges that belong to the same boundary. - for (uint32_t e = 0; e < edgeCount; e++) { - halfedge::Edge *startEdge = mesh->edgeAt(e); - if (startEdge != NULL && startEdge->isBoundary() && bitFlags.bitAt(e) == false) { - xaDebugAssert(startEdge->face != NULL); - xaDebugAssert(startEdge->pair->face == NULL); - startEdge = startEdge->pair; - const halfedge::Edge *edge = startEdge; - do { - xaDebugAssert(edge->face == NULL); - xaDebugAssert(bitFlags.bitAt(edge->id / 2) == false); - bitFlags.setBitAt(edge->id / 2); - edge = edge->next; - } while (startEdge != edge); - boundaryEdges.push_back(startEdge); - } - } - } - - // Chart mesh. - std::auto_ptr<halfedge::Mesh> m_chartMesh; + Basis m_basis; + Mesh *m_mesh; + Mesh *m_unifiedMesh; + bool m_isDisk, m_isOrtho, m_isPlanar; + uint32_t m_warningFlags; + uint32_t m_closedHolesCount, m_fixedTJunctionsCount; - std::auto_ptr<halfedge::Mesh> m_unifiedMesh; - bool m_isDisk; - bool m_isVertexMapped; - // List of faces of the original mesh that belong to this chart. - std::vector<uint32_t> m_faceArray; + Array<uint32_t> m_faceArray; // Map vertices of the chart mesh to vertices of the original mesh. - std::vector<uint32_t> m_chartToOriginalMap; + Array<uint32_t> m_chartToOriginalMap; + + Array<uint32_t> m_chartToUnifiedMap; - std::vector<uint32_t> m_chartToUnifiedMap; + ParameterizationQuality m_paramQuality; +#if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION + Array<uint32_t> m_paramFlippedFaces; +#endif }; -// Estimate quality of existing parameterization. -class ParameterizationQuality +struct CreateChartTaskArgs { -public: - ParameterizationQuality() - { - m_totalTriangleCount = 0; - m_flippedTriangleCount = 0; - m_zeroAreaTriangleCount = 0; - m_parametricArea = 0.0f; - m_geometricArea = 0.0f; - m_stretchMetric = 0.0f; - m_maxStretchMetric = 0.0f; - m_conformalMetric = 0.0f; - m_authalicMetric = 0.0f; - } - - ParameterizationQuality(const halfedge::Mesh *mesh) - { - xaDebugAssert(mesh != NULL); - m_totalTriangleCount = 0; - m_flippedTriangleCount = 0; - m_zeroAreaTriangleCount = 0; - m_parametricArea = 0.0f; - m_geometricArea = 0.0f; - m_stretchMetric = 0.0f; - m_maxStretchMetric = 0.0f; - m_conformalMetric = 0.0f; - m_authalicMetric = 0.0f; - const uint32_t faceCount = mesh->faceCount(); - for (uint32_t f = 0; f < faceCount; f++) { - const halfedge::Face *face = mesh->faceAt(f); - const halfedge::Vertex *vertex0 = NULL; - Vector3 p[3]; - Vector2 t[3]; - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Edge *edge = it.current(); - if (vertex0 == NULL) { - vertex0 = edge->vertex; - p[0] = vertex0->pos; - t[0] = vertex0->tex; - } else if (edge->to() != vertex0) { - p[1] = edge->from()->pos; - p[2] = edge->to()->pos; - t[1] = edge->from()->tex; - t[2] = edge->to()->tex; - processTriangle(p, t); - } - } - } - if (m_flippedTriangleCount + m_zeroAreaTriangleCount == faceCount) { - // If all triangles are flipped, then none is. - m_flippedTriangleCount = 0; - } - xaDebugAssert(std::isfinite(m_parametricArea) && m_parametricArea >= 0); - xaDebugAssert(std::isfinite(m_geometricArea) && m_geometricArea >= 0); - xaDebugAssert(std::isfinite(m_stretchMetric)); - xaDebugAssert(std::isfinite(m_maxStretchMetric)); - xaDebugAssert(std::isfinite(m_conformalMetric)); - xaDebugAssert(std::isfinite(m_authalicMetric)); - } - - bool isValid() const - { - return m_flippedTriangleCount == 0; // @@ Does not test for self-overlaps. - } - - float rmsStretchMetric() const - { - if (m_geometricArea == 0) return 0.0f; - float normFactor = sqrtf(m_parametricArea / m_geometricArea); - return sqrtf(m_stretchMetric / m_geometricArea) * normFactor; - } - - float maxStretchMetric() const - { - if (m_geometricArea == 0) return 0.0f; - float normFactor = sqrtf(m_parametricArea / m_geometricArea); - return m_maxStretchMetric * normFactor; - } - - float rmsConformalMetric() const - { - if (m_geometricArea == 0) return 0.0f; - return sqrtf(m_conformalMetric / m_geometricArea); - } + const Mesh *mesh; + const Array<uint32_t> *faceArray; + const Basis *basis; + uint32_t meshId; + uint32_t chartGroupId; + uint32_t chartId; + Chart **chart; +}; - float maxAuthalicMetric() const - { - if (m_geometricArea == 0) return 0.0f; - return sqrtf(m_authalicMetric / m_geometricArea); - } +static void runCreateChartTask(void *userData) +{ + XA_PROFILE_START(createChartMeshesThread) + auto args = (CreateChartTaskArgs *)userData; + *(args->chart) = XA_NEW(MemTag::Default, Chart, args->mesh, *(args->faceArray), *(args->basis), args->meshId, args->chartGroupId, args->chartId); + XA_PROFILE_END(createChartMeshesThread) +} - void operator+=(const ParameterizationQuality &pq) - { - m_totalTriangleCount += pq.m_totalTriangleCount; - m_flippedTriangleCount += pq.m_flippedTriangleCount; - m_zeroAreaTriangleCount += pq.m_zeroAreaTriangleCount; - m_parametricArea += pq.m_parametricArea; - m_geometricArea += pq.m_geometricArea; - m_stretchMetric += pq.m_stretchMetric; - m_maxStretchMetric = std::max(m_maxStretchMetric, pq.m_maxStretchMetric); - m_conformalMetric += pq.m_conformalMetric; - m_authalicMetric += pq.m_authalicMetric; - } +struct ParameterizeChartTaskArgs +{ + Chart *chart; + ParameterizeFunc func; +}; -private: - void processTriangle(Vector3 q[3], Vector2 p[3]) - { - m_totalTriangleCount++; - // Evaluate texture stretch metric. See: - // - "Texture Mapping Progressive Meshes", Sander, Snyder, Gortler & Hoppe - // - "Mesh Parameterization: Theory and Practice", Siggraph'07 Course Notes, Hormann, Levy & Sheffer. - float t1 = p[0].x; - float s1 = p[0].y; - float t2 = p[1].x; - float s2 = p[1].y; - float t3 = p[2].x; - float s3 = p[2].y; - float geometricArea = length(cross(q[1] - q[0], q[2] - q[0])) / 2; - float parametricArea = ((s2 - s1) * (t3 - t1) - (s3 - s1) * (t2 - t1)) / 2; - if (isZero(parametricArea)) { - m_zeroAreaTriangleCount++; - return; - } - Vector3 Ss = (q[0] * (t2 - t3) + q[1] * (t3 - t1) + q[2] * (t1 - t2)) / (2 * parametricArea); - Vector3 St = (q[0] * (s3 - s2) + q[1] * (s1 - s3) + q[2] * (s2 - s1)) / (2 * parametricArea); - float a = dot(Ss, Ss); // E - float b = dot(Ss, St); // F - float c = dot(St, St); // G - // Compute eigen-values of the first fundamental form: - float sigma1 = sqrtf(0.5f * std::max(0.0f, a + c - sqrtf(square(a - c) + 4 * square(b)))); // gamma uppercase, min eigenvalue. - float sigma2 = sqrtf(0.5f * std::max(0.0f, a + c + sqrtf(square(a - c) + 4 * square(b)))); // gamma lowercase, max eigenvalue. - xaAssert(sigma2 >= sigma1); - // isometric: sigma1 = sigma2 = 1 - // conformal: sigma1 / sigma2 = 1 - // authalic: sigma1 * sigma2 = 1 - float rmsStretch = sqrtf((a + c) * 0.5f); - float rmsStretch2 = sqrtf((square(sigma1) + square(sigma2)) * 0.5f); - xaDebugAssert(equal(rmsStretch, rmsStretch2, 0.01f)); -#ifdef NDEBUG - rmsStretch2 = 0; // silence unused parameter warning +static void runParameterizeChartTask(void *userData) +{ + auto args = (ParameterizeChartTaskArgs *)userData; + Mesh *mesh = args->chart->unifiedMesh(); + XA_PROFILE_START(parameterizeChartsOrthogonal) +#if 1 + computeOrthogonalProjectionMap(mesh); +#else + for (uint32_t i = 0; i < vertexCount; i++) + mesh->texcoord(i) = Vector2(dot(args->chart->basis().tangent, mesh->position(i)), dot(args->chart->basis().bitangent, mesh->position(i))); #endif - if (parametricArea < 0.0f) { - // Count flipped triangles. - m_flippedTriangleCount++; - parametricArea = fabsf(parametricArea); - } - m_stretchMetric += square(rmsStretch) * geometricArea; - m_maxStretchMetric = std::max(m_maxStretchMetric, sigma2); - if (!isZero(sigma1, 0.000001f)) { - // sigma1 is zero when geometricArea is zero. - m_conformalMetric += (sigma2 / sigma1) * geometricArea; - } - m_authalicMetric += (sigma1 * sigma2) * geometricArea; - // Accumulate total areas. - m_geometricArea += geometricArea; - m_parametricArea += parametricArea; - //triangleConformalEnergy(q, p); - } - - uint32_t m_totalTriangleCount; - uint32_t m_flippedTriangleCount; - uint32_t m_zeroAreaTriangleCount; - float m_parametricArea; - float m_geometricArea; - float m_stretchMetric; - float m_maxStretchMetric; - float m_conformalMetric; - float m_authalicMetric; -}; + XA_PROFILE_END(parameterizeChartsOrthogonal) + args->chart->evaluateOrthoParameterizationQuality(); + if (!args->chart->isOrtho() && !args->chart->isPlanar()) { + XA_PROFILE_START(parameterizeChartsLSCM) + if (args->func) + args->func(&mesh->position(0).x, &mesh->texcoord(0).x, mesh->vertexCount(), mesh->indices(), mesh->indexCount()); + else if (args->chart->isDisk()) + computeLeastSquaresConformalMap(mesh); + XA_PROFILE_END(parameterizeChartsLSCM) + args->chart->evaluateParameterizationQuality(); + } + // @@ Check that parameterization quality is above a certain threshold. + // Transfer parameterization from unified mesh to chart mesh. + args->chart->transferParameterization(); +} -// Set of charts corresponding to a single mesh. -class MeshCharts +// Set of charts corresponding to mesh faces in the same face group. +class ChartGroup { public: - MeshCharts(const halfedge::Mesh *mesh) : m_mesh(mesh) {} - - ~MeshCharts() - { - for (size_t i = 0; i < m_chartArray.size(); i++) - delete m_chartArray[i]; - } - - uint32_t chartCount() const - { - return m_chartArray.size(); - } - uint32_t vertexCount () const - { - return m_totalVertexCount; - } - - const Chart *chartAt(uint32_t i) const - { - return m_chartArray[i]; - } - Chart *chartAt(uint32_t i) - { - return m_chartArray[i]; - } - - // Extract the charts of the input mesh. - void extractCharts() - { - const uint32_t faceCount = m_mesh->faceCount(); - int first = 0; - std::vector<uint32_t> queue; - queue.reserve(faceCount); - BitArray bitFlags(faceCount); - bitFlags.clearAll(); + ChartGroup(uint32_t id, const Mesh *sourceMesh, uint32_t faceGroup) : m_sourceId(sourceMesh->id()), m_id(id), m_isVertexMap(faceGroup == UINT32_MAX), m_paramAddedChartsCount(0), m_paramDeletedChartsCount(0) + { + // Create new mesh from the source mesh, using faces that belong to this group. + const uint32_t sourceFaceCount = sourceMesh->faceCount(); + for (uint32_t f = 0; f < sourceFaceCount; f++) { + if (sourceMesh->faceGroupAt(f) == faceGroup) + m_faceToSourceFaceMap.push_back(f); + } + // Only initial meshes have face groups and ignored faces. The only flag we care about is HasNormals. + const uint32_t faceCount = m_faceToSourceFaceMap.size(); + m_mesh = XA_NEW(MemTag::Mesh, Mesh, sourceMesh->epsilon(), faceCount * 3, faceCount, sourceMesh->flags() & MeshFlags::HasNormals); + XA_DEBUG_ASSERT(faceCount > 0); + Array<uint32_t> meshIndices; + meshIndices.resize(sourceMesh->vertexCount(), (uint32_t)~0); for (uint32_t f = 0; f < faceCount; f++) { - if (bitFlags.bitAt(f) == false) { - // Start new patch. Reset queue. - first = 0; - queue.clear(); - queue.push_back(f); - bitFlags.setBitAt(f); - while (first != (int)queue.size()) { - const halfedge::Face *face = m_mesh->faceAt(queue[first]); - // Visit face neighbors of queue[first] - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - const halfedge::Edge *edge = it.current(); - xaDebugAssert(edge->pair != NULL); - if (!edge->isBoundary() && /*!edge->isSeam()*/ - //!(edge->from()->tex() != edge->pair()->to()->tex() || edge->to()->tex() != edge->pair()->from()->tex())) - !(edge->from() != edge->pair->to() || edge->to() != edge->pair->from())) { // Preserve existing seams (not just texture seams). - const halfedge::Face *neighborFace = edge->pair->face; - xaDebugAssert(neighborFace != NULL); - if (bitFlags.bitAt(neighborFace->id) == false) { - queue.push_back(neighborFace->id); - bitFlags.setBitAt(neighborFace->id); - } - } - } - first++; + const uint32_t face = m_faceToSourceFaceMap[f]; + for (uint32_t i = 0; i < 3; i++) { + const uint32_t vertex = sourceMesh->vertexAt(face * 3 + i); + if (meshIndices[vertex] == (uint32_t)~0) { + meshIndices[vertex] = m_mesh->vertexCount(); + m_vertexToSourceVertexMap.push_back(vertex); + Vector3 normal(0.0f); + if (sourceMesh->flags() & MeshFlags::HasNormals) + normal = sourceMesh->normal(vertex); + m_mesh->addVertex(sourceMesh->position(vertex), normal, sourceMesh->texcoord(vertex)); } - Chart *chart = new Chart(); - chart->build(m_mesh, queue); - m_chartArray.push_back(chart); } } + // Add faces. + for (uint32_t f = 0; f < faceCount; f++) { + const uint32_t face = m_faceToSourceFaceMap[f]; + uint32_t indices[3]; + for (uint32_t i = 0; i < 3; i++) { + const uint32_t vertex = sourceMesh->vertexAt(face * 3 + i); + XA_DEBUG_ASSERT(meshIndices[vertex] != (uint32_t)~0); + indices[i] = meshIndices[vertex]; + } + // Don't copy flags, it doesn't matter if a face is ignored after this point. All ignored faces get their own vertex map (m_isVertexMap) ChartGroup. + // Don't hash edges if m_isVertexMap, they may be degenerate. + Mesh::AddFaceResult::Enum result = m_mesh->addFace(indices, false, !m_isVertexMap); + XA_UNUSED(result); + XA_DEBUG_ASSERT(result == Mesh::AddFaceResult::OK); + } + if (!m_isVertexMap) { + m_mesh->createColocals(); + m_mesh->createBoundaries(); + m_mesh->linkBoundaries(); + } +#if XA_DEBUG_EXPORT_OBJ_CHART_GROUPS + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u.obj", m_sourceId, m_id); + m_mesh->writeObjFile(filename); +#else + XA_UNUSED(m_id); +#endif + } + + ~ChartGroup() + { + m_mesh->~Mesh(); + XA_FREE(m_mesh); + for (uint32_t i = 0; i < m_chartArray.size(); i++) { + m_chartArray[i]->~Chart(); + XA_FREE(m_chartArray[i]); + } } + uint32_t chartCount() const { return m_chartArray.size(); } + Chart *chartAt(uint32_t i) const { return m_chartArray[i]; } + uint32_t paramAddedChartsCount() const { return m_paramAddedChartsCount; } + uint32_t paramDeletedChartsCount() const { return m_paramDeletedChartsCount; } + bool isVertexMap() const { return m_isVertexMap; } + uint32_t mapFaceToSourceFace(uint32_t face) const { return m_faceToSourceFaceMap[face]; } + uint32_t mapVertexToSourceVertex(uint32_t i) const { return m_vertexToSourceVertexMap[i]; } + const Mesh *mesh() const { return m_mesh; } + /* Compute charts using a simple segmentation algorithm. @@ -6481,867 +6169,1304 @@ public: - emphasize roundness metrics to prevent those cases. - If interior self-overlaps: preserve boundary parameterization and use mean-value map. */ - void computeCharts(const CharterOptions &options, const std::vector<uint32_t> &unchartedMaterialArray) - { - Chart *vertexMap = NULL; - if (unchartedMaterialArray.size() != 0) { - vertexMap = new Chart(); - vertexMap->buildVertexMap(m_mesh, unchartedMaterialArray); - if (vertexMap->faceCount() == 0) { - delete vertexMap; - vertexMap = NULL; - } - } - AtlasBuilder builder(m_mesh); - if (vertexMap != NULL) { - // Mark faces that do not need to be charted. - builder.markUnchartedFaces(vertexMap->faceArray()); - m_chartArray.push_back(vertexMap); - } - if (builder.facesLeft != 0) { - // Tweak these values: - const float maxThreshold = 2; - const uint32_t growFaceCount = 32; - const uint32_t maxIterations = 4; - builder.options = options; - //builder.options.proxyFitMetricWeight *= 0.75; // relax proxy fit weight during initial seed placement. - //builder.options.roundnessMetricWeight = 0; - //builder.options.straightnessMetricWeight = 0; - // This seems a reasonable estimate. - uint32_t maxSeedCount = std::max(6U, builder.facesLeft); - // Create initial charts greedely. - xaPrint("### Placing seeds\n"); - builder.placeSeeds(maxThreshold, maxSeedCount); - xaPrint("### Placed %d seeds (max = %d)\n", builder.chartCount(), maxSeedCount); - builder.updateProxies(); - builder.mergeCharts(); - #if 1 - xaPrint("### Relocating seeds\n"); - builder.relocateSeeds(); - xaPrint("### Reset charts\n"); - builder.resetCharts(); - if (vertexMap != NULL) { - builder.markUnchartedFaces(vertexMap->faceArray()); - } - builder.options = options; - xaPrint("### Growing charts\n"); - // Restart process growing charts in parallel. - uint32_t iteration = 0; - while (true) { - if (!builder.growCharts(maxThreshold, growFaceCount)) { - xaPrint("### Can't grow anymore\n"); - // If charts cannot grow more: fill holes, merge charts, relocate seeds and start new iteration. - xaPrint("### Filling holes\n"); - builder.fillHoles(maxThreshold); - xaPrint("### Using %d charts now\n", builder.chartCount()); - builder.updateProxies(); - xaPrint("### Merging charts\n"); - builder.mergeCharts(); - xaPrint("### Using %d charts now\n", builder.chartCount()); - xaPrint("### Reseeding\n"); - if (!builder.relocateSeeds()) { - xaPrint("### Cannot relocate seeds anymore\n"); - // Done! - break; - } - if (iteration == maxIterations) { - xaPrint("### Reached iteration limit\n"); - break; - } - iteration++; - xaPrint("### Reset charts\n"); - builder.resetCharts(); - if (vertexMap != NULL) { - builder.markUnchartedFaces(vertexMap->faceArray()); - } - xaPrint("### Growing charts\n"); - } - }; - #endif - // Make sure no holes are left! - xaDebugAssert(builder.facesLeft == 0); - const uint32_t chartCount = builder.chartArray.size(); - for (uint32_t i = 0; i < chartCount; i++) { - Chart *chart = new Chart(); - m_chartArray.push_back(chart); - chart->build(m_mesh, builder.chartFaces(i)); - } - } - const uint32_t chartCount = m_chartArray.size(); - // Build face indices. - m_faceChart.resize(m_mesh->faceCount()); - m_faceIndex.resize(m_mesh->faceCount()); + void computeCharts(TaskScheduler *taskScheduler, const ChartOptions &options) + { + m_chartOptions = options; + // This function may be called multiple times, so destroy existing charts. + for (uint32_t i = 0; i < m_chartArray.size(); i++) { + m_chartArray[i]->~Chart(); + XA_FREE(m_chartArray[i]); + } + m_chartArray.clear(); +#if XA_DEBUG_SINGLE_CHART + Array<uint32_t> chartFaces; + chartFaces.resize(m_mesh->faceCount()); + for (uint32_t i = 0; i < chartFaces.size(); i++) + chartFaces[i] = i; + Chart *chart = XA_NEW(MemTag::Default, Chart, m_mesh, chartFaces, m_sourceId, m_id, 0); + m_chartArray.push_back(chart); +#else + XA_PROFILE_START(atlasBuilder) + AtlasBuilder builder(m_mesh, nullptr, options); + runAtlasBuilder(builder, options); + XA_PROFILE_END(atlasBuilder) + const uint32_t chartCount = builder.chartCount(); + m_chartArray.resize(chartCount); + Array<CreateChartTaskArgs> taskArgs; + taskArgs.resize(chartCount); for (uint32_t i = 0; i < chartCount; i++) { - const Chart *chart = m_chartArray[i]; - const uint32_t faceCount = chart->faceCount(); - for (uint32_t f = 0; f < faceCount; f++) { - uint32_t idx = chart->faceAt(f); - m_faceChart[idx] = i; - m_faceIndex[idx] = f; - } + CreateChartTaskArgs &args = taskArgs[i]; + args.mesh = m_mesh; + args.faceArray = &builder.chartFaces(i); + args.basis = &builder.chartBasis(i); + args.meshId = m_sourceId; + args.chartGroupId = m_id; + args.chartId = i; + args.chart = &m_chartArray[i]; + } + XA_PROFILE_START(createChartMeshesReal) + TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartCount); + for (uint32_t i = 0; i < chartCount; i++) { + Task task; + task.userData = &taskArgs[i]; + task.func = runCreateChartTask; + taskScheduler->run(taskGroup, task); } - // Build an exclusive prefix sum of the chart vertex counts. - m_chartVertexCountPrefixSum.resize(chartCount); - if (chartCount > 0) { - m_chartVertexCountPrefixSum[0] = 0; - for (uint32_t i = 1; i < chartCount; i++) { - const Chart *chart = m_chartArray[i - 1]; - m_chartVertexCountPrefixSum[i] = m_chartVertexCountPrefixSum[i - 1] + chart->vertexCount(); + taskScheduler->wait(&taskGroup); + XA_PROFILE_END(createChartMeshesReal) +#endif +#if XA_DEBUG_EXPORT_OBJ_CHARTS + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_charts.obj", m_sourceId, m_id); + FILE *file; + XA_FOPEN(file, filename, "w"); + if (file) { + m_mesh->writeObjVertices(file); + for (uint32_t i = 0; i < chartCount; i++) { + fprintf(file, "o chart_%04d\n", i); + fprintf(file, "s off\n"); + const Array<uint32_t> &faces = builder.chartFaces(i); + for (uint32_t f = 0; f < faces.size(); f++) + m_mesh->writeObjFace(file, faces[f]); } - m_totalVertexCount = m_chartVertexCountPrefixSum[chartCount - 1] + m_chartArray[chartCount - 1]->vertexCount(); - } else { - m_totalVertexCount = 0; + m_mesh->writeObjBoundaryEges(file); + m_mesh->writeObjLinkedBoundaries(file); + fclose(file); } +#endif } - void parameterizeCharts() + void parameterizeCharts(TaskScheduler *taskScheduler, ParameterizeFunc func) { - ParameterizationQuality globalParameterizationQuality; - // Parameterize the charts. - uint32_t diskCount = 0; const uint32_t chartCount = m_chartArray.size(); - for (uint32_t i = 0; i < chartCount; i++) - { + Array<ParameterizeChartTaskArgs> taskArgs; + taskArgs.resize(chartCount); + TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartCount); + for (uint32_t i = 0; i < chartCount; i++) { + ParameterizeChartTaskArgs &args = taskArgs[i]; + args.chart = m_chartArray[i]; + args.func = func; + Task task; + task.userData = &args; + task.func = runParameterizeChartTask; + taskScheduler->run(taskGroup, task); + } + taskScheduler->wait(&taskGroup); +#if XA_RECOMPUTE_CHARTS + // Find charts with invalid parameterizations. + Array<Chart *> invalidCharts; + for (uint32_t i = 0; i < chartCount; i++) { Chart *chart = m_chartArray[i]; - - bool isValid = false; - - if (chart->isVertexMapped()) - { - continue; - } - - if (chart->isDisk()) - { - diskCount++; - ParameterizationQuality chartParameterizationQuality; - if (chart->faceCount() == 1) { - computeSingleFaceMap(chart->unifiedMesh()); - chartParameterizationQuality = ParameterizationQuality(chart->unifiedMesh()); - } else { - computeOrthogonalProjectionMap(chart->unifiedMesh()); - ParameterizationQuality orthogonalQuality(chart->unifiedMesh()); - computeLeastSquaresConformalMap(chart->unifiedMesh()); - ParameterizationQuality lscmQuality(chart->unifiedMesh()); - chartParameterizationQuality = lscmQuality; - } - isValid = chartParameterizationQuality.isValid(); - if (!isValid) { - xaPrint("*** Invalid parameterization.\n"); + const ParameterizationQuality &quality = chart->paramQuality(); + if (quality.boundaryIntersection || quality.flippedTriangleCount > 0) + invalidCharts.push_back(chart); + } + if (invalidCharts.isEmpty()) + return; + // Recompute charts with invalid parameterizations. + Array<uint32_t> meshFaces; + for (uint32_t i = 0; i < invalidCharts.size(); i++) { + Chart *invalidChart = invalidCharts[i]; + const Mesh *invalidMesh = invalidChart->mesh(); + const uint32_t faceCount = invalidMesh->faceCount(); + meshFaces.resize(faceCount); + float invalidChartArea = 0.0f; + for (uint32_t j = 0; j < faceCount; j++) { + meshFaces[j] = invalidChart->mapFaceToSourceFace(j); + invalidChartArea += invalidMesh->faceArea(j); + } + ChartOptions options = m_chartOptions; + options.maxChartArea = invalidChartArea * 0.2f; + options.maxThreshold = 0.25f; + options.maxIterations = 3; + AtlasBuilder builder(m_mesh, &meshFaces, options); + runAtlasBuilder(builder, options); + for (uint32_t j = 0; j < builder.chartCount(); j++) { + Chart *chart = XA_NEW(MemTag::Default, Chart, m_mesh, builder.chartFaces(j), builder.chartBasis(j), m_sourceId, m_id, m_chartArray.size()); + m_chartArray.push_back(chart); + m_paramAddedChartsCount++; + } +#if XA_DEBUG_EXPORT_OBJ_RECOMPUTED_CHARTS + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u_chartgroup_%03u_recomputed_chart_%u.obj", m_sourceId, m_id, i); + FILE *file; + XA_FOPEN(file, filename, "w"); + if (file) { + m_mesh->writeObjVertices(file); + for (uint32_t j = 0; j < builder.chartCount(); j++) { + fprintf(file, "o chart_%04d\n", j); + fprintf(file, "s off\n"); + const Array<uint32_t> &faces = builder.chartFaces(j); + for (uint32_t f = 0; f < faces.size(); f++) + m_mesh->writeObjFace(file, faces[f]); } - // @@ Check that parameterization quality is above a certain threshold. - // @@ Detect boundary self-intersections. - globalParameterizationQuality += chartParameterizationQuality; + fclose(file); } - - // Transfer parameterization from unified mesh to chart mesh. - chart->transferParameterization(); - +#endif + } + // Parameterize the new charts. + taskGroup = taskScheduler->createTaskGroup(m_chartArray.size() - chartCount); + taskArgs.resize(m_chartArray.size() - chartCount); + for (uint32_t i = chartCount; i < m_chartArray.size(); i++) { + ParameterizeChartTaskArgs &args = taskArgs[i - chartCount]; + args.chart = m_chartArray[i]; + args.func = func; + Task task; + task.userData = &args; + task.func = runParameterizeChartTask; + taskScheduler->run(taskGroup, task); + } + taskScheduler->wait(&taskGroup); + // Remove and delete the invalid charts. + for (uint32_t i = 0; i < invalidCharts.size(); i++) { + Chart *chart = invalidCharts[i]; + removeChart(chart); + chart->~Chart(); + XA_FREE(chart); + m_paramDeletedChartsCount++; } - xaPrint(" Parameterized %d/%d charts.\n", diskCount, chartCount); - xaPrint(" RMS stretch metric: %f\n", globalParameterizationQuality.rmsStretchMetric()); - xaPrint(" MAX stretch metric: %f\n", globalParameterizationQuality.maxStretchMetric()); - xaPrint(" RMS conformal metric: %f\n", globalParameterizationQuality.rmsConformalMetric()); - xaPrint(" RMS authalic metric: %f\n", globalParameterizationQuality.maxAuthalicMetric()); +#endif } - uint32_t faceChartAt(uint32_t i) const - { - return m_faceChart[i]; - } - uint32_t faceIndexWithinChartAt(uint32_t i) const +private: + void runAtlasBuilder(AtlasBuilder &builder, const ChartOptions &options) { - return m_faceIndex[i]; + if (builder.facesLeft() == 0) + return; + // This seems a reasonable estimate. + XA_PROFILE_START(atlasBuilderCreateInitialCharts) + // Create initial charts greedely. + builder.placeSeeds(options.maxThreshold * 0.5f); + if (options.maxIterations == 0) { + XA_DEBUG_ASSERT(builder.facesLeft() == 0); + XA_PROFILE_END(atlasBuilderCreateInitialCharts) + return; + } + builder.updateProxies(); + builder.relocateSeeds(); + builder.resetCharts(); + XA_PROFILE_END(atlasBuilderCreateInitialCharts) + // Restart process growing charts in parallel. + uint32_t iteration = 0; + while (true) { + if (!builder.growCharts(options.maxThreshold, options.growFaceCount)) { + // If charts cannot grow more: fill holes, merge charts, relocate seeds and start new iteration. + builder.fillHoles(options.maxThreshold * 0.5f); + builder.updateProxies(); +#if XA_MERGE_CHARTS + builder.mergeCharts(); +#endif + if (++iteration == options.maxIterations) + break; + if (!builder.relocateSeeds()) + break; + builder.resetCharts(); + } + } + // Make sure no holes are left! + XA_DEBUG_ASSERT(builder.facesLeft() == 0); } - uint32_t vertexCountBeforeChartAt(uint32_t i) const + void removeChart(const Chart *chart) { - return m_chartVertexCountPrefixSum[i]; + for (uint32_t i = 0; i < m_chartArray.size(); i++) { + if (m_chartArray[i] == chart) { + m_chartArray.removeAt(i); + return; + } + } } -private: + uint32_t m_sourceId, m_id; + bool m_isVertexMap; + Mesh *m_mesh; + Array<uint32_t> m_faceToSourceFaceMap; // List of faces of the source mesh that belong to this chart group. + Array<uint32_t> m_vertexToSourceVertexMap; // Map vertices of the mesh to vertices of the source mesh. + Array<Chart *> m_chartArray; + ChartOptions m_chartOptions; + uint32_t m_paramAddedChartsCount; // Number of new charts added by recomputing charts with invalid parameterizations. + uint32_t m_paramDeletedChartsCount; // Number of charts with invalid parameterizations that were deleted, after charts were recomputed. +}; - const halfedge::Mesh *m_mesh; +struct CreateChartGroupTaskArgs +{ + uint32_t faceGroup; + uint32_t groupId; + const Mesh *mesh; + ChartGroup **chartGroup; +}; - std::vector<Chart *> m_chartArray; +static void runCreateChartGroupTask(void *userData) +{ + XA_PROFILE_START(addMeshCreateChartGroupsThread) + auto args = (CreateChartGroupTaskArgs *)userData; + *(args->chartGroup) = XA_NEW(MemTag::Default, ChartGroup, args->groupId, args->mesh, args->faceGroup); + XA_PROFILE_END(addMeshCreateChartGroupsThread) +} - std::vector<uint32_t> m_chartVertexCountPrefixSum; - uint32_t m_totalVertexCount; +struct ComputeChartsTaskArgs +{ + TaskScheduler *taskScheduler; + ChartGroup *chartGroup; + const ChartOptions *options; + Progress *progress; +}; - std::vector<uint32_t> m_faceChart; // the chart of every face of the input mesh. - std::vector<uint32_t> m_faceIndex; // the index within the chart for every face of the input mesh. +static void runComputeChartsJob(void *userData) +{ + auto args = (ComputeChartsTaskArgs *)userData; + if (args->progress->cancel) + return; + XA_PROFILE_START(computeChartsThread) + args->chartGroup->computeCharts(args->taskScheduler, *args->options); + XA_PROFILE_END(computeChartsThread) + args->progress->value++; + args->progress->update(); +} + +struct ParameterizeChartsTaskArgs +{ + TaskScheduler *taskScheduler; + ChartGroup *chartGroup; + ParameterizeFunc func; + Progress *progress; }; -/// An atlas is a set of charts. +static void runParameterizeChartsJob(void *userData) +{ + auto args = (ParameterizeChartsTaskArgs *)userData; + if (args->progress->cancel) + return; + XA_PROFILE_START(parameterizeChartsThread) + args->chartGroup->parameterizeCharts(args->taskScheduler, args->func); + XA_PROFILE_END(parameterizeChartsThread) + args->progress->value++; + args->progress->update(); +} + +/// An atlas is a set of chart groups. class Atlas { public: + Atlas() : m_chartsComputed(false), m_chartsParameterized(false) {} + ~Atlas() { - for (size_t i = 0; i < m_meshChartsArray.size(); i++) - delete m_meshChartsArray[i]; + for (uint32_t i = 0; i < m_chartGroups.size(); i++) { + m_chartGroups[i]->~ChartGroup(); + XA_FREE(m_chartGroups[i]); + } } - uint32_t meshCount() const - { - return m_meshChartsArray.size(); - } + bool chartsComputed() const { return m_chartsComputed; } + bool chartsParameterized() const { return m_chartsParameterized; } - const MeshCharts *meshAt(uint32_t i) const + uint32_t chartGroupCount(uint32_t mesh) const { - return m_meshChartsArray[i]; + uint32_t count = 0; + for (uint32_t i = 0; i < m_chartGroups.size(); i++) { + if (m_chartGroupSourceMeshes[i] == mesh) + count++; + } + return count; } - MeshCharts *meshAt(uint32_t i) + const ChartGroup *chartGroupAt(uint32_t mesh, uint32_t group) const { - return m_meshChartsArray[i]; + for (uint32_t c = 0; c < m_chartGroups.size(); c++) { + if (m_chartGroupSourceMeshes[c] != mesh) + continue; + if (group == 0) + return m_chartGroups[c]; + group--; + } + return nullptr; } uint32_t chartCount() const { uint32_t count = 0; - for (uint32_t c = 0; c < m_meshChartsArray.size(); c++) { - count += m_meshChartsArray[c]->chartCount(); - } + for (uint32_t i = 0; i < m_chartGroups.size(); i++) + count += m_chartGroups[i]->chartCount(); return count; } - const Chart *chartAt(uint32_t i) const + Chart *chartAt(uint32_t i) { - for (uint32_t c = 0; c < m_meshChartsArray.size(); c++) { - uint32_t count = m_meshChartsArray[c]->chartCount(); + for (uint32_t c = 0; c < m_chartGroups.size(); c++) { + uint32_t count = m_chartGroups[c]->chartCount(); if (i < count) { - return m_meshChartsArray[c]->chartAt(i); + return m_chartGroups[c]->chartAt(i); } i -= count; } - return NULL; + return nullptr; } - Chart *chartAt(uint32_t i) + // This function is thread safe. + void addMesh(TaskScheduler *taskScheduler, const Mesh *mesh) { - for (uint32_t c = 0; c < m_meshChartsArray.size(); c++) { - uint32_t count = m_meshChartsArray[c]->chartCount(); - if (i < count) { - return m_meshChartsArray[c]->chartAt(i); + // Get list of face groups. + const uint32_t faceCount = mesh->faceCount(); + Array<uint32_t> faceGroups; + for (uint32_t f = 0; f < faceCount; f++) { + const uint32_t group = mesh->faceGroupAt(f); + bool exists = false; + for (uint32_t g = 0; g < faceGroups.size(); g++) { + if (faceGroups[g] == group) { + exists = true; + break; + } } - i -= count; + if (!exists) + faceGroups.push_back(group); + } + // Create one chart group per face group. + // Chart group creation is slow since it copies a chunk of the source mesh, so use tasks. + Array<ChartGroup *> chartGroups; + chartGroups.resize(faceGroups.size()); + Array<CreateChartGroupTaskArgs> taskArgs; + taskArgs.resize(chartGroups.size()); + for (uint32_t g = 0; g < chartGroups.size(); g++) { + CreateChartGroupTaskArgs &args = taskArgs[g]; + args.chartGroup = &chartGroups[g]; + args.faceGroup = faceGroups[g]; + args.groupId = g; + args.mesh = mesh; + } + TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartGroups.size()); + for (uint32_t g = 0; g < chartGroups.size(); g++) { + Task task; + task.userData = &taskArgs[g]; + task.func = runCreateChartGroupTask; + taskScheduler->run(taskGroup, task); + } + taskScheduler->wait(&taskGroup); + // Thread-safe append. + m_addMeshMutex.lock(); + for (uint32_t g = 0; g < chartGroups.size(); g++) { + m_chartGroups.push_back(chartGroups[g]); + m_chartGroupSourceMeshes.push_back(mesh->id()); + } + m_addMeshMutex.unlock(); + } + + bool computeCharts(TaskScheduler *taskScheduler, const ChartOptions &options, ProgressFunc progressFunc, void *progressUserData) + { + m_chartsComputed = false; + m_chartsParameterized = false; + // Ignore vertex maps. + uint32_t chartGroupCount = 0; + for (uint32_t i = 0; i < m_chartGroups.size(); i++) { + if (!m_chartGroups[i]->isVertexMap()) + chartGroupCount++; + } + Progress progress(ProgressCategory::ComputeCharts, progressFunc, progressUserData, chartGroupCount); + Array<ComputeChartsTaskArgs> taskArgs; + taskArgs.reserve(chartGroupCount); + for (uint32_t i = 0; i < m_chartGroups.size(); i++) { + if (!m_chartGroups[i]->isVertexMap()) { + ComputeChartsTaskArgs args; + args.taskScheduler = taskScheduler; + args.chartGroup = m_chartGroups[i]; + args.options = &options; + args.progress = &progress; + taskArgs.push_back(args); + } + } + // Sort chart groups by mesh indexCount. + m_chartGroupsRadix = RadixSort(); + Array<float> chartGroupSortData; + chartGroupSortData.resize(chartGroupCount); + for (uint32_t i = 0; i < chartGroupCount; i++) + chartGroupSortData[i] = (float)taskArgs[i].chartGroup->mesh()->indexCount(); + m_chartGroupsRadix.sort(chartGroupSortData); + // Larger chart group meshes are added first to reduce the chance of thread starvation. + TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartGroupCount); + for (uint32_t i = 0; i < chartGroupCount; i++) { + Task task; + task.userData = &taskArgs[m_chartGroupsRadix.ranks()[chartGroupCount - i - 1]]; + task.func = runComputeChartsJob; + taskScheduler->run(taskGroup, task); + } + taskScheduler->wait(&taskGroup); + if (progress.cancel) + return false; + m_chartsComputed = true; + return true; + } + + bool parameterizeCharts(TaskScheduler *taskScheduler, ParameterizeFunc func, ProgressFunc progressFunc, void *progressUserData) + { + m_chartsParameterized = false; + // Ignore vertex maps. + uint32_t chartGroupCount = 0; + for (uint32_t i = 0; i < m_chartGroups.size(); i++) { + if (!m_chartGroups[i]->isVertexMap()) + chartGroupCount++; + } + Progress progress(ProgressCategory::ParameterizeCharts, progressFunc, progressUserData, chartGroupCount); + Array<ParameterizeChartsTaskArgs> taskArgs; + taskArgs.reserve(chartGroupCount); + for (uint32_t i = 0; i < m_chartGroups.size(); i++) { + if (!m_chartGroups[i]->isVertexMap()) { + ParameterizeChartsTaskArgs args; + args.taskScheduler = taskScheduler; + args.chartGroup = m_chartGroups[i]; + args.func = func; + args.progress = &progress; + taskArgs.push_back(args); + } + } + // Larger chart group meshes are added first to reduce the chance of thread starvation. + TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(chartGroupCount); + for (uint32_t i = 0; i < chartGroupCount; i++) { + Task task; + task.userData = &taskArgs[m_chartGroupsRadix.ranks()[chartGroupCount - i - 1]]; + task.func = runParameterizeChartsJob; + taskScheduler->run(taskGroup, task); + } + taskScheduler->wait(&taskGroup); + if (progress.cancel) + return false; + // Save original texcoords so PackCharts can be called multiple times (packing overwrites the texcoords). + const uint32_t nCharts = chartCount(); + m_originalChartTexcoords.resize(nCharts); + for (uint32_t i = 0; i < nCharts; i++) { + const Mesh *mesh = chartAt(i)->mesh(); + m_originalChartTexcoords[i].resize(mesh->vertexCount()); + for (uint32_t j = 0; j < mesh->vertexCount(); j++) + m_originalChartTexcoords[i][j] = mesh->texcoord(j); } - return NULL; + m_chartsParameterized = true; + return true; } - // Add mesh charts and takes ownership. - // Extract the charts and add to this atlas. - void addMeshCharts(MeshCharts *meshCharts) + void restoreOriginalChartTexcoords() { - m_meshChartsArray.push_back(meshCharts); + const uint32_t nCharts = chartCount(); + for (uint32_t i = 0; i < nCharts; i++) { + Mesh *mesh = chartAt(i)->mesh(); + for (uint32_t j = 0; j < mesh->vertexCount(); j++) + mesh->texcoord(j) = m_originalChartTexcoords[i][j]; + } } - void extractCharts(const halfedge::Mesh *mesh) +private: + std::mutex m_addMeshMutex; + bool m_chartsComputed; + bool m_chartsParameterized; + Array<ChartGroup *> m_chartGroups; + RadixSort m_chartGroupsRadix; // By mesh indexCount. + Array<uint32_t> m_chartGroupSourceMeshes; + Array<Array<Vector2> > m_originalChartTexcoords; +}; + +} // namespace param + +namespace pack { + +#if XA_DEBUG_EXPORT_ATLAS_IMAGES +const uint8_t TGA_TYPE_RGB = 2; +const uint8_t TGA_ORIGIN_UPPER = 0x20; + +#pragma pack(push, 1) +struct TgaHeader +{ + uint8_t id_length; + uint8_t colormap_type; + uint8_t image_type; + uint16_t colormap_index; + uint16_t colormap_length; + uint8_t colormap_size; + uint16_t x_origin; + uint16_t y_origin; + uint16_t width; + uint16_t height; + uint8_t pixel_size; + uint8_t flags; + enum { Size = 18 }; +}; +#pragma pack(pop) + +static void WriteTga(const char *filename, const uint8_t *data, uint32_t width, uint32_t height) +{ + XA_DEBUG_ASSERT(sizeof(TgaHeader) == TgaHeader::Size); + FILE *f; + XA_FOPEN(f, filename, "wb"); + if (!f) + return; + TgaHeader tga; + tga.id_length = 0; + tga.colormap_type = 0; + tga.image_type = TGA_TYPE_RGB; + tga.colormap_index = 0; + tga.colormap_length = 0; + tga.colormap_size = 0; + tga.x_origin = 0; + tga.y_origin = 0; + tga.width = (uint16_t)width; + tga.height = (uint16_t)height; + tga.pixel_size = 24; + tga.flags = TGA_ORIGIN_UPPER; + fwrite(&tga, sizeof(TgaHeader), 1, f); + fwrite(data, sizeof(uint8_t), width * height * 3, f); + fclose(f); +} +#endif + +class AtlasImage +{ +public: + AtlasImage(uint32_t width, uint32_t height) : m_width(width), m_height(height) { - MeshCharts *meshCharts = new MeshCharts(mesh); - meshCharts->extractCharts(); - addMeshCharts(meshCharts); + m_data.resize(m_width * m_height); + memset(m_data.data(), 0, sizeof(uint32_t) * m_data.size()); } - void computeCharts(const halfedge::Mesh *mesh, const CharterOptions &options, const std::vector<uint32_t> &unchartedMaterialArray) + void resize(uint32_t width, uint32_t height) { - MeshCharts *meshCharts = new MeshCharts(mesh); - meshCharts->computeCharts(options, unchartedMaterialArray); - addMeshCharts(meshCharts); + Array<uint32_t> data; + data.resize(width * height); + memset(data.data(), 0, sizeof(uint32_t) * data.size()); + for (uint32_t y = 0; y < min(m_height, height); y++) + memcpy(&data[y * width], &m_data[y * m_width], min(m_width, width) * sizeof(uint32_t)); + m_width = width; + m_height = height; + swap(m_data, data); } - void parameterizeCharts() + void addChart(uint32_t chartIndex, const BitImage *image, bool imageHasPadding, int atlas_w, int atlas_h, int offset_x, int offset_y) { - for (uint32_t i = 0; i < m_meshChartsArray.size(); i++) { - m_meshChartsArray[i]->parameterizeCharts(); + const int w = image->width(); + const int h = image->height(); + for (int y = 0; y < h; y++) { + const int yy = y + offset_y; + if (yy < 0) + continue; + for (int x = 0; x < w; x++) { + const int xx = x + offset_x; + if (xx >= 0 && xx < atlas_w && yy < atlas_h && image->bitAt(x, y)) { + const uint32_t dataOffset = xx + yy * m_width; + if (m_data[dataOffset] != 0) + continue; + uint32_t value = chartIndex | kImageHasChartIndexBit; + if (imageHasPadding) + value |= kImageIsPaddingBit; + m_data[dataOffset] = value; + } + } } } + void copyTo(uint32_t *dest, uint32_t destWidth, uint32_t destHeight) const + { + for (uint32_t y = 0; y < destHeight; y++) + memcpy(&dest[y * destWidth], &m_data[y * m_width], destWidth * sizeof(uint32_t)); + } + +#if XA_DEBUG_EXPORT_ATLAS_IMAGES + void writeTga(const char *filename, uint32_t width, uint32_t height) const + { + Array<uint8_t> image; + image.resize(width * height * 3); + for (uint32_t y = 0; y < height; y++) { + if (y >= m_height) + continue; + for (uint32_t x = 0; x < width; x++) { + if (x >= m_width) + continue; + const uint32_t data = m_data[x + y * m_width]; + if (!(data & kImageHasChartIndexBit)) + continue; + const uint32_t chartIndex = data & kImageChartIndexMask; + uint8_t *color = &image[(x + y * width) * 3]; + if (data & kImageIsPaddingBit) { + color[0] = 255; + color[1] = 0; + color[2] = 255; + } else { + const int mix = 192; + srand((unsigned int)chartIndex); + color[0] = uint8_t((rand() % 255 + mix) * 0.5f); + color[1] = uint8_t((rand() % 255 + mix) * 0.5f); + color[2] = uint8_t((rand() % 255 + mix) * 0.5f); + } + } + } + WriteTga(filename, image.data(), width, height); + } +#endif + private: - std::vector<MeshCharts *> m_meshChartsArray; + uint32_t m_width, m_height; + Array<uint32_t> m_data; +}; + +struct Chart +{ + int32_t atlasIndex; + uint32_t material; + uint32_t indexCount; + const uint32_t *indices; + float parametricArea; + float surfaceArea; + Vector2 *vertices; + uint32_t vertexCount; + Array<uint32_t> uniqueVertices; + bool allowRotate; + // bounding box + Vector2 majorAxis, minorAxis, minCorner, maxCorner; + + Vector2 &uniqueVertexAt(uint32_t v) { return uniqueVertices.isEmpty() ? vertices[v] : vertices[uniqueVertices[v]]; } + uint32_t uniqueVertexCount() const { return uniqueVertices.isEmpty() ? vertexCount : uniqueVertices.size(); } +}; + +struct FindChartLocationBruteForceTaskArgs +{ + std::atomic<bool> *finished; // One of the tasks found a location that doesn't expand the atlas. + Vector2i startPosition; + const BitImage *atlasBitImage; + const BitImage *chartBitImage; + const BitImage *chartBitImageRotated; + int w, h; + bool blockAligned, resizableAtlas, allowRotate; + // out + bool best_insideAtlas; + int best_metric, best_x, best_y, best_w, best_h, best_r; }; -struct AtlasPacker +static void runFindChartLocationBruteForceTask(void *userData) +{ + XA_PROFILE_START(packChartsFindLocationThread) + auto args = (FindChartLocationBruteForceTaskArgs *)userData; + args->best_metric = INT_MAX; + if (args->finished->load()) + return; + // Try two different orientations. + for (int r = 0; r < 2; r++) { + int cw = args->chartBitImage->width(); + int ch = args->chartBitImage->height(); + if (r == 1) { + if (args->allowRotate) + swap(cw, ch); + else + break; + } + const int y = args->startPosition.y; + const int stepSize = args->blockAligned ? 4 : 1; + for (int x = args->startPosition.x; x <= args->w + stepSize; x += stepSize) { // + 1 not really necessary here. + if (!args->resizableAtlas && (x > (int)args->atlasBitImage->width() - cw || y > (int)args->atlasBitImage->height() - ch)) + continue; + if (args->finished->load()) + break; + // Early out if metric not better. + const int area = max(args->w, x + cw) * max(args->h, y + ch); + const int extents = max(max(args->w, x + cw), max(args->h, y + ch)); + const int metric = extents * extents + area; + if (metric > args->best_metric) + continue; + // If metric is the same, pick the one closest to the origin. + if (metric == args->best_metric && max(x, y) >= max(args->best_x, args->best_y)) + continue; + if (!args->atlasBitImage->canBlit(r == 1 ? *(args->chartBitImageRotated) : *(args->chartBitImage), x, y)) + continue; + args->best_metric = metric; + args->best_insideAtlas = area == args->w * args->h; + args->best_x = x; + args->best_y = y; + args->best_w = cw; + args->best_h = ch; + args->best_r = r; + if (args->best_insideAtlas) { + args->finished->store(true); + break; + } + } + } + XA_PROFILE_END(packChartsFindLocationThread) +} + +struct Atlas { - AtlasPacker(Atlas *atlas) : m_atlas(atlas), m_width(0), m_height(0) + ~Atlas() { - // Save the original uvs. - m_originalChartUvs.resize(m_atlas->chartCount()); - for (uint32_t i = 0; i < m_atlas->chartCount(); i++) { - const halfedge::Mesh *mesh = atlas->chartAt(i)->chartMesh(); - m_originalChartUvs[i].resize(mesh->vertexCount()); - for (uint32_t j = 0; j < mesh->vertexCount(); j++) - m_originalChartUvs[i][j] = mesh->vertexAt(j)->tex; + for (uint32_t i = 0; i < m_bitImages.size(); i++) { + m_bitImages[i]->~BitImage(); + XA_FREE(m_bitImages[i]); + } + for (uint32_t i = 0; i < m_charts.size(); i++) { + m_charts[i]->~Chart(); + XA_FREE(m_charts[i]); } } uint32_t getWidth() const { return m_width; } uint32_t getHeight() const { return m_height; } + uint32_t getNumAtlases() const { return m_bitImages.size(); } + float getTexelsPerUnit() const { return m_texelsPerUnit; } + const Chart *getChart(uint32_t index) const { return m_charts[index]; } + uint32_t getChartCount() const { return m_charts.size(); } + const Array<AtlasImage *> &getImages() const { return m_atlasImages; } + float getUtilization(uint32_t atlas) const { return m_utilization[atlas]; } + + void addChart(param::Chart *paramChart) + { + Mesh *mesh = paramChart->mesh(); + Chart *chart = XA_NEW(MemTag::Default, Chart); + chart->atlasIndex = -1; + chart->material = 0; + chart->indexCount = mesh->indexCount(); + chart->indices = mesh->indices(); + chart->parametricArea = paramChart->computeParametricArea(); + if (chart->parametricArea < kAreaEpsilon) { + // When the parametric area is too small we use a rough approximation to prevent divisions by very small numbers. + const Vector2 bounds = paramChart->computeParametricBounds(); + chart->parametricArea = bounds.x * bounds.y; + } + chart->surfaceArea = paramChart->computeSurfaceArea(); + chart->vertices = mesh->texcoords(); + chart->vertexCount = mesh->vertexCount(); + chart->allowRotate = true; + // Compute list of boundary vertices. + Array<Vector2> boundary; + boundary.reserve(16); + for (uint32_t v = 0; v < chart->vertexCount; v++) { + if (mesh->isBoundaryVertex(v)) + boundary.push_back(mesh->texcoord(v)); + } + XA_DEBUG_ASSERT(boundary.size() > 0); + // Compute bounding box of chart. + m_boundingBox.compute(boundary.data(), boundary.size(), mesh->texcoords(), mesh->vertexCount()); + chart->majorAxis = m_boundingBox.majorAxis(); + chart->minorAxis = m_boundingBox.minorAxis(); + chart->minCorner = m_boundingBox.minCorner(); + chart->maxCorner = m_boundingBox.maxCorner(); + m_charts.push_back(chart); + } + + void addUvMeshCharts(UvMeshInstance *mesh) + { + BitArray vertexUsed(mesh->texcoords.size()); + Array<Vector2> boundary; + boundary.reserve(16); + for (uint32_t c = 0; c < mesh->mesh->charts.size(); c++) { + UvMeshChart *uvChart = mesh->mesh->charts[c]; + Chart *chart = XA_NEW(MemTag::Default, Chart); + chart->atlasIndex = -1; + chart->material = uvChart->material; + chart->indexCount = uvChart->indices.size(); + chart->indices = uvChart->indices.data(); + chart->vertices = mesh->texcoords.data(); + chart->vertexCount = mesh->texcoords.size(); + chart->allowRotate = mesh->rotateCharts; + // Find unique vertices. + vertexUsed.clearAll(); + for (uint32_t i = 0; i < chart->indexCount; i++) { + const uint32_t vertex = chart->indices[i]; + if (!vertexUsed.bitAt(vertex)) { + vertexUsed.setBitAt(vertex); + chart->uniqueVertices.push_back(vertex); + } + } + // Compute parametric and surface areas. + chart->parametricArea = 0.0f; + for (uint32_t f = 0; f < chart->indexCount / 3; f++) { + const Vector2 &v1 = chart->vertices[chart->indices[f * 3 + 0]]; + const Vector2 &v2 = chart->vertices[chart->indices[f * 3 + 1]]; + const Vector2 &v3 = chart->vertices[chart->indices[f * 3 + 2]]; + chart->parametricArea += fabsf(triangleArea(v1, v2, v3)); + } + chart->parametricArea *= 0.5f; + chart->surfaceArea = chart->parametricArea; // Identical for UV meshes. + if (chart->parametricArea < kAreaEpsilon) { + // When the parametric area is too small we use a rough approximation to prevent divisions by very small numbers. + Vector2 minCorner(FLT_MAX, FLT_MAX); + Vector2 maxCorner(-FLT_MAX, -FLT_MAX); + for (uint32_t v = 0; v < chart->uniqueVertexCount(); v++) { + minCorner = min(minCorner, chart->uniqueVertexAt(v)); + maxCorner = max(maxCorner, chart->uniqueVertexAt(v)); + } + const Vector2 bounds = (maxCorner - minCorner) * 0.5f; + chart->parametricArea = bounds.x * bounds.y; + } + // Compute list of boundary vertices. + // Using all unique vertices for simplicity, can compute real boundaries if this is too slow. + boundary.clear(); + for (uint32_t v = 0; v < chart->uniqueVertexCount(); v++) + boundary.push_back(chart->uniqueVertexAt(v)); + XA_DEBUG_ASSERT(boundary.size() > 0); + // Compute bounding box of chart. + m_boundingBox.compute(boundary.data(), boundary.size(), boundary.data(), boundary.size()); + chart->majorAxis = m_boundingBox.majorAxis(); + chart->minorAxis = m_boundingBox.minorAxis(); + chart->minCorner = m_boundingBox.minCorner(); + chart->maxCorner = m_boundingBox.maxCorner(); + m_charts.push_back(chart); + } + } // Pack charts in the smallest possible rectangle. - void packCharts(const PackerOptions &options) - { - const uint32_t chartCount = m_atlas->chartCount(); - if (chartCount == 0) return; - float texelsPerUnit = 1; - if (options.method == PackMethod::TexelArea) - texelsPerUnit = options.texelArea; - for (int iteration = 0;; iteration++) { - m_rand = MTRand(); - std::vector<float> chartOrderArray(chartCount); - std::vector<Vector2> chartExtents(chartCount); + bool packCharts(TaskScheduler *taskScheduler, const PackOptions &options, ProgressFunc progressFunc, void *progressUserData) + { + if (progressFunc) { + if (!progressFunc(ProgressCategory::PackCharts, 0, progressUserData)) + return false; + } + const uint32_t chartCount = m_charts.size(); + XA_PRINT("Packing %u charts\n", chartCount); + if (chartCount == 0) { + if (progressFunc) { + if (!progressFunc(ProgressCategory::PackCharts, 100, progressUserData)) + return false; + } + return true; + } + uint32_t resolution = options.resolution; + m_texelsPerUnit = options.texelsPerUnit; + if (resolution <= 0 || m_texelsPerUnit <= 0) { + if (resolution <= 0 && m_texelsPerUnit <= 0) + resolution = 1024; float meshArea = 0; - for (uint32_t c = 0; c < chartCount; c++) { - Chart *chart = m_atlas->chartAt(c); - if (!chart->isVertexMapped() && !chart->isDisk()) { - chartOrderArray[c] = 0; - // Skip non-disks. - continue; - } - Vector2 extents(0.0f); - if (chart->isVertexMapped()) { - // Arrange vertices in a rectangle. - extents.x = float(chart->vertexMapWidth); - extents.y = float(chart->vertexMapHeight); + for (uint32_t c = 0; c < chartCount; c++) + meshArea += m_charts[c]->surfaceArea; + if (resolution <= 0) { + // Estimate resolution based on the mesh surface area and given texel scale. + const float texelCount = max(1.0f, meshArea * square(m_texelsPerUnit) / 0.75f); // Assume 75% utilization. + resolution = max(1u, nextPowerOfTwo(uint32_t(sqrtf(texelCount)))); + } + if (m_texelsPerUnit <= 0) { + // Estimate a suitable texelsPerUnit to fit the given resolution. + const float texelCount = max(1.0f, meshArea / 0.75f); // Assume 75% utilization. + m_texelsPerUnit = sqrtf((resolution * resolution) / texelCount); + XA_PRINT(" Estimating texelsPerUnit as %g\n", m_texelsPerUnit); + } + } + Array<float> chartOrderArray; + chartOrderArray.resize(chartCount); + Array<Vector2> chartExtents; + chartExtents.resize(chartCount); + float minChartPerimeter = FLT_MAX, maxChartPerimeter = 0.0f; + for (uint32_t c = 0; c < chartCount; c++) { + Chart *chart = m_charts[c]; + //chartOrderArray[c] = chart.surfaceArea; + // Compute chart scale + float scale = (chart->surfaceArea / chart->parametricArea) * m_texelsPerUnit; + if (chart->parametricArea == 0) { // < kAreaEpsilon) + scale = 0; + } + XA_ASSERT(isFinite(scale)); + // Sort charts by perimeter. @@ This is sometimes producing somewhat unexpected results. Is this right? + //chartOrderArray[c] = ((chart->maxCorner.x - chart->minCorner.x) + (chart->maxCorner.y - chart->minCorner.y)) * scale; + // Translate, rotate and scale vertices. Compute extents. + Vector2 minCorner(FLT_MAX, FLT_MAX); + if (!chart->allowRotate) { + for (uint32_t i = 0; i < chart->uniqueVertexCount(); i++) + minCorner = min(minCorner, chart->uniqueVertexAt(i)); + } + Vector2 extents(0.0f); + for (uint32_t i = 0; i < chart->uniqueVertexCount(); i++) { + Vector2 &texcoord = chart->uniqueVertexAt(i); + if (chart->allowRotate) { + const float x = dot(texcoord, chart->majorAxis); + const float y = dot(texcoord, chart->minorAxis); + texcoord.x = x; + texcoord.y = y; + texcoord -= chart->minCorner; } else { - // Compute surface area to sort charts. - float chartArea = chart->computeSurfaceArea(); - meshArea += chartArea; - //chartOrderArray[c] = chartArea; - // Compute chart scale - float parametricArea = fabsf(chart->computeParametricArea()); // @@ There doesn't seem to be anything preventing parametric area to be negative. - if (parametricArea < NV_EPSILON) { - // When the parametric area is too small we use a rough approximation to prevent divisions by very small numbers. - Vector2 bounds = chart->computeParametricBounds(); - parametricArea = bounds.x * bounds.y; - } - float scale = (chartArea / parametricArea) * texelsPerUnit; - if (parametricArea == 0) { // < NV_EPSILON) - scale = 0; - } - xaAssert(std::isfinite(scale)); - // Compute bounding box of chart. - Vector2 majorAxis, minorAxis, origin, end; - computeBoundingBox(chart, &majorAxis, &minorAxis, &origin, &end); - xaAssert(isFinite(majorAxis) && isFinite(minorAxis) && isFinite(origin)); - // Sort charts by perimeter. @@ This is sometimes producing somewhat unexpected results. Is this right? - //chartOrderArray[c] = ((end.x - origin.x) + (end.y - origin.y)) * scale; - // Translate, rotate and scale vertices. Compute extents. - halfedge::Mesh *mesh = chart->chartMesh(); - const uint32_t vertexCount = mesh->vertexCount(); - for (uint32_t i = 0; i < vertexCount; i++) { - halfedge::Vertex *vertex = mesh->vertexAt(i); - //Vector2 t = vertex->tex - origin; - Vector2 tmp; - tmp.x = dot(vertex->tex, majorAxis); - tmp.y = dot(vertex->tex, minorAxis); - tmp -= origin; - tmp *= scale; - if (tmp.x < 0 || tmp.y < 0) { - xaPrint("tmp: %f %f\n", tmp.x, tmp.y); - xaPrint("scale: %f\n", scale); - xaPrint("origin: %f %f\n", origin.x, origin.y); - xaPrint("majorAxis: %f %f\n", majorAxis.x, majorAxis.y); - xaPrint("minorAxis: %f %f\n", minorAxis.x, minorAxis.y); - xaDebugAssert(false); - } - //xaAssert(tmp.x >= 0 && tmp.y >= 0); - vertex->tex = tmp; - xaAssert(std::isfinite(vertex->tex.x) && std::isfinite(vertex->tex.y)); - extents = max(extents, tmp); - } - xaDebugAssert(extents.x >= 0 && extents.y >= 0); - // Limit chart size. - if (extents.x > 1024 || extents.y > 1024) { - float limit = std::max(extents.x, extents.y); - scale = 1024 / (limit + 1); - for (uint32_t i = 0; i < vertexCount; i++) { - halfedge::Vertex *vertex = mesh->vertexAt(i); - vertex->tex *= scale; - } - extents *= scale; - xaDebugAssert(extents.x <= 1024 && extents.y <= 1024); - } - // Scale the charts to use the entire texel area available. So, if the width is 0.1 we could scale it to 1 without increasing the lightmap usage and making a better - // use of it. In many cases this also improves the look of the seams, since vertices on the chart boundaries have more chances of being aligned with the texel centers. - float scale_x = 1.0f; - float scale_y = 1.0f; - float divide_x = 1.0f; - float divide_y = 1.0f; - if (extents.x > 0) { - int cw = ftoi_ceil(extents.x); - if (options.blockAlign && chart->blockAligned) { - // Align all chart extents to 4x4 blocks, but taking padding into account. - if (options.conservative) { - cw = align(cw + 2, 4) - 2; - } else { - cw = align(cw + 1, 4) - 1; - } - } - scale_x = (float(cw) - NV_EPSILON); - divide_x = extents.x; - extents.x = float(cw); - } - if (extents.y > 0) { - int ch = ftoi_ceil(extents.y); - if (options.blockAlign && chart->blockAligned) { - // Align all chart extents to 4x4 blocks, but taking padding into account. - if (options.conservative) { - ch = align(ch + 2, 4) - 2; - } else { - ch = align(ch + 1, 4) - 1; - } - } - scale_y = (float(ch) - NV_EPSILON); - divide_y = extents.y; - extents.y = float(ch); - } - for (uint32_t v = 0; v < vertexCount; v++) { - halfedge::Vertex *vertex = mesh->vertexAt(v); - vertex->tex.x /= divide_x; - vertex->tex.y /= divide_y; - vertex->tex.x *= scale_x; - vertex->tex.y *= scale_y; - xaAssert(std::isfinite(vertex->tex.x) && std::isfinite(vertex->tex.y)); - } + texcoord -= minCorner; + } + texcoord *= scale; + XA_DEBUG_ASSERT(texcoord.x >= 0 && texcoord.y >= 0); + XA_DEBUG_ASSERT(isFinite(texcoord.x) && isFinite(texcoord.y)); + extents = max(extents, texcoord); + } + XA_DEBUG_ASSERT(extents.x >= 0 && extents.y >= 0); + // Limit chart size. + const float maxChartSize = (float)options.maxChartSize; + if (extents.x > maxChartSize || extents.y > maxChartSize) { + const float limit = max(extents.x, extents.y); + scale = maxChartSize / (limit + 1.0f); + for (uint32_t i = 0; i < chart->uniqueVertexCount(); i++) + chart->uniqueVertexAt(i) *= scale; + extents *= scale; + XA_DEBUG_ASSERT(extents.x <= maxChartSize && extents.y <= maxChartSize); + } + // Scale the charts to use the entire texel area available. So, if the width is 0.1 we could scale it to 1 without increasing the lightmap usage and making a better + // use of it. In many cases this also improves the look of the seams, since vertices on the chart boundaries have more chances of being aligned with the texel centers. + float scale_x = 1.0f; + float scale_y = 1.0f; + float divide_x = 1.0f; + float divide_y = 1.0f; + if (extents.x > 0) { + int cw = ftoi_ceil(extents.x); + if (options.blockAlign) { + // Align all chart extents to 4x4 blocks, but taking padding into account. + cw = align(cw + 2, 4) - 2; + } + scale_x = (float(cw) - kEpsilon); + divide_x = extents.x; + extents.x = float(cw); + } + if (extents.y > 0) { + int ch = ftoi_ceil(extents.y); + if (options.blockAlign) { + // Align all chart extents to 4x4 blocks, but taking padding into account. + ch = align(ch + 2, 4) - 2; + } + scale_y = (float(ch) - kEpsilon); + divide_y = extents.y; + extents.y = float(ch); + } + for (uint32_t v = 0; v < chart->uniqueVertexCount(); v++) { + Vector2 &texcoord = chart->uniqueVertexAt(v); + texcoord.x /= divide_x; + texcoord.y /= divide_y; + texcoord.x *= scale_x; + texcoord.y *= scale_y; + XA_ASSERT(isFinite(texcoord.x) && isFinite(texcoord.y)); + } + chartExtents[c] = extents; + // Sort charts by perimeter. + chartOrderArray[c] = extents.x + extents.y; + minChartPerimeter = min(minChartPerimeter, chartOrderArray[c]); + maxChartPerimeter = max(maxChartPerimeter, chartOrderArray[c]); + } + // Sort charts by perimeter. + m_radix = RadixSort(); + m_radix.sort(chartOrderArray); + const uint32_t *ranks = m_radix.ranks(); + // Divide chart perimeter range into buckets. + const float chartPerimeterBucketSize = (maxChartPerimeter - minChartPerimeter) / 16.0f; + uint32_t currentChartBucket = 0; + Array<Vector2i> chartStartPositions; // per atlas + chartStartPositions.push_back(Vector2i(0, 0)); + // Pack sorted charts. +#if XA_DEBUG_EXPORT_ATLAS_IMAGES + const bool createImage = true; +#else + const bool createImage = options.createImage; +#endif + BitImage chartBitImage, chartBitImageRotated; + int atlasWidth = 0, atlasHeight = 0; + const bool resizableAtlas = !(options.resolution > 0 && options.texelsPerUnit > 0.0f); + int progress = 0; + for (uint32_t i = 0; i < chartCount; i++) { + uint32_t c = ranks[chartCount - i - 1]; // largest chart first + Chart *chart = m_charts[c]; + // @@ Add special cases for dot and line charts. @@ Lightmap rasterizer also needs to handle these special cases. + // @@ We could also have a special case for chart quads. If the quad surface <= 4 texels, align vertices with texel centers and do not add padding. May be very useful for foliage. + // @@ In general we could reduce the padding of all charts by one texel by using a rasterizer that takes into account the 2-texel footprint of the tent bilinear filter. For example, + // if we have a chart that is less than 1 texel wide currently we add one texel to the left and one texel to the right creating a 3-texel-wide bitImage. However, if we know that the + // chart is only 1 texel wide we could align it so that it only touches the footprint of two texels: + // | | <- Touches texels 0, 1 and 2. + // | | <- Only touches texels 0 and 1. + // \ \ / \ / / + // \ X X / + // \ / \ / \ / + // V V V + // 0 1 2 + XA_PROFILE_START(packChartsRasterize) + // Leave room for padding. + chartBitImage.resize(ftoi_ceil(chartExtents[c].x) + 1 + options.padding * 2, ftoi_ceil(chartExtents[c].y) + 1 + options.padding * 2, true); + if (chart->allowRotate) + chartBitImageRotated.resize(chartBitImage.height(), chartBitImage.width(), true); + // Rasterize chart faces. + const uint32_t faceCount = chart->indexCount / 3; + for (uint32_t f = 0; f < faceCount; f++) { + // Offset vertices by padding. + Vector2 vertices[3]; + for (uint32_t v = 0; v < 3; v++) + vertices[v] = chart->vertices[chart->indices[f * 3 + v]] + Vector2(0.5f) + Vector2(float(options.padding)); + DrawTriangleCallbackArgs args; + args.chartBitImage = &chartBitImage; + args.chartBitImageRotated = chart->allowRotate ? &chartBitImageRotated : nullptr; + raster::drawTriangle(Vector2((float)chartBitImage.width(), (float)chartBitImage.height()), vertices, drawTriangleCallback, &args); + } + // Expand chart by padding pixels. (dilation) + BitImage chartBitImageNoPadding(chartBitImage), chartBitImageNoPaddingRotated(chartBitImageRotated); + if (options.padding > 0) { + XA_PROFILE_START(packChartsDilate) + chartBitImage.dilate(options.padding); + if (chart->allowRotate) + chartBitImageRotated.dilate(options.padding); + XA_PROFILE_END(packChartsDilate) + } + XA_PROFILE_END(packChartsRasterize) + // Update brute force bucketing. + if (options.bruteForce) { + if (chartOrderArray[c] > minChartPerimeter && chartOrderArray[c] <= maxChartPerimeter - (chartPerimeterBucketSize * (currentChartBucket + 1))) { + // Moved to a smaller bucket, reset start location. + for (uint32_t j = 0; j < chartStartPositions.size(); j++) + chartStartPositions[j] = Vector2i(0, 0); + currentChartBucket++; } - chartExtents[c] = extents; - // Sort charts by perimeter. - chartOrderArray[c] = extents.x + extents.y; - } - // @@ We can try to improve compression of small charts by sorting them by proximity like we do with vertex samples. - // @@ How to do that? One idea: compute chart centroid, insert into grid, compute morton index of the cell, sort based on morton index. - // @@ We would sort by morton index, first, then quantize the chart sizes, so that all small charts have the same size, and sort by size preserving the morton order. - //xaPrint("Sorting charts.\n"); - // Sort charts by area. - m_radix = RadixSort(); - m_radix.sort(chartOrderArray); - const uint32_t *ranks = m_radix.ranks(); - // First iteration - guess texelsPerUnit. - if (options.method != PackMethod::TexelArea && iteration == 0) { - // Estimate size of the map based on the mesh surface area and given texel scale. - const float texelCount = std::max(1.0f, meshArea * square(texelsPerUnit) / 0.75f); // Assume 75% utilization. - texelsPerUnit = sqrt((options.resolution * options.resolution) / texelCount); - resetUvs(); - continue; } - // Init bit map. - m_bitmap.clearAll(); - m_bitmap.resize(options.resolution, options.resolution, false); - int w = 0; - int h = 0; - // Add sorted charts to bitmap. - for (uint32_t i = 0; i < chartCount; i++) { - uint32_t c = ranks[chartCount - i - 1]; // largest chart first - Chart *chart = m_atlas->chartAt(c); - if (!chart->isVertexMapped() && !chart->isDisk()) continue; - //float scale_x = 1; - //float scale_y = 1; - BitMap chart_bitmap; - if (chart->isVertexMapped()) { - chart->blockAligned = false; - // Init all bits to 1. - chart_bitmap.resize(ftoi_ceil(chartExtents[c].x), ftoi_ceil(chartExtents[c].y), /*initValue=*/true); - // @@ Another alternative would be to try to map each vertex to a different texel trying to fill all the available unused texels. - } else { - // @@ Add special cases for dot and line charts. @@ Lightmap rasterizer also needs to handle these special cases. - // @@ We could also have a special case for chart quads. If the quad surface <= 4 texels, align vertices with texel centers and do not add padding. May be very useful for foliage. - // @@ In general we could reduce the padding of all charts by one texel by using a rasterizer that takes into account the 2-texel footprint of the tent bilinear filter. For example, - // if we have a chart that is less than 1 texel wide currently we add one texel to the left and one texel to the right creating a 3-texel-wide bitmap. However, if we know that the - // chart is only 1 texel wide we could align it so that it only touches the footprint of two texels: - // | | <- Touches texels 0, 1 and 2. - // | | <- Only touches texels 0 and 1. - // \ \ / \ / / - // \ X X / - // \ / \ / \ / - // V V V - // 0 1 2 - if (options.conservative) { - // Init all bits to 0. - chart_bitmap.resize(ftoi_ceil(chartExtents[c].x) + 1 + options.padding, ftoi_ceil(chartExtents[c].y) + 1 + options.padding, /*initValue=*/false); // + 2 to add padding on both sides. - // Rasterize chart and dilate. - drawChartBitmapDilate(chart, &chart_bitmap, options.padding); - } else { - // Init all bits to 0. - chart_bitmap.resize(ftoi_ceil(chartExtents[c].x) + 1, ftoi_ceil(chartExtents[c].y) + 1, /*initValue=*/false); // Add half a texels on each side. - // Rasterize chart and dilate. - drawChartBitmap(chart, &chart_bitmap, Vector2(1), Vector2(0.5)); - } + // Find a location to place the chart in the atlas. + uint32_t currentAtlas = 0; + int best_x = 0, best_y = 0; + int best_cw = 0, best_ch = 0; + int best_r = 0; + for (;;) + { + bool firstChartInBitImage = false; + if (currentAtlas + 1 > m_bitImages.size()) { + // Chart doesn't fit in the current bitImage, create a new one. + BitImage *bi = XA_NEW(MemTag::Default, BitImage); + bi->resize(resolution, resolution, true); + m_bitImages.push_back(bi); + firstChartInBitImage = true; + if (createImage) + m_atlasImages.push_back(XA_NEW(MemTag::Default, AtlasImage, resolution, resolution)); + // Start positions are per-atlas, so create a new one of those too. + chartStartPositions.push_back(Vector2i(0, 0)); } - int best_x, best_y; - int best_cw, best_ch; // Includes padding now. - int best_r; - findChartLocation(options.quality, &chart_bitmap, chartExtents[c], w, h, &best_x, &best_y, &best_cw, &best_ch, &best_r, chart->blockAligned); - /*if (w < best_x + best_cw || h < best_y + best_ch) - { - xaPrint("Resize extents to (%d, %d).\n", best_x + best_cw, best_y + best_ch); - }*/ - // Update parametric extents. - w = std::max(w, best_x + best_cw); - h = std::max(h, best_y + best_ch); - w = align(w, 4); - h = align(h, 4); - // Resize bitmap if necessary. - if (uint32_t(w) > m_bitmap.width() || uint32_t(h) > m_bitmap.height()) { - //xaPrint("Resize bitmap (%d, %d).\n", nextPowerOfTwo(w), nextPowerOfTwo(h)); - m_bitmap.resize(nextPowerOfTwo(uint32_t(w)), nextPowerOfTwo(uint32_t(h)), false); + XA_PROFILE_START(packChartsFindLocation) + const bool foundLocation = findChartLocation(taskScheduler, chartStartPositions[currentAtlas], options.bruteForce, m_bitImages[currentAtlas], &chartBitImage, &chartBitImageRotated, atlasWidth, atlasHeight, &best_x, &best_y, &best_cw, &best_ch, &best_r, options.blockAlign, resizableAtlas, chart->allowRotate); + XA_PROFILE_END(packChartsFindLocation) + if (firstChartInBitImage && !foundLocation) { + // Chart doesn't fit in an empty, newly allocated bitImage. texelsPerUnit must be too large for the resolution. + XA_ASSERT(true && "chart doesn't fit"); + break; + } + if (resizableAtlas) { + XA_DEBUG_ASSERT(foundLocation); + break; + } + if (foundLocation) + break; + // Chart doesn't fit in the current bitImage, try the next one. + currentAtlas++; + } + // Update brute force start location. + if (options.bruteForce) { + // Reset start location if the chart expanded the atlas. + if (best_x + best_cw > atlasWidth || best_y + best_ch > atlasHeight) { + for (uint32_t j = 0; j < chartStartPositions.size(); j++) + chartStartPositions[j] = Vector2i(0, 0); } - //xaPrint("Add chart at (%d, %d).\n", best_x, best_y); - addChart(&chart_bitmap, w, h, best_x, best_y, best_r); - //float best_angle = 2 * PI * best_r; - // Translate and rotate chart texture coordinates. - halfedge::Mesh *mesh = chart->chartMesh(); - const uint32_t vertexCount = mesh->vertexCount(); - for (uint32_t v = 0; v < vertexCount; v++) { - halfedge::Vertex *vertex = mesh->vertexAt(v); - Vector2 t = vertex->tex; - if (best_r) std::swap(t.x, t.y); - //vertex->tex.x = best_x + t.x * cosf(best_angle) - t.y * sinf(best_angle); - //vertex->tex.y = best_y + t.x * sinf(best_angle) + t.y * cosf(best_angle); - vertex->tex.x = best_x + t.x + 0.5f; - vertex->tex.y = best_y + t.y + 0.5f; - xaAssert(vertex->tex.x >= 0 && vertex->tex.y >= 0); - xaAssert(std::isfinite(vertex->tex.x) && std::isfinite(vertex->tex.y)); + else { + chartStartPositions[currentAtlas] = Vector2i(best_x, best_y); } } - //w -= padding - 1; // Leave one pixel border! - //h -= padding - 1; - m_width = std::max(0, w); - m_height = std::max(0, h); - xaAssert(isAligned(m_width, 4)); - xaAssert(isAligned(m_height, 4)); - if (options.method == PackMethod::ExactResolution) { - texelsPerUnit *= sqrt((options.resolution * options.resolution) / (float)(m_width * m_height)); - if (iteration > 1 && m_width <= options.resolution && m_height <= options.resolution) { - m_width = m_height = options.resolution; - return; + // Update parametric extents. + atlasWidth = max(atlasWidth, best_x + best_cw); + atlasHeight = max(atlasHeight, best_y + best_ch); + if (resizableAtlas) { + // Resize bitImage if necessary. + if (uint32_t(atlasWidth) > m_bitImages[0]->width() || uint32_t(atlasHeight) > m_bitImages[0]->height()) { + m_bitImages[0]->resize(nextPowerOfTwo(uint32_t(atlasWidth)), nextPowerOfTwo(uint32_t(atlasHeight)), false); + if (createImage) + m_atlasImages[0]->resize(m_bitImages[0]->width(), m_bitImages[0]->height()); } - resetUvs(); } else { - return; + atlasWidth = min((int)options.resolution, atlasWidth); + atlasHeight = min((int)options.resolution, atlasHeight); + } + XA_PROFILE_START(packChartsBlit) + addChart(m_bitImages[currentAtlas], &chartBitImage, &chartBitImageRotated, atlasWidth, atlasHeight, best_x, best_y, best_r); + XA_PROFILE_END(packChartsBlit) + if (createImage) { + m_atlasImages[currentAtlas]->addChart(c, best_r == 0 ? &chartBitImageNoPadding : &chartBitImageNoPaddingRotated, false, atlasWidth, atlasHeight, best_x, best_y); + m_atlasImages[currentAtlas]->addChart(c, best_r == 0 ? &chartBitImage : &chartBitImageRotated, true, atlasWidth, atlasHeight, best_x, best_y); + } + chart->atlasIndex = (int32_t)currentAtlas; + // Translate and rotate chart texture coordinates. + for (uint32_t v = 0; v < chart->uniqueVertexCount(); v++) { + Vector2 &texcoord = chart->uniqueVertexAt(v); + Vector2 t = texcoord; + if (best_r) { + XA_DEBUG_ASSERT(chart->allowRotate); + swap(t.x, t.y); + } + texcoord.x = best_x + t.x + 0.5f; + texcoord.y = best_y + t.y + 0.5f; + XA_ASSERT(texcoord.x >= 0 && texcoord.y >= 0); + XA_ASSERT(isFinite(texcoord.x) && isFinite(texcoord.y)); + } + if (progressFunc) { + const int newProgress = int((i + 1) / (float)chartCount * 100.0f); + if (newProgress != progress) { + progress = newProgress; + if (!progressFunc(ProgressCategory::PackCharts, progress, progressUserData)) + return false; + } } } - } - - float computeAtlasUtilization() const - { - const uint32_t w = m_width; - const uint32_t h = m_height; - xaDebugAssert(w <= m_bitmap.width()); - xaDebugAssert(h <= m_bitmap.height()); - uint32_t count = 0; - for (uint32_t y = 0; y < h; y++) { - for (uint32_t x = 0; x < w; x++) { - count += m_bitmap.bitAt(x, y); + if (resizableAtlas) { + m_width = max(0, atlasWidth - (int)options.padding * 2); + m_height = max(0, atlasHeight - (int)options.padding * 2); + } else { + m_width = m_height = options.resolution; + } + XA_PRINT(" %dx%d resolution\n", m_width, m_height); + m_utilization.resize(m_bitImages.size()); + for (uint32_t i = 0; i < m_utilization.size(); i++) { + uint32_t count = 0; + for (uint32_t y = 0; y < m_height; y++) { + for (uint32_t x = 0; x < m_width; x++) + count += m_bitImages[i]->bitAt(x, y); + } + m_utilization[i] = float(count) / (m_width * m_height); + if (m_utilization.size() > 1) { + XA_PRINT(" %u: %f%% utilization\n", i, m_utilization[i] * 100.0f); + } + else { + XA_PRINT(" %f%% utilization\n", m_utilization[i] * 100.0f); } } - return float(count) / (w * h); - } - -private: - void resetUvs() - { - for (uint32_t i = 0; i < m_atlas->chartCount(); i++) { - halfedge::Mesh *mesh = m_atlas->chartAt(i)->chartMesh(); - for (uint32_t j = 0; j < mesh->vertexCount(); j++) - mesh->vertexAt(j)->tex = m_originalChartUvs[i][j]; +#if XA_DEBUG_EXPORT_ATLAS_IMAGES + for (uint32_t i = 0; i < m_atlasImages.size(); i++) { + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_atlas_image%02u.tga", i); + m_atlasImages[i]->writeTga(filename, m_width, m_height); + } +#endif + if (progressFunc && progress != 100) { + if (!progressFunc(ProgressCategory::PackCharts, 100, progressUserData)) + return false; } + return true; } +private: // IC: Brute force is slow, and random may take too much time to converge. We start inserting large charts in a small atlas. Using brute force is lame, because most of the space // is occupied at this point. At the end we have many small charts and a large atlas with sparse holes. Finding those holes randomly is slow. A better approach would be to // start stacking large charts as if they were tetris pieces. Once charts get small try to place them randomly. It may be interesting to try a intermediate strategy, first try // along one axis and then try exhaustively along that axis. - void findChartLocation(int quality, const BitMap *bitmap, Vector2::Arg extents, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, bool blockAligned) - { - int attempts = 256; - if (quality == 1) attempts = 4096; - if (quality == 2) attempts = 2048; - if (quality == 3) attempts = 1024; - if (quality == 4) attempts = 512; - if (quality == 0 || w * h < attempts) { - findChartLocation_bruteForce(bitmap, extents, w, h, best_x, best_y, best_w, best_h, best_r, blockAligned); - } else { - findChartLocation_random(bitmap, extents, w, h, best_x, best_y, best_w, best_h, best_r, attempts, blockAligned); - } + bool findChartLocation(TaskScheduler *taskScheduler, const Vector2i &startPosition, bool bruteForce, const BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, bool blockAligned, bool resizableAtlas, bool allowRotate) + { + const int attempts = 4096; + if (bruteForce || attempts >= w * h) + return findChartLocation_bruteForce(taskScheduler, startPosition, atlasBitImage, chartBitImage, chartBitImageRotated, w, h, best_x, best_y, best_w, best_h, best_r, blockAligned, resizableAtlas, allowRotate); + return findChartLocation_random(atlasBitImage, chartBitImage, chartBitImageRotated, w, h, best_x, best_y, best_w, best_h, best_r, attempts, blockAligned, resizableAtlas, allowRotate); } - void findChartLocation_bruteForce(const BitMap *bitmap, Vector2::Arg /*extents*/, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, bool blockAligned) + bool findChartLocation_bruteForce(TaskScheduler *taskScheduler, const Vector2i &startPosition, const BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, bool blockAligned, bool resizableAtlas, bool allowRotate) { - const int BLOCK_SIZE = 4; + const int stepSize = blockAligned ? 4 : 1; + uint32_t taskCount = 0; + for (int y = startPosition.y; y <= h + stepSize; y += stepSize) + taskCount++; + Array<FindChartLocationBruteForceTaskArgs> taskArgs; + taskArgs.resize(taskCount); + TaskGroupHandle taskGroup = taskScheduler->createTaskGroup(taskCount); + std::atomic<bool> finished(false); // One of the tasks found a location that doesn't expand the atlas. + uint32_t i = 0; + for (int y = startPosition.y; y <= h + stepSize; y += stepSize) { + FindChartLocationBruteForceTaskArgs &args = taskArgs[i]; + args.finished = &finished; + args.startPosition = Vector2i(y == startPosition.y ? startPosition.x : 0, y); + args.atlasBitImage = atlasBitImage; + args.chartBitImage = chartBitImage; + args.chartBitImageRotated = chartBitImageRotated; + args.w = w; + args.h = h; + args.blockAligned = blockAligned; + args.resizableAtlas = resizableAtlas; + args.allowRotate = allowRotate; + Task task; + task.userData = &taskArgs[i]; + task.func = runFindChartLocationBruteForceTask; + taskScheduler->run(taskGroup, task); + i++; + } + taskScheduler->wait(&taskGroup); + // Find the task result with the best metric. int best_metric = INT_MAX; - int step_size = blockAligned ? BLOCK_SIZE : 1; - // Try two different orientations. - for (int r = 0; r < 2; r++) { - int cw = bitmap->width(); - int ch = bitmap->height(); - if (r & 1) std::swap(cw, ch); - for (int y = 0; y <= h + 1; y += step_size) { // + 1 to extend atlas in case atlas full. - for (int x = 0; x <= w + 1; x += step_size) { // + 1 not really necessary here. - // Early out. - int area = std::max(w, x + cw) * std::max(h, y + ch); - //int perimeter = max(w, x+cw) + max(h, y+ch); - int extents = std::max(std::max(w, x + cw), std::max(h, y + ch)); - int metric = extents * extents + area; - if (metric > best_metric) { - continue; - } - if (metric == best_metric && std::max(x, y) >= std::max(*best_x, *best_y)) { - // If metric is the same, pick the one closest to the origin. - continue; - } - if (canAddChart(bitmap, w, h, x, y, r)) { - best_metric = metric; - *best_x = x; - *best_y = y; - *best_w = cw; - *best_h = ch; - *best_r = r; - if (area == w * h) { - // Chart is completely inside, do not look at any other location. - goto done; - } - } - } - } + bool best_insideAtlas = false; + for (i = 0; i < taskCount; i++) { + FindChartLocationBruteForceTaskArgs &args = taskArgs[i]; + if (args.best_metric > best_metric) + continue; + // A location that doesn't expand the atlas is always preferred. + if (!args.best_insideAtlas && best_insideAtlas) + continue; + // If metric is the same, pick the one closest to the origin. + if (args.best_insideAtlas == best_insideAtlas && args.best_metric == best_metric && max(args.best_x, args.best_y) >= max(*best_x, *best_y)) + continue; + best_metric = args.best_metric; + best_insideAtlas = args.best_insideAtlas; + *best_x = args.best_x; + *best_y = args.best_y; + *best_w = args.best_w; + *best_h = args.best_h; + *best_r = args.best_r; } - done: - xaDebugAssert (best_metric != INT_MAX); + return best_metric != INT_MAX; } - void findChartLocation_random(const BitMap *bitmap, Vector2::Arg /*extents*/, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, int minTrialCount, bool blockAligned) + bool findChartLocation_random(const BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int w, int h, int *best_x, int *best_y, int *best_w, int *best_h, int *best_r, int minTrialCount, bool blockAligned, bool resizableAtlas, bool allowRotate) { + bool result = false; const int BLOCK_SIZE = 4; int best_metric = INT_MAX; - for (int i = 0; i < minTrialCount || best_metric == INT_MAX; i++) { - int r = m_rand.getRange(1); - int x = m_rand.getRange(w + 1); // + 1 to extend atlas in case atlas full. We may want to use a higher number to increase probability of extending atlas. - int y = m_rand.getRange(h + 1); // + 1 to extend atlas in case atlas full. + for (int i = 0; i < minTrialCount; i++) { + int cw = chartBitImage->width(); + int ch = chartBitImage->height(); + int r = allowRotate ? m_rand.getRange(1) : 0; + if (r == 1) + swap(cw, ch); + // + 1 to extend atlas in case atlas full. We may want to use a higher number to increase probability of extending atlas. + int xRange = w + 1; + int yRange = h + 1; + if (!resizableAtlas) { + xRange = min(xRange, (int)atlasBitImage->width() - cw); + yRange = min(yRange, (int)atlasBitImage->height() - ch); + } + int x = m_rand.getRange(xRange); + int y = m_rand.getRange(yRange); if (blockAligned) { x = align(x, BLOCK_SIZE); y = align(y, BLOCK_SIZE); + if (!resizableAtlas && (x > (int)atlasBitImage->width() - cw || y > (int)atlasBitImage->height() - ch)) + continue; // Block alignment pushed the chart outside the atlas. } - int cw = bitmap->width(); - int ch = bitmap->height(); - if (r & 1) std::swap(cw, ch); // Early out. - int area = std::max(w, x + cw) * std::max(h, y + ch); + int area = max(w, x + cw) * max(h, y + ch); //int perimeter = max(w, x+cw) + max(h, y+ch); - int extents = std::max(std::max(w, x + cw), std::max(h, y + ch)); + int extents = max(max(w, x + cw), max(h, y + ch)); int metric = extents * extents + area; if (metric > best_metric) { continue; } - if (metric == best_metric && std::min(x, y) > std::min(*best_x, *best_y)) { + if (metric == best_metric && min(x, y) > min(*best_x, *best_y)) { // If metric is the same, pick the one closest to the origin. continue; } - if (canAddChart(bitmap, w, h, x, y, r)) { + if (atlasBitImage->canBlit(r == 1 ? *chartBitImageRotated : *chartBitImage, x, y)) { + result = true; best_metric = metric; *best_x = x; *best_y = y; *best_w = cw; *best_h = ch; - *best_r = r; + *best_r = allowRotate ? r : 0; if (area == w * h) { // Chart is completely inside, do not look at any other location. break; } } } + return result; } - void drawChartBitmapDilate(const Chart *chart, BitMap *bitmap, int padding) - { - const int w = bitmap->width(); - const int h = bitmap->height(); - const Vector2 extents = Vector2(float(w), float(h)); - // Rasterize chart faces, check that all bits are not set. - const uint32_t faceCount = chart->faceCount(); - for (uint32_t f = 0; f < faceCount; f++) { - const halfedge::Face *face = chart->chartMesh()->faceAt(f); - Vector2 vertices[4]; - uint32_t edgeCount = 0; - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - if (edgeCount < 4) { - vertices[edgeCount] = it.vertex()->tex + Vector2(0.5) + Vector2(float(padding), float(padding)); - } - edgeCount++; - } - if (edgeCount == 3) { - raster::drawTriangle(raster::Mode_Antialiased, extents, true, vertices, AtlasPacker::setBitsCallback, bitmap); - } else { - raster::drawQuad(raster::Mode_Antialiased, extents, true, vertices, AtlasPacker::setBitsCallback, bitmap); - } - } - // Expand chart by padding pixels. (dilation) - BitMap tmp(w, h); - for (int i = 0; i < padding; i++) { - tmp.clearAll(); - for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - bool b = bitmap->bitAt(x, y); - if (!b) { - if (x > 0) { - b |= bitmap->bitAt(x - 1, y); - if (y > 0) b |= bitmap->bitAt(x - 1, y - 1); - if (y < h - 1) b |= bitmap->bitAt(x - 1, y + 1); - } - if (y > 0) b |= bitmap->bitAt(x, y - 1); - if (y < h - 1) b |= bitmap->bitAt(x, y + 1); - if (x < w - 1) { - b |= bitmap->bitAt(x + 1, y); - if (y > 0) b |= bitmap->bitAt(x + 1, y - 1); - if (y < h - 1) b |= bitmap->bitAt(x + 1, y + 1); - } - } - if (b) tmp.setBitAt(x, y); - } - } - std::swap(tmp, *bitmap); - } - } - - void drawChartBitmap(const Chart *chart, BitMap *bitmap, const Vector2 &scale, const Vector2 &offset) + void addChart(BitImage *atlasBitImage, const BitImage *chartBitImage, const BitImage *chartBitImageRotated, int atlas_w, int atlas_h, int offset_x, int offset_y, int r) { - const int w = bitmap->width(); - const int h = bitmap->height(); - const Vector2 extents = Vector2(float(w), float(h)); - static const Vector2 pad[4] = { - Vector2(-0.5, -0.5), - Vector2(0.5, -0.5), - Vector2(-0.5, 0.5), - Vector2(0.5, 0.5) - }; - // Rasterize 4 times to add proper padding. - for (int i = 0; i < 4; i++) { - // Rasterize chart faces, check that all bits are not set. - const uint32_t faceCount = chart->chartMesh()->faceCount(); - for (uint32_t f = 0; f < faceCount; f++) { - const halfedge::Face *face = chart->chartMesh()->faceAt(f); - Vector2 vertices[4]; - uint32_t edgeCount = 0; - for (halfedge::Face::ConstEdgeIterator it(face->edges()); !it.isDone(); it.advance()) { - if (edgeCount < 4) { - vertices[edgeCount] = it.vertex()->tex * scale + offset + pad[i]; - xaAssert(ftoi_ceil(vertices[edgeCount].x) >= 0); - xaAssert(ftoi_ceil(vertices[edgeCount].y) >= 0); - xaAssert(ftoi_ceil(vertices[edgeCount].x) <= w); - xaAssert(ftoi_ceil(vertices[edgeCount].y) <= h); - } - edgeCount++; - } - if (edgeCount == 3) { - raster::drawTriangle(raster::Mode_Antialiased, extents, /*enableScissors=*/true, vertices, AtlasPacker::setBitsCallback, bitmap); - } else { - raster::drawQuad(raster::Mode_Antialiased, extents, /*enableScissors=*/true, vertices, AtlasPacker::setBitsCallback, bitmap); - } - } - } - // Expand chart by padding pixels. (dilation) - BitMap tmp(w, h); - tmp.clearAll(); + XA_DEBUG_ASSERT(r == 0 || r == 1); + const BitImage *image = r == 0 ? chartBitImage : chartBitImageRotated; + const int w = image->width(); + const int h = image->height(); for (int y = 0; y < h; y++) { - for (int x = 0; x < w; x++) { - bool b = bitmap->bitAt(x, y); - if (!b) { - if (x > 0) { - b |= bitmap->bitAt(x - 1, y); - if (y > 0) b |= bitmap->bitAt(x - 1, y - 1); - if (y < h - 1) b |= bitmap->bitAt(x - 1, y + 1); - } - if (y > 0) b |= bitmap->bitAt(x, y - 1); - if (y < h - 1) b |= bitmap->bitAt(x, y + 1); - if (x < w - 1) { - b |= bitmap->bitAt(x + 1, y); - if (y > 0) b |= bitmap->bitAt(x + 1, y - 1); - if (y < h - 1) b |= bitmap->bitAt(x + 1, y + 1); - } - } - if (b) tmp.setBitAt(x, y); - } - } - std::swap(tmp, *bitmap); - } - - bool canAddChart(const BitMap *bitmap, int atlas_w, int atlas_h, int offset_x, int offset_y, int r) - { - xaDebugAssert(r == 0 || r == 1); - // Check whether the two bitmaps overlap. - const int w = bitmap->width(); - const int h = bitmap->height(); - if (r == 0) { - for (int y = 0; y < h; y++) { - int yy = y + offset_y; - if (yy >= 0) { - for (int x = 0; x < w; x++) { - int xx = x + offset_x; - if (xx >= 0) { - if (bitmap->bitAt(x, y)) { - if (xx < atlas_w && yy < atlas_h) { - if (m_bitmap.bitAt(xx, yy)) return false; - } - } - } - } - } - } - } else if (r == 1) { - for (int y = 0; y < h; y++) { - int xx = y + offset_x; - if (xx >= 0) { - for (int x = 0; x < w; x++) { - int yy = x + offset_y; - if (yy >= 0) { - if (bitmap->bitAt(x, y)) { - if (xx < atlas_w && yy < atlas_h) { - if (m_bitmap.bitAt(xx, yy)) return false; - } - } - } - } - } - } - } - return true; - } - - void addChart(const BitMap *bitmap, int atlas_w, int atlas_h, int offset_x, int offset_y, int r) - { - xaDebugAssert(r == 0 || r == 1); - // Check whether the two bitmaps overlap. - const int w = bitmap->width(); - const int h = bitmap->height(); - if (r == 0) { - for (int y = 0; y < h; y++) { - int yy = y + offset_y; - if (yy >= 0) { - for (int x = 0; x < w; x++) { - int xx = x + offset_x; - if (xx >= 0) { - if (bitmap->bitAt(x, y)) { - if (xx < atlas_w && yy < atlas_h) { - xaDebugAssert(m_bitmap.bitAt(xx, yy) == false); - m_bitmap.setBitAt(xx, yy); - } - } - } - } - } - } - } else if (r == 1) { - for (int y = 0; y < h; y++) { - int xx = y + offset_x; - if (xx >= 0) { - for (int x = 0; x < w; x++) { - int yy = x + offset_y; - if (yy >= 0) { - if (bitmap->bitAt(x, y)) { - if (xx < atlas_w && yy < atlas_h) { - xaDebugAssert(m_bitmap.bitAt(xx, yy) == false); - m_bitmap.setBitAt(xx, yy); - } + int yy = y + offset_y; + if (yy >= 0) { + for (int x = 0; x < w; x++) { + int xx = x + offset_x; + if (xx >= 0) { + if (image->bitAt(x, y)) { + if (xx < atlas_w && yy < atlas_h) { + XA_DEBUG_ASSERT(atlasBitImage->bitAt(xx, yy) == false); + atlasBitImage->setBitAt(xx, yy); } } } @@ -7350,458 +7475,996 @@ private: } } - static bool setBitsCallback(void *param, int x, int y, Vector3::Arg, Vector3::Arg, Vector3::Arg, float area) + struct DrawTriangleCallbackArgs { - BitMap *bitmap = (BitMap * )param; - if (area > 0.0) { - bitmap->setBitAt(x, y); - } - return true; - } + BitImage *chartBitImage; + BitImage *chartBitImageRotated; + }; - // Compute the convex hull using Graham Scan. - static void convexHull(const std::vector<Vector2> &input, std::vector<Vector2> &output, float epsilon) + static bool drawTriangleCallback(void *param, int x, int y) { - const uint32_t inputCount = input.size(); - std::vector<float> coords(inputCount); - for (uint32_t i = 0; i < inputCount; i++) { - coords[i] = input[i].x; - } - RadixSort radix; - radix.sort(coords); - const uint32_t *ranks = radix.ranks(); - std::vector<Vector2> top; - top.reserve(inputCount); - std::vector<Vector2> bottom; - bottom.reserve(inputCount); - Vector2 P = input[ranks[0]]; - Vector2 Q = input[ranks[inputCount - 1]]; - float topy = std::max(P.y, Q.y); - float boty = std::min(P.y, Q.y); - for (uint32_t i = 0; i < inputCount; i++) { - Vector2 p = input[ranks[i]]; - if (p.y >= boty) top.push_back(p); - } - for (uint32_t i = 0; i < inputCount; i++) { - Vector2 p = input[ranks[inputCount - 1 - i]]; - if (p.y <= topy) bottom.push_back(p); - } - // Filter top list. - output.clear(); - output.push_back(top[0]); - output.push_back(top[1]); - for (uint32_t i = 2; i < top.size(); ) { - Vector2 a = output[output.size() - 2]; - Vector2 b = output[output.size() - 1]; - Vector2 c = top[i]; - float area = triangleArea(a, b, c); - if (area >= -epsilon) { - output.pop_back(); - } - if (area < -epsilon || output.size() == 1) { - output.push_back(c); - i++; - } - } - uint32_t top_count = output.size(); - output.push_back(bottom[1]); - // Filter bottom list. - for (uint32_t i = 2; i < bottom.size(); ) { - Vector2 a = output[output.size() - 2]; - Vector2 b = output[output.size() - 1]; - Vector2 c = bottom[i]; - float area = triangleArea(a, b, c); - if (area >= -epsilon) { - output.pop_back(); - } - if (area < -epsilon || output.size() == top_count) { - output.push_back(c); - i++; - } - } - // Remove duplicate element. - xaDebugAssert(output.front() == output.back()); - output.pop_back(); + auto args = (DrawTriangleCallbackArgs *)param; + args->chartBitImage->setBitAt(x, y); + if (args->chartBitImageRotated) + args->chartBitImageRotated->setBitAt(y, x); + return true; } - // This should compute convex hull and use rotating calipers to find the best box. Currently it uses a brute force method. - static void computeBoundingBox(Chart *chart, Vector2 *majorAxis, Vector2 *minorAxis, Vector2 *minCorner, Vector2 *maxCorner) - { - // Compute list of boundary points. - std::vector<Vector2> points; - points.reserve(16); - halfedge::Mesh *mesh = chart->chartMesh(); - const uint32_t vertexCount = mesh->vertexCount(); - for (uint32_t i = 0; i < vertexCount; i++) { - halfedge::Vertex *vertex = mesh->vertexAt(i); - if (vertex->isBoundary()) { - points.push_back(vertex->tex); - } - } - xaDebugAssert(points.size() > 0); - std::vector<Vector2> hull; - convexHull(points, hull, 0.00001f); - // @@ Ideally I should use rotating calipers to find the best box. Using brute force for now. - float best_area = FLT_MAX; - Vector2 best_min; - Vector2 best_max; - Vector2 best_axis; - const uint32_t hullCount = hull.size(); - for (uint32_t i = 0, j = hullCount - 1; i < hullCount; j = i, i++) { - if (equal(hull[i], hull[j])) { - continue; - } - Vector2 axis = normalize(hull[i] - hull[j], 0.0f); - xaDebugAssert(isFinite(axis)); - // Compute bounding box. - Vector2 box_min(FLT_MAX, FLT_MAX); - Vector2 box_max(-FLT_MAX, -FLT_MAX); - for (uint32_t v = 0; v < hullCount; v++) { - Vector2 point = hull[v]; - float x = dot(axis, point); - if (x < box_min.x) box_min.x = x; - if (x > box_max.x) box_max.x = x; - float y = dot(Vector2(-axis.y, axis.x), point); - if (y < box_min.y) box_min.y = y; - if (y > box_max.y) box_max.y = y; - } - // Compute box area. - float area = (box_max.x - box_min.x) * (box_max.y - box_min.y); - if (area < best_area) { - best_area = area; - best_min = box_min; - best_max = box_max; - best_axis = axis; - } - } - // Consider all points, not only boundary points, in case the input chart is malformed. - for (uint32_t i = 0; i < vertexCount; i++) { - halfedge::Vertex *vertex = mesh->vertexAt(i); - Vector2 point = vertex->tex; - float x = dot(best_axis, point); - if (x < best_min.x) best_min.x = x; - if (x > best_max.x) best_max.x = x; - float y = dot(Vector2(-best_axis.y, best_axis.x), point); - if (y < best_min.y) best_min.y = y; - if (y > best_max.y) best_max.y = y; - } - *majorAxis = best_axis; - *minorAxis = Vector2(-best_axis.y, best_axis.x); - *minCorner = best_min; - *maxCorner = best_max; - } - - Atlas *m_atlas; - BitMap m_bitmap; + Array<AtlasImage *> m_atlasImages; + Array<float> m_utilization; + Array<BitImage *> m_bitImages; + BoundingBox2D m_boundingBox; + Array<Chart *> m_charts; RadixSort m_radix; - uint32_t m_width; - uint32_t m_height; - MTRand m_rand; - std::vector<std::vector<Vector2> > m_originalChartUvs; + uint32_t m_width = 0; + uint32_t m_height = 0; + float m_texelsPerUnit = 0.0f; + KISSRng m_rand; }; -} // namespace param +} // namespace pack } // namespace internal -struct Atlas -{ - internal::param::Atlas atlas; - std::vector<internal::halfedge::Mesh *> heMeshes; - uint32_t width = 0; - uint32_t height = 0; - OutputMesh **outputMeshes = NULL; +struct Context +{ + Atlas atlas; + uint32_t meshCount = 0; + internal::Progress *addMeshProgress = nullptr; + internal::TaskGroupHandle addMeshTaskGroup; + internal::param::Atlas paramAtlas; + ProgressFunc progressFunc = nullptr; + void *progressUserData = nullptr; + internal::TaskScheduler *taskScheduler; + internal::Array<internal::UvMesh *> uvMeshes; + internal::Array<internal::UvMeshInstance *> uvMeshInstances; }; -void SetPrint(PrintFunc print) +Atlas *Create() { - internal::s_print = print; + Context *ctx = XA_NEW(internal::MemTag::Default, Context); + memset(&ctx->atlas, 0, sizeof(Atlas)); + ctx->taskScheduler = XA_NEW(internal::MemTag::Default, internal::TaskScheduler); + return &ctx->atlas; } -Atlas *Create() -{ - Atlas *atlas = new Atlas(); - return atlas; +static void DestroyOutputMeshes(Context *ctx) +{ + if (!ctx->atlas.meshes) + return; + for (int i = 0; i < (int)ctx->atlas.meshCount; i++) { + Mesh &mesh = ctx->atlas.meshes[i]; + for (uint32_t j = 0; j < mesh.chartCount; j++) { + if (mesh.chartArray[j].indexArray) + XA_FREE(mesh.chartArray[j].indexArray); + } + if (mesh.chartArray) + XA_FREE(mesh.chartArray); + if (mesh.vertexArray) + XA_FREE(mesh.vertexArray); + if (mesh.indexArray) + XA_FREE(mesh.indexArray); + } + if (ctx->atlas.meshes) + XA_FREE(ctx->atlas.meshes); + ctx->atlas.meshes = nullptr; } void Destroy(Atlas *atlas) { - xaAssert(atlas); - for (int i = 0; i < (int)atlas->heMeshes.size(); i++) { - delete atlas->heMeshes[i]; - if (atlas->outputMeshes) { - OutputMesh *outputMesh = atlas->outputMeshes[i]; - for (uint32_t j = 0; j < outputMesh->chartCount; j++) - delete [] outputMesh->chartArray[j].indexArray; - delete [] outputMesh->chartArray; - delete [] outputMesh->vertexArray; - delete [] outputMesh->indexArray; - delete outputMesh; - } - } - delete [] atlas->outputMeshes; - delete atlas; + XA_DEBUG_ASSERT(atlas); + Context *ctx = (Context *)atlas; + if (atlas->utilization) + XA_FREE(atlas->utilization); + if (atlas->image) + XA_FREE(atlas->image); + DestroyOutputMeshes(ctx); + if (ctx->addMeshProgress) { + ctx->addMeshProgress->cancel = true; + AddMeshJoin(atlas); // frees addMeshProgress + } + ctx->taskScheduler->~TaskScheduler(); + XA_FREE(ctx->taskScheduler); + for (uint32_t i = 0; i < ctx->uvMeshes.size(); i++) { + internal::UvMesh *mesh = ctx->uvMeshes[i]; + for (uint32_t j = 0; j < mesh->charts.size(); j++) { + mesh->charts[j]->~UvMeshChart(); + XA_FREE(mesh->charts[j]); + } + mesh->~UvMesh(); + XA_FREE(mesh); + } + for (uint32_t i = 0; i < ctx->uvMeshInstances.size(); i++) { + internal::UvMeshInstance *mesh = ctx->uvMeshInstances[i]; + mesh->~UvMeshInstance(); + XA_FREE(mesh); + } + ctx->~Context(); + XA_FREE(ctx); +#if XA_DEBUG_HEAP + internal::ReportLeaks(); +#endif } -static internal::Vector3 DecodePosition(const InputMesh &mesh, uint32_t index) +struct AddMeshTaskArgs { - xaAssert(mesh.vertexPositionData); - return *((const internal::Vector3 *)&((const uint8_t *)mesh.vertexPositionData)[mesh.vertexPositionStride * index]); + Context *ctx; + internal::Mesh *mesh; +}; + +static void runAddMeshTask(void *userData) +{ + XA_PROFILE_START(addMeshThread) + auto args = (AddMeshTaskArgs *)userData; // Responsible for freeing this. + internal::Mesh *mesh = args->mesh; + internal::Progress *progress = args->ctx->addMeshProgress; + if (progress->cancel) + goto cleanup; + { + XA_PROFILE_START(addMeshCreateColocals) + mesh->createColocals(); + XA_PROFILE_END(addMeshCreateColocals) + } + if (progress->cancel) + goto cleanup; + { + XA_PROFILE_START(addMeshCreateFaceGroups) + mesh->createFaceGroups(); + XA_PROFILE_END(addMeshCreateFaceGroups) + } + if (progress->cancel) + goto cleanup; + { + XA_PROFILE_START(addMeshCreateBoundaries) + mesh->createBoundaries(); + XA_PROFILE_END(addMeshCreateBoundaries) + } + if (progress->cancel) + goto cleanup; +#if XA_DEBUG_EXPORT_OBJ_SOURCE_MESHES + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_mesh_%03u.obj", mesh->id()); + FILE *file; + XA_FOPEN(file, filename, "w"); + if (file) { + mesh->writeObjVertices(file); + // groups + uint32_t numGroups = 0; + for (uint32_t i = 0; i < mesh->faceGroupCount(); i++) { + if (mesh->faceGroupAt(i) != UINT32_MAX) + numGroups = internal::max(numGroups, mesh->faceGroupAt(i) + 1); + } + for (uint32_t i = 0; i < numGroups; i++) { + fprintf(file, "o group_%04d\n", i); + fprintf(file, "s off\n"); + for (uint32_t f = 0; f < mesh->faceGroupCount(); f++) { + if (mesh->faceGroupAt(f) == i) + mesh->writeObjFace(file, f); + } + } + fprintf(file, "o group_ignored\n"); + fprintf(file, "s off\n"); + for (uint32_t f = 0; f < mesh->faceGroupCount(); f++) { + if (mesh->faceGroupAt(f) == UINT32_MAX) + mesh->writeObjFace(file, f); + } + mesh->writeObjBoundaryEges(file); + fclose(file); + } +#endif + { + XA_PROFILE_START(addMeshCreateChartGroupsReal) + args->ctx->paramAtlas.addMesh(args->ctx->taskScheduler, mesh); // addMesh is thread safe + XA_PROFILE_END(addMeshCreateChartGroupsReal) + } + if (progress->cancel) + goto cleanup; + progress->value++; + progress->update(); +cleanup: + mesh->~Mesh(); + XA_FREE(mesh); + args->~AddMeshTaskArgs(); + XA_FREE(args); + XA_PROFILE_END(addMeshThread) } -static internal::Vector3 DecodeNormal(const InputMesh &mesh, uint32_t index) +static internal::Vector3 DecodePosition(const MeshDecl &meshDecl, uint32_t index) { - xaAssert(mesh.vertexNormalData); - return *((const internal::Vector3 *)&((const uint8_t *)mesh.vertexNormalData)[mesh.vertexNormalStride * index]); + XA_DEBUG_ASSERT(meshDecl.vertexPositionData); + XA_DEBUG_ASSERT(meshDecl.vertexPositionStride > 0); + return *((const internal::Vector3 *)&((const uint8_t *)meshDecl.vertexPositionData)[meshDecl.vertexPositionStride * index]); } -static internal::Vector2 DecodeUv(const InputMesh &mesh, uint32_t index) +static internal::Vector3 DecodeNormal(const MeshDecl &meshDecl, uint32_t index) { - xaAssert(mesh.vertexUvData); - return *((const internal::Vector2 *)&((const uint8_t *)mesh.vertexUvData)[mesh.vertexUvStride * index]); + XA_DEBUG_ASSERT(meshDecl.vertexNormalData); + XA_DEBUG_ASSERT(meshDecl.vertexNormalStride > 0); + return *((const internal::Vector3 *)&((const uint8_t *)meshDecl.vertexNormalData)[meshDecl.vertexNormalStride * index]); } -static uint32_t DecodeIndex(IndexFormat::Enum format, const void *indexData, uint32_t i) +static internal::Vector2 DecodeUv(const MeshDecl &meshDecl, uint32_t index) { - if (format == IndexFormat::HalfFloat) - return (uint32_t)((const uint16_t *)indexData)[i]; - return ((const uint32_t *)indexData)[i]; + XA_DEBUG_ASSERT(meshDecl.vertexUvData); + XA_DEBUG_ASSERT(meshDecl.vertexUvStride > 0); + return *((const internal::Vector2 *)&((const uint8_t *)meshDecl.vertexUvData)[meshDecl.vertexUvStride * index]); } -static float EdgeLength(internal::Vector3 pos1, internal::Vector3 pos2) +static uint32_t DecodeIndex(IndexFormat::Enum format, const void *indexData, int32_t offset, uint32_t i) { - return internal::length(pos2 - pos1); + XA_DEBUG_ASSERT(indexData); + if (format == IndexFormat::UInt16) + return uint16_t((int32_t)((const uint16_t *)indexData)[i] + offset); + return uint32_t((int32_t)((const uint32_t *)indexData)[i] + offset); } -AddMeshError AddMesh(Atlas *atlas, const InputMesh &mesh, bool useColocalVertices) +AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t meshCountHint) { - xaAssert(atlas); - AddMeshError error; - error.code = AddMeshErrorCode::Success; - error.face = error.index0 = error.index1 = UINT32_MAX; - // Expecting triangle faces. - if ((mesh.indexCount % 3) != 0) - { - error.code = AddMeshErrorCode::InvalidIndexCount; - return error; - } - // Check if any index is out of range. - for (uint32_t j = 0; j < mesh.indexCount; j++) { - const uint32_t index = DecodeIndex(mesh.indexFormat, mesh.indexData, j); - if (index < 0 || index >= mesh.vertexCount) { - error.code = AddMeshErrorCode::IndexOutOfRange; - error.index0 = index; - return error; - } - } - // Build half edge mesh. - internal::halfedge::Mesh *heMesh = new internal::halfedge::Mesh; - std::vector<uint32_t> canonicalMap; - canonicalMap.reserve(mesh.vertexCount); - for (uint32_t i = 0; i < mesh.vertexCount; i++) { - internal::halfedge::Vertex *vertex = heMesh->addVertex(DecodePosition(mesh, i)); - if (mesh.vertexNormalData) - vertex->nor = DecodeNormal(mesh, i); - if (mesh.vertexUvData) - vertex->tex = DecodeUv(mesh, i); - // Link colocals. You probably want to do this more efficiently! Sort by one axis or use a hash or grid. - uint32_t firstColocal = i; - if (useColocalVertices) { - for (uint32_t j = 0; j < i; j++) { - if (vertex->pos != DecodePosition(mesh, j)) - continue; -#if 0 - if (mesh.vertexNormalData && vertex->nor != DecodeNormal(mesh, j)) - continue; + XA_DEBUG_ASSERT(atlas); + if (!atlas) { + XA_PRINT_WARNING("AddMesh: atlas is null.\n"); + return AddMeshError::Error; + } + Context *ctx = (Context *)atlas; + if (!ctx->uvMeshes.isEmpty()) { + XA_PRINT_WARNING("AddMesh: Meshes and UV meshes cannot be added to the same atlas.\n"); + return AddMeshError::Error; + } +#if XA_PROFILE + if (ctx->meshCount == 0) + internal::s_profile.addMeshReal = clock(); #endif - if (mesh.vertexUvData && vertex->tex != DecodeUv(mesh, j)) - continue; - firstColocal = j; - break; - } - } - canonicalMap.push_back(firstColocal); + // Don't know how many times AddMesh will be called, so progress needs to adjusted each time. + if (!ctx->addMeshProgress) { + ctx->addMeshProgress = XA_NEW(internal::MemTag::Default, internal::Progress, ProgressCategory::AddMesh, ctx->progressFunc, ctx->progressUserData, 1); + } + else { + ctx->addMeshProgress->setMaxValue(internal::max(ctx->meshCount + 1, meshCountHint)); } - heMesh->linkColocalsWithCanonicalMap(canonicalMap); - for (uint32_t i = 0; i < mesh.indexCount / 3; i++) { + bool decoded = (meshDecl.indexCount <= 0); + uint32_t indexCount = decoded ? meshDecl.vertexCount : meshDecl.indexCount; + XA_PRINT("Adding mesh %d: %u vertices, %u triangles\n", ctx->meshCount, meshDecl.vertexCount, indexCount / 3); + // Expecting triangle faces. + if ((indexCount % 3) != 0) + return AddMeshError::InvalidIndexCount; + if (!decoded) { + // Check if any index is out of range. + for (uint32_t i = 0; i < indexCount; i++) { + const uint32_t index = DecodeIndex(meshDecl.indexFormat, meshDecl.indexData, meshDecl.indexOffset, i); + if (index >= meshDecl.vertexCount) + return AddMeshError::IndexOutOfRange; + } + } + uint32_t meshFlags = internal::MeshFlags::HasFaceGroups | internal::MeshFlags::HasIgnoredFaces; + if (meshDecl.vertexNormalData) + meshFlags |= internal::MeshFlags::HasNormals; + internal::Mesh *mesh = XA_NEW(internal::MemTag::Mesh, internal::Mesh, meshDecl.epsilon, meshDecl.vertexCount, indexCount / 3, meshFlags, ctx->meshCount); + for (uint32_t i = 0; i < meshDecl.vertexCount; i++) { + internal::Vector3 normal(0.0f); + internal::Vector2 texcoord(0.0f); + if (meshDecl.vertexNormalData) + normal = DecodeNormal(meshDecl, i); + if (meshDecl.vertexUvData) + texcoord = DecodeUv(meshDecl, i); + mesh->addVertex(DecodePosition(meshDecl, i), normal, texcoord); + } + for (uint32_t i = 0; i < indexCount / 3; i++) { uint32_t tri[3]; for (int j = 0; j < 3; j++) - tri[j] = DecodeIndex(mesh.indexFormat, mesh.indexData, i * 3 + j); - // Check for zero length edges. + tri[j] = decoded ? i * 3 + j : DecodeIndex(meshDecl.indexFormat, meshDecl.indexData, meshDecl.indexOffset, i * 3 + j); + bool ignore = false; + // Check for degenerate or zero length edges. for (int j = 0; j < 3; j++) { - const uint32_t edges[6] = { 0, 1, 1, 2, 2, 0 }; - const uint32_t index1 = tri[edges[j * 2 + 0]]; - const uint32_t index2 = tri[edges[j * 2 + 1]]; - const internal::Vector3 pos1 = DecodePosition(mesh, index1); - const internal::Vector3 pos2 = DecodePosition(mesh, index2); - if (EdgeLength(pos1, pos2) <= 0.0f) { - delete heMesh; - error.code = AddMeshErrorCode::ZeroLengthEdge; - error.face = i; - error.index0 = index1; - error.index1 = index2; - return error; - } - } - // Check for zero area faces. - { - const internal::Vector3 a = DecodePosition(mesh, tri[0]); - const internal::Vector3 b = DecodePosition(mesh, tri[1]); - const internal::Vector3 c = DecodePosition(mesh, tri[2]); - const float area = internal::length(internal::cross(b - a, c - a)) * 0.5f; - if (area <= 0.0f) { - delete heMesh; - error.code = AddMeshErrorCode::ZeroAreaFace; - error.face = i; - return error; - } - } - internal::halfedge::Face *face = heMesh->addFace(tri[0], tri[1], tri[2]); - - // -- GODOT start -- - if (!face && heMesh->errorCode == internal::halfedge::Mesh::ErrorCode::AlreadyAddedEdge) { - //there is still hope for this, no reason to not add, at least add as separate - face = heMesh->addUniqueFace(tri[0], tri[1], tri[2]); - } - // -- GODOT end -- - - if (!face) { - if (heMesh->errorCode == internal::halfedge::Mesh::ErrorCode::AlreadyAddedEdge) - error.code = AddMeshErrorCode::AlreadyAddedEdge; - else if (heMesh->errorCode == internal::halfedge::Mesh::ErrorCode::DegenerateColocalEdge) - error.code = AddMeshErrorCode::DegenerateColocalEdge; - else if (heMesh->errorCode == internal::halfedge::Mesh::ErrorCode::DegenerateEdge) - error.code = AddMeshErrorCode::DegenerateEdge; - else if (heMesh->errorCode == internal::halfedge::Mesh::ErrorCode::DuplicateEdge) - error.code = AddMeshErrorCode::DuplicateEdge; - error.face = i; - error.index0 = heMesh->errorIndex0; - error.index1 = heMesh->errorIndex1; - delete heMesh; - return error; - } - if (mesh.faceMaterialData) - face->material = mesh.faceMaterialData[i]; - } - heMesh->linkBoundary(); - atlas->heMeshes.push_back(heMesh); - return error; + const uint32_t index1 = tri[j]; + const uint32_t index2 = tri[(j + 1) % 3]; + if (index1 == index2) { + ignore = true; + XA_PRINT(" Degenerate edge: index %d, index %d\n", index1, index2); + break; + } + const internal::Vector3 &pos1 = mesh->position(index1); + const internal::Vector3 &pos2 = mesh->position(index2); + if (internal::length(pos2 - pos1) <= 0.0f) { + ignore = true; + XA_PRINT(" Zero length edge: index %d position (%g %g %g), index %d position (%g %g %g)\n", index1, pos1.x, pos1.y, pos1.z, index2, pos2.x, pos2.y, pos2.z); + break; + } + } + const internal::Vector3 &a = mesh->position(tri[0]); + const internal::Vector3 &b = mesh->position(tri[1]); + const internal::Vector3 &c = mesh->position(tri[2]); + // Check for zero area faces. Don't bother if a degenerate or zero length edge was already detected. + float area = 0.0f; + if (!ignore) { + area = internal::length(internal::cross(b - a, c - a)) * 0.5f; + if (area <= internal::kAreaEpsilon) { + ignore = true; + XA_PRINT(" Zero area face: %d, indices (%d %d %d), area is %f\n", i, tri[0], tri[1], tri[2], area); + } + } + if (!ignore) { + if (internal::equal(a, b, meshDecl.epsilon) || internal::equal(a, c, meshDecl.epsilon) || internal::equal(b, c, meshDecl.epsilon)) { + ignore = true; + XA_PRINT(" Degenerate face: %d, area is %f\n", i, area); + } + } + if (meshDecl.faceIgnoreData && meshDecl.faceIgnoreData[i]) + ignore = true; + mesh->addFace(tri[0], tri[1], tri[2], ignore); + } + if (ctx->addMeshTaskGroup.value == UINT32_MAX) + ctx->addMeshTaskGroup = ctx->taskScheduler->createTaskGroup(); + AddMeshTaskArgs *taskArgs = XA_NEW(internal::MemTag::Default, AddMeshTaskArgs); // The task frees this. + taskArgs->ctx = ctx; + taskArgs->mesh = mesh; + internal::Task task; + task.userData = taskArgs; + task.func = runAddMeshTask; + ctx->taskScheduler->run(ctx->addMeshTaskGroup, task); + ctx->meshCount++; + return AddMeshError::Success; } -void Generate(Atlas *atlas, CharterOptions charterOptions, PackerOptions packerOptions) -{ - xaAssert(atlas); - xaAssert(packerOptions.texelArea > 0); - // Chart meshes. - for (int i = 0; i < (int)atlas->heMeshes.size(); i++) { - std::vector<uint32_t> uncharted_materials; - atlas->atlas.computeCharts(atlas->heMeshes[i], charterOptions, uncharted_materials); - } - atlas->atlas.parameterizeCharts(); - internal::param::AtlasPacker packer(&atlas->atlas); - packer.packCharts(packerOptions); - //float utilization = return packer.computeAtlasUtilization(); - atlas->width = packer.getWidth(); - atlas->height = packer.getHeight(); - // Build output meshes. - atlas->outputMeshes = new OutputMesh*[atlas->heMeshes.size()]; - for (int i = 0; i < (int)atlas->heMeshes.size(); i++) { - const internal::halfedge::Mesh *heMesh = atlas->heMeshes[i]; - OutputMesh *outputMesh = atlas->outputMeshes[i] = new OutputMesh; - const internal::param::MeshCharts *charts = atlas->atlas.meshAt(i); - // Vertices. - outputMesh->vertexCount = charts->vertexCount(); - outputMesh->vertexArray = new OutputVertex[outputMesh->vertexCount]; - for (uint32_t i = 0; i < charts->chartCount(); i++) { - const internal::param::Chart *chart = charts->chartAt(i); - const uint32_t vertexOffset = charts->vertexCountBeforeChartAt(i); - for (uint32_t v = 0; v < chart->vertexCount(); v++) { - OutputVertex &output_vertex = outputMesh->vertexArray[vertexOffset + v]; - output_vertex.xref = chart->mapChartVertexToOriginalVertex(v); - internal::Vector2 uv = chart->chartMesh()->vertexAt(v)->tex; - output_vertex.uv[0] = uv.x; - output_vertex.uv[1] = uv.y; - } - } - // Indices. - outputMesh->indexCount = heMesh->faceCount() * 3; - outputMesh->indexArray = new uint32_t[outputMesh->indexCount]; - for (uint32_t f = 0; f < heMesh->faceCount(); f++) { - const uint32_t c = charts->faceChartAt(f); - const uint32_t i = charts->faceIndexWithinChartAt(f); - const uint32_t vertexOffset = charts->vertexCountBeforeChartAt(c); - const internal::param::Chart *chart = charts->chartAt(c); - xaDebugAssert(i < chart->chartMesh()->faceCount()); - xaDebugAssert(chart->faceAt(i) == f); - const internal::halfedge::Face *face = chart->chartMesh()->faceAt(i); - const internal::halfedge::Edge *edge = face->edge; - outputMesh->indexArray[3 * f + 0] = vertexOffset + edge->vertex->id; - outputMesh->indexArray[3 * f + 1] = vertexOffset + edge->next->vertex->id; - outputMesh->indexArray[3 * f + 2] = vertexOffset + edge->next->next->vertex->id; - } - // Charts. - outputMesh->chartCount = charts->chartCount(); - outputMesh->chartArray = new OutputChart[outputMesh->chartCount]; - for (uint32_t i = 0; i < charts->chartCount(); i++) { - OutputChart *outputChart = &outputMesh->chartArray[i]; - const internal::param::Chart *chart = charts->chartAt(i); - const uint32_t vertexOffset = charts->vertexCountBeforeChartAt(i); - const internal::halfedge::Mesh *mesh = chart->chartMesh(); - outputChart->indexCount = mesh->faceCount() * 3; - outputChart->indexArray = new uint32_t[outputChart->indexCount]; - for (uint32_t j = 0; j < mesh->faceCount(); j++) { - const internal::halfedge::Face *face = mesh->faceAt(j); - const internal::halfedge::Edge *edge = face->edge; - outputChart->indexArray[3 * j + 0] = vertexOffset + edge->vertex->id; - outputChart->indexArray[3 * j + 1] = vertexOffset + edge->next->vertex->id; - outputChart->indexArray[3 * j + 2] = vertexOffset + edge->next->next->vertex->id; +void AddMeshJoin(Atlas *atlas) +{ + XA_DEBUG_ASSERT(atlas); + if (!atlas) { + XA_PRINT_WARNING("AddMeshJoin: atlas is null.\n"); + return; + } + Context *ctx = (Context *)atlas; + if (!ctx->addMeshProgress) + return; + ctx->taskScheduler->wait(&ctx->addMeshTaskGroup); + ctx->addMeshProgress->~Progress(); + XA_FREE(ctx->addMeshProgress); + ctx->addMeshProgress = nullptr; +#if XA_PROFILE + XA_PRINT("Added %u meshes\n", ctx->meshCount); + internal::s_profile.addMeshReal = clock() - internal::s_profile.addMeshReal; +#endif + XA_PROFILE_PRINT_AND_RESET(" Total (real): ", addMeshReal) + XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", addMeshThread) + XA_PROFILE_PRINT_AND_RESET(" Create colocals: ", addMeshCreateColocals) + XA_PROFILE_PRINT_AND_RESET(" Create face groups: ", addMeshCreateFaceGroups) + XA_PROFILE_PRINT_AND_RESET(" Create boundaries: ", addMeshCreateBoundaries) + XA_PROFILE_PRINT_AND_RESET(" Create chart groups (real): ", addMeshCreateChartGroupsReal) + XA_PROFILE_PRINT_AND_RESET(" Create chart groups (thread): ", addMeshCreateChartGroupsThread) + XA_PRINT_MEM_USAGE +} + +struct EdgeKey +{ + EdgeKey() {} + EdgeKey(const EdgeKey &k) : v0(k.v0), v1(k.v1) {} + EdgeKey(uint32_t v0, uint32_t v1) : v0(v0), v1(v1) {} + + void operator=(const EdgeKey &k) + { + v0 = k.v0; + v1 = k.v1; + } + bool operator==(const EdgeKey &k) const + { + return v0 == k.v0 && v1 == k.v1; + } + + uint32_t v0; + uint32_t v1; +}; + +AddMeshError::Enum AddUvMesh(Atlas *atlas, const UvMeshDecl &decl) +{ + XA_DEBUG_ASSERT(atlas); + if (!atlas) { + XA_PRINT_WARNING("AddUvMesh: atlas is null.\n"); + return AddMeshError::Error; + } + Context *ctx = (Context *)atlas; + if (ctx->meshCount > 0) { + XA_PRINT_WARNING("AddUvMesh: Meshes and UV meshes cannot be added to the same atlas.\n"); + return AddMeshError::Error; + } + const bool decoded = (decl.indexCount <= 0); + const uint32_t indexCount = decoded ? decl.vertexCount : decl.indexCount; + XA_PRINT("Adding UV mesh %d: %u vertices, %u triangles\n", ctx->uvMeshes.size(), decl.vertexCount, indexCount / 3); + // Expecting triangle faces. + if ((indexCount % 3) != 0) + return AddMeshError::InvalidIndexCount; + if (!decoded) { + // Check if any index is out of range. + for (uint32_t i = 0; i < indexCount; i++) { + const uint32_t index = DecodeIndex(decl.indexFormat, decl.indexData, decl.indexOffset, i); + if (index >= decl.vertexCount) + return AddMeshError::IndexOutOfRange; + } + } + internal::UvMeshInstance *meshInstance = XA_NEW(internal::MemTag::Default, internal::UvMeshInstance); + meshInstance->texcoords.resize(decl.vertexCount); + for (uint32_t i = 0; i < decl.vertexCount; i++) + meshInstance->texcoords[i] = *((const internal::Vector2 *)&((const uint8_t *)decl.vertexUvData)[decl.vertexStride * i]); + meshInstance->rotateCharts = decl.rotateCharts; + // See if this is an instance of an already existing mesh. + internal::UvMesh *mesh = nullptr; + for (uint32_t m = 0; m < ctx->uvMeshes.size(); m++) { + if (memcmp(&ctx->uvMeshes[m]->decl, &decl, sizeof(UvMeshDecl)) == 0) { + meshInstance->mesh = mesh = ctx->uvMeshes[m]; + break; + } + } + if (!mesh) { + // Copy geometry to mesh. + meshInstance->mesh = mesh = XA_NEW(internal::MemTag::Default, internal::UvMesh); + mesh->decl = decl; + mesh->indices.resize(decl.indexCount); + for (uint32_t i = 0; i < indexCount; i++) + mesh->indices[i] = decoded ? i : DecodeIndex(decl.indexFormat, decl.indexData, decl.indexOffset, i); + mesh->vertexToChartMap.resize(decl.vertexCount); + for (uint32_t i = 0; i < mesh->vertexToChartMap.size(); i++) + mesh->vertexToChartMap[i] = UINT32_MAX; + // Calculate charts (incident faces). + internal::HashMap<internal::Vector2, uint32_t> vertexToFaceMap(internal::MemTag::Default, indexCount); + const uint32_t faceCount = indexCount / 3; + for (uint32_t i = 0; i < indexCount; i++) + vertexToFaceMap.add(meshInstance->texcoords[mesh->indices[i]], i / 3); + internal::BitArray faceAssigned(faceCount); + faceAssigned.clearAll(); + internal::Array<uint32_t> chartFaces; + for (uint32_t f = 0; f < faceCount; f++) { + if (faceAssigned.bitAt(f)) + continue; + // Found an unassigned face, create a new chart. + internal::UvMeshChart *chart = XA_NEW(internal::MemTag::Default, internal::UvMeshChart); + chart->material = decl.faceMaterialData ? decl.faceMaterialData[f] : 0; + // Walk incident faces and assign them to the chart. + faceAssigned.setBitAt(f); + chartFaces.clear(); + chartFaces.push_back(f); + for (;;) { + bool newFaceAssigned = false; + const uint32_t faceCount2 = chartFaces.size(); + for (uint32_t f2 = 0; f2 < faceCount2; f2++) { + const uint32_t face = chartFaces[f2]; + for (uint32_t i = 0; i < 3; i++) { + const internal::Vector2 &texcoord = meshInstance->texcoords[meshInstance->mesh->indices[face * 3 + i]]; + uint32_t mapFaceIndex = vertexToFaceMap.get(texcoord); + while (mapFaceIndex != UINT32_MAX) { + const uint32_t face2 = vertexToFaceMap.value(mapFaceIndex); + // Materials must match. + if (!faceAssigned.bitAt(face2) && (!decl.faceMaterialData || decl.faceMaterialData[face] == decl.faceMaterialData[face2])) { + faceAssigned.setBitAt(face2); + chartFaces.push_back(face2); + newFaceAssigned = true; + } + mapFaceIndex = vertexToFaceMap.getNext(mapFaceIndex); + } + } + } + if (!newFaceAssigned) + break; + } + for (uint32_t i = 0; i < chartFaces.size(); i++) { + for (uint32_t j = 0; j < 3; j++) { + const uint32_t vertex = meshInstance->mesh->indices[chartFaces[i] * 3 + j]; + chart->indices.push_back(vertex); + mesh->vertexToChartMap[vertex] = mesh->charts.size(); + } + } + mesh->charts.push_back(chart); + } + ctx->uvMeshes.push_back(mesh); + } else { + XA_PRINT(" instance of a previous UV mesh\n"); + } + XA_PRINT(" %u charts\n", meshInstance->mesh->charts.size()); + ctx->uvMeshInstances.push_back(meshInstance); + return AddMeshError::Success; +} + +void ComputeCharts(Atlas *atlas, ChartOptions chartOptions) +{ + if (!atlas) { + XA_PRINT_WARNING("ComputeCharts: atlas is null.\n"); + return; + } + Context *ctx = (Context *)atlas; + if (!ctx->uvMeshInstances.isEmpty()) { + XA_PRINT_WARNING("ComputeCharts: This function should not be called with UV meshes.\n"); + return; + } + AddMeshJoin(atlas); + if (ctx->meshCount == 0) { + XA_PRINT_WARNING("ComputeCharts: No meshes. Call AddMesh first.\n"); + return; + } + XA_PRINT("Computing charts\n"); + uint32_t chartCount = 0, chartsWithHolesCount = 0, holesCount = 0, chartsWithTJunctionsCount = 0, tJunctionsCount = 0; + XA_PROFILE_START(computeChartsReal) + if (!ctx->paramAtlas.computeCharts(ctx->taskScheduler, chartOptions, ctx->progressFunc, ctx->progressUserData)) { + XA_PRINT(" Cancelled by user\n"); + return; + } + XA_PROFILE_END(computeChartsReal) + // Count charts and print warnings. + for (uint32_t i = 0; i < ctx->meshCount; i++) { + for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) { + const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j); + if (chartGroup->isVertexMap()) + continue; + for (uint32_t k = 0; k < chartGroup->chartCount(); k++) { + const internal::param::Chart *chart = chartGroup->chartAt(k); + if (chart->warningFlags() & internal::param::ChartWarningFlags::CloseHolesFailed) + XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): failed to close holes\n", chartCount, i, j, k); + if (chart->warningFlags() & internal::param::ChartWarningFlags::FixTJunctionsDuplicatedEdge) + XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): fixing t-junctions created non-manifold geometry\n", chartCount, i, j, k); + if (chart->warningFlags() & internal::param::ChartWarningFlags::FixTJunctionsFailed) + XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): fixing t-junctions failed\n", chartCount, i, j, k); + if (chart->warningFlags() & internal::param::ChartWarningFlags::TriangulateDuplicatedEdge) + XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): triangulation created non-manifold geometry\n", chartCount, i, j, k); + if (!chart->isDisk()) + XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u): doesn't have disk topology\n", chartCount, i, j, k); + holesCount += chart->closedHolesCount(); + if (chart->closedHolesCount() > 0) + chartsWithHolesCount++; + tJunctionsCount += chart->fixedTJunctionsCount(); + if (chart->fixedTJunctionsCount() > 0) + chartsWithTJunctionsCount++; + chartCount++; + } + } + } + if (holesCount > 0) + XA_PRINT(" Closed %u holes in %u charts\n", holesCount, chartsWithHolesCount); + if (tJunctionsCount > 0) + XA_PRINT(" Fixed %u t-junctions in %u charts\n", tJunctionsCount, chartsWithTJunctionsCount); + XA_PRINT(" %u charts\n", chartCount); + XA_PROFILE_PRINT_AND_RESET(" Total (real): ", computeChartsReal) + XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", computeChartsThread) + XA_PROFILE_PRINT_AND_RESET(" Atlas builder: ", atlasBuilder) + XA_PROFILE_PRINT_AND_RESET(" Init: ", atlasBuilderInit) + XA_PROFILE_PRINT_AND_RESET(" Create initial charts: ", atlasBuilderCreateInitialCharts) + XA_PROFILE_PRINT_AND_RESET(" Grow charts: ", atlasBuilderGrowCharts) + XA_PROFILE_PRINT_AND_RESET(" Merge charts: ", atlasBuilderMergeCharts) + XA_PROFILE_PRINT_AND_RESET(" Create chart meshes (real): ", createChartMeshesReal) + XA_PROFILE_PRINT_AND_RESET(" Create chart meshes (thread): ", createChartMeshesThread) + XA_PROFILE_PRINT_AND_RESET(" Fix t-junctions: ", fixChartMeshTJunctions) + XA_PROFILE_PRINT_AND_RESET(" Close holes: ", closeChartMeshHoles) + XA_PRINT_MEM_USAGE +} + +void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func) +{ + if (!atlas) { + XA_PRINT_WARNING("ParameterizeCharts: atlas is null.\n"); + return; + } + Context *ctx = (Context *)atlas; + if (!ctx->uvMeshInstances.isEmpty()) { + XA_PRINT_WARNING("ParameterizeCharts: This function should not be called with UV meshes.\n"); + return; + } + if (!ctx->paramAtlas.chartsComputed()) { + XA_PRINT_WARNING("ParameterizeCharts: ComputeCharts must be called first.\n"); + return; + } + atlas->atlasCount = 0; + atlas->height = 0; + atlas->texelsPerUnit = 0; + atlas->width = 0; + if (atlas->utilization) { + XA_FREE(atlas->utilization); + atlas->utilization = nullptr; + } + if (atlas->image) { + XA_FREE(atlas->image); + atlas->image = nullptr; + } + DestroyOutputMeshes(ctx); + XA_PRINT("Parameterizing charts\n"); + XA_PROFILE_START(parameterizeChartsReal) + if (!ctx->paramAtlas.parameterizeCharts(ctx->taskScheduler, func, ctx->progressFunc, ctx->progressUserData)) { + XA_PRINT(" Cancelled by user\n"); + return; + } + XA_PROFILE_END(parameterizeChartsReal) + uint32_t chartCount = 0, orthoChartsCount = 0, planarChartsCount = 0, chartsAddedCount = 0, chartsDeletedCount = 0; + for (uint32_t i = 0; i < ctx->meshCount; i++) { + for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) { + const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j); + if (chartGroup->isVertexMap()) + continue; + for (uint32_t k = 0; k < chartGroup->chartCount(); k++) { + const internal::param::Chart *chart = chartGroup->chartAt(k); + if (chart->isPlanar()) + planarChartsCount++; + else if (chart->isOrtho()) + orthoChartsCount++; + } + chartCount += chartGroup->chartCount(); + chartsAddedCount += chartGroup->paramAddedChartsCount(); + chartsDeletedCount += chartGroup->paramDeletedChartsCount(); + } + } + XA_PRINT(" %u planar charts, %u ortho charts, %u other\n", planarChartsCount, orthoChartsCount, chartCount - (planarChartsCount + orthoChartsCount)); + if (chartsDeletedCount > 0) { + XA_PRINT(" %u charts deleted due to invalid parameterizations, %u new charts added\n", chartsDeletedCount, chartsAddedCount); + XA_PRINT(" %u charts\n", ctx->paramAtlas.chartCount()); + } + uint32_t chartIndex = 0, invalidParamCount = 0; + for (uint32_t i = 0; i < ctx->meshCount; i++) { + for (uint32_t j = 0; j < ctx->paramAtlas.chartGroupCount(i); j++) { + const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, j); + if (chartGroup->isVertexMap()) + continue; + for (uint32_t k = 0; k < chartGroup->chartCount(); k++) { + const internal::param::Chart *chart = chartGroup->chartAt(k); + const internal::param::ParameterizationQuality &quality = chart->paramQuality(); +#if XA_DEBUG_EXPORT_OBJ_CHARTS_AFTER_PARAMETERIZATION + { + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_chart_%03u_after_parameterization.obj", chartIndex); + chart->unifiedMesh()->writeObjFile(filename); + } +#endif + bool invalid = false; + if (quality.boundaryIntersection) { + invalid = true; + XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, self-intersecting boundary.\n", chartIndex, i, j, k, chart->isPlanar() ? "planar" : chart->isOrtho() ? "ortho" : "other"); + } + if (quality.flippedTriangleCount > 0) { + invalid = true; + XA_PRINT_WARNING(" Chart %u (mesh %u, group %u, id %u) (%s): invalid parameterization, %u / %u flipped triangles.\n", chartIndex, i, j, k, chart->isPlanar() ? "planar" : chart->isOrtho() ? "ortho" : "other", quality.flippedTriangleCount, quality.totalTriangleCount); + } + if (invalid) + invalidParamCount++; +#if XA_DEBUG_EXPORT_OBJ_INVALID_PARAMETERIZATION + if (invalid) { + char filename[256]; + XA_SPRINTF(filename, sizeof(filename), "debug_chart_%03u_invalid_parameterization.obj", chartIndex); + const internal::Mesh *mesh = chart->unifiedMesh(); + FILE *file; + XA_FOPEN(file, filename, "w"); + if (file) { + mesh->writeObjVertices(file); + fprintf(file, "s off\n"); + fprintf(file, "o object\n"); + for (uint32_t f = 0; f < mesh->faceCount(); f++) + mesh->writeObjFace(file, f); + if (!chart->paramFlippedFaces().isEmpty()) { + fprintf(file, "o flipped_faces\n"); + for (uint32_t f = 0; f < chart->paramFlippedFaces().size(); f++) + mesh->writeObjFace(file, chart->paramFlippedFaces()[f]); + } + mesh->writeObjBoundaryEges(file); + mesh->writeObjLinkedBoundaries(file); + fclose(file); + } + } +#endif + chartIndex++; } } } + if (invalidParamCount > 0) + XA_PRINT_WARNING(" %u charts with invalid parameterizations\n", invalidParamCount); + XA_PROFILE_PRINT_AND_RESET(" Total (real): ", parameterizeChartsReal) + XA_PROFILE_PRINT_AND_RESET(" Total (thread): ", parameterizeChartsThread) + XA_PROFILE_PRINT_AND_RESET(" Orthogonal: ", parameterizeChartsOrthogonal) + XA_PROFILE_PRINT_AND_RESET(" LSCM: ", parameterizeChartsLSCM) + XA_PROFILE_PRINT_AND_RESET(" Evaluate quality: ", parameterizeChartsEvaluateQuality) + XA_PRINT_MEM_USAGE } -uint32_t GetWidth(const Atlas *atlas) +void PackCharts(Atlas *atlas, PackOptions packOptions) { - xaAssert(atlas); - return atlas->width; + // Validate arguments and context state. + if (!atlas) { + XA_PRINT_WARNING("PackCharts: atlas is null.\n"); + return; + } + Context *ctx = (Context *)atlas; + if (ctx->meshCount == 0 && ctx->uvMeshInstances.isEmpty()) { + XA_PRINT_WARNING("PackCharts: No meshes. Call AddMesh or AddUvMesh first.\n"); + return; + } + if (ctx->uvMeshInstances.isEmpty()) { + if (!ctx->paramAtlas.chartsComputed()) { + XA_PRINT_WARNING("PackCharts: ComputeCharts must be called first.\n"); + return; + } + if (!ctx->paramAtlas.chartsParameterized()) { + XA_PRINT_WARNING("PackCharts: ParameterizeCharts must be called first.\n"); + return; + } + } + if (packOptions.texelsPerUnit < 0.0f) { + XA_PRINT_WARNING("PackCharts: PackOptions::texelsPerUnit is negative.\n"); + packOptions.texelsPerUnit = 0.0f; + } + // Cleanup atlas. + DestroyOutputMeshes(ctx); + if (atlas->utilization) { + XA_FREE(atlas->utilization); + atlas->utilization = nullptr; + } + if (atlas->image) { + XA_FREE(atlas->image); + atlas->image = nullptr; + } + atlas->meshCount = 0; + // Pack charts. + internal::pack::Atlas packAtlas; + if (!ctx->uvMeshInstances.isEmpty()) { + for (uint32_t i = 0; i < ctx->uvMeshInstances.size(); i++) + packAtlas.addUvMeshCharts(ctx->uvMeshInstances[i]); + } + else if (ctx->paramAtlas.chartCount() > 0) { + ctx->paramAtlas.restoreOriginalChartTexcoords(); + for (uint32_t i = 0; i < ctx->paramAtlas.chartCount(); i++) + packAtlas.addChart(ctx->paramAtlas.chartAt(i)); + } + XA_PROFILE_START(packCharts) + if (!packAtlas.packCharts(ctx->taskScheduler, packOptions, ctx->progressFunc, ctx->progressUserData)) + return; + XA_PROFILE_END(packCharts) + // Populate atlas object with pack results. + atlas->atlasCount = packAtlas.getNumAtlases(); + atlas->chartCount = packAtlas.getChartCount(); + atlas->width = packAtlas.getWidth(); + atlas->height = packAtlas.getHeight(); + atlas->texelsPerUnit = packAtlas.getTexelsPerUnit(); + if (atlas->atlasCount > 0) { + atlas->utilization = XA_ALLOC_ARRAY(internal::MemTag::Default, float, atlas->atlasCount); + for (uint32_t i = 0; i < atlas->atlasCount; i++) + atlas->utilization[i] = packAtlas.getUtilization(i); + } + if (packOptions.createImage) { + atlas->image = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, atlas->atlasCount * atlas->width * atlas->height); + for (uint32_t i = 0; i < atlas->atlasCount; i++) + packAtlas.getImages()[i]->copyTo(&atlas->image[atlas->width * atlas->height * i], atlas->width, atlas->height); + } + XA_PROFILE_PRINT_AND_RESET(" Total: ", packCharts) + XA_PROFILE_PRINT_AND_RESET(" Rasterize: ", packChartsRasterize) + XA_PROFILE_PRINT_AND_RESET(" Dilate (padding): ", packChartsDilate) + XA_PROFILE_PRINT_AND_RESET(" Find location (real): ", packChartsFindLocation) + XA_PROFILE_PRINT_AND_RESET(" Find location (thread): ", packChartsFindLocationThread) + XA_PROFILE_PRINT_AND_RESET(" Blit: ", packChartsBlit) + XA_PRINT_MEM_USAGE + XA_PRINT("Building output meshes\n"); + int progress = 0; + if (ctx->progressFunc) { + if (!ctx->progressFunc(ProgressCategory::BuildOutputMeshes, 0, ctx->progressUserData)) + return; + } + if (ctx->uvMeshInstances.isEmpty()) + atlas->meshCount = ctx->meshCount; + else + atlas->meshCount = ctx->uvMeshInstances.size(); + atlas->meshes = XA_ALLOC_ARRAY(internal::MemTag::Default, Mesh, atlas->meshCount); + memset(atlas->meshes, 0, sizeof(Mesh) * atlas->meshCount); + if (ctx->uvMeshInstances.isEmpty()) { + uint32_t chartIndex = 0; + for (uint32_t i = 0; i < ctx->meshCount; i++) { + Mesh &outputMesh = atlas->meshes[i]; + // Count and alloc arrays. Ignore vertex mapped chart groups in Mesh::chartCount, since they're ignored faces. + for (uint32_t cg = 0; cg < ctx->paramAtlas.chartGroupCount(i); cg++) { + const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, cg); + if (chartGroup->isVertexMap()) { + outputMesh.vertexCount += chartGroup->mesh()->vertexCount(); + outputMesh.indexCount += chartGroup->mesh()->faceCount() * 3; + } else { + for (uint32_t c = 0; c < chartGroup->chartCount(); c++) { + const internal::param::Chart *chart = chartGroup->chartAt(c); + outputMesh.vertexCount += chart->mesh()->vertexCount(); + outputMesh.indexCount += chart->mesh()->faceCount() * 3; + outputMesh.chartCount++; + } + } + } + outputMesh.vertexArray = XA_ALLOC_ARRAY(internal::MemTag::Default, Vertex, outputMesh.vertexCount); + outputMesh.indexArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputMesh.indexCount); + outputMesh.chartArray = XA_ALLOC_ARRAY(internal::MemTag::Default, Chart, outputMesh.chartCount); + XA_PRINT(" mesh %u: %u vertices, %u triangles, %u charts\n", i, outputMesh.vertexCount, outputMesh.indexCount / 3, outputMesh.chartCount); + // Copy mesh data. + uint32_t firstVertex = 0; + uint32_t meshChartIndex = 0; + for (uint32_t cg = 0; cg < ctx->paramAtlas.chartGroupCount(i); cg++) { + const internal::param::ChartGroup *chartGroup = ctx->paramAtlas.chartGroupAt(i, cg); + if (chartGroup->isVertexMap()) { + const internal::Mesh *mesh = chartGroup->mesh(); + // Vertices. + for (uint32_t v = 0; v < mesh->vertexCount(); v++) { + Vertex &vertex = outputMesh.vertexArray[firstVertex + v]; + vertex.atlasIndex = -1; + vertex.chartIndex = -1; + vertex.uv[0] = vertex.uv[1] = 0.0f; + vertex.xref = chartGroup->mapVertexToSourceVertex(v); + } + // Indices. + for (uint32_t f = 0; f < mesh->faceCount(); f++) { + const uint32_t indexOffset = chartGroup->mapFaceToSourceFace(f) * 3; + for (uint32_t j = 0; j < 3; j++) + outputMesh.indexArray[indexOffset + j] = firstVertex + mesh->vertexAt(f * 3 + j); + } + firstVertex += mesh->vertexCount(); + } else { + for (uint32_t c = 0; c < chartGroup->chartCount(); c++) { + const internal::param::Chart *chart = chartGroup->chartAt(c); + const internal::Mesh *mesh = chart->mesh(); + // Vertices. + for (uint32_t v = 0; v < mesh->vertexCount(); v++) { + Vertex &vertex = outputMesh.vertexArray[firstVertex + v]; + vertex.atlasIndex = packAtlas.getChart(chartIndex)->atlasIndex; + XA_DEBUG_ASSERT(vertex.atlasIndex >= 0); + vertex.chartIndex = (int32_t)chartIndex; + const internal::Vector2 &uv = mesh->texcoord(v); + vertex.uv[0] = internal::max(0.0f, uv.x); + vertex.uv[1] = internal::max(0.0f, uv.y); + vertex.xref = chartGroup->mapVertexToSourceVertex(chart->mapChartVertexToOriginalVertex(v)); + } + // Indices. + for (uint32_t f = 0; f < mesh->faceCount(); f++) { + const uint32_t indexOffset = chartGroup->mapFaceToSourceFace(chart->mapFaceToSourceFace(f)) * 3; + for (uint32_t j = 0; j < 3; j++) + outputMesh.indexArray[indexOffset + j] = firstVertex + mesh->vertexAt(f * 3 + j); + } + // Charts. + Chart *outputChart = &outputMesh.chartArray[meshChartIndex]; + const int32_t atlasIndex = packAtlas.getChart(chartIndex)->atlasIndex; + XA_DEBUG_ASSERT(atlasIndex >= 0); + outputChart->atlasIndex = (uint32_t)atlasIndex; + outputChart->flags = 0; + if (chart->paramQuality().boundaryIntersection || chart->paramQuality().flippedTriangleCount > 0) + outputChart->flags |= ChartFlags::Invalid; + outputChart->indexCount = mesh->faceCount() * 3; + outputChart->indexArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputChart->indexCount); + for (uint32_t f = 0; f < mesh->faceCount(); f++) { + for (uint32_t j = 0; j < 3; j++) + outputChart->indexArray[3 * f + j] = firstVertex + mesh->vertexAt(f * 3 + j); + } + outputChart->material = 0; + meshChartIndex++; + chartIndex++; + firstVertex += chart->mesh()->vertexCount(); + } + } + } + XA_DEBUG_ASSERT(outputMesh.vertexCount == firstVertex); + XA_DEBUG_ASSERT(outputMesh.chartCount == meshChartIndex); + if (ctx->progressFunc) { + const int newProgress = int((i + 1) / (float)atlas->meshCount * 100.0f); + if (newProgress != progress) { + progress = newProgress; + if (!ctx->progressFunc(ProgressCategory::BuildOutputMeshes, progress, ctx->progressUserData)) + return; + } + } + } + } else { + uint32_t chartIndex = 0; + for (uint32_t m = 0; m < ctx->uvMeshInstances.size(); m++) { + Mesh &outputMesh = atlas->meshes[m]; + const internal::UvMeshInstance *mesh = ctx->uvMeshInstances[m]; + // Alloc arrays. + outputMesh.vertexCount = mesh->texcoords.size(); + outputMesh.indexCount = mesh->mesh->indices.size(); + outputMesh.chartCount = mesh->mesh->charts.size(); + outputMesh.vertexArray = XA_ALLOC_ARRAY(internal::MemTag::Default, Vertex, outputMesh.vertexCount); + outputMesh.indexArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputMesh.indexCount); + outputMesh.chartArray = XA_ALLOC_ARRAY(internal::MemTag::Default, Chart, outputMesh.chartCount); + XA_PRINT(" UV mesh %u: %u vertices, %u triangles, %u charts\n", m, outputMesh.vertexCount, outputMesh.indexCount / 3, outputMesh.chartCount); + // Copy mesh data. + // Vertices. + for (uint32_t v = 0; v < mesh->texcoords.size(); v++) { + Vertex &vertex = outputMesh.vertexArray[v]; + vertex.uv[0] = mesh->texcoords[v].x; + vertex.uv[1] = mesh->texcoords[v].y; + vertex.xref = v; + const uint32_t meshChartIndex = mesh->mesh->vertexToChartMap[v]; + if (meshChartIndex == UINT32_MAX) { + // Vertex doesn't exist in any chart. + vertex.atlasIndex = -1; + vertex.chartIndex = -1; + } else { + const internal::pack::Chart *chart = packAtlas.getChart(chartIndex + meshChartIndex); + vertex.atlasIndex = chart->atlasIndex; + vertex.chartIndex = (int32_t)chartIndex + meshChartIndex; + } + } + // Indices. + memcpy(outputMesh.indexArray, mesh->mesh->indices.data(), mesh->mesh->indices.size() * sizeof(uint32_t)); + // Charts. + for (uint32_t c = 0; c < mesh->mesh->charts.size(); c++) { + Chart *outputChart = &outputMesh.chartArray[c]; + const internal::pack::Chart *chart = packAtlas.getChart(chartIndex); + XA_DEBUG_ASSERT(chart->atlasIndex >= 0); + outputChart->atlasIndex = (uint32_t)chart->atlasIndex; + outputChart->indexCount = chart->indexCount; + outputChart->indexArray = XA_ALLOC_ARRAY(internal::MemTag::Default, uint32_t, outputChart->indexCount); + outputChart->material = chart->material; + memcpy(outputChart->indexArray, chart->indices, chart->indexCount * sizeof(uint32_t)); + chartIndex++; + } + if (ctx->progressFunc) { + const int newProgress = int((m + 1) / (float)atlas->meshCount * 100.0f); + if (newProgress != progress) { + progress = newProgress; + if (!ctx->progressFunc(ProgressCategory::BuildOutputMeshes, progress, ctx->progressUserData)) + return; + } + } + } + } + if (ctx->progressFunc && progress != 100) + ctx->progressFunc(ProgressCategory::BuildOutputMeshes, 100, ctx->progressUserData); + XA_PRINT_MEM_USAGE +} + +void Generate(Atlas *atlas, ChartOptions chartOptions, ParameterizeFunc paramFunc, PackOptions packOptions) +{ + if (!atlas) { + XA_PRINT_WARNING("Generate: atlas is null.\n"); + return; + } + Context *ctx = (Context *)atlas; + if (!ctx->uvMeshInstances.isEmpty()) { + XA_PRINT_WARNING("Generate: This function should not be called with UV meshes.\n"); + return; + } + if (ctx->meshCount == 0) { + XA_PRINT_WARNING("Generate: No meshes. Call AddMesh first.\n"); + return; + } + ComputeCharts(atlas, chartOptions); + ParameterizeCharts(atlas, paramFunc); + PackCharts(atlas, packOptions); } -uint32_t GetHeight(const Atlas *atlas) +void SetProgressCallback(Atlas *atlas, ProgressFunc progressFunc, void *progressUserData) { - xaAssert(atlas); - return atlas->height; + if (!atlas) { + XA_PRINT_WARNING("SetProgressCallback: atlas is null.\n"); + return; + } + Context *ctx = (Context *)atlas; + ctx->progressFunc = progressFunc; + ctx->progressUserData = progressUserData; } -uint32_t GetNumCharts(const Atlas *atlas) +void SetRealloc(ReallocFunc reallocFunc) { - xaAssert(atlas); - return atlas->atlas.chartCount(); + internal::s_realloc = reallocFunc; +} + +void SetPrint(PrintFunc print, bool verbose) +{ + internal::s_print = print; + internal::s_printVerbose = verbose; } -const OutputMesh * const *GetOutputMeshes(const Atlas *atlas) +const char *StringForEnum(AddMeshError::Enum error) { - xaAssert(atlas); - return atlas->outputMeshes; + if (error == AddMeshError::Error) + return "Unspecified error"; + if (error == AddMeshError::IndexOutOfRange) + return "Index out of range"; + if (error == AddMeshError::InvalidIndexCount) + return "Invalid index count"; + return "Success"; } -const char *StringForEnum(AddMeshErrorCode::Enum error) -{ - if (error == AddMeshErrorCode::AlreadyAddedEdge) - return "already added edge"; - if (error == AddMeshErrorCode::DegenerateColocalEdge) - return "degenerate colocal edge"; - if (error == AddMeshErrorCode::DegenerateEdge) - return "degenerate edge"; - if (error == AddMeshErrorCode::DuplicateEdge) - return "duplicate edge"; - if (error == AddMeshErrorCode::IndexOutOfRange) - return "index out of range"; - if (error == AddMeshErrorCode::InvalidIndexCount) - return "invalid index count"; - if (error == AddMeshErrorCode::ZeroAreaFace) - return "zero area face"; - if (error == AddMeshErrorCode::ZeroLengthEdge) - return "zero length edge"; - return "success"; +const char *StringForEnum(ProgressCategory::Enum category) +{ + if (category == ProgressCategory::AddMesh) + return "Adding mesh(es)"; + if (category == ProgressCategory::ComputeCharts) + return "Computing charts"; + if (category == ProgressCategory::ParameterizeCharts) + return "Parameterizing charts"; + if (category == ProgressCategory::PackCharts) + return "Packing charts"; + if (category == ProgressCategory::BuildOutputMeshes) + return "Building output meshes"; + return ""; } } // namespace xatlas diff --git a/thirdparty/xatlas/xatlas.h b/thirdparty/xatlas/xatlas.h index dbf8ca08c7..c123e800b4 100644 --- a/thirdparty/xatlas/xatlas.h +++ b/thirdparty/xatlas/xatlas.h @@ -1,176 +1,254 @@ -// This code is in the public domain -- castanyo@yahoo.es +/* +MIT License + +Copyright (c) 2018-2019 Jonathan Young + +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. +*/ +/* +thekla_atlas +MIT License +https://github.com/Thekla/thekla_atlas +Copyright (c) 2013 Thekla, Inc +Copyright NVIDIA Corporation 2006 -- Ignacio Castano <icastano@nvidia.com> +*/ #pragma once #ifndef XATLAS_H #define XATLAS_H -#include <float.h> // FLT_MAX -// -- GODOT start -- -#include <limits.h> // INT_MAX, UINT_MAX -// -- GODOT end -- +#include <stdint.h> namespace xatlas { -typedef void (*PrintFunc)(const char *, ...); +struct ChartFlags +{ + enum + { + Invalid = 1 << 0 + }; +}; -struct Atlas; +// A group of connected faces, belonging to a single atlas. +struct Chart +{ + uint32_t atlasIndex; // Sub-atlas index. + uint32_t flags; + uint32_t *indexArray; + uint32_t indexCount; + uint32_t material; +}; -struct CharterOptions +// Output vertex. +struct Vertex { - float proxyFitMetricWeight; - float roundnessMetricWeight; - float straightnessMetricWeight; - float normalSeamMetricWeight; - float textureSeamMetricWeight; - float maxChartArea; - float maxBoundaryLength; - - CharterOptions() - { - // These are the default values we use on The Witness. - proxyFitMetricWeight = 2.0f; - roundnessMetricWeight = 0.01f; - straightnessMetricWeight = 6.0f; - normalSeamMetricWeight = 4.0f; - textureSeamMetricWeight = 0.5f; - /* - proxyFitMetricWeight = 1.0f; - roundnessMetricWeight = 0.1f; - straightnessMetricWeight = 0.25f; - normalSeamMetricWeight = 1.0f; - textureSeamMetricWeight = 0.1f; - */ - maxChartArea = FLT_MAX; - maxBoundaryLength = FLT_MAX; - } + int32_t atlasIndex; // Sub-atlas index. -1 if the vertex doesn't exist in any atlas. + int32_t chartIndex; // -1 if the vertex doesn't exist in any chart. + float uv[2]; // Not normalized - values are in Atlas width and height range. + uint32_t xref; // Index of input vertex from which this output vertex originated. }; -struct PackMethod +// Output mesh. +struct Mesh { - enum Enum - { - TexelArea, // texel_area determines resolution - ApproximateResolution, // guess texel_area to approximately match desired resolution - ExactResolution // run the packer multiple times to exactly match the desired resolution (slow) - }; + Chart *chartArray; + uint32_t chartCount; + uint32_t *indexArray; + uint32_t indexCount; + Vertex *vertexArray; + uint32_t vertexCount; }; -struct PackerOptions +static const uint32_t kImageChartIndexMask = 0x3FFFFFFF; +static const uint32_t kImageHasChartIndexBit = 0x40000000; +static const uint32_t kImageIsPaddingBit = 0x80000000; + +// Empty on creation. Populated after charts are packed. +struct Atlas { - PackMethod::Enum method; - - // 0 - brute force - // 1 - 4096 attempts - // 2 - 2048 - // 3 - 1024 - // 4 - 512 - // other - 256 - // Avoid brute force packing, since it can be unusably slow in some situations. - int quality; - - float texelArea; // This is not really texel area, but 1 / texel width? - uint32_t resolution; - bool blockAlign; // Align charts to 4x4 blocks. - bool conservative; // Pack charts with extra padding. - int padding; - - PackerOptions() - { - method = PackMethod::ApproximateResolution; - quality = 1; - texelArea = 8; - resolution = 512; - blockAlign = false; - conservative = false; - padding = 0; - } + uint32_t width; // Atlas width in texels. + uint32_t height; // Atlas height in texels. + uint32_t atlasCount; // Number of sub-atlases. Equal to 0 unless PackOptions resolution is changed from default (0). + uint32_t chartCount; // Total number of charts in all meshes. + uint32_t meshCount; // Number of output meshes. Equal to the number of times AddMesh was called. + Mesh *meshes; // The output meshes, corresponding to each AddMesh call. + float *utilization; // Normalized atlas texel utilization array. E.g. a value of 0.8 means 20% empty space. atlasCount in length. + float texelsPerUnit; // Equal to PackOptions texelsPerUnit if texelsPerUnit > 0, otherwise an estimated value to match PackOptions resolution. + uint32_t *image; }; -struct AddMeshErrorCode +// Create an empty atlas. +Atlas *Create(); + +void Destroy(Atlas *atlas); + +struct IndexFormat { enum Enum { - Success, - AlreadyAddedEdge, // index0 and index1 are the edge indices - DegenerateColocalEdge, // index0 and index1 are the edge indices - DegenerateEdge, // index0 and index1 are the edge indices - DuplicateEdge, // index0 and index1 are the edge indices - IndexOutOfRange, // index0 is the index - InvalidIndexCount, // not evenly divisible by 3 - expecting triangles - ZeroAreaFace, - ZeroLengthEdge // index0 and index1 are the edge indices + UInt16, + UInt32 }; }; -struct AddMeshError +// Input mesh declaration. +struct MeshDecl { - AddMeshErrorCode::Enum code; - uint32_t face; - uint32_t index0, index1; + uint32_t vertexCount = 0; + const void *vertexPositionData = nullptr; + uint32_t vertexPositionStride = 0; + const void *vertexNormalData = nullptr; // optional + uint32_t vertexNormalStride = 0; // optional + const void *vertexUvData = nullptr; // optional. The input UVs are provided as a hint to the chart generator. + uint32_t vertexUvStride = 0; // optional + uint32_t indexCount = 0; + const void *indexData = nullptr; // optional + int32_t indexOffset = 0; // optional. Add this offset to all indices. + IndexFormat::Enum indexFormat = IndexFormat::UInt16; + + // Optional. indexCount / 3 (triangle count) in length. + // Don't atlas faces set to true. Ignored faces still exist in the output meshes, Vertex uv is set to (0, 0) and Vertex atlasIndex to -1. + const bool *faceIgnoreData = nullptr; + + // Vertex positions within epsilon distance of each other are considered colocal. + float epsilon = 1.192092896e-07F; }; -struct IndexFormat +struct AddMeshError { enum Enum { - HalfFloat, - Float + Success, // No error. + Error, // Unspecified error. + IndexOutOfRange, // An index is >= MeshDecl vertexCount. + InvalidIndexCount // Not evenly divisible by 3 - expecting triangles. }; }; -struct InputMesh -{ - uint32_t vertexCount; - const void *vertexPositionData; - uint32_t vertexPositionStride; - const void *vertexNormalData; // optional - uint32_t vertexNormalStride; // optional - - // optional - // The input UVs are provided as a hint to the chart generator. - const void *vertexUvData; - uint32_t vertexUvStride; +// Add a mesh to the atlas. MeshDecl data is copied, so it can be freed after AddMesh returns. +AddMeshError::Enum AddMesh(Atlas *atlas, const MeshDecl &meshDecl, uint32_t meshCountHint = 0); - uint32_t indexCount; - const void *indexData; - IndexFormat::Enum indexFormat; +// Wait for AddMesh async processing to finish. ComputeCharts / Generate call this internally. +void AddMeshJoin(Atlas *atlas); - // optional. indexCount / 3 in length. - // Charter also uses material boundaries as a hint to cut charts. - const uint16_t *faceMaterialData; +struct UvMeshDecl +{ + uint32_t vertexCount = 0; + uint32_t vertexStride = 0; + const void *vertexUvData = nullptr; + uint32_t indexCount = 0; + const void *indexData = nullptr; // optional + int32_t indexOffset = 0; // optional. Add this offset to all indices. + IndexFormat::Enum indexFormat = IndexFormat::UInt16; + const uint32_t *faceMaterialData = nullptr; // Optional. Faces with different materials won't be assigned to the same chart. Must be indexCount / 3 in length. + bool rotateCharts = true; }; -struct OutputChart +AddMeshError::Enum AddUvMesh(Atlas *atlas, const UvMeshDecl &decl); + +struct ChartOptions { - uint32_t *indexArray; - uint32_t indexCount; + float maxChartArea = 0.0f; // Don't grow charts to be larger than this. 0 means no limit. + float maxBoundaryLength = 0.0f; // Don't grow charts to have a longer boundary than this. 0 means no limit. + + // Weights determine chart growth. Higher weights mean higher cost for that metric. + float proxyFitMetricWeight = 2.0f; // Angle between face and average chart normal. + float roundnessMetricWeight = 0.01f; + float straightnessMetricWeight = 6.0f; + float normalSeamMetricWeight = 4.0f; // If > 1000, normal seams are fully respected. + float textureSeamMetricWeight = 0.5f; + + float maxThreshold = 2.0f; // If total of all metrics * weights > maxThreshold, don't grow chart. Lower values result in more charts. + uint32_t growFaceCount = 32; // Grow this many faces at a time. + uint32_t maxIterations = 1; // Number of iterations of the chart growing and seeding phases. Higher values result in better charts. }; -struct OutputVertex +// Call after all AddMesh calls. Can be called multiple times to recompute charts with different options. +void ComputeCharts(Atlas *atlas, ChartOptions chartOptions = ChartOptions()); + +// Custom parameterization function. texcoords initial values are an orthogonal parameterization. +typedef void (*ParameterizeFunc)(const float *positions, float *texcoords, uint32_t vertexCount, const uint32_t *indices, uint32_t indexCount); + +// Call after ComputeCharts. Can be called multiple times to re-parameterize charts with a different ParameterizeFunc. +void ParameterizeCharts(Atlas *atlas, ParameterizeFunc func = nullptr); + +struct PackOptions { - float uv[2]; - uint32_t xref; // Index of input vertex from which this output vertex originated. + // Slower, but gives the best result. If false, use random chart placement. + bool bruteForce = false; + + // Create Atlas::image + bool createImage = false; + + // Unit to texel scale. e.g. a 1x1 quad with texelsPerUnit of 32 will take up approximately 32x32 texels in the atlas. + // If 0, an estimated value will be calculated to approximately match the given resolution. + // If resolution is also 0, the estimated value will approximately match a 1024x1024 atlas. + float texelsPerUnit = 0.0f; + + // If 0, generate a single atlas with texelsPerUnit determining the final resolution. + // If not 0, and texelsPerUnit is not 0, generate one or more atlases with that exact resolution. + // If not 0, and texelsPerUnit is 0, texelsPerUnit is estimated to approximately match the resolution. + uint32_t resolution = 0; + + // Charts larger than this will be scaled down. + uint32_t maxChartSize = 1024; + + // Align charts to 4x4 blocks. Also improves packing speed, since there are fewer possible chart locations to consider. + bool blockAlign = false; + + // Number of pixels to pad charts with. + uint32_t padding = 0; }; -struct OutputMesh +// Call after ParameterizeCharts. Can be called multiple times to re-pack charts with different options. +void PackCharts(Atlas *atlas, PackOptions packOptions = PackOptions()); + +// Equivalent to calling ComputeCharts, ParameterizeCharts and PackCharts in sequence. Can be called multiple times to regenerate with different options. +void Generate(Atlas *atlas, ChartOptions chartOptions = ChartOptions(), ParameterizeFunc paramFunc = nullptr, PackOptions packOptions = PackOptions()); + +// Progress tracking. +struct ProgressCategory { - OutputChart *chartArray; - uint32_t chartCount; - uint32_t *indexArray; - uint32_t indexCount; - OutputVertex *vertexArray; - uint32_t vertexCount; + enum Enum + { + AddMesh, + ComputeCharts, + ParameterizeCharts, + PackCharts, + BuildOutputMeshes + }; }; -void SetPrint(PrintFunc print); -Atlas *Create(); -void Destroy(Atlas *atlas); -// useColocalVertices - generates fewer charts (good), but is more sensitive to bad geometry. -AddMeshError AddMesh(Atlas *atlas, const InputMesh &mesh, bool useColocalVertices = true); -void Generate(Atlas *atlas, CharterOptions charterOptions = CharterOptions(), PackerOptions packerOptions = PackerOptions()); -uint32_t GetWidth(const Atlas *atlas); -uint32_t GetHeight(const Atlas *atlas); -uint32_t GetNumCharts(const Atlas *atlas); -const OutputMesh * const *GetOutputMeshes(const Atlas *atlas); -const char *StringForEnum(AddMeshErrorCode::Enum error); +// May be called from any thread. Return false to cancel. +typedef bool (*ProgressFunc)(ProgressCategory::Enum category, int progress, void *userData); + +void SetProgressCallback(Atlas *atlas, ProgressFunc progressFunc = nullptr, void *progressUserData = nullptr); + +// Custom memory allocation. +typedef void *(*ReallocFunc)(void *, size_t); +void SetRealloc(ReallocFunc reallocFunc); + +// Custom print function. +typedef int (*PrintFunc)(const char *, ...); +void SetPrint(PrintFunc print, bool verbose); + +// Helper functions for error messages. +const char *StringForEnum(AddMeshError::Enum error); +const char *StringForEnum(ProgressCategory::Enum category); } // namespace xatlas |